[Solved] - Encoding hooverboard motors with rotary encoder

Do I need to put the odrive in dfu mode? (using the switches) because I got…

DfuError: Could not determine hardware version. Flashing precompiled firmware could lead to unexpected results. Please use an STLink/2 to force-update the firmware anyway. Refer to https://docs.odriverobotics.com/developer-guide for details.

Also, the command “odrv0.config.enable_uart_a = True” still gives me an AttributeError

Yes, you should put it in DFU mode. Sounds like your firmware is insanely old, haha.

I’m still working on connecting the Arduino to the Odrive, but recently my motor started acting weird. When I go to input a position, the motor moves, but it shakes and makes a lot of noise, as if it were struggling to move. Any idea on how I could fix this so that it runs smoother?

Have you tuned PID gains?

What’s that?

The ODrive uses an algorithm called a PID controller to do velocity/position control on the motor. The algorithm requires tuning of the “gains” - the parameters influencing its operation. The default values work for many motors, but not all, and need to be tuned based on the motor and use case.

https://docs.odriverobotics.com/v/0.5.4/control.html

I solved the problem but I’m having another one. I’m trying to connect an Arduino to the Odrive to move the motor, but it seems to not be not working. I’m following this video: https://www.youtube.com/watch?v=OGZaya6PvBY&list=PLc2RScfrSFEDcQp6Qvc7mBNre8ABCoz9p&index=6
I’m also using M1 for the motor. Anything you think I could do to fix this?

Can you provide a bit more information as to what’s not working? Can you connect over USB and do a dump_errors(odrv0) in ODrivetool after trying to command a position/velocity move? Is the motor calibrated? Can the motor move if commanded from ODrivetool? Generally there’s not any way I can help if I don’t know anything about the errors being thrown or what you’re actually trying to do :slight_smile:

There are no errors. When I upload the sketch, everything is fine, but when I send a command (“s”) the motor does not move. Here is the code:

#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(8, 9); //RX (ODrive TX), TX (ODrive RX)
// Note: you must also connect GND on ODrive to GND on Arduino!

// ODrive object
ODriveArduino odrive(odrive_serial);

void setup() {
// ODrive uses 115200 baud
odrive_serial.begin(115200);

// Serial to PC
Serial.begin(115200);
while (!Serial) ; // wait for Arduino Serial Monitor to open

Serial.println(“ODriveArduino”);
Serial.println(“Setting parameters…”);

// In this example we set the same parameters to both motors.
// You can of course set them different if you want.
// See the documentation or play around in odrivetool to see the available parameters
for (int axis = 1; axis < 2; ++axis) {
odrive_serial << “w axis” << axis << ".controller.config.vel_limit " << 50.0f << ‘\n’;
odrive_serial << “w axis” << axis << ".motor.config.current_lim " << 11.0f << ‘\n’;
// This ends up writing something like “w axis0.motor.config.current_lim 10.0\n”
}

Serial.println(“Ready!”);
//Serial.println(“Send the character ‘0’ or ‘1’ to calibrate respective motor (you must do this before you can command movement)”);
Serial.println(“Send the character ‘s’ to exectue test move”);
Serial.println(“Send the character ‘b’ to read bus voltage”);
Serial.println(“Send the character ‘p’ to read motor positions in a 10s loop”);
}

void loop() {

if (Serial.available()) {
char c = Serial.read();

// Run calibration sequence
/*if (c == '0' || c == '1') {
  int motornum = c-'0';
  int requested_state;

  requested_state = ODriveArduino::AXIS_STATE_MOTOR_CALIBRATION;
  Serial << "Axis" << c << ": Requesting state " << requested_state << '\n';
  odrive.run_state(motornum, requested_state, true);

  requested_state = ODriveArduino::AXIS_STATE_ENCODER_OFFSET_CALIBRATION;
  Serial << "Axis" << c << ": Requesting state " << requested_state << '\n';
  odrive.run_state(motornum, requested_state, true);

  requested_state = ODriveArduino::AXIS_STATE_CLOSED_LOOP_CONTROL;
  Serial << "Axis" << c << ": Requesting state " << requested_state << '\n';
  odrive.run_state(motornum, requested_state, false); // don't wait
}*/

// Sinusoidal test move
if (c == 's') {
  Serial.println("Executing test move");
  for (float ph = 0.0f; ph < 6.28318530718f; ph += 0.01f) {
    float pos_m1 = 50.0f * cos(ph);
    //float pos_m1 = 20000.0f * sin(ph);
    odrive.SetPosition(1, pos_m1);
    //odrive.SetPosition(1, pos_m1);
    delay(5);
  }
}

// Read bus voltage
if (c == 'b') {
  odrive_serial << "r vbus_voltage\n";
  Serial << "Vbus voltage: " << odrive.readFloat() << '\n';
}

// print motor positions in a 10s loop
if (c == 'p') {
  static const unsigned long duration = 10000;
  unsigned long start = millis();
  while(millis() - start < duration) {
    for (int motor = 1; motor < 2; ++motor) {
      odrive_serial << "r axis" << motor << ".encoder.pos_estimate\n";
      Serial << odrive.readFloat() << '\t';
    }
    Serial << '\n';
  }
}

}
}

Do you have a logic analyzer or similar? Is it able to read the bus voltage? Have you run the calibration sequence? You can’t move until you calibrate.

I do not have a logic analyzer, but the Odrive is calibrated. Currently I have a new issue I want to deal with first.
The issue is with the motor. When I send a position, it moves to that position, but keeps moving back and fourth when its in it’s final position. Do you know how I can increase the torque so that the motor moves into its position more precisely and does not move back and fourth?

Your vel gains (likely vel integrator gain) is likely too high. You need to tune your gains before you can expect good control (Control Structure and Tuning — ODrive Documentation 0.5.4 documentation)

Thanks for the info, it seems to have worked. Now back to my original problem.

Do you know what version of the firmware I need in order to connect the Odrive to the Arduino? Also, do you know where I can find this firmware at to download?

Is your ODrive updated to 0.5.6? You can find the Arduino library here https://github.com/odriverobotics/ODrive/tree/master/Arduino/ODriveArduino

Thanks for the info, but I’m having another problem. When I enter a position for my motor to move into, it does not move, but when I turn the motor, the motor moves into position really fast and stops working. This is the error I get for the motor:

motor: Error(s):
MotorError.CURRENT_LIMIT_VIOLATION

Do you have any idea on how I could fix this?

You should ensure the motor doesn’t have any external forces occurring during calibration - i.e. it should be able to spin freely.

It does not. The problem happens when I put the motor in closed loop control mode, and I input a position.

I’m having some issues running my motor in closed loop mode. Every time I run it, it does not move right away, and then out of no where it moves really fast and stops. I keep getting this error:

controller: Error(s):
ControllerError.OVERSPEED

I could I fix this?

Hello

Can you make a new post, it’s hard to help without any context. In the new post you can place a picture of your setup, a diagram and the ODrive configuration.

Stijn

I’ve solved this problem, but I’m running into a new problem. Do you know how I can limit the speed of my motor?