4

I would like to test the contents of data received over a serial connection. In my loop() I store the data in bffr; and afterwards I would like to test to see if there are some predefined words in it.

#define BFFSZ 90
char bffr[BFFSZ];
char bffridx; 

void loop()
{
   readline();

   //- Test the bffr
       if(strstr(bffr, "CLOSED")){ //- WORKS
          Serial.println("> conn. closed");
          digitalWrite(A1, HIGH); 
       }else if(strstr(bffr, "RING")){ //- WORKS
          Serial.println("> Someone is ringing");
          digitalWrite(A2, HIGH);
       }else if(strstr(bffr, "0,7,j,BLINK")){ //- Doesn't work
          Serial.println("> Blink");
          digitalWrite(A2, HIGH);
          delay(300);
          digitalWrite(A2, LOW);
       }
}


void readline()
{
   memset(bffr,0,sizeof(bffr));
   char c;
   int i =0;
   bffridx = 0; // start at beginning


   long previousMillis = millis();
   while (1) {
     unsigned long currentMillis = millis();
     if(currentMillis - previousMillis > 20000) {
       Serial.println("TIMEOUT");
       return;
     }
     delay(2);

     c=gsm.SimpleRead2();
     //- debug only, to see if there is something received.     
     Serial.write(c);

     if (c == -1)
       continue;
     if (c == '\n')
       continue;
     if ((bffridx == BFFSZ-1) || (c == '\r')) {
       bffr[bffridx] = 0;
       return;
     }

     bffr[bffridx++]= c;
     delay(2);
   }
}

The debug-line makes that I can see the data flowing, eg when I phone the SIM.

But it looks like the buffer isn't tested properly. The first two will work, but the last test fails. It is part of a larger string: $0,7,j,BLINK,567^ But I thought the strstr(1,2) searches for 2 in 1. And as 0,7,j,BLINK, is within the haystack I assume it wil return true. But apparently not...

The gsm.SimpleRead2() comes from GSMlib and is my altered version of gsm.SimpleRead(). Instead of printing the char, I just return it so we can buffer it in the readline function.

void SIMCOM900::SimpleRead()
{

 char datain;
 if(_cell.available()>0){
   datain=_cell.read();
   if(datain>0){
     Serial.print(datain);
   }
 }
}
char SIMCOM900::SimpleRead2()
{

 char datain;
 if(_cell.available()>0){
   datain=_cell.read();
   if(datain>0){
     return datain;
   }
 }
}

Does anyone know the answer to this?

stUrb
  • 351
  • 2
  • 5
  • 10

1 Answers1

1

After a serial.read();, the data [as far as I can tell] is pretty much destroyed. You have two main options to accomplish this:

  • Store the data in a string when read and then reference this later. I'd do this with a global variable, that is declared outside of a method and accessible throughout your whole sketch.
  • I haven't read throughout your whole code, but, if you only need to read one character, you can use serial.peek();. This only works if you need the first character of the buffer.

Most likely, your only option would be the first bullet. I'd implement this by adding a method something like this:

String buffer_string_serial;

void setup() { //code here }

void loop() { //code here }

int serial_read_buffer() {
  while(serial.avaliable() > 0) {
    buffer_string_serial = buffer_string_serial + serial.peek();
    return serial.read();
  }
}

Then, just use serial_read_buffer();. That will act similar to serial.read();. The only difference is it will fill up the buffer_string_serial string. You'll have to clear that out after you used all the data so it doesn't get full.

Anonymous Penguin
  • 6,365
  • 10
  • 34
  • 62