Sending a struct of float from Arduino to another? (Serial communication?)

I have a struct like this:

struct fullWeatherDataPackage{  
    float outTemperature;
    float outHumidity;
    float inTemperature;
    float inHumidity;
typedef struct fullWeatherDataPackage FullWeatherDataPackage;
FullWeatherDataPackage inOutWeatherData;

I want to send this "inOutWeatherData" to an other Arduino. This is what I have tried:

Sender (baud:115200, but also tried 9600):

Serial.write((byte*)&inOutWeatherData, sizeof(inOutWeatherData));


Serial.readBytes((byte*)&inOutWeatherData, sizeof(inOutWeatherData));

It seems it receives the data but it is unknown characters and impossible values, when I print it out on the receiver it looks like:

Outside Temperature: 0.0°C Outside Humidity: 0% Inside Temperature: ovf°C Inside Humidity: ovf%

Is there any possible way to send these data to an other Arduino. It is not essential to send it in a struct, if it is easier to achieve.

(On the receiver I want to print the values out on a TFT.)

Thing is, there is noting synchronizing the two. So the receiver might start listening on the wrong moment. Easiest fix, have a look at Robin2’s Serial Input Basics.

Post your full code

Oh, I think I found it. The problem was I also had Serial.prints on the sender unit for me to check the data. This is what messed up the whole sending process. I commented out the Serial.print line and it looks like it is working.

But I still want to hear you opinions. Can I have problems with this method? Is there a better way to do this? Maybe I2C?

Thing is, there is noting synchronizing the two. So the receiver might start listening on the wrong moment. Easiest fix, have a look at Robin2's Serial Input Basics.

Thanks I'll check it.

Here is my full code. (I put the sender and receiver together)

You can have issues. The moment you miss a byte for whatever reason, the bets are off and it will be hard to get back in sync. Signaling start and end of communication with magic numbers (if you know the range of legit data you can use a value that you know is impossible) will help or you can make it an ASCII, BCD, Base64 encoded protocol and use Robin’s tutoria (cf link in post #1) to receive the data

I have read Robin2's Serial Input Basics post but I don't really know what should I do with it.

Should I send my struct with a start char and check it on the receiver, and if it recognizes the start char, then it can read the struct? How do I do that?
I am a bit confused right know, as the post does not show the sender sides.

Implement it :wink:

Aka, drop sending the struct. Because your struct can contain every byte imaginable. Aka, doesn't leave a specific byte to be used as a start/stop marker. Just send your values as ASCII with a simple .print(). Add start en stop bytes to know (on both ends) where you are and use a separator to separate the values.

Allright I will try it. Hope I will understand the code.

Well in general case indeed the struct could contain any possible byte, but here it represents T° and humidity. They will have known min and max based on sensor

With an Si7021 you get a ± 3% relative humidity measurements with a range of 0–80% RH, and ±0.4 °C temperature accuracy at a range of -10°C to +85 °C

With a DHT22 Humidity will range from 0 to 100% with a 2-5% accuracy and Temperature from -40°C to 80°C, ±0.5°C accuracy

If this is this type of application, there is no real point to even keep decimals... you could use a int8_t to represent the data between -128 to 127... any sense of accuracy beyond that is just vain...

And as -128 0r -113 (for example) is not a possible value, you could use that as you start/end marker

If you want to keep one decimal digit, multiply by 10 and store in int16_t. Then you have two bytes per data so it’s a bit more tricky but You can use a 3 byte marker such that any two bytes (1 and 2 or 2 and 3) would not form a possible value. That would be your magic pattern to track.for example -113 (0x8F or 0b10001111) repeated 3 times would work as you’ll see 8F8F8F coming in and 8F8F is -28785 which is not a possible value. So you would know it’s the start frame

That being said, in many cases ascii with start market and separators works well too - it’s just a bit more verbose