Passing a uint32_t over serial

Hi guys

I'm having a bit of trouble passing a potentially large number between two arduinos which are connected via serial using two XRF units.

Basically on one arduino I have:

int32_t currentHeight = 0;
...
currentHeight = pressureSensor.convertToAltitude(le->getPressure(), settings.heightUnits);
// *Telemetry mod*
// Send flag, a for alt
Serial.write("a");
// Now current height is a 4 byte word so we need to do some bit shifting.
Serial.write( lowByte(currentHeight) );
Serial.write( lowByte(currentHeight >> 8) );
Serial.write( lowByte(currentHeight >> 16) );
Serial.write( lowByte(currentHeight >> 24) );

and on the other I have:

    int incomingByte = 0;
    int32_t currentHeight = 0;
    ...
    incomingByte = Serial.read();
    if ( incomingByte == 'a' )
    {
      lcd.print((char)incomingByte);
      byte1 = Serial.read();
      byte2 = Serial.read();
      byte3 = Serial.read();
      byte4 = Serial.read();
      currentHeight = byte4;
      currentHeight = currentHeight << 8;
      currentHeight = currentHeight | byte3;
      currentHeight = currentHeight << 8;
      currentHeight = currentHeight | byte2;
      currentHeight = currentHeight << 8;
      currentHeight = currentHeight | byte1;
      lcd.setCursor(1, 0);
      lcd.print(currentHeight, DEC);
      currentHeight = 0;
    }

The number output is not correct - the first digit is varying quite a lot. So, for example, if the LCD were outputting a number like 455ft the first digit (4) would keep changing to anything from 0 to 9.

Clearly I am not reforming the number correctly but I've been doing it so long today that I can't see where I am going wrong. A fresh set of eyes would be very much appreciated :wink:

Thanks a lot

How do you know you have data to read?

It's constantly streaming numbers. That's a code snippet which misses the if (Serial.available() > 0) bit.

I think I have figured it's an LCD issue, I need to flush the screen before updating else I might get some left over digits.

Hint: if you have a code problem, post the code.

Serial.write( lowByte(currentHeight) );
Serial.write( lowByte(currentHeight >> 8) );
Serial.write( lowByte(currentHeight >> 16) );
Serial.write( lowByte(currentHeight >> 24) );

I would think a union of an int32_t and a 4 byte array, where you assign the int32_t part and write the 4 bytes would be a better solution.

I think I have figured it's an LCD issue, I need to flush the screen before updating else I might get some left over digits.

You also need to take into consideration that serial data transmission, especially via radio, is not guaranteed. You need some kind of start and end of packet markers, so you can make sure that you have read all 4 bytes from the same value before you try to use that value.

What happens, with the code you have now, if the 3rd byte gets lost/mangled?

Hint: if you have a code problem, post the code.

No point posting code that has no errors in it!

I would think a union of an int32_t and a 4 byte array, where you assign the int32_t part and write the 4 bytes would be a better solution.

Yeah you are probably right, I planned to tidy it up once I know it is working fundamentally (poor practice I know!) Actually after more consideration there is no need to send four bytes, two will do so I just cast it as an integer (I'm hacking a device so better to cast it rather than change it and break something else!) and use lowByte(), highByte() and word(h,l) (but there is nothing wrong with the code I posted above with bit shifting).

I think I have figured it's an LCD issue, I need to flush the screen before updating else I might get some left over digits.

That was the error it all works fine now.

You need some kind of start and end of packet markers

I guess you're right but since they're just numbers being spewed out twice a second I'll know if one byte has gone bad. If I get too much packet loss (with increasing range) I will have to build in some error tolerance but for a bare bones beta version a start flag is good enough to demonstrate functionality.

Thanks for your help.

No point posting code that has no errors in it

I wish I had a pound for every time I've heard that one.

I guess you're right but since they're just numbers being spewed out twice a second I'll know if one byte has gone bad.

Please explain how you will know if one byte is missing/incorrect. I'm really interested. Is Karnac the Magnificent involved somehow? Ouji boards?

No just simple intuition! If it is spitting out numbers and you know your aircraft is flying at ~100ft, if it suddenly says it is at 0ft clearly a byte has gone missing :wink: Also you can tell by the noise in the data - if it is fluctuating by large amounts clearly something is going astray.

  • if it is fluctuating by large amounts clearly something is going astray.

Or you're flying through a strong up/down-draught.