结构从arduino到ctype结构

时间:2015-02-01 21:33:32

标签: python arduino ctypes

我在一个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))

0 个答案:

没有答案