Go Down

Topic: reading sms (Read 15336 times) previous topic - next topic

PaulS

Quote
ok,this is my full code,does not loop when checking for sms's,

What output do you get?

Why is that Serial.flush() back? GET RID OF IT!!!

PaulS

#16
Jan 10, 2013, 02:38 pm Last Edit: Jan 10, 2013, 02:40 pm by PaulS Reason: 1
Quote
stops checking after ;

You don't know that. All you know is that your reading loop never ends. So, what is happening in that loop?

Code: [Select]
 for (x=0;x < 255;x++){            
   data[x]='\0';                        
 }

If you understood C strings, you'd know why this was unnecessary.
Code: [Select]
data[0] = '\0';
is all that is needed.

Make some changes.
 x=0;
 do{
   while(Serial.available()==0);
   data[x++]=Serial.read();  
   data[ x ] = '\0'; // Keep string NULL terminated
   if(data[x-1]==0x0D&&data[x-2]=='"')
   { // Down here where it belongs!
     x=0;
     data[ 0 ] = '\0';
   }
   Serial.print("data: [");
   Serial.print(data);
   Serial.println("]");

 }
 while(!(data[x-1]=='K'&&data[x-2]=='O'));

Show us the output (and the code).

PaulS

Code: [Select]
  x=0;
  do{
  }
  while(!(data[x-1]=='K'&&data[x-2]=='O'));

How valid do you suppose -1 and -2 are as indices into data?

You really need to ditch the do/while loop, and use some other construct to wait for data, and then read all data until OK appears. But, before you get started on that, think about what happens if the AT command fails, and the return does NOT include OK.

PaulS

Quote
all i have is this perfect code

Code: [Select]
        x=0;
        do{
        }while(!(data[x-1]=='K'&&data[x-2]=='O'));

When x is 0, as it is initially, it gets incremented to 1 inside the body of the do/while statement. Then, at then end you check the values in data[ 0 ] and data[ -1 ], to see if they are O and K. And, you call code that references an invalid element of the array "perfect". I don't think so.

Add the if(strcmp(data, "on") == 0) block to that code. After the if block, print data again. With the '[' before and ']' after it. Does data get corrupted by the strcmp() call?

PaulS

Quote
hi sir, not sure if its done correctly but there's my attempt,
yes the data does get corrupted.

No, it doesn't. If it did, the output would be correct before the if statement, and corrupt after. It is not correct at any point.

The fact that you are trying to talk to the phone and the PC on the same serial port is the problem.

Quote
found a sketch for sim900,that should activate led pin output when receives an sms with on but does not,my serial monitors shows the sketch reading the sms without any problems but no led lights up.Got the gsm shield set on software serial and using uno R3,also tried using it in hardware serial mode,did not work,in hardware serial mode pin1 and 2 are (txrx),not sure how to re-configure in the sketch and not sure why led is not high when sms with ,on is sent.


Look through the output you showed. Where do you see "on" or "off" in  that output?

zoomkat

Quote
hi sir, not sure if its done correctly but there's my attempt,


The below web code shows how to capture an incomming string and see if it contains an "on' or "off", then act appropriately. Might have something useful for you.

Code: [Select]

//zoomkat 12-08-12
//get submit box code
//for use with IDE 1.0
//open serial monitor to see what the arduino receives
//use the \ slash to escape the " in the html or use a '
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields
//note that the below bug fix may be required
// http://code.google.com/p/arduino/issues/detail?id=605

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84);; //server port

String readString;

//////////////////////

void setup(){

  pinMode(5, OUTPUT); //pin selected to control
  //start Ethernet
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();

  //enable serial data print
  Serial.begin(9600);
  Serial.println("server text box test1"); // so I can keep track of what is loaded
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string
          readString += c;
          //Serial.print(c);
        }

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //see what was captured

          //now output HTML data header

          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Arduino GET test page</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>HTML form GET example</H1>");

          client.println("<FORM ACTION='/' method=get >"); //uses IP/port of web page

          client.println("Pin 5 'on' or 'off': <INPUT TYPE=TEXT NAME='LED' VALUE='' SIZE='25' MAXLENGTH='50'><BR>");

          client.println("<INPUT TYPE=SUBMIT NAME='submit' VALUE='Change Pin 5!'>");

          client.println("</FORM>");

          client.println("<BR>");

          client.println("</BODY>");
          client.println("</HTML>");

          delay(1);
          //stopping client
          client.stop();

          /////////////////////
          if(readString.indexOf("on") >0)//checks for on
          {
            digitalWrite(5, HIGH);    // set pin 5 high
            Serial.println("Led On");
          }
          if(readString.indexOf("off") >0)//checks for off
          {
            digitalWrite(5, LOW);    // set pin 5 low
            Serial.println("Led Off");
          }
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

Google forum search: Use Google Search box in upper right side of this page.
Why I like my 2005 Rio Yellow Honda S2000  https://www.youtube.com/watch?v=pWjMvrkUqX0

PaulS

Code: [Select]
this sketch reads incoming sms's and stores it perfectly,the stored sms  doesnt show the contents of it,the word 'on' doesnt appear anywhere on the serial monitor only the cellphone number and some other details,according to the sketch it should activate the led when an sms 'on' is sent,i checked all AT commands they seem to be right,not sure how to modify the part that is responsible for reading the sms,
The is NOT code. Learn how to post comments OUTSIDE of the code tags.

Code: [Select]
    if(Serial.available())
    else  if(mySerial.available())

Why are these exclusive?

Code: [Select]
        char SerialInByte;
        SerialInByte = (unsigned char)mySerial.read();

Why are you separating the declaration and the initialization?

Code: [Select]
        char SerialInByte = (unsigned char)mySerial.read();
Casting to an unsigned char to store in a signed char is a bad idea, by the way. The cast is not needed at all.

Code: [Select]
        // FR: Si le message se termine par un <CR> alors traiter le message
        if( SerialInByte == 13 ){

Why not make it clear what the code is doing?
Code: [Select]
        if( SerialInByte == '\n' ){
If you can add a space after the open parenthesis, why can't you add one after the close parenthesis? Studying the code every time is a waste of time. Organize the code so it is readable.

Code: [Select]
         if( SerialInByte == 10 ){
            // EN: Skip Line feed

Again, why not make the code clearer?
Code: [Select]
         if( SerialInByte == '\r' ) {

Code: [Select]
           msg += String(SerialInByte);
Invoking the constructor, the copy constructor, the assignment operator, and the destructor for the String class to add one character is a waste of resources. The += operator is overloaded to add a character. Use that overload instead of converting the one character to a new String.

In fact, you should get rid of the String class, altogether.

Anyway, none of this has anything to do with why the AT commands are not returning entirely what you expect. That doesn't mean that they should not be fixed. What it tells me is that you are issuing the wrong AT command to read the SMS.

MikkoR

I'm fighting with a similar issue. I have a bit different code, and yes, it is far away from optimized or good-looking or professional etc. code. But, never mind, it works almost. I took it from the GeeTech GPRS module wiki page and made some modifications.

This code waits and reacts when a new SMS has received. It reads it (or try to read) and in the future it should do something based on the message content and then delete it. Currently it only deletes it. This part works, it notices a new SMS, reads it and deletes it. Next SMS works similar way.

The problem is in the message itself. If I send a SMS "Testing", only part of it will be displayed, like in the example output below, there is only "Test". If I wrote a longer SMS, the result is not truncated but contains random letters from the SMS sent. Any ideas why?

All I want is to get it working, may the code be brilliant or not  :)

Code: [Select]
#include <SoftwareSerial.h>
#include <string.h>
SoftwareSerial GSM(7, 8);

char buffer[300];

boolean clear = true;

int count=0;

void setup ()
{
  GSM.begin (19200);
  Serial.begin (19200);
  delay (4000);
}

void ClearBufferArray ()
{
  for (int i=0; i<count; i++)
      buffer[i] = NULL;
}

void loop ()
{
  if (clear) {

// First delete possibly existing messages and put into text mode
// Somehow these does not work in Setup (), maybe...
   
    GSM.println ("AT+CMGD=1,4");
    clear = false; 
    Serial.println ("Existing SMSs deleted");
    delay (1000);
    GSM.println ("AT+CMGF=1");
    Serial.println ("Text mode");
  }

  if (GSM.available()) {
   
//Read data from GSM into buffer

    while (GSM.available ()) {
     
      buffer[count++] = GSM.read ();
      buffer[count] = '\0';
     
// Avoid overflow     
      if(count == 300)
        break;
    }

//New message arrives, print the message announcement
   
    if (strstr (buffer,"+CMTI:")) {
 
      Serial.println ("SMS Received");

// Send reading command to GSM     
     
      GSM.println ("AT+CMGR=1");   
    }

// Handle the message
   
    if (strstr (buffer,"+CMGR:")) {

// So far only print the new one and delete it (all)
     
      Serial.println ("Reading SMS");
      GSM.println ("AT+CMGD=1,4");
    } 
   
// If no more data, transmission ends, print the buffer

    Serial.println (buffer);           

    ClearBufferArray ();
    count = 0;
  }

  if (Serial.available ())
    GSM.write (Serial.read ());
}


And output:

Code: [Select]
Existing SMSs deleted
Text mode
AT+CMGD=1,4

OK

AT+CMGF=1

OK

SMS Received

+CMTI: "SM",1

AT+CMGR=1

Reading SMS

+CMGR: "REC UNREAD","+358405833XXX","","13/01/21,23:56:46+08"
Test

OK

AT+CMGD=1,4


OK


PeterH


If I send a SMS "Testing", only part of it will be displayed, like in the example output below, there is only "Test". If I wrote a longer SMS, the result is not truncated but contains random letters from the SMS sent. Any ideas why?


Code: [Select]

while (GSM.available ()) {

buffer[count++] = GSM.read ();
buffer[count] = '\0';

// Avoid overflow      
if(count == 300)
break;
}

I doubt that it is causing you any problems, but for robustness you should do the overflow check before appending the received character to the buffer rather than after.

In your message handling code you assume that a complete message has been received as soon as GSM.available() returns zero, but all that really means is that the Arduino is reading characters from the serial connection faster than the GSM module is writing them. You should keep reading until you know you have received the complete response to your command. I don't know why you're seeing garbled messages but the fact you may only be reading the first few characters of each response from the GSM module could mean that the serial connection is overflowing at the sending side so perhaps that is the problem. In any case you need to sort out the serial port handling here before you look for any further problems.
I only provide help via the forum - please do not contact me for private consultancy.

MikkoR



In your message handling code you assume that a complete message has been received as soon as GSM.available() returns zero, but all that really means is that the Arduino is reading characters from the serial connection faster than the GSM module is writing them. You should keep reading until you know you have received the complete response to your command. I don't know why you're seeing garbled messages but the fact you may only be reading the first few characters of each response from the GSM module could mean that the serial connection is overflowing at the sending side so perhaps that is the problem. In any case you need to sort out the serial port handling here before you look for any further problems.


Sounds very reasonable, but how can I be sure that the serial input is actually finished? I'm not so familiar with these. Or should I read until "\nOK" is received? I think it is in the end of the message given by AT command (if everything goes right). Adding some delay did not work and is not a good idea anyway.

PeterH


Sounds very reasonable, but how can I be sure that the serial input is actually finished? I'm not so familiar with these. Or should I read until "\nOK" is received? I think it is in the end of the message given by AT command (if everything goes right). Adding some delay did not work and is not a good idea anyway.


A delay is certainly not the way to do it, agreed.

You need to work out how to detect the end of the response. If you know that each command response is followed by "\nOK\n" then you could wait until you receive that.
I only provide help via the forum - please do not contact me for private consultancy.

DigitalDash

#26
Mar 27, 2013, 12:09 am Last Edit: Mar 28, 2013, 12:19 am by DigitalDash Reason: 1
Sorry for bumping an old thread but Google led me here so this might help others.

You are probably overflowing the SoftwareSerial buffer which is set to 64 bytes.

You can confirm this by checking GSM.overflow() returns true

(reference http://arduino.cc/en/Reference/SoftwareSerialOverflow)

A dirty hack is to increase the SoftwareSerial buffer. Under libraries/SoftwareSerial/SoftwareSerial.h you'll find this line:

Code: [Select]
#define _SS_MAX_RX_BUFF 64 // RX buffer size

Increase it, keeping in mind the SRAM limitations on your Arduino device.

Edit:

After playing around a bit more I found the following in addition:


  • I had to change _SS_MAX_RX_BUFF directly in the SoftwareSerial.h class. Trying to #define it in my own project (either before or after the #include) resulted in failures still. I'm not sure why...printing out _SS_MAX_RX_BUFF and doing a sizeof(_receive_buffer) matched my values but it was still overflowing at 64.

  • I get corruption if I use any buffer size that isn't a power of 2. I don't know why.

  • To use a buffer size over 255 (well, 128) the variables _receive_buffer_tail and _receive_buffer_head need to be changed from uint8_t to uint16_t. I couldn't go above 128 without making that change.



Some reference info related to the two above things I found at http://arduino.cc/forum/index.php/topic,128544.msg967171.html


uttampal19

Hello,

Has someone come up with a solution with the above stated problem?

We are using Arduino Duemilanove and SIM 900 GSM module (http://robokits.co.in/shop/index.php?main_page=product_info&products_id=303)

We've tried to work on the similar problem of lightning Leds from port 9-12 when we send an sms #aibicidi, where i = 0 or 1, 0 =off, 1=on.
Eg. #a1b1c1d1 will switch on all the Led's.

When we upload the code and run it through serial monitor and enter the #a1b1c1d1 in the serial monitor, we can see all the led's lighten up.  But if we send the sms with having content "#a1b1c1d1", we dont see any function of leds.

It would be great if anyone can give some guidance about the same.


Code: [Select]



char inchar; //Will hold the incoming character from the Serial Port.


int led1 = 9;
int led2 = 10;
int led3 = 11;
int led4 = 12;

void setup()
{
// prepare the digital output pins
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW);
//Initialize GSM module serial port for communication.


Serial.begin(9600);
delay(3000); // give time for GSM module to register on network etc.
Serial.println("AT+CMGF=1"); // set SMS mode to text
delay(200);
Serial.println("AT+CNMI=3,3,0,0"); // set module to send SMS data to serial out upon receipt
delay(200);
}

void loop()
{
//If #a1b1c1d1 comes as sms, all led's should light up.
if(Serial.available() >0)
{
inchar=Serial.read();
if (inchar=='#')
   {
   delay(10);
   inchar=Serial.read();
   
//first led
   if (inchar=='a')
     {
   delay(10);
   inchar=Serial.read();
   
if (inchar=='0')
   {
   digitalWrite(led1, LOW);
   }
else if (inchar=='1')
   {
   digitalWrite(led1, HIGH);
   }
delay(10);


//Second led
inchar=Serial.read();

if (inchar=='b')
   {
   inchar=Serial.read();
if (inchar=='0')
{
digitalWrite(led2, LOW);
}

else if (inchar=='1')
{
digitalWrite(led2, HIGH);
}
delay(10);

// Third led
inchar=Serial.read();
if (inchar=='c')
{
inchar=Serial.read();
if (inchar=='0')
{
digitalWrite(led3, LOW);
}
else if (inchar=='1')
{
digitalWrite(led3, HIGH);
}
delay(10);

//Fourth led

inchar=Serial.read();
if (inchar=='d')
{
delay(10);
inchar=Serial.read();
if (inchar=='0')
{
digitalWrite(led4, LOW);
}
else if (inchar=='1')
{
digitalWrite(led4, HIGH);
}
delay(10);
}
}
Serial.println("AT+CMGD=1,4"); // delete all SMS
}
}
}
}
}

uttampal19

We were able to lighten up the LED with an sms.

Keeping the code below. This code will lighten 9 leds which are kept from port 4 to 12. The sms code is "0#iii#iii#iii, where i =0 or 1 meaning off or on respectively. Ex. 0#111#111#111 will switch on all the leds.

The modification was AT+CNMI=2,2,0,0,0 instead of AT+CNMI=3,3,0,0 from our previous code.

Code: [Select]
char inchar; //Will hold the incoming character from the Serial Port.


int led1 = 4;
int led2 = 5;
int led3 = 6;
int led4 = 7;
int led5 = 8;
int led6 = 9;
int led7 = 10;
int led8 = 11;
int led9 = 12;

void setup()
{
// prepare the digital output pins
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(led5, OUTPUT);
pinMode(led6, OUTPUT);
pinMode(led7, OUTPUT);
pinMode(led8, OUTPUT);
pinMode(led9, OUTPUT);


// initially all are off
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW);
digitalWrite(led5, LOW);
digitalWrite(led6, LOW);
digitalWrite(led7, LOW);
digitalWrite(led8, LOW);
digitalWrite(led9, LOW);




//Initialize GSM module serial port for communication.
Serial.begin(9600);
delay(3000); // give time for GSM module to register on network etc.
Serial.println("AT+CMGF=1\r"); // set SMS mode to text
delay(200);
Serial.println("AT+CSMS=1\r");
delay(200);

// Serial.println("AT+CNMI=3,3,0,0"); // set module to send SMS data to serial out upon receipt
Serial.println("AT+CNMI=2,2,0,0,0"); // set module to send SMS data to serial out upon receipt

delay(200);
}

void loop()
{
//If a character comes in from the Serialular module...

if(Serial.available() >0)


delay(10);
inchar=Serial.read();
if (inchar=='0')   // to catch the 1st 0 in our string 0#101#101#101
{     
       // digitalWrite(13, HIGH);
       // for #101________________
       inchar=Serial.read(); // read next char i.e '#'
       if (inchar=='#')
       {
             inchar=Serial.read(); //read next char i.e 1
             if (inchar=='0')
             {
                 digitalWrite(led1, LOW);
             }
             else if (inchar=='1')
             {
                 digitalWrite(led1, HIGH);
             }
             
             
       delay(10);
             inchar=Serial.read(); //read next char i.e 0
             if (inchar=='0')
             {
                 digitalWrite(led2, LOW);
             }
             else if (inchar=='1')
             {
                 digitalWrite(led2, HIGH);
             }
             
       delay(10);
             inchar=Serial.read(); //read next char i.e 1
             if (inchar=='0')
             {
                 digitalWrite(led3, LOW);
             }
             else if (inchar=='1')
             {
                 digitalWrite(led3, HIGH);
             }     
       } //end of  1st 'if char==#' loop
       
       
       
       
       //for _____  #101  _______
       inchar=Serial.read(); // read next char i.e '#'
       if (inchar=='#')
       {
             inchar=Serial.read(); //read next char i.e 1
             if (inchar=='0')
             {
                 digitalWrite(led4, LOW);
             }
             else if (inchar=='1')
             {
                 digitalWrite(led4, HIGH);
             }
             
             
       delay(10);
             inchar=Serial.read(); //read next char i.e 0
             if (inchar=='0')
             {
                 digitalWrite(led5, LOW);
             }
             else if (inchar=='1')
             {
                 digitalWrite(led5, HIGH);
             }
             
       delay(10);
             inchar=Serial.read(); //read next char i.e 1
             if (inchar=='0')
             {
                 digitalWrite(led6, LOW);
             }
             else if (inchar=='1')
             {
                 digitalWrite(led6, HIGH);
             }     
       } //end of 2nd 'if char==#' loop
       
       
       
       
       //for _____ _____ #101
       inchar=Serial.read(); // read next char i.e '#'
       if (inchar=='#')
       {
             inchar=Serial.read(); //read next char i.e 1
             if (inchar=='0')
             {
                 digitalWrite(led7, LOW);
             }
             else if (inchar=='1')
             {
                 digitalWrite(led7, HIGH);
             }
             
             
       delay(10);
             inchar=Serial.read(); //read next char i.e 0
             if (inchar=='0')
             {
                 digitalWrite(led8, LOW);
             }
             else if (inchar=='1')
             {
                 digitalWrite(led8, HIGH);
             }
             
       delay(10);
             inchar=Serial.read(); //read next char i.e 1
             if (inchar=='0')
             {
                 digitalWrite(led9, LOW);
             }
             else if (inchar=='1')
             {
                 digitalWrite(led9, HIGH);
             }     
       } //end of 3rd 'if char==#' loop
       
       
       
} // "ckeck 0 in front of string" wala loop close

//Serial.println("AT+CMGD=1,4"); // delete all SMS

} // serial available condition close


//   Serial.println("AT+CMGR=1\r");
//   delay(4000);
} // LOOP function close

dhruvit

hello i am doing the same thing tried to use the above code but it is not working

i can control the led pin 13 using serial consol by sending 0#1 and can make off by 0#0  but when i am sending the message 0#1 the led is not glowing here is my code
can anybody tell me what is the problem??
Code: [Select]

char inchar; //Will hold the incoming character from the Serial Port.


int led1 = 13;
void setup()
{
// prepare the digital output pins
pinMode(led1, OUTPUT);

// initially all are off
digitalWrite(led1, LOW);
//Initialize GSM module serial port for communication.
Serial.begin(9600);
delay(3000); // give time for GSM module to register on network etc.
Serial.println("AT+CMGF=1\r"); // set SMS mode to text
delay(200);
Serial.println("AT+CSMS=1\r");
delay(200);

//Serial.println("AT+CNMI=3,3,0,0"); // set module to send SMS data to serial out upon receipt
Serial.println("AT+CNMI=2,2,0,0,0"); // set module to send SMS data to serial out upon receipt
//Serial.println("AT+CSMP=17,167,0,0");
delay(200);
}
void loop()
{
//If a character comes in from the Serialular module...
if(Serial.available() >0)


delay(10);
inchar=Serial.read();
if (inchar=='0')   // to catch the 1st 0 in our string 0#101#101#101
{     
      // digitalWrite(led1, HIGH);
       // for #101________________
       inchar=Serial.read(); // read next char i.e '#'
       if (inchar=='#')
       {
             inchar=Serial.read(); //read next char i.e 1
             if (inchar=='0')
             {
                 digitalWrite(led1, LOW);
             }
             else if (inchar=='1')
             {
                 digitalWrite(led1, HIGH);
             }
                  } //end of 3rd 'if char==#' loop
       
       } // "ckeck 0 in front of string" wala loop close

//Serial.println("AT+CMGD=1,4"); // delete all SMS
  } // serial available condition close

//   Serial.println("AT+CMGR=1\r");
//   delay(4000);
} // LOOP function close

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy