Odd Replies to Native Protocol over UART

I’ve been working on getting the native protocol to work over UART using a teensy/Arduino.

After scouring the documentation and some Wireshark sniffing of the USB transactions between the python odrivetool and the board I finally got it to reply. But the responses make no sense.

I’m running FW 0.5.1RC and running odrivetool generate-code tells me that my json_crc is 0x9B40. UART Baud is 115200.

When I sniff the USB calling the serial_number endpoint, 4, I get the following (chosen since it outputs the same number every time):

Request: 0x91, 0x00, 0x04, 0x80, 0x08, 0x00, 0x40, 0x9B

Response: 0x91 0x80 0x48 0x50 0x7A 0x33 0x5E 0x20
which corresponds to the correct serial number of 20 5E 33 7A 50 48 (HEX) / 35588962668616 (dec)

I can correlate the above the protocol documentation and it makes sense.

The issue is now when I go to use it over UART. I set tup.config to native for the UART and flashed the firmware.

It is my understanding the the UART expects the stream version of the protocol.

I dug into /Firmware/fibre/python/fibre/protocol.py and tried to figure out the proper packet format for a Stream.

After hours of playing, I finally got replies from the ODrive when I sent the following request for the serial number:

byte request = {0xAA, 0x06, 0x00, 0x91, 0x00, 0x04, 0x80, 0x08, 0x00, 0x0A, 0x33};

I calculated the last 2 CRC16 bytes using the polynomial and initial value at the bottom of the documentation for {0x91, 0x00, 0x04, 0x80, 0x08, 0x00} to be 0x0A33

Here’s where I’m lost (although probably sending the wrong thing too).

When I send a “valid” request, the reply I get from the ODrive is always:

756E6B6E6F776E20636F6D6D616E64DA (HEX).

Out of curiosity, the following permutations of the request all have the same response as above (others give nothing):

byte request = {0xAA, 0x06, 0x00, 0x91, 0x00, 0x04, 0x80, 0x08, 0x00, 0x0A};
byte request = {0xAA, 0x08, 0x00, 0x91, 0x00, 0x04, 0x80, 0x08, 0x00, 0x0A};
byte request = {0x91, 0x00, 0x04, 0x80, 0x08, 0x00, 0x0A, 0x33};
byte request = {0xAA, 0x06, 0x00, 0x91, 0x00, 0x04, 0x80, 0x08, 0x00, 0x33, 0x0A};

I looked through the raw binary output on both my serial terminal and on a oscilloscope to see if I can find the “10101010” representing AA without luck (assuming that maybe there was a shift in the data).

Any suggestions on where I’m going wrong?

Thanks in advance,
Matt

P.S. Here is my teensy code:

#include <Arduino.h>

void setup()
{
  Serial.begin(115200);
  Serial3.begin(115200);
}

elapsedMillis sendCommandTimer;

byte request[] = {0xAA, 0x06, 0x00, 0x91, 0x00, 0x04, 0x80, 0x08, 0x00, 0x0A, 0x33};
//byte request[] = {0xAA, 0x08, 0xFC, 0x00, 0x91, 0x80, 0x04, 0x00, 0x08, 0x9B, 0x40, 0xE6, 0x5E};

void loop()
{

  if (sendCommandTimer > 20)
  {
    Serial.println();
    Serial.println("new send");
    sendCommandTimer = 0;
    Serial3.write(request,11);
  }


  while (Serial3.available() > 0)
  {
    byte c = Serial3.read();
    Serial.print(c,HEX);
  }

}

Update: I figured out my problem and also how the protocol works over UART!

Made a video about it that will hopefully help anyone else struggling.

Now going to try and modify the I2C Arduino example to work over UART.

1 Like