No UART Communication

It looks like I am sending and I can see something spitting back fro Odrive on my scope, but I think something is amiss with my software.

My board is a custom version of a Teensy 3.2. I am using the TeensyArduino software running on PlatformIO. Essentially, I am trying to verify that I can send commands and get data back, but the data is always zeros.

My code:

#include <Arduino.h>
#include <SoftwareSerial.h>
#include <ODriveArduino.h>

// Printing with stream operator
template inline Print& operator <<(Print &obj, T arg) { obj.print(arg); return obj; }
template<> inline Print& operator <<(Print &obj, float arg) { obj.print(arg, 4); return obj; }

// Serial to the ODrive
SoftwareSerial odrive_serial(0, 1); //RX (ODrive TX), TX (ODrive RX)

// ODrive object
ODriveArduino odrive(odrive_serial);

void setup()
{
//-------------------------------------------------------------------------
// TCXO Oscillator Setup
// -------------------------
// Clear EREFS2 bit in MCG_C2 - External reference clock requested.
//-------------------------------------------------------------------------
MCG_C2 = 0x20; // MLD 6/13/20

//-------------------------------------------------------------------------
// Below are some sample configurations.
// You can comment out the default Teensy one and uncomment the one you wish to use.
// You can of course use something different if you like
// Don't forget to also connect ODrive GND to Arduino GND.
//
// Teensy 3 and 4 (all versions) - Serial1
// pin 0: RX - connect to ODrive TX
// pin 1: TX - connect to ODrive RX
// See https://www.pjrc.com/teensy/td_uart.html for other options on Teensy
//-------------------------------------------------------------------------
// ODrive uses 115200 baud
//-------------------------------------------------------------------------
odrive_serial.begin(115200);

// Serial to PC for debugging
Serial.begin(115200);

analogReadResolution(12);       // Set all A/D converters to 12-bit precision.

} // END setup()

void loop()
{
analog_inputs ();
digital_grip_io ();

if (PrintDelay++ > 100)  // Do this every 500mS.
{
    Serial.print("Analog Channel X = ");
    Serial.println(average_x);

    Serial.print("Analog Channel Y = ");
    Serial.println(average_y);

    Serial << "Vbus voltage: " << odrive.getBusVoltage() << '\n';
    Serial << "Roll_Pos: " << odrive.GetParameter(0, odrive.PARAM_FLOAT_ENCODER_PLL_POS) << '\n';
    Serial << "Pitch_Pos: " << odrive.GetParameter(1, odrive.PARAM_FLOAT_ENCODER_PLL_POS) << '\n';
    
    Serial << '\n';

    PrintDelay = 0;
}

//---------------------------------------------------------------------------
// A brief delay, so this loop runs "approximately" once every 5 milliseconds.
//---------------------------------------------------------------------------
delay(5);

} // END loop ()

Update:

Well, bought an oscilloscope with UART decode and what I found was interesting…

The ASCII data sent from my microcontroller is: $G 0 0!

This was generated from the following code using the Arduino library: odrive.getBusVoltage();

The response back from the Odrive 3.6, which I wasn’t able to decode until now, is: UNKNOWN COMMAND

The getBusVoltage command appears to be from the Odrive library as:

float ODriveArduino::GetParameter(int motor_number, ParamNamesFloat parameter) {
int idx = kMotorOffsetFloat + kMotorStrideFloat * motor_number + parameter;
serial_ << "$g 0 " << idx << “!”;
return readString().toFloat();
}

The documentation on the Odrive web page for ASCII does not match this format (there is no example for the g command, so I am substituting this):

v 0 1 0

The documentation doesn’t show a $ or the terminating ! in the command string. Is my Arduino-Odrive library wrong or more likely the way I am calling it wrong?

What is the correct format for this command?

Figured it out, sort of.

For whatever reason the library does not work as I expected.

Simply sending the command as follows: odrive_serial << “r axis0.encoder.shadow_count\n”;

works fine.

1 Like