Having trouble loading serial data into a variable..

I am sending my Arduino text messages. The message is formated beginning with a ‘?’ followed by the message contents.

For some reason, I cannot get the incoming serial data to load into my variable “load” properly. Once the function Update_schedule is called all it outputs is a “!”

Any help is greatly apprecaited.

My code:

#include <SoftwareSerial.h>
#include <SPI.h>
#include <Wire.h>
#include <PString.h>
#include <RTClib.h>
#include <RTC_DS3234.h>

SoftwareSerial rfid(12,13);

// Create an RTC instance, using the chip select pin it's connected to
RTC_DS3234 RTC(8);

//RTC time buffer variables
const int len = 32;
char buf[len];

//RFID variables
int flag = 0;
int Tag[11];
char Tag1[] = "39f2ead2";
char Tag2[] = "39fldf22";
int counter = 0;

//SM5100B variables
int firstTimeInLoop = 1;
int request_count = 1;
char incoming_char=0;
char buffer[60];
PString myString(buffer,sizeof(buffer));
int COMM_Ready=0;
int Network_Ready=0;
#define BUFFSIZ 90
char at_buffer[BUFFSIZ];
char buffidx;
char mobilenumber[] = "7708436766";
int SMS_counter = 0;

//Load Variables
String load = "";




//Function Prototypes
void parse(void);
void print_serial(void);
void read_serial(void);
void seek(void);
void set_flag(void);

void setup()
{
  Serial.begin(9600);
  //Initialize SM5100B comms
  Serial1.begin(9600);
  
  Serial.println("Starting...");
  delay(10000);
  //Initialize RTC
  SPI.begin();
  RTC.begin();
  
  //Initialize RFID
  rfid.begin(19200);
  delay(10);
  
  //LEDs
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
}

void loop()
{ 
  
  while(Serial1.available() >0)
{
    incoming_char=Serial1.read();    
    Serial.print(incoming_char);
  if(incoming_char == '?')
  { 
    for(int id = 0; id<20; id++)
    {
      load[id] = incoming_char;
    }
    //Serial.println();
    //Serial.print("Load is: ");
    //Serial.println(load);
    Update_schedule();
  }
}

  
  if(firstTimeInLoop) 
  {
    digitalWrite(6, HIGH);
    firstTimeInLoop = 0;
    
    while (COMM_Ready == 0 || Network_Ready == 0) 
    {
     readATString();
     ProcessATString();
   }
  
   if(Network_Ready) {
     Serial.println();
     Serial.println("Network Ready");
     delay(1000);
   }
   if(COMM_Ready) {
     Serial.println("Module Ready for Communications");
     delay(1000);}
     
   Serial.println("Configuring for SMS Text");
   delay(1000);
   
   Serial1.println("AT+CMGF=1");
   delay(5000);
   Serial.println("Configuring Serial Output");
   Serial1.println("AT+CNMI=3,3,0,0");
   delay(10000);
   digitalWrite(6, LOW);
   //Serial1.println("AT+CMGF?");
}

if(request_count)
{ Serial.println("Load Message Sent Now");
  Load_schedule();
  request_count = 0;
}


  
  seek();
  delay(10);
  parse();
  set_flag();
  print_serial();
  delay(100);
  
  
  
}

void seek()
{
  
  rfid.write(255);
  
  int i = 0;
  rfid.write(i);
  rfid.write(1);
  rfid.write(130);
  rfid.write(131);
  delay(10);
}

void parse()
{
  while(rfid.available())
  {
    if(rfid.read() == 255)
    {
      for(int i=1;i<11;i++)
      {
        Tag[i]= rfid.read();
      }
    }
  }
}

void set_flag()
{
  if(Tag[2] == 6){
    flag++;
    
  }
  if(Tag[2] == 2){
    flag = 0;
  }
}

void print_serial()
{ 
  if(flag == 1)
  {
    
    
    String TagID = "";
    
    char buffer[8];
    for(int index = 8; index>4; index--)
    {
      itoa(Tag[index], buffer,16);
      TagID += buffer;
    }
    
    for(int x = 0; x<TagID.length(); x++)
    {
      if(TagID[x] == Tag1[x] || TagID[x] == Tag2[x])
      {
        counter++;
      }
    }
    
    Serial.println("Tag Read");
    Serial.print("Counter: ");
    Serial.println(counter);
    delay(4000);
  if(counter < 7)
  {
    digitalWrite(6, HIGH);
    delay(1000);
    digitalWrite(6, LOW);
    
    
  }
  
  if(counter >= 7)
  {
    send_message(TagID);
  }
  
  counter = 0;}
  
}

void send_message(String ID)
{
  digitalWrite(7,HIGH);
  int len = 32;
  char buf[len];
    
  DateTime now = RTC.now();
  String time = now.toString(buf,len);
  delay(100);
  
  Serial.println("Message Contents:");
  Serial.print("Tag ID Is: ");
  Serial.println(ID);
  Serial.print("Tag Read At: ");
  Serial.println(time);
  delay(2000);
  
  
  
 
  Serial1.print("AT+CMGS=\"");
  
  Serial1.print(mobilenumber);
  
  Serial1.println("\"");
  
  delay(1000);
  Serial1.print("?");
  Serial1.print(ID);
  Serial1.print(time);
  Serial1.print("!");
  char ctrlz = 0x1A;
  Serial1.print(ctrlz);
  delay(2000);
  digitalWrite(7, LOW);
  
}

void readATString (void) {
  
  char c;
  buffidx = 0; //start at beginning
  while (1) {
    if(Serial1.available() > 0) {
      c=Serial1.read();
      if (c== -1) {
        at_buffer[buffidx] = '\0';
        return;
      }
      
      if(c == '\n') {
        continue;
      }
      
      if((buffidx == BUFFSIZ - 1 || (c == '\r'))){
        at_buffer[buffidx] = '\0';
        return;
      }
      
      at_buffer[buffidx++]= c;
      
    }
  }
}

/* Processes the AT string to determine if GPRS is registered and AT is ready */

void ProcessATString() {
  
  if( strstr(at_buffer, "+SIND: 8") != 0 ) {
    Network_Ready = 0;
    Serial.println("Network Not Available");
  }
  
  if( strstr(at_buffer, "+SIND: 11") != 0 ) {
    Network_Ready = 1;
    
  }
  
  if( strstr(at_buffer, "+SIND: 4") != 0 ) {
    COMM_Ready = 1;
    
    
    
  }
  
  
 
}

void Load_schedule()
{ Serial.println("Sending Request To Load Schedule");
  Serial1.print("AT+CMGS=\"");
  
  Serial1.print(mobilenumber);
  
  Serial1.println("\"");
  
  delay(1000);
  Serial1.print("?");
  Serial1.print("Load");
  Serial1.print("!");
  char ctrlz = 0x1A;
  Serial1.print(ctrlz);
  delay(2000);
  Serial.println("Request Sent");
  
  
}

void Update_schedule()
{
  Serial.println();
  Serial.print("Load is: ");
  for(int c =0; c<load.length(); c++)
  {
  Serial.print(load[c]);
  }
}
if(incoming_char == '?')
  { 
    for(int id = 0; id<20; id++)
    {
      load[id] = incoming_char;
    }

load is NOT an array, so what are you doing? If you receive a ‘?’, you want 20 copies of it in the String?

If you receive anything other than a ‘?’, you throw it away.

I see, so what's in my if statement is only called when incoming_char is '?'. That looks obvious now, how can I basically iterate through the next 20 characters coming through the serial port and load them into load? A while loop?

For instance:

if(incoming_char == '?') { while(incoming_char != '!') //Message contents are terminated in a '!' { load += incoming_char; }

A while loop?

Something like that.

#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[80];
byte index;

void setup()
{
   Serial.begin(57600);
   // Other stuff...
}

void loop()
{
  // Read all serial data available, as fast as possible
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}

Change the values of SOP and EOP to match your start and end of packet markers. Where it says “Process the packet” put your code for using the data in the packet.

Thanks for the code! I loaded it up and it worked…once.

Not sure why, but after that first time I receive all the data leading up to the SOP character: ‘?’ and then nothing.

Here is my code with your code integrated. I bumped up the baud rate to 115200 also. Any ideas?

#include <SoftwareSerial.h>
#include <SPI.h>
#include <Wire.h>
#include <PString.h>
#include <RTClib.h>
#include <RTC_DS3234.h>

SoftwareSerial rfid(12,13);

// Create an RTC instance, using the chip select pin it's connected to
RTC_DS3234 RTC(8);

//RTC time buffer variables
const int len = 32;
char buf[len];

//RFID variables
int flag = 0;
int Tag[11];
char Tag1[] = "39f2ead2";
char Tag2[] = "39fldf22";
int counter = 0;

//SM5100B variables
int firstTimeInLoop = 1;
int request_count = 1;
char incoming_char=0;
char buffer[60];
PString myString(buffer,sizeof(buffer));
int COMM_Ready=0;
int Network_Ready=0;
#define BUFFSIZ 90
char at_buffer[BUFFSIZ];
char buffidx;
char mobilenumber[] = "7708436766";
int SMS_counter = 0;

//Load Variables
#define SOP '?'
#define EOP '!'

bool started = false;
bool ended = false;

char inData[80];
byte index;




//Function Prototypes
void parse(void);
void print_serial(void);
void read_serial(void);
void seek(void);
void set_flag(void);

void setup()
{
  Serial.begin(115200);
  //Initialize SM5100B comms
  Serial1.begin(115200);
  
  Serial.println("Starting...");
  delay(10000);
  //Initialize RTC
  SPI.begin();
  RTC.begin();
  
  //Initialize RFID
  rfid.begin(19200);
  delay(10);
  
  //LEDs
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
}

void loop()
{ 
  
  while(Serial1.available() >0)
{
    char inChar = Serial1.read();
    Serial.print(inChar);
    if(inChar == SOP)
    {
      index = 0;
      inData[index] = '\0';
      started = true;
      ended = false;
    }
    
    else if(inChar == EOP)
    {
      ended = true;
      break;
    }
    
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
}

if(started && ended)
{
  //Serial.println();
  //Serial.print("Schedule Data: ");
  for(int x = 0; x<80; x++)
  {
  Serial.println(inData[x]);
  }
  started = false;
  ended = false;
  index = 0;
  inData[index] = '\0';
}



  
  if(firstTimeInLoop) 
  {
    digitalWrite(6, HIGH);
    firstTimeInLoop = 0;
    
    while (COMM_Ready == 0 || Network_Ready == 0) 
    {
     readATString();
     ProcessATString();
   }
  
   if(Network_Ready) {
     Serial.println();
     Serial.println("Network Ready");
     delay(1000);
   }
   if(COMM_Ready) {
     Serial.println("Module Ready for Communications");
     delay(1000);}
     
   Serial.println("Configuring for SMS Text");
   delay(1000);
   
   Serial1.println("AT+CMGF=1");
   delay(5000);
   Serial.println("Configuring Serial Output");
   Serial1.println("AT+CNMI=3,3,0,0");
   delay(10000);
   digitalWrite(6, LOW);
   //Serial1.println("AT+CMGF?");
}

if(request_count)
{ Serial.println("Load Message Sent Now");
  Load_schedule();
  request_count = 0;
}


  
  seek();
  delay(10);
  parse();
  set_flag();
  print_serial();
  delay(100);
  
  
  
}

void seek()
{
  
  rfid.write(255);
  
  int i = 0;
  rfid.write(i);
  rfid.write(1);
  rfid.write(130);
  rfid.write(131);
  delay(10);
}

void parse()
{
  while(rfid.available())
  {
    if(rfid.read() == 255)
    {
      for(int i=1;i<11;i++)
      {
        Tag[i]= rfid.read();
      }
    }
  }
}

void set_flag()
{
  if(Tag[2] == 6){
    flag++;
    
  }
  if(Tag[2] == 2){
    flag = 0;
  }
}

void print_serial()
{ 
  if(flag == 1)
  {
    
    
    String TagID = "";
    
    char buffer[8];
    for(int index = 8; index>4; index--)
    {
      itoa(Tag[index], buffer,16);
      TagID += buffer;
    }
    
    for(int x = 0; x<TagID.length(); x++)
    {
      if(TagID[x] == Tag1[x] || TagID[x] == Tag2[x])
      {
        counter++;
      }
    }
    
    Serial.println("Tag Read");
    Serial.print("Counter: ");
    Serial.println(counter);
    delay(4000);
  if(counter < 7)
  {
    digitalWrite(6, HIGH);
    delay(1000);
    digitalWrite(6, LOW);
    
    
  }
  
  if(counter >= 7)
  {
    send_message(TagID);
  }
  
  counter = 0;}
  
}

void send_message(String ID)
{
  digitalWrite(7,HIGH);
  int len = 32;
  char buf[len];
    
  DateTime now = RTC.now();
  String time = now.toString(buf,len);
  delay(100);
  
  Serial.println("Message Contents:");
  Serial.print("Tag ID Is: ");
  Serial.println(ID);
  Serial.print("Tag Read At: ");
  Serial.println(time);
  delay(2000);
  
  
  
 
  Serial1.print("AT+CMGS=\"");
  
  Serial1.print(mobilenumber);
  
  Serial1.println("\"");
  
  delay(1000);
  Serial1.print("?");
  Serial1.print(ID);
  Serial1.print(time);
  Serial1.print("!");
  char ctrlz = 0x1A;
  Serial1.print(ctrlz);
  delay(2000);
  digitalWrite(7, LOW);
  
}

void readATString (void) {
  
  char c;
  buffidx = 0; //start at beginning
  while (1) {
    if(Serial1.available() > 0) {
      c=Serial1.read();
      if (c== -1) {
        at_buffer[buffidx] = '\0';
        return;
      }
      
      if(c == '\n') {
        continue;
      }
      
      if((buffidx == BUFFSIZ - 1 || (c == '\r'))){
        at_buffer[buffidx] = '\0';
        return;
      }
      
      at_buffer[buffidx++]= c;
      
    }
  }
}

/* Processes the AT string to determine if GPRS is registered and AT is ready */

void ProcessATString() {
  
  if( strstr(at_buffer, "+SIND: 8") != 0 ) {
    Network_Ready = 0;
    Serial.println("Network Not Available");
  }
  
  if( strstr(at_buffer, "+SIND: 11") != 0 ) {
    Network_Ready = 1;
    
  }
  
  if( strstr(at_buffer, "+SIND: 4") != 0 ) {
    COMM_Ready = 1;
    
    
    
  }
  
  
 
}

void Load_schedule()
{ Serial.println("Sending Request To Load Schedule");
  Serial1.print("AT+CMGS=\"");
  
  Serial1.print(mobilenumber);
  
  Serial1.println("\"");
  
  delay(1000);
  Serial1.print("?");
  Serial1.print("Load");
  Serial1.print("!");
  char ctrlz = 0x1A;
  Serial1.print(ctrlz);
  delay(2000);
  Serial.println("Request Sent");
  
  
}

What version of the IDE are you using?

PString myString(buffer,sizeof(buffer));

Why?

  for(int x = 0; x<80; x++)
  {
  Serial.println(inData[x]);
  }

The inData buffer is a NULL terminated string. Printing 80 characters in a loop is silly.

Why are you not doing anything with the data?

Your parse code is STILL wrong.

I'm using Arduino 1.0

When I sent a text message, I get all the heading up until the '?' then nothing on the serial terminal.

I will be parsing out various values from inData and sending it over a bluetooth or zigbee to another board, just haven't implemented that part yet.

I was trying to print out inData to see what it's contents are.

I tried a few different terminating characters and also a simple test statement in lieu of any code to see if it's even entering the if(started && ended) statement.

No dice..it won't even print that it's entered the if statement.

If I comment out the parse code we've been discussing the full message contents still won't display past the '?'. After messing around, only the first character of the message contents will display on the serial monitor..

Below is simple code that collects data until a , is received, at which time the data is acted upon.

//zoomkat 3-5-12 simple delimited ',' string parce 
//from serial port input (via serial monitor)
//and print result out serial port
// CR/LF could also be a delimiter

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("serial delimit test 1.0"); // so I can keep track of what is loaded
}

void loop() {

  //expect a string like wer,qwe rty,123 456,hyre kjhg,
  //or like hello world,who are you?,bye!,
  
  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      //do stuff
      Serial.println(readString); //prints string to serial port out
      readString=""; //clears variable for new input      
     }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

So I got this code working. Thanks very much to PaulS for that code, it works great.

I figured it out by building a program that exclusively parsed and incoming text message, the code worked no problem.

I then selectively commented out the various functions that were running in loop to see which was effecting the parse. Looks like my RFID functions were interfering so a simple modification telling them specifically when to run fixed it.

Thanks