我在一个bytearray中存储从AVR / Arduino发送的串行数据。 由于该数组存储了2个不是结构数据的字节,我需要找到一种“忽略”theese的方法。我通过将指针增加2 * typelength找到了解决方案 和memmove的使用(忽略我的代码中struct id的解释,因为它不相关)。当我打印出我的结构变量时,我得不到我想要的结果,这些值完全不同。使用Arduino Nano aka 328p。
class BMS_Struct(LittleEndianStructure):
_fields_ = [("cells", c_uint16 * 13),
("total_voltage", c_uint16),
("current", c_uint16),
("rsense", c_uint16),
("cellreference", c_uint8),
("cellcount", c_uint8),
("bms_mode", c_bool)]
ctype_struct = BMS_Struct()
arduino = serial.Serial()
def receive_struct():
start = 0x85
detected_start = False
message_length = 0
data_in = 0
crc = 0
arduino.baudrate = 57600
arduino.timeout = 0
arduino.port = 'COM8'
try:
arduino.open()
except serial.SerialException, e:
print e
while True:
if(arduino.inWaiting() > 1 and detected_start == False):
data = ord(arduino.read())
if data == start:
detected_start = True
else: print data
elif(arduino.inWaiting() > 1 and detected_start == True and message_length == 0):
message_length = ord(arduino.read())
print "Got message length ", message_length
data_in = c_uint8 * message_length
data_in = data_in()
data_in[0] = message_length
elif(arduino.inWaiting() >= message_length-1 and detected_start == True and message_length != 0):
for index in range(message_length-5):
data_in[index+1] = ord(arduino.read())
for index in range(4):
crc |= (ord(arduino.read())<<(index*8) )
print "CRC arduino = ",hex(crc), format(crc, '032b')
crc_python = (binascii.crc32(data_in) & 0xffffffff)
print "CRC pyhton = ", hex(crc_python),format(crc_python, '032b')
test = data_in[2:len(data_in)-1] // returns a list instead of c_ubyte array
ptr = cast(data_in, POINTER(c_ubyte))
ptr = cast(pointer(ptr), POINTER(c_void_p))
ptr.contents.value += sizeof(ptr._type_)* 2 // increase pointer by 2 * type
memmove(pointer(ctype_struct), ptr, len(data_in)-2)
print ctype_struct.cells[0]
print ctype_struct.cells[2]
ctype_struct.cells[0] = 5
detected_start = False
message_length = 0
crc = 0
在arduino方面
void setup() {
Serial.begin(57600);
bms.cells[1] = 327;
bms.cellcount = 10;
}
void loop() {
write_struct_serial((byte*)&bms, sizeof(bms), BMS_ID);
delay(1000);
}
byte write_struct_serial(uint8_t* struct_ptr, uint8_t struct_length, uint8_t struct_id){
byte data_out[struct_length + 2]; // msg_length1, struct_id1, struct[], crc4 defined as message
data_out[0] = 2 + struct_length + 4; // Mesage length
data_out[1] = struct_id;
for(byte i=0; i<struct_length; i++){
data_out[i+2] = *(struct_ptr+i);
}
unsigned long crc = crc_string_byte((byte*)data_out, sizeof data_out);
Serial.write(start);
Serial.write(data_out, sizeof data_out);
Serial.write(crc);
Serial.write(crc>>8);
Serial.write(crc>>16);
Serial.write(crc>>24);
}
struct BMS
{
unsigned int cells[13];
unsigned int bms_total_voltage;
unsigned int current;
unsigned int rsense;
byte cellreference; //1.22 for cell type 0/1, for 2/3 0.61
byte cellcount;
boolean bms_mode;
};
在C中,我通过在2 AVR之间通过I2C使用指针和memcpy,运行良好。
struct BMS bms;
byte* struct_ptr = ((byte*)&msg_in)+2; // msg_in byte[]
memcpy(&bms,struct_ptr,struct_length); //
也许存在问题,因为ctype结构不等同于保存在AVR上的ram结构中,也许我应该使用Union?
我没有在ctypes doc上找到任何提示,指出结构如何在内存中表示(或与所有c编译结构兼容),只是它创建了c兼容类型。 Arduino使用gnu-c编译器,我使用ver 1.05也许我必须检查两个编译器是否有相同的版本? 进一步的调查导致我的结构数据不是一直都是一样的,但是我一遍又一遍地发送它,这甚至可以按照我想要的方式工作吗?
修改 似乎指针解决方案不起作用,ptr.contents.value + = sizeof(ptr。 type )* 2似乎增加10和+ = 2增量2但数据仍然是错误的。我找到了一个简单的解决方案! 供参考:
test = c_uint8 * (message_length -6)
test = test()
for index in range(sizeof(test)):
test[index] = data_in[index+2]
memmove(pointer(ctype_struct),pointer(test), len(test))