Strange behavior with serial.read()

I’m having some weird behavior here. I think I’m missing something obvious.

I am sending a data structure that was copied onto a char array over the serial link from a Gumstix to the Arduino. (This works in the other direction) I get the first copy of the structure fine, but subsequent ones aren’t right.

Structure:

typedef struct {
  int8_t id;
  int16_t messageCount;
  int16_t time;
} packet_header_t;

typedef struct {
  packet_header_t header;
  int8_t flapAngle;
  int8_t motorSpeed;
  uint16_t checksum;
} control_packet_t;

Loop:

void loop() { 
  char temp;
  if(Serial.available()) {
    radio.println("Data");
    int8_t id = Serial.read();

    if(id == 99) {
      radio.println("Got the id");
      rec = 1;
      while(rec < 8) {
        temp = Serial.read();
        if(temp == -1) rec = 8;
        buffer[rec] = temp;
        rec++;
      }
      radio.print("Size: ");
      radio.println(sizeof(temp));
      memcpy(&controlPacket, buffer, sizeof(buffer));
      radio.print("Flap Angle: ");
      radio.println(controlPacket.flapAngle);
      Serial.read();
      rec = 0;
    }
  }

Here's a little data... looks like I get the first copy fine and then the next one, I only get every other byte. (Should be 9 bytes)

Data
Got the id
3C
0
4B
0
33
A
28
0
Size: 1
Flap Angle: 51
Data
Got the id
3C
4B
34
21
9
FFFFFFFF

What is your declaration of ‘buffer’? It could be by setting rec=8 inside the loop then on the next line writing buffer[rec]=temp you are overwriting the buffer.

You have a Serial.avalaible() before the first Serial.read() but none inside your loop. You can try adding a test of Serial.avalaible() before reading new bytes inside the loop like:

while((rec < 8) && (Serial.avalaible()!=0))

There is a drawback the while loop will hang if there is less than 8 data transmitted (in case of a missed data for example).

Hey Everyone,

Thanks for the replies. I gave all of them a shot. No better though.

I went so far as to just do this in my loop:

  if(Serial.available()) {
    stop = false;
    while(Serial.available() !=0) {
      radio.println(Serial.read(), HEX);
    }

I still see the same thing. First set of bytes is fine. Next set gets every other.

Perhaps it's time to look at the emitter, are you sure there is no bug in the emitter software part? Can you spy the data sent?

It could be a problem with the data source. I did manage to get some code to work. Here's what actually works to read the data in.

There are still some issues that I'm trying to work out. Like sometimes I get it at a regular interval, others it comes in a flurry.

Note: The val == 99 part is an id field it is using to sync up with.

  if(Serial.available()) {

  int8_t val;
  val = Serial.read();
  if(val!=-1 && (idx > 0 || val==99)){
    buffer[idx++] = val;
  }
  if(idx >= sizeof(controlPacket)){
      idx = 0;
      memcpy(&controlPacket, buffer, sizeof(controlPacket));
      //radio.print("Flap: " );
      radio.println(controlPacket.flapAngle);
  }

Here’s the current version. It looks for the message ID to sync up to. Then it reads the whole message in.

Is there a way to speed this read process up?

 if(Serial.available()) {
    int8_t val;
    val = Serial.read();
    if(val == 99) {
      buffer[0] = val;
      int i = 1;
      while(i<8) {
        val = Serial.read();
        if(val!= -1) {
          buffer[i] = val;
          i++;  
        }
      }
      memcpy(&controlPacket, buffer, sizeof(controlPacket));
    }
  }

Well, I’m not sure what kind of a speed up you’re looking for, but I can see a problem in the code.

      while(i<8) {
        val = Serial.read();
        if(val!= -1) {
          buffer[i] = val;
          i++;
        }
      }

will give you values in the wrong places. You need to make sure your serial data is in sync.

      while(i<8) {
        while(!Serial.available());  // this will wait until we have our next byte
        val = Serial.read();
        buffer[i] = val;
        i++;
      }

This will ensure you get your entire message.

b