stuck on "while" statement

I am trying to write a program to read serial data in byte increments and store it for further processing. I was following an example of setting up a state machine to read the serial messages. However my program stops advancing at the “while” statement shown in the code. I inserted Serial Println statements to find out what was happening. I get as far as a repeated printing of the “while line”. What am I doing wrong in the “state” statements?

//other variables declared also

typedef enum { 
  messageInit, messageWaitFor10, messageWaitForID, p5DsCollectTheData, p49sCollectGLO, pF5sCollectTheData, pF5s2CollectTheData, pF6sCollectTheData, p49sCollectGPS, pF7sSystemID, Fini, } 
IDstate_t;





bool Serial2_WaitForByte(byte* v) 
{
  TimerA =millis();
  while ( Serial2.available () <=0)
  {
    if (millis()-TimerA >= 500UL){
      Serial.println("timeout no COMM");
      return false;
    }
  }
  *v = Serial2.read();
  return true ;
}





void inMessage()
{
  IDstate_t state;
  byte n;
  byte inbyte;
  state = messageInit;

  while ( state != Fini )   
  {
    Serial.println("while line"); //debug... //this is the point the program gets stuck

    switch ( state )
    {
      Serial.println("switch state line"); //debug
messageWaitFor10:
      TimerA =millis();
      if ( Serial2_WaitForByte( &inbyte ) )
      {
        if ( inbyte == 0x10 )
        {
          state = messageWaitForID;
        }
      }
      else if(millis()-TimerA >= 1000UL){
        Serial.println("reciever communication time out error message start");
      }
      break;

messageWaitForID:
      TimerA =millis();
      if ( Serial2_WaitForByte( &inbyte ) )
      {
        if ( inbyte == 0x10 ) // if 0x10 continue waiting for an ID byte to come
        {
          state = messageWaitForID; 
        }
        if ( inbyte == 0x54 ) // comm response good
        {
          comm2 = true;
          state = Fini;
        }
        if ( inbyte == 0xF5 )   //channel raw info
        {
          state = pF5sCollectTheData;
        }
        if ( inbyte == 0xF6 )   //coord of antenna
        {
          state = pF6sCollectTheData;
        }
        if ( inbyte == 0xF7 )    //empheritis
        {
          for (int n=0; n<32; n++){
            gpsEmp[n] = false;      //set all positions false
          }
          for (int n=0; n<24; n++){
            gloEmp[n] = false;      //set all positions false
          }
          state = pF7sSystemID;
        }
        if ( inbyte == 0x5D )     //tropo and iono corrections per SV#
        {
          state = p5DsCollectTheData;
        }
      }  
      else if (millis()-TimerA >= 500UL){
        Serial.println("reciever communication time out error message ID");
        state = messageWaitFor10; 
      }  
      break;

// more states related to each inMessage type complete this function
     }
   }
  }
}

void setup(){

  Wire.begin();
  Serial.begin(9600);     // error reporting output
  Serial2.begin(115200);  // comm with reciever
  Serial3.begin(115200);  // comm with LAN adapter or serial
  delay(3000);
  handshake();
  startup();
  TimerB = 0;
}// end of setup  


void loop(){

  if (Serial2.available()){
    inMessage(); 
  }
  if (TimerB >= 1000){
    sendMessage();
    TimerB = 0;
  }

}

Switch without case?

I get as far as a repeated printing of the "while line". What am I doing wrong in the "state" statements?

Sorry, my crystal ball is out at the cleaners. It might be back next week. You could stop back by then, or show us what you are receiving on Serial2.

What are these for?

messageWaitFor10:
messageWaitForID:

You're not planning to use goto, are you?

The syntax of your switch statement is wrong. It may compile, but it's not semantically correct.

see: http://arduino.cc/en/Reference/SwitchCase

You have to use the literal word "case" for each value of the statement. Do not put statements before the first case, that's undefined behavior.

See the code section of this playground entry for an example:
http://arduino.cc/playground/Main/ShowInfo

Serial2 is recieving GPS streaming byte message data. Each message begins with an 0x10, followed by a message ID byte. Depending on what the message ID is I want to read bytes into an array then at the expected byte length check the end bytes 0x10, 0x03 that all messages end with. If the data in the array is good then I will store it in an I2C FRAM for later value extraction and conversion to another format.

A while back I asked about it and it was suggested with a similar example to make a state machine. The manner in which the example was written is what I followed. It will compile but I had not tried uploading and running it untill yesterday.
I tried adding “case” before each state yesderday but I believe when I tried it I did not include the single quotation marks. I will try it again.

The Arduino’s are fun to play with but there are many functions only slightly explained on the playground. For someone like me with no C experience it can take a while to catch on. PaulS, I used to program in basic back when I was a kid and had a Comadore 64. :slight_smile:

What quotation marks?
A case doesn't have any.

Last night I wrote a tutorial on Finite State Machines - you might find it useful.

http://hacking.majenko.co.uk/finite-state-machine

Thanks everyone. I realized the quote marks used on the Arduino example was due to it being a serial read.

I made changes and it now is at least functioning. I’m getting my timeout messages to the serial monitor.

//other variables declared also

typedef enum { 
  messageInit, messageWaitFor10, messageWaitForID, p5DsCollectTheData, p49sCollectGLO, pF5sCollectTheData, pF5s2CollectTheData, pF6sCollectTheData, p49sCollectGPS, pF7sSystemID, Fini, } 
IDstate_t;





bool Serial2_WaitForByte(byte* v) 
{
  TimerA =millis();
  while ( Serial2.available () <=0)
  {
    if (millis()-TimerA >= 500UL){
      Serial.println("timeout no COMM");
      return false;
    }
  }
  *v = Serial2.read();
  return true ;
}





void inMessage()
{
  IDstate_t state;
  byte n;
  byte inbyte;
  //  state = messageInit; this was my main issue changed to
   state = messageWaitFor10;  // and added "case"
  while ( state != Fini )   
  {
    Serial.println("while line"); //debug... //this is the point the program gets stuck

    switch ( state )
    {
      Serial.println("switch state line"); //debug
case messageWaitFor10:
      TimerA =millis();
      if ( Serial2_WaitForByte( &inbyte ) )
      {
        if ( inbyte == 0x10 )
        {
          state = messageWaitForID;  
        }
      }
      else if(millis()-TimerA >= 1000UL){
      }
      break;

case messageWaitForID:
      TimerA =millis();
      if ( Serial2_WaitForByte( &inbyte ) )
      {
        if ( inbyte == 0x10 ) // if 0x10 continue waiting for an ID byte to come
        {
          state = messageWaitForID; 
        }
        if ( inbyte == 0x54 ) // comm response good
        {
          comm2 = true;
          state = Fini;
        }
        if ( inbyte == 0xF5 )   //channel raw info
        {
          state = pF5sCollectTheData;
        }
        if ( inbyte == 0xF6 )   //coord of antenna
        {
          state = pF6sCollectTheData;
        }
        if ( inbyte == 0xF7 )    //empheritis
        {
          for (int n=0; n<32; n++){
            gpsEmp[n] = false;      //set all positions false
          }
          for (int n=0; n<24; n++){
            gloEmp[n] = false;      //set all positions false
          }
          state = pF7sSystemID;
        }
        if ( inbyte == 0x5D )     //tropo and iono corrections per SV#
        {
          state = p5DsCollectTheData;
        }
      }  
      else if (millis()-TimerA >= 500UL){
        Serial.println("reciever communication time out error message ID");
        state = messageWaitFor10; 
      }  
      break;

// more states related to each inMessage type complete this function
     }
   }
  }
}

void setup(){

  Wire.begin();
  Serial.begin(9600);     // error reporting output
  Serial2.begin(115200);  // comm with reciever
  Serial3.begin(115200);  // comm with LAN adapter or serial
  delay(3000);
  handshake();
  startup();
  TimerB = 0;
}// end of setup  


void loop(){

  if (Serial2.available()){
    inMessage(); 
  }
  if (TimerB >= 1000){
    sendMessage();
    TimerB = 0;
  }

}

Now I need to connect my device board however I’m having some confusion with setting the Serial2 to odd parity. I need 8 data, odd parity, 1 stop
I get that no parity these to bits are set to 0. Is the _BV() going to change them each to 1? I need both set to 1 for odd parity.

//after initializing Serial2
Serial2.begin(115200);
UCSR2C = _BV(UPM21) | _BV(UPM20);