0

I am using the following code for reading any incoming message, and doing something after decoding the incoming string. There is a delay of 10sec in the code. When this delay is not introduced in the code, it is working nice. In this case, the output is like below.

+CIEV: "MESSAGE",1

+CMT: "+919080404532",,"2018/02/09,19:30:51+06"
This is an incoming test message

When the delay is introduced, I am unable to see the message on the serial monitor, and subsequent action is not taken by the code. The output is like below.

+CIEV: "MESSAGE",1
+CMT: "+919080404532",,"2018/02/09,1

It is clear that, I am missing some character in serial monitor. If delay is reduced to 400 ms, the output is like below.

+CMT: "+919080404532",,"2018/02/09,19:30:51+06"
This is an incoI am working other job

I checked the following, but did not get any improvement.

  1. Serial.flush and mySerial.flush

  2. Increased both hardware, and software aerial buffer size

  3. used if (!mySerial.available() before delay

  4. Changed baud rate for both

  5. Instead of of Serial.readString(), I used Serial.read() character by character inside function loop

Without use of the delay, it is working nice. I Think you guys are experienced, and can sort out the problem easily.

//while Introducing any delay in function loop, incoming message cant be read
//working with power failure but with serial monitor
#include <SoftwareSerial.h>
SoftwareSerial mySerial(9, 10);  // TX-Pin11, RX-Pin10
String str="";
void updateSerial()
{
  delay(2000);
  while (Serial.available()) {
    mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while(mySerial.available()) {
    Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
  }

}   

void setup()
{
  Serial.begin(9600);
  mySerial.begin(9600);
  modemsetup();
}

void loop()
{ 
 Serial.println("I am working other job");
 //delay(10000);            //If you give this delay, then incoming message cant be read
 smstask();
}

void smstask()
{
if(mySerial.available()) 
{
str=mySerial.readString();
Serial.println(str);
int bra = str.indexOf('@');
int ket = str.indexOf('#');
String str1=str.substring(bra+1,ket);

if(str1=="server")
{
Serial.println(str);
int i=random(1,500);
String str2=(String)i;
String str3="@deviceA#"+str2;
mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
updateSerial();
mySerial.println("AT+CMGS=\"+917602304567\"\r"); // Replace x with mobile number
updateSerial();
mySerial.println(str3);// The SMS text you want to send
updateSerial();
mySerial.println((char)26);// ASCII code of CTRL+Z
updateSerial();
mySerial.println("AT+CMGD=1,4"); // AT Command to receive a live SMS
updateSerial();
}
}




}

void modemsetup()
{
  for(int i=0;i<3;i++)
  {
  mySerial.println("AT");          //Once the handshake test is successful, it will back to OK
  updateSerial();

  mySerial.println("AT+CSQ");      //Signal quality test, value range is 0-31, 31 is the best
  updateSerial();

  mySerial.println("AT+CCID");    //Read SIM information to confirm whether the SIM is plugged
  updateSerial();

  mySerial.println("AT+CREG?");    //Check whether it has registered in the network
  updateSerial();    

  mySerial.println("AT+SNFS=0");  //Adjust to earphone mode(AT+SNFS=1 is microphone mode) 
  updateSerial();

  mySerial.println("AT+CRSL=2");  //Adjust volume, volume range is 0-15, maximum:15
  updateSerial();

  mySerial.println("AT+CMGF=1"); 
  updateSerial();

  mySerial.println("AT+CMGD=1,4");
  updateSerial();
  }

  mySerial.println("AT+CMGS=\"+917602304567\"\r");
  updateSerial();

  mySerial.println("I am SMS from GSM Module");
  updateSerial();

  mySerial.println((char)26);// ASCII code of CTRL+Z
  updateSerial();

}
  • 1
    What is the purpose of delay(2000) in updateSerial()? – jose can u c Feb 9 '18 at 14:55
  • That is response time of gsm modem. But that delay is not creating any problem.Problem is the delay inside loop – Partha Arduino Java Feb 9 '18 at 18:50
  • 1
    What I was getting at is that sprinkling long delays like you are doing is poor practice, and when you are using the UART like this, you are bound to run into problems. Instead of pausing the entire CPU while you wait for an external device to maybe answer... instead, just check if it has an answer, and if not, check again later. That is, if (Serial.available()) { ... }, rather than delay(20000) and then drain the buffer. – jose can u c Feb 9 '18 at 18:55
  • Yes, that is a good practice. But actual problem is , if any message is received when arduino is busy with doing other stuff, character is missing. – Partha Arduino Java Feb 9 '18 at 19:29
  • This is not true -- the Arduino has a serial buffer which holds bytes until your code can get around to processing them. However, you have to structure your code so that it doesn't use a lot of long delay() calls, otherwise, it will miss characters, as you are experiencing. It's possible for the Arduino to collect characters one or two at a time, and only deal with the string when you get a character that defines the end of a logical command/result (such as a newline or carriage-return). – jose can u c Feb 9 '18 at 19:33
3

If serial data is coming in, and your code is doing a delay, the incoming data is stored in a buffer (of 64 bytes). But if you wait too long, the buffer will fill-up. Once it's full, any further incoming serial data isn't stored, and will be lost.

In your third output example, you get exactly 63 characters. Which is the maximum size a 64-byte cyclic buffer can store.

  • Thank you for your reply. But I increased buffer size to 256 bytes from SoftwareSerial.h – Partha Arduino Java Feb 9 '18 at 17:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.