2

I am using the following device: https://www.aliexpress.com/item/1005003152097545.html?spm=a2g0o.order_list.order_list_main.119.222218028PapM6

I am trying to make an IoT sound-measurer which will send an SMS, once a sound above a certain threshold has been registered for a certain amount of time. Furthermore, it should send a "pulse" SMS every Nth hour, to ensure, that the module is still alive.

To achieve the SMS-part of this project I am using the TinyGSM module. It worked for a long time, and then suddenly it wouldn't work anymore. The only related event I can think of that happened before this, is that I tried to use the modem on the ESP-IDF, and I tried to use the GPS capabilities of the modem, once again on the ESP-IDF.

I believe this might have had something to do with the settings I had sat on the ESP-IDF, which are defined through the following AT-commands: "AT+CFUN=0\r", "AT+CPIN="1234"\r", "AT+COPS=0,0,"Telenor DK Telenor DK",7\r", "AT+CMGF=0\r".

But after running "AT+CRESET" and "AT+CPOF" and rerunning the Arduino script, I am still stuck with the original error.

The error occurs, when I try to run the sendText method, and the message (With my phone number redacted) is:

AT+CMGF=1
AT+CMGF=1

ERROR
AT+CSCS="GSM"
AT+CSCS="GSM"

ERROR
AT+CMGS="+REDACTED"
AT+CMGS="+REDACTED"

ERROR

The full Arduino code (Where I've once again written REDACTED instead of my actual IRL phone number):

//SIMKORT indstillinger

// Pincode for simkortet
#define GSM_PIN "\"1234\""

// GRPRS credentials for simkortet
const char apn[]  = "Telenor Internet";     //SET TO YOUR APN
const char gprsUser[] = "";
const char gprsPass[] = "";

// Nummer til SMS samt besked
#define SMS_TARGET_NOISY  "+REDACTED"
#define SMS_TARGET_PULSE "+REDACTED"
#define SMS_MESSAGE_NOISY "B"
#define SMS_MESSAGE_PULSE "L"

//Netværks indstillinger fra Debugging 1 koden
#define NETWORK_MODE 2
#define PREFFERED_NETWORK_MODE 2


//Modem indstillinger
#define TINY_GSM_MODEM_SIM7600 //Om du bruger SIM7000 eller SIM7600 (TTGO'en er 7600)
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
#define SerialAT Serial1

//Libraries
#define DUMP_AT_COMMANDS  //Bruges til debugging

#include <TinyGsmClient.h>
#include <SPI.h>
#include <SD.h>
#include <Ticker.h>


#ifdef DUMP_AT_COMMANDS  // if enabled it requires the streamDebugger lib
  #include <StreamDebugger.h>
  StreamDebugger debugger(SerialAT, Serial);
  TinyGsm modem(debugger);
#else
  TinyGsm modem(SerialAT);
#endif

//ESP32-Modem Forbindelser Indstillinger
#define uS_TO_S_FACTOR 1000000ULL  // Conversion factor for micro seconds to seconds

#define UART_BAUD   115200
#define PIN_DTR     25
#define PIN_TX      27
#define PIN_RX      26
#define PWR_PIN     4

//SD Kort forbindelser
#define SD_MISO     2
#define SD_MOSI     15
#define SD_SCLK     14
#define SD_CS       13
#define LED_PIN     12

int counter, lastIndex, numberOfPieces = 24;
String pieces[24], input;

//Indstillinger for dBAMåleren
#define VREF 3.3 //Voltagen som din MCU bruger, Arduino = 5
#define soundSensorPin 25 //Den pin på MCU'en, der er forbundet til outputtet på dBA måleren
#define analogMaxRange 4096 //Analog max range for din MCU, esp32: 4096, Arduino: 1023

//Funktionelle indstillinger
#define dBAMax 3.0 //Hvornår der skal sendes en SMS
#define errorMeasurement 0.0 //Fejlmarginen
#define waitBeforeSendingtext (10*1000) //Målt i millisekunder, tid før vi sender noisySMS
#define waitBeforeGoingIdle (100*1000) //Hvor lang tid dBAMeasurement må være under vores dBAMax, før vi går tilbage til idle stadiet
#define waitIntervalBetweenPulseText (1000*1000) //Antal millisekunder i mellem, at vi sender en pulse SMS



//Variable vedrørende FSMD'en - MÅ IKKE ÆNDRES
//States:
//Idle 0, dBA above Max 1, dBA momentarily below max 2, send noisy text 3, send pulse text 4
int state = 0; //Initialiserer stadiet ved 0
float dbAMeasurement;
unsigned long timeSinceLastIdle; //Bruges til at triggere loudSMS
unsigned long timeSinceLastPulse = 0; //Bruges til at pulseSMS
unsigned long timeSincedBAMax; //Tid der er gået siden, vi optog vores første dBAMax i denne omgang
  
//Funktioner

void sendText(String SMSTarget,String message,TinyGsm modem){
    modem.sendSMS(SMSTarget, message);
}

float getdBAMeasurement(){
  float dbAMeasurement = ((analogRead(soundSensorPin) / 4096.0 * VREF)*50.0); //Slipper for at bruge clock cycluser på at definere variable
  delay(125); //Sampling cyclus delay for stabilitet
  return dbAMeasurement;
} 

bool isAbovedBAThreshold(){
  float dbAMeasurement = getdBAMeasurement();
  if(dbAMeasurement>(dBAMax - errorMeasurement)){
    return true;
  }else{
    return false;
  }
}

void setup() {
  Serial.begin(115200);

  //Opstart af Modem
  // Set LED OFF
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  pinMode(PWR_PIN, OUTPUT);
  digitalWrite(PWR_PIN, HIGH);
  delay(300);
  digitalWrite(PWR_PIN, LOW);

  //Tjekker for SD kort
  SPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);
  if (!SD.begin(SD_CS)) {
    Serial.println("SDCard MOUNT FAIL");
  } else {
    uint32_t cardSize = SD.cardSize() / (1024 * 1024);
    String str = "SDCard Size: " + String(cardSize) + "MB";
    Serial.println(str);
  }

  Serial.println("\nWait...");

  delay(1000);

  SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX);

  // Restart takes quite some time
  // To skip it, call init() instead of restart()
  Serial.println("Initializing modem...");
  if (!modem.restart()) {
    Serial.println("Failed to restart modem, attempting to continue without restarting");
  }

  
  // Unlock your SIM card with a PIN if needed
  if ( GSM_PIN && modem.getSimStatus() != 3 ) {
      modem.simUnlock(GSM_PIN);
  }
  modem.sendAT("+CFUN=0 ");
  if (modem.waitResponse(10000L) != 1) {
    DBG(" +CFUN=0  false ");
  }
  delay(200);

  /*
    2 Automatic
    13 GSM only
    38 LTE only
    51 GSM and LTE only
  * * * */
  String res;
  // CHANGE NETWORK MODE, IF NEEDED
  res = modem.setNetworkMode(NETWORK_MODE);
  if (res != "1") {
    DBG("setNetworkMode  false ");
    return ;
  }
  delay(200);

  /*
    1 CAT-M
    2 NB-Iot
    3 CAT-M and NB-IoT
  * * */
  // CHANGE PREFERRED MODE, IF NEEDED
  res = modem.setNetworkMode(PREFFERED_NETWORK_MODE);
  if (res != "1") {
    DBG("setPreferredMode  false ");
    return ;
  }
  delay(200);

  /*AT+CBANDCFG=<mode>,<band>[,<band>…]
   * <mode> "CAT-M"   "NB-IOT"
   * <band>  The value of <band> must is in the band list of getting from  AT+CBANDCFG=?
   * For example, my SIM card carrier "NB-iot" supports B8.  I will configure +CBANDCFG= "Nb-iot ",8
   */
  /* modem.sendAT("+CBANDCFG=\"NB-IOT\",8 ");*/
  
  /* if (modem.waitResponse(10000L) != 1) {
       DBG(" +CBANDCFG=\"NB-IOT\" ");
   }*/
   delay(200);

  modem.sendAT("+CFUN=1 ");
  if (modem.waitResponse(10000L) != 1) {
    DBG(" +CFUN=1  false ");
  }
  delay(200);

  SerialAT.println("AT+CGDCONT?");
  delay(500);
  if (SerialAT.available()) {
    input = SerialAT.readString();
    for (int i = 0; i < input.length(); i++) {
      if (input.substring(i, i + 1) == "\n") {
        pieces[counter] = input.substring(lastIndex, i);
        lastIndex = i + 1;
        counter++;
       }
        if (i == input.length() - 1) {
          pieces[counter] = input.substring(lastIndex, i);
        }
      }
      // Reset for reuse
      input = "";
      counter = 0;
      lastIndex = 0;

      for ( int y = 0; y < numberOfPieces; y++) {
        for ( int x = 0; x < pieces[y].length(); x++) {
          char c = pieces[y][x];  //gets one byte from buffer
          if (c == ',') {
            if (input.indexOf(": ") >= 0) {
              String data = input.substring((input.indexOf(": ") + 1));
              if ( data.toInt() > 0 && data.toInt() < 25) {
                modem.sendAT("+CGDCONT=" + String(data.toInt()) + ",\"IP\",\"" + String(apn) + "\",\"0.0.0.0\",0,0,0,0");
              }
              input = "";
              break;
            }
          // Reset for reuse
          input = "";
         } else {
          input += c;
         }
      }
    }
  } else {
    Serial.println("Failed to get PDP!");
  }

  Serial.println("\n\n\nWaiting for network...");
  if (!modem.waitForNetwork()) {
    delay(10000);
    return;
  }

  if (modem.isNetworkConnected()) {
    Serial.println("Network connected");
  }

}

void loop() {

  switch(state){
    case 0:  // Idle: Venter på at dbAMeasurement går over dbAMax - Error
      Serial.println("Back in state 0");
      dbAMeasurement = getdBAMeasurement();
      timeSinceLastIdle = millis(); //Millisekunder siden start
      Serial.println(dbAMeasurement);
      Serial.println(timeSinceLastIdle);
      Serial.println(timeSinceLastPulse);

      if((timeSinceLastIdle - timeSinceLastPulse) > waitIntervalBetweenPulseText){ //Vi vil hellere sende pulse SMS'en, før vi advarer
        state = 4;
      }
      if ((dbAMeasurement>(dBAMax - errorMeasurement))&(state != 4)){ //If we go above the allowed dBAMeasurement, we start counting until we send noisySMS
        state = 1;
      }

      break;
    case 1:  // We're counting up to sending the loudSMS
      Serial.println("Back in state 1");

      dbAMeasurement = getdBAMeasurement();
      Serial.println(dbAMeasurement);

      timeSincedBAMax = millis() - timeSinceLastIdle;
      Serial.println(timeSincedBAMax);
      if(timeSincedBAMax>waitBeforeSendingtext){
        state = 3; //SendnoisySMS
      }
      if(dbAMeasurement<(dBAMax - errorMeasurement)){
        state = 2; //Momentært under dBAMax
      }

      break;
    case 2:  // Hvis vi momentært går under dBAMax
      Serial.println("Back in state 2");
      dbAMeasurement = getdBAMeasurement();
      
      if((millis() - timeSincedBAMax)> waitBeforeGoingIdle){ //Når der er gået lang nok tid, hvor vi ikke måler en høj nok lyd, så genstarter vi timeren for at sende noisySMS
        state = 0;
      }

      if(dbAMeasurement>(dBAMax - errorMeasurement)){ //Vi går igen over vores threshold og går tilbage til tælle op til at sende noisySMS uden at genstarte timeren
        state = 1;
      }
      

      break;
    case 3:  // Send noisySMS
      sendText(SMS_TARGET_NOISY,SMS_MESSAGE_NOISY,modem);
      Serial.println("Back in state 3");
      state = 0;
      break;

    case 4:
      Serial.println("Back in state 4");
      timeSinceLastPulse = millis();
      sendText(SMS_TARGET_PULSE,SMS_MESSAGE_PULSE,modem);
      state = 0; //Go back to idle
      break;
  }
}

The odd thing here however, is that if I manually send the AT commands over UART using the ESP-IDF, I can make it send text messages without a hick.

4
  • TinyGSM has the capability of turning on DUMP_AT_COMMANDS for debugging , have you done that? Commented Feb 12, 2023 at 5:14
  • modem.setNetworkMode() return a bool true or false, not a char or string as you are checking in if (res != "1"). Commented Feb 12, 2023 at 5:23
  • @hcheung I do not believe that is the issue. I believe it is boxed into a boolean. Commented Feb 22, 2023 at 10:18
  • Well, you can believe whatever you want, did you read the source code? You had #define DUMP_AT_COMMANDS turn on, what does the log on the Serial Monitor shown? Commented Feb 23, 2023 at 15:31

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.