Python struct构造bytearray串口循环发送校验和错误修复
校验和错误原因
你的while循环段代码存在3处问题,直接导致校验和计算失败:
- 校验和遍历循环的计数变量是
y,但读取数组元素时错误使用了外层第一次计算校验和遗留的变量x(第一次for循环结束后x值固定为74),循环全程没有遍历4~74位的所有字节,一直在重复累加array1[74]这一个位置的值 - 每次进入循环计算新的校验和前,没有将
check_sum变量重置为0,会在上一次计算的结果基础上继续累加,数值持续累积后取模的结果完全不符合校验规则 - 计数器
counter持续自增未做截断,当值超过255时,赋值给单字节长度的array1[5]会触发值溢出错误
修复方案
将while循环段的逻辑修正即可,修复后可正常连续传输数据,核心修改点:
- 每次计算校验和前将
check_sum重置为0 - 遍历校验段时使用当前循环变量
y读取对应字节值 - 计数器赋值时做模256处理,适配单字节存储要求
修复后的完整可运行代码:
import serial import struct import time ser = serial.Serial('COM16', 19200, serial.EIGHTBITS, serial.PARITY_NONE, serial.STOPBITS_ONE) size = 78 array1 = bytearray(size) array1[0] = 0xFF array1[1] = 0xFF array1[2] = 0x54 array1[3] = 0x52 array1[5] = 0 array1[76] = 0x0D array1[77] = 0x0A counter = 0 altitude = input("altitude: ") altitude_gps = input("gps altitude: ") locationx = input("location x: ") locationy = input("location y : ") payload_altitude = input("payload altitude: ") locationx_payload = input("location x payload: ") locationy_paylaod = input("location y payload: ") altitude_array = struct.pack('<f', float(altitude)) altitude_gps_array = struct.pack('<f', float(altitude_gps)) locationx_array = struct.pack('<f', float(locationx)) locationy_array = struct.pack('<f', float(locationy)) payload_altitude_array = struct.pack('<f', float(payload_altitude)) locationx_payload_array = struct.pack('<f', float(locationx_payload)) locationy_paylaod_array = struct.pack('<f', float(locationy_paylaod)) array1[6] = altitude_array[0] array1[7] = altitude_array[1] array1[8] = altitude_array[2] array1[9] = altitude_array[3] array1[10] = altitude_gps_array[0] array1[11] = altitude_gps_array[1] array1[12] = altitude_gps_array[2] array1[13] = altitude_gps_array[3] array1[14] = locationx_array[0] array1[15] = locationx_array[1] array1[16] = locationx_array[2] array1[17] = locationx_array[3] array1[18] = locationy_array[0] array1[19] = locationy_array[1] array1[20] = locationy_array[2] array1[21] = locationy_array[3] array1[22] = payload_altitude_array[0] array1[23] = payload_altitude_array[1] array1[24] = payload_altitude_array[2] array1[25] = payload_altitude_array[3] array1[26] = locationx_payload_array[0] array1[27] = locationx_payload_array[1] array1[28] = locationx_payload_array[2] array1[29] = locationx_payload_array[3] array1[30] = locationy_paylaod_array[0] array1[31] = locationy_paylaod_array[1] array1[32] = locationy_paylaod_array[2] array1[33] = locationy_paylaod_array[3] # 首次发送 check_sum = 0 for x in range(4, 75): check_sum += array1[x] check_sum = check_sum % 256 array1[75] = check_sum ser.write(array1) time.sleep(3) while True: counter = counter + 1 array1[5] = counter % 256 # 单字节截断,避免值溢出 # 每次计算校验和前重置为0 check_sum = 0 # 用正确的循环变量y遍历 for y in range(4, 75): check_sum += array1[y] check_sum = check_sum % 256 array1[75] = check_sum ser.write(array1) time.sleep(3)
注:如果你的协议要求计数器是多字节长度,可根据实际协议调整counter的字节拆分逻辑,不要直接赋值给单字节位置即可。
内容的提问来源于stack exchange,提问作者Inertial Measurement Unit
相关产品推荐
相关产品推荐

