I am using A6 GSM modem to read incoming message with an Arduino UNO, and processing it as per requirement. My code is here . Received sms is processed by a function smstask() which is between line no 35 to 65. Function wait() is same as delay() function. Only advantage is using wait() instead of delay() is additional checking inside delay(). The code is working fine. It is clear that,line no 37, and 112 is cleaning the serial buffer. Processing part is done after that. My question is, as the buffer is being cleaned immediately after receiving new message, why still am I able to get incoming message in the serial monitor? It is to be noted that without line no line no 37, and 112, it is still working. You guys can only tell.
It is clear that,line no 37, and 112 is cleaning the serial buffer.
If the Serial buffer is being cleared by line 37 then why do you check whether there is any serial data available in line 38 ?
Do you appreciate how much faster the Arduino operates compared with how fast serial data arrives, especially at 9600 baud ?
I note the use of Strings (capital S) which is generally regarded as a bad idea on a memory limited system. I also note the insane repetition of text rather than using a for loop and the F() macro if you feel that you should have such inane output in your program.
for(int j=0;j<100;j++)
for(int k=0;k<100;k++)
int m=k*j;
What is this nonsense ?
Dear UKHeliBob,
I introduced the nonsense for loop intentionally. I have to use some other codes there for lora communication. As loRA is not available with me right now, I used that for loop for simulation purpose. My question was why this program showing received sms on serial monitor? I am confused regarding the behavior o serial communication.
cotsquire:
My question is, as the buffer is being cleaned immediately after receiving new message, why still am I able to get incoming message in the serial monitor?
Because 'updateSerial()' is waiting two seconds and then sending to Serial Monitor every character received from 'mySerial'.
Thanks johnwasser. But I dont think it is correct answer as update serial is called after
while( mySerial.available() > 0) mySerial.read();
Once buffer is cleaned, is it possible to read from buffer?????
Serial is
S
L
O
W
So even if incoming characters are being sent "continuously" there's thousands of Arduino operations possible between each character arriving. So after clearing the buffer, you have to wait.
Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.
It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.
Make it easy for people to help you - post your code here..
...R
//Polling method device A, Delay issue solved
//Better to use minimum print statement
//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()
{
smstask();
lora();
}
void smstask()
{
while( mySerial.available() > 0) mySerial.read(); //If you dont use this line, still working
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")
{
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();
}
void wait(unsigned int timeout) //It works for timeout time.
{
uint8_t x=0;
unsigned long previous;
while( mySerial.available() > 0) mySerial.read(); // Clean the input buffer//If you dont use this line, still working
previous = millis();
do{
smstask();
}
while(((millis() - previous) < timeout));
}
void lora()
{
int m,n;
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
wait(10000);
Serial.println("I am working other job");
for(int j=0;j<100;j++)
for(int k=0;k<100;k++)
int m=k*j;
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
wait(10000);
for(int j=0;j<100;j++)
for(int k=0;k<100;k++)
m=k*j;
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
wait(10000);
for(int j=0;j<100;j++)
for(int k=0;k<100;k++)
m=k*j;
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
wait(10000);
for(int j=0;j<100;j++)
for(int k=0;k<100;k++)
m=k+j;
Serial.println("I am working other job");
}
MorganS:
Serial isS
L
O
W
So even if incoming characters are being sent "continuously" there's thousands of Arduino operations possible between each character arriving. So after clearing the buffer, you have to wait.
So, you are telling that, it takes some time to clear the buffer also. Am I right?
cotsquire:
Thanks johnwasser. But I dont think it is correct answer as update serial is called after
while( mySerial.available() > 0) mySerial.read();
Once buffer is cleaned, is it possible to read from buffer?????
Yes, if you wait two seconds for more characters to arrive. Like you do.
void loop()
{
while( mySerial.available() > 0) mySerial.read();
// Inside 'updateSerial()'
delay(2000); // During this wait, character can arrive in the serial buffer
while(mySerial.available()) {
// This will display any characters that have arrived in the 2+ seconds since updateSerial() was called
Serial.write(mySerial.read()); //Forward what Software Serial received to Serial Port
}
}
So, you are telling that, it takes some time to clear the buffer also. Am I right?
No, you are very, very wrong.
You're comparing a simple operation involving perhaps a couple of dozen instructions (the buffer flush) with operations that take up to (and exceeding) 160000 instruction cycles (the time a single character spends "in flight" at 9600 bits per second)
cotsquire:
So, you are telling that, it takes some time to clear the buffer also. Am I right?
No, it's like me sending you a letter in the post once a month. Yes, there is a certain amount of time for you to walk to the mailbox and remove the letter from the box but that time is so short that you really cannot tell if I'm sending you another letter next month. All you know is there is one letter there now. The program has to be written to work without seeing the next letter.
Ok. Finaily, I have written this new program. I am able to send and receive sms. I can also decode the received sms. But after 20-30 min, it stops working. It is working again if serial monitor is opened again after closing once. After checking once again, I have observed that the previous program has the same issue. The new program is copied here. What should I do to make it continuously operational without deletion of function lora()?
NEW PROGRAM
//Try to change String class by cstring
#include <SoftwareSerial.h>
SoftwareSerial mySerial(9, 10);
int8_t answer;
void setup(){
Serial.begin(9600);
mySerial.begin(9600);
Serial.println("Starting...");
power_on();
delay(3000);
Serial.println("Connecting to the network...");
//while( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );
Serial.print("Setting SMS mode...");
sendATcommand("AT+CMGF=1", "OK", 1000); // sets the SMS mode to text
Serial.println("Sending SMS");
//mySerial.println("AT+CMGS="+917602304567"\r");
answer = sendATcommand("AT+CMGS="+917602304567"\r", ">", 2000); // send the SMS number
if (answer == 1)
{
mySerial.println("Test-Arduino-Hello World");
mySerial.write(0x1A);
answer = sendATcommand("", "OK", 20000);
if (answer == 1)
{
Serial.print("Sent ");
}
else
{
Serial.print("error ");
}
}
else
{
Serial.print("error ");
Serial.println(answer, DEC);
}
}
void loop()
{
smstask();
lora();
}
void power_on(){
uint8_t answer=0;
// checks if the module is started
answer = sendATcommand("AT", "OK", 2000);
if (answer == 0)
{
while(answer == 0){ // Send AT every two seconds and wait for the answer
answer = sendATcommand("AT", "OK", 2000);
}
}
Serial.println("modem ready");
}
int8_t sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout){
uint8_t x=0, answer=0;
char response[100];
unsigned long previous;
memset(response, '\0', 100); // Initialice the string
delay(100);
while( mySerial.available() > 0) mySerial.read(); // Clean the input buffer
mySerial.println(ATcommand); // Send the AT command
x = 0;
previous = millis();
// this loop waits for the answer
do{
if(mySerial.available() != 0){ // if there are data in the UART input buffer, reads it and checks for the asnwer
response[x] = mySerial.read();
x++;
if (strstr(response, expected_answer) != NULL) // check if the desired answer is in the response of the module
{
answer = 1;
}
}
}while((answer == 0) && ((millis() - previous) < timeout)); // Waits for the asnwer with time out
return answer;
}
void smstask()
{
String str="";
while( mySerial.available() > 0) mySerial.read(); //If you dont use this line, still working
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")
{
int i=random(1,500);
String str2=(String)i;
String str3="@deviceA#"+str2;
sendATcommand("AT+CMGF=1", "OK", 1000); // sets the SMS mode to text
answer = sendATcommand("AT+CMGS="+917602304567"\r", ">", 2000); // send the SMS number
if (answer == 1)
{
mySerial.println(str3);
mySerial.write(0x1A);
answer = sendATcommand("", "OK", 20000);
if (answer == 1)
{
Serial.println("Sent ");
}
else
{
Serial.print("message sending error ");
}
}
answer = sendATcommand("AT+CMGD=1,4", "OK", 2000);
if(answer==1)
Serial.println("deleted");
}
}
}
void wait(unsigned int timeout) //It works for timeout time.
{
uint8_t x=0;
unsigned long previous;
while( mySerial.available() > 0) mySerial.read(); // Clean the input buffer//If you dont use this line, still working
previous = millis();
do{
smstask();
}
while(((millis() - previous) < timeout));
}
void lora()
{
int m,n;
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
wait(10000);
Serial.println("I am working other job");
for(int j=0;j<100;j++)
for(int k=0;k<100;k++)
int m=k*j;
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
wait(10000);
for(int j=0;j<100;j++)
for(int k=0;k<100;k++)
m=k*j;
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
wait(10000);
for(int j=0;j<100;j++)
for(int k=0;k<100;k++)
m=k*j;
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("Hi");
Serial.println("I am working other job");
Serial.println("I am working other job");
Serial.println("I am working other job");
wait(10000);
for(int j=0;j<100;j++)
for(int k=0;k<100;k++)
m=k+j;
Serial.println("I am working other job");
}
Please use code tags. The forum software eats some of your code if you don't.
while( mySerial.available() > 0) mySerial.read(); //If you dont use this line, still working
Check
while construct
it is generally used / coded as
while(condition)
{
process while loop
}
continue processing
also check
mySerial.read() function
it reads / returns one byte from Serial buffer.
Most functions reading from Serial buffer CLEAR data read from the buffer.
Since you are not using the value returned by the function it gets lost.
There are other functions in Serial which could help you to make receiving serial data more stable.
Follow these there basic steps when processing ANY serial data
- Detect presence of data in Serial buffer
- Unless you have to continue some other processing or it is impractical to do so - read ALL serial data at once until ALL received. Store received data in local buffer using appropriate Serial function. (You can either wait for all data to arrive or modify , make more complex, your code to receive only limited amount of data at once ).
- Verify data received and if valid process it.
232:
while( mySerial.available() > 0) mySerial.read(); //If you dont use this line, still workingCheck
while construct
USE CODE TAGS! >:( INDENT!!!
-dev:
USE CODE TAGS! >:( INDENT!!!
Would you kindly tell me how when I quote from post ?
Any why you need code tags , OP seems to careless, for code tags for single line of code anyway?
Customary here to shout also?
Chill and KISS or contribute something meaningful in your post.
...KISS...
My reply could not have been simpler. This will be longer.
Would you kindly tell me how when I quote from post ?
If you don't know how to
* select text and press the code button (looks like "</>") or
* type the tags manually, [code] like this [/code]
,
...then you should not be posting. Your other posts are also lacking code tags. It looks like you have not read these important pages:
* Serial Input Basics - "read ALL serial data at once " is extraordinarily BAD advice.
BTW, it is considered polite to remove most of the quoted reply, so we don't have to read through a large quote to get to your response. I see from your other posts that you don't do this. How about this gem with 3 copies of a quote?
Customary here to shout also?
Now you're paying attention.
The reply right above yours said to use code tags. Didn't you read it? Maybe if we shout, you will. How many posts have you read that say "use code tags"? Some people have it as their signature.
Did you not understand that reply? It is customary to figure it out before trying to help. Otherwise, you may be duplicating some else's answer or distracting the op.
Any why you need code tags , OP seems to careless, for code tags for single line of code anyway?
__* __To be able to distinguish between text commentary and program code.
__* __To be able to copy the code for use.
__* __To prevent code from being interpreted as formatting. Example: array[i]
turns on italics for the rest of the post, because it contains the italics tag. :-/
Do I really need to explain why you should indent the code?
Do these things, as an example to the OP.
Don't do these things and you perpetuate poor post content.
And if you ignore other replies, you invite CAPITALS.
If you really want to help, spend the effort to make clear, readable posts. Make them ugly and confusing, and you can expect correction.
BTW, this conversation is considered a "hijack" of the OP. Many of us won't or can't help until the OP posts code and error messages correctly.
Robin2:
Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.
Make it easy for people to help you - post your code here..
...R
Dear Rabin, thanks for your help. I studied the serial input basics.I am using the function recvWithEndMarker(). If my input serial string has no endmarker, I am still receiving that string next time when I am sending string with end marker. Is it possible to parmanently discard the string which has no endmarker?
232:
while( mySerial.available() > 0) mySerial.read(); //If you dont use this line, still workingCheck
while constructit is generally used / coded as
while(condition)
{
process while loop}
continue processingalso check
mySerial.read() function
it reads / returns one byte from Serial buffer.
Most functions reading from Serial buffer CLEAR data read from the buffer.
Since you are not using the value returned by the function it gets lost.There are other functions in Serial which could help you to make receiving serial data more stable.
Follow these there basic steps when processing ANY serial data
- Detect presence of data in Serial buffer
- Unless you have to continue some other processing or it is impractical to do so - read ALL serial data at once until ALL received. Store received data in local buffer using appropriate Serial function. (You can either wait for all data to arrive or modify , make more complex, your code to receive only limited amount of data at once ).
- Verify data received and if valid process it.
If I use a delay after while( mySerial.available() > 0) mySerial.read(); then will my buffer be creared? If it is true, what should minimum be delay amount?