SIM800L, not sending SMS after uploading data to Firebase by POST method

Hi fellows,

I'm working on a project that powered by Atmega328p and SIM800L. While the alarm triggered, the device will upload data to Firebase Realtime database using POST method, then send SMS to a certain phone. It's OK to only send SMS and only send data to Firebase. But, if I try the software of device to do them together when alarm triggered, it fails to send an SMS and produce data to send to Firebase database. There is some parts of my code:

void updateSerial()
{
  delay(500);
  while (Serial.available()) 
  {
    gsm.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while(gsm.available()) 
  {
    Serial.write(gsm.read());//Forward what Software Serial received to Serial Port
  }
}

void sendSMS(String tel){
  //for(int i = 0; i < 4; i++){
    //Serial.println(tels[i]);
    gsm.println("AT+CMGS=\"+"+tel+"\"");//change ZZ with country code and xxxxxxxxxxx with phone number to sms
    updateSerial();
    gsm.print("Alarm Alert!"); //text content
    updateSerial();
    gsm.write(26);
    updateSerial();
    //delay(2000);

    /*for(int j=0; j<5; ++j){
      digitalWrite(buzzer, HIGH);
      delay(1500);
      digitalWrite(buzzer, LOW);
      delay(500);
    }*/
  //}
}

void triggerAlarm(){
  isTriggered = 1;
  alarmInitTime = millis();

  sendSMS(primary_tel);

  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Send data to Firebase part:
  String response;

  do{
    gsm.println("AT+CCLK?"); // Send command to get current time
    delay(500); // Wait for the response to be available
    gsm.readStringUntil('\"');// Read response from SIM800L
    delay(500);
    response = gsm.readStringUntil('\r');
    //response = gsm.readStringUntil('\"');
    if(response.length() > 1)
      response.remove(response.length() - 1);
    Serial.println(response);
    updateSerial();
  }while(response.length() != 20);
  do{
    data = "";
    data += "{\"action\": ";
    data += "\"3\", ";
    data += "\"time\": \"";
    data += response;
    data +=  "\"";
    data += "}";
  }while(data.length() != 47);

  Serial.println(data.length());
  post_to_firebase();
}

void post_to_firebase()
{ 
  Serial.println(data);
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Start HTTP connection
  gsm.println("AT+HTTPINIT");
  updateSerial();
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Enabling SSL 1.0
  if(USE_SSL == true){
    gsm.println("AT+HTTPSSL=1");
    updateSerial();
  }
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Setting up parameters for HTTP session
  gsm.println("AT+HTTPPARA=\"CID\",1");
  updateSerial();
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Set the HTTP URL - Firebase URL and FIREBASE SECRET
  Serial.println(db_url);
  gsm.println(db_url);
  updateSerial();
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Setting up re direct
  gsm.println("AT+HTTPPARA=\"REDIR\",1");
  updateSerial();
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Setting up content type
  gsm.println("AT+HTTPPARA=\"CONTENT\",\"application/json\"");
  updateSerial();
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Setting up Data Size
  //+HTTPACTION: 1,601,0 - error occurs if data length is not correct
  Serial.println(data);
  gsm.println("AT+HTTPDATA=" + String(data.length()) + ",50000");
  updateSerial();
  //waitResponse("DOWNLOAD");
  //delay(DELAY_MS);
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Sending Data
  gsm.println(data);
  updateSerial();
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Sending HTTP POST request
  gsm.println("AT+HTTPACTION=1");
  updateSerial();
  
  /*for (uint32_t start = millis(); millis() - start < 20000;){
    while(!gsm.available());
    String response = gsm.readString();
    if(response.indexOf("+HTTPACTION:") > 0)
    {
      Serial.println(response);
      break;
    }
  }*/
    
  delay(DELAY_MS);
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //+HTTPACTION: 1,603,0 (POST to Firebase failed)
  //+HTTPACTION: 0,200,0 (POST to Firebase successfull)
  //Read the response
  gsm.println("AT+HTTPREAD");
  //waitResponse("OK");
  //delay(DELAY_MS);
  updateSerial();
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Stop HTTP connection
  gsm.println("AT+HTTPTERM");
  //waitResponse("OK",1000);
  //delay(DELAY_MS);
  updateSerial();
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
}

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//Connect to the internet
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
void gprs_connect()
{
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //DISABLE GPRS
  gsm.println("AT+SAPBR=0,1");
  waitResponse("OK",60000);
  delay(DELAY_MS);
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Connecting to GPRS: GPRS - bearer profile 1
  gsm.println("AT+SAPBR=3,1,\"Contype\",\"GPRS\"");
  updateSerial();
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //sets the APN settings for your sim card network provider.
  gsm.println("AT+SAPBR=3,1,\"APN\",\""+APN+"\"");
  updateSerial();
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //sets the user name settings for your sim card network provider.
  if(USER != ""){
    gsm.println("AT+SAPBR=3,1,\"USER\",\""+USER+"\"");
    updateSerial();
  }
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //sets the password settings for your sim card network provider.
  if(PASS != ""){
    gsm.println("AT+SAPBR=3,1,\"PASS\",\""+PASS+"\"");
    updateSerial();
  }
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //after executing the following command. the LED light of 
  //gsml blinks very fast (twice a second) 
  //enable the GPRS: enable bearer 1
  gsm.println("AT+SAPBR=1,1");
  //waitResponse("OK", 30000);
  updateSerial();
  delay(DELAY_MS);
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Get IP Address - Query the GPRS bearer context status
  gsm.println("AT+SAPBR=2,1");
  //waitResponse("OK");
  updateSerial();
  delay(DELAY_MS);
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
}


/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* Function: gprs_disconnect()
* AT+CGATT = 1 modem is attached to GPRS to a network. 
* AT+CGATT = 0 modem is not attached to GPRS to a network
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
boolean gprs_disconnect()
{
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Disconnect GPRS
  gsm.println("AT+CGATT=0");
  waitResponse("OK",60000);
  //delay(DELAY_MS);
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //DISABLE GPRS
  //gsm.println("AT+SAPBR=0,1");
  //waitResponse("OK",60000);
  //delay(DELAY_MS);
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

  return true;
}





/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* Function: gprs_disconnect()
* checks if the gprs connected.
* AT+CGATT = 1 modem is attached to GPRS to a network. 
* AT+CGATT = 0 modem is not attached to GPRS to a network
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
boolean is_gprs_connected()
{
  gsm.println("AT+CGATT?");
  if(waitResponse("+CGATT: 1",6000) == 1) { return false; }

  return true;
}

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//Handling AT COMMANDS
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
boolean waitResponse(String expected_answer="OK", unsigned int timeout=2000) //uncomment if syntax error (arduino)
//boolean waitResponse(String expected_answer, unsigned int timeout) //uncomment if syntax error (esp8266)
{
  uint8_t x=0, answer=0;
  String response;
  unsigned long previous;
    
  //Clean the input buffer
  while( gsm.available() > 0) gsm.read();
  
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
  previous = millis();
  do{
    //if data in UART INPUT BUFFER, reads it
    if(gsm.available() != 0){
        char c = gsm.read();
        response.concat(c);
        x++;
        //checks if the (response == expected_answer)
        if(response.indexOf(expected_answer) > 0){
            answer = 1;
        }
    }
  }while((answer == 0) && ((millis() - previous) < timeout));
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
  
  Serial.println(response);
  return answer;
}

void init_gsm()
{
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Testing AT Command
  gsm.println("AT");
  updateSerial();
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Checks if the SIM is ready
  gsm.println("AT+CPIN?");
  waitResponse("+CPIN: READY");
  delay(DELAY_MS);
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Turning ON full functionality
  gsm.println("AT+CFUN=1");
  updateSerial();
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Turn ON verbose error codes
  gsm.println("AT+CMEE=2");
  updateSerial();
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Enable battery checks
  gsm.println("AT+CBATCHK=1");
  updateSerial();
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Register Network (+CREG: 0,1 or +CREG: 0,5 for valid network)
  //+CREG: 0,1 or +CREG: 0,5 for valid network connection
  gsm.println("AT+CREG?");
  waitResponse("+CREG: 0,");
  delay(DELAY_MS);
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //setting SMS text mode
  gsm.print("AT+CMGF=1\r");
  waitResponse("OK");
  delay(DELAY_MS);
  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
}

In this part, triggerAlarm() function:

void triggerAlarm(){
  isTriggered = 1;
  alarmInitTime = millis();

  sendSMS(primary_tel);

  //MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
  //Send data to Firebase part:
  String response;

  do{
    gsm.println("AT+CCLK?"); // Send command to get current time
    delay(500); // Wait for the response to be available
    gsm.readStringUntil('\"');// Read response from SIM800L
    delay(500);
    response = gsm.readStringUntil('\r');
    //response = gsm.readStringUntil('\"');
    if(response.length() > 1)
      response.remove(response.length() - 1);
    Serial.println(response);
    updateSerial();
  }while(response.length() != 20);
  do{
    data = "";
    data += "{\"action\": ";
    data += "\"3\", ";
    data += "\"time\": \"";
    data += response;
    data +=  "\"";
    data += "}";
  }while(data.length() != 47);

  Serial.println(data.length());
  post_to_firebase();
}

if I disable one of the these function calls: post_to_firebase() (posts data to firebase) or sendSMS() (sends SMS) by commenting out, the other called function work. But, if I call both functions in my code, it fails sending SMS and it could not produce the data with length of 47 characters and it stuck on this loop:

  do{
    data = "";
    data += "{\"action\": ";
    data += "\"3\", ";
    data += "\"time\": \"";
    data += response;
    data +=  "\"";
    data += "}";
  }while(data.length() != 47);

When I don't use loop and just the produce data whatever I can like this:

data = "";
    data += "{\"action\": ";
    data += "\"3\", ";
    data += "\"time\": \"";
    data += response;
    data +=  "\"";
    data += "}";

it sends data to Firebase with no values, just with "error: no data supplied", or name.

I also tried clean the buffer of the SoftwareSerial variable "gsm" between calling of two functions like:

while(gsm.available)
    gsm.read();

but nothing changed. I am really stuck now.

Have you checked the SIM800L module separately? I mean without firebase? Only sending SMS from an Arduino?

Yes, I checked that. It is able to send SMS. Also able to send data to Firebase. But when doing both, it fails. @liaifat85

Instead of relying on the length of the data string to be exactly 47 characters, which might not always be the case due to varying response lengths from the SIM800L module, you can modify the loop to exit when the desired length is reached or if a certain maximum number of iterations is exceeded. You can modify the relevant part of your code like this:

int max_attempts = 10;
int attempt = 0;
do {
    data = "";
    data += "{\"action\": ";
    data += "\"3\", ";
    data += "\"time\": \"";
    data += response;
    data +=  "\"";
    data += "}";
    attempt++;
} while (data.length() != 47 && attempt < max_attempts);

This modification ensures that the loop doesn't get stuck indefinitely and allows for a maximum number of attempts to create the data string.

Regarding the issue with sending both SMS and data to Firebase, it's possible that the SIM800L module is getting overwhelmed when trying to handle both tasks simultaneously. One thing you can try is to introduce some delay between sending the SMS and initiating the process to send data to Firebase. For example, you can add a delay after sending the SMS:

sendSMS(primary_tel);
delay(2000); // Add a delay to allow time for the SMS to be sent before proceeding
post_to_firebase();

By the way, here is another firebase that you may be interested in. It does not need a GSM module: Home Automation With Firebase + Android App + ESP8266 - 01 - Share Project - PCBWay

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.