I’m attempting to control an ODrive using an arduino pro micro over serial and am having trouble with the serial connection - specifically reading data from the ODrive while the motors are running closed loop position control. I’d like to be able to read/write to both axes at ~100hz and will need fast baudrates to free up processing time on the arduino. ODrive is a new v3.6.56 board running 0.5.4
I can use the GetPosition() function to read at 250000 baud reliably from both axes with the motors off, but switch the motors on and within a few seconds GetPosition() begins timing out and never returns a valid number again.
It will work for longer at 57600 baud, up to a few minutes, but eventually the GetPosition() will fail.
At all baud rates I still reliably use SetPosition() to control both motors, even after GetPosition begins to timeout.
I am using hardware serial on the micro, and have toroids with 6 wraps on the motor lines as well as shielding wrap with a drain wire on the motor lines, encoders, and the short serial line to the arduino. Arduino and odrive are connected to my computer with usb isolators. Odrive runs off a 24v madewell power supply.
Have the same problem with a teensy2.0 board.
#include <HardwareSerial.h>
#include <ODriveArduino.h>
#include <ODriveEnums.h>
// Printing with stream operator helper functions
template<class T> 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;
}
//Hardware serial port
HardwareSerial& odrive_serial = Serial1;
// ODrive object
ODriveArduino odrive(odrive_serial);
int counter = 0;
float testPosY = 0.0;
float testPosX = 0.0;
float readXPos, readYPos;
void setup() {
  //PC serial
  Serial.begin(115200);
  // Arduino -> Odrive serial begin
  odrive_serial.begin(115200);
  //Start motors
  odrive.run_state(0, AXIS_STATE_CLOSED_LOOP_CONTROL, false);
  delay(1);
  odrive.run_state(1, AXIS_STATE_CLOSED_LOOP_CONTROL, false);
  delay(1);
  odrive.SetPosition(0, 0);
  delay(1);
  odrive.SetPosition(1, 0);
  delay(500);
}
void loop() {
  //read positions
  odrive_serial << "r axis0.encoder.pos_estimate\n";
  delay(1);
  Serial << odrive.readFloat() << "\n";
  odrive_serial << "r axis1.encoder.pos_estimate\n";
  delay(1);
  Serial << odrive.readFloat() << "\n";
    
  if(counter == 1000){
    counter = 0;
  }
  testPosY = 0.1*sin(counter*0.0062831853);
  testPosX = 0.1*cos(counter*0.0062831853);
  odrive.SetPosition(0,testPosY);
  odrive.SetPosition(1,testPosX);
  counter++;
}
I get the same results using normal GetPositon functions without delays between reads/writes.
Can anyone point me in the right direction? Do I need to come up with my own error handling on the serial line? I don’t have a scope to check what’s really going on.



