Wednesday, February 16, 2022

[SOLVED] How can a Raspberry PI receives a struct from Arduino?

Issue

I am trying to find a solution to this problem for a few days and nothing worked for me so far. I have to mention thou that Python is not my strong point.

Anyway, I am trying to send a typedef struct using a LoRa transceiver(RFM95) that I programmed with the Radiohead library. The structure looks like this:

typedef struct {
    double temp;
    double hum;
} Payload;

I am able to receive the data on the raspberry side, but like an array of bytes.

Received: [0, 0, 228, 65, 154, 153, 65, 66]

How can I convert this into an object like {temp: VALUE_OF_TEMP, hum: VALUE_OF_HUM}?

Is there a way to do so like in C? Example:

typedef struct {
    double temp;
    double hum;
} ReceivedData;
ReceivedData data;

data = *(Payload*)receivedBuffer;

Please help! I ran out of ideeas!


Solution

You didn't mention what kind of Arduino you are using, I'm assuming that you are using an Arduino Uno or something with an 8-bit MCU. For Arduino with 8-bit MCU, the double is just like float consists of 4 bytes instead of 8 bytes in 32-bit MCU or Raspberry Pi.

So to unpack the struct on the RPI with Python, I think this is what you are looking for:

import struct

data = [0, 0, 228, 65, 154, 153, 65, 66]

bstr = bytearray(data)
result = struct.unpack("<ff", bstr)
print(result)

This would product the result as:

(28.5, 48.400001525878906)

I think these are the two values that you sent over the Arduino.

Update

If you are receiving data that consists of multiple data structs, you can use iter_unpack() method:

import struct
data = [0, 0, 228, 65, 154, 153, 65, 66, 0, 0, 228, 65, 154, 153, 65, 66, 0, 0, 228, 65, 154, 153, 65, 66]
bstr = bytearray(data)
results = struct.iter_unpack("<ff", bstr)
for result in results:
    print(result)

I would suggest you read the documentation of Python struct in more details to take the full advantage of the library.



Answered By - hcheung
Answer Checked By - Cary Denson (WPSolving Admin)