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.