Skip to content

Arduino tx_data + pySerialTransfer rx_data example fails with esp32 Arduino #51

@PaulBouchier

Description

@PaulBouchier

On multi-byte wide processors the compiler aligns data items to their native alignment, unless directed otherwise. Thus a float is aligned to a 4-byte boundary. Therefore the testStruct in tx_data is laid out in memory differently between an Arduino Uno & a board like an esp32. Since txObj uses sizeof(T) as the number of bytes to transmit, tx_data sends a different number of bytes from esp32 compared to Uno.

testStruct is shown below with the fix needed for processors with > 8-bit wide data bus
struct STRUCT {
char z;
float y;
//} testStruct;
} attribute((packed)) testStruct;

The original code (commented out line 4 above) causes 3 empty bytes to be placed after z, and before y on esp32, so txObj sends 8 bytes on an esp32, but only 5 on an Arduino Uno. pySerialTransfer is unaware of the packing difference, so tries to pull the float out of bytes 1-4 (counting byte 0 as z), regardless of the sender-architecture.

The example as provided prints the following correct message on pySerialTransfer + Uno:
b'$'4.5 | hello
but the following error message on pySerialTransfer with esp32, caused by pySerialTransfer reading the float out of bytes 1-4 then trying to read the char array out of byte 5, which is actually the 2nd byte of the float.:
Traceback (most recent call last):
File "./rx_data.py", line 30, in
arr = link.rx_obj(obj_type=str,
File "/home/bouchier/.local/lib/python3.8/site-packages/pySerialTransfer/pySerialTransfer.py", line 359, in rx_obj
unpacked_response = unpacked_response.decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x90 in position 1: invalid start byte

Removing the string transfer part of the example prints the following incorrect message on pySerialTransfer + esp32, :
b'$'0.0 |
Note the float, which should be 4.5, is 0.0 because pySerialTransfer is reading the float out of the 3 empty bytes plus first byte of the float.

The correct way to eliminate machine/compiler dependent packing is with the packed attribute as shown on line 5 of testStruct above. Making this change produces the correct output on both Uno & esp32:
b'$'4.5 | hello

Are you open to pull requests to fix the examples so they work on both Uno & esp32? I would test any such changes on both.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions