Python向Arduino发送长整型串口数据重组异常问题排查
Fixing 4-byte Long Integer Serial Communication Between Python and Arduino
Let's break down the issues in your Arduino code that are causing incorrect reconstruction of the 4-byte long integers sent from Python:
1. Critical Errors in the readfourbytes Function
Your function has two major bugs that immediately break the value reconstruction:
- Duplicate parameter names + undefined variable: You've named two parameters
thirdbyte, and the function referencessecondbytewhich isn't even declared as a parameter. This leads the Arduino compiler to use random garbage values forsecondbyte, which explains why your second position value is completely wrong. - Incorrect endianness handling: Python uses
<llto pack the values in little-endian order (least significant byte first), but your shift logic treats the last byte as the most significant byte (big-endian order), which reverses the byte significance entirely.
Fixed Arduino Code
First, fix the readfourbytes function to handle little-endian correctly and resolve the parameter issues:
// Reconstruct a 4-byte little-endian long integer long readfourbytes(byte lsb, byte byte2, byte byte3, byte msb){ // Cast each byte to long before shifting to avoid sign extension issues long result = ((long)msb << 24) | ((long)byte3 << 16) | ((long)byte2 << 8) | lsb; return result; }
Then, ensure your main serial reading code uses the correct array (make sure data is declared as byte data[8]; to hold 8 bytes total):
byte data[8]; // Declare array to hold 2 x 4-byte longs if(Serial.available() >= 8){ // Wait until full 8 bytes are available size_t numbytes = Serial.readBytes(data, 8); for(int i=0; i<8; i++){ Serial.println(data[i], HEX); } // Pass bytes in little-endian order (LSB to MSB) long pos1 = readfourbytes(data[0], data[1], data[2], data[3]); long pos2 = readfourbytes(data[4], data[5], data[6], data[7]); Serial.println(pos1); Serial.println(pos2); }
Key Notes
- Endianness match: Python's
<llpacks each long as[LSB, byte2, byte3, MSB], so our fixed function takes those bytes in the same order and reconstructs the value by shifting the MSB to the highest position, then combining with bitwise OR (safer than addition for byte combination). - Wait for full data: Changed
Serial.available()>0toSerial.available()>=8to ensure we only read when all 8 bytes are present, avoiding partial reads that could corrupt your data. - Sign extension prevention: Casting each byte to
longbefore shifting prevents issues where a byte with the highest bit set would be sign-extended to a negative value in smaller integer types.
With these fixes, sending 100 and 100 from Python will result in Arduino receiving 0x64 0x00 0x00 0x00 0x64 0x00 0x00 0x00, and correctly reconstructing both values as 100.
内容的提问来源于stack exchange,提问作者evan
相关产品推荐
相关产品推荐

