Interpreting some Arduino Serial Code

Hi, all! I’ve been working with the lovely hoverboard-firmware-hack project on github. The host of the repo graciously supplied some Arduino C code to interface with the overridden hoverboard over a UART connection. It goes like so:

typedef struct MsgToHoverboard_t{
  unsigned char SOM;  // 0x02
  unsigned char len;  // len is len of ALL bytes to follow, including CS
  unsigned char cmd;  // 'W'
  unsigned char code; // code of value to write
  int16_t base_pwm;   // absolute value ranging from -1000 to 1000 .. base_pwm plus/minus steer is the raw PWM value
  int16_t steer;      // absolute value ranging from -1000 to 1000 .. wether steer is added or substracted depends on the side R/L
  unsigned char CS;   // checksumm
};

uint16_t baseSpeed = 0;

typedef union UART_Packet_t{
  MsgToHoverboard_t msgToHover;
  byte UART_Packet[sizeof(MsgToHoverboard_t)];
};

void setHoverboardPWM( int16_t base_pwm, int16_t steer )
{
  UART_Packet_t ups;

  ups.msgToHover.SOM = 2 ;  // PROTOCOL_SOM; //Start of Message;
  ups.msgToHover.len = 7;   // payload + SC only
  ups.msgToHover.cmd  = 'W'; // PROTOCOL_CMD_WRITEVAL;  // Write value
  ups.msgToHover.code = 0x07; // speed data from params array
  ups.msgToHover.base_pwm = base_pwm;
  ups.msgToHover.steer = steer;
  ups.msgToHover.CS = 0;

  for (int i = 0; i < ups.msgToHover.len; i++){
    ups.msgToHover.CS -= ups.UART_Packet[i+1];
  }

  mySerial.write(ups.UART_Packet,sizeof(UART_Packet_t));
}

So what I am trying to do here is get the code to run on a raspberry pi, which works a little differently. I’ve tried recreating this code in Python, and then in c++ trying out termios.h and wiringSerial.h.

I think the reason it isn’t working is that I simply don’t understand what’s going on in that little for loop there. I feel like it is just building the checksum (0 - the data bits). But at the same time, the mySerial.write() command uses the ups.UART_PACKET, which doesn’t really make sense to me since only the ups.msgToHover is ever modified here. That being said, it’s probably a lack of understanding on my part. Obviously something is working here because it works flawlessly on an arduino.

I started up minicom on the Pi and made a connection to the arduino in Hex mode to see if I couldn’t just mimic the bits and the first thing I noticed is that although I had the code set up to send the exact same command every second, the hex bits didn’t always match! Like between calls, even those first couple bits (like SOM and len) weren’t always 0x02 and 0x07, which really surprised me. That’s probably another thing I don’t understand.

What’s going on here? Should I go ask on an RPi forum instead?

Thanks so much.

The code is using a Union (between the struct MsgToHoverboard_t and a byte array) so it can send the content of the struct as a series of bytes. A Union is a way of giving the same memory space two different names and viewing it as two different datatypes.

My guess is that the problem is that your Python program is not interpreting the received data the same way as the Arduino. Have a look at the Python struct.unpack() function.

...R