Hi
I’m trying to connect the absolute encoder AMT203-V to ODRIVE via Arduino as wrote Lewis_Siempelkamp (https://discourse.odriverobotics.com/u/lewis_siempelkamp/summary)
but I’m having trouble - the motor torque is much less than expected, I guess I didn’t take into account the offset changing
I know that maybe absolute encoder support will soon be in the firmware of Odrive, but I’d like to figure out how it works myself.
Could you look at my code and tell me what’s wrong?
I managed to connect an encoder. ODrive sees it and I can control it via Arduino.
But I’m not quite sure how to set up the correct encoder.offset to make things work.
I rebuilt the firmware with the changes in ascii_protocol.cpp (added a new command to set set_linear_count via Arduino)
if (cmd[0] == 'e') {
unsigned motor_number;
int value;
int numscan = sscanf(cmd, "e %u %i", &motor_number, &value);
if (numscan < 2) {
respond(response_channel, use_checksum, "invalid command format");
} else if (motor_number >= AXIS_COUNT) {
respond(response_channel, use_checksum, "invalid motor %u", motor_number);
} else {
Axis* axis = axes[motor_number];
axis->encoder_.set_linear_count(value);
axis->watchdog_feed();
}
}
I connected the AMT203-V encoder to the ODrive with the N5065 motor
and performed initial initialization by
AXIS_STATE_MOTOR_CALIBRATION
AXIS_STATE_ENCODER_OFFSET_CALIBRATION
and saved the settings using odrv0.save_configuration()
at json, I got the following
“axis0”: {
“config”: {
“startup_motor_calibration”: false,
“startup_encoder_index_search”: false,
“startup_encoder_offset_calibration”: false,
“startup_closed_loop_control”: false,
“startup_sensorless_control”: false,
“enable_step_dir”: false,
“counts_per_step”: 2,
“watchdog_timeout”: 0,
“step_gpio_pin”: 1,
“dir_gpio_pin”: 2
},
…
“encoder”: {
“config”: {
“mode”: 0,
“use_index”: false,
“find_idx_on_lockin_only”: false,
“pre_calibrated”: false,
“zero_count_on_find_idx”: true,
“cpr”: 4096,
“offset”: 7063,
“offset_float”: 1.1783593893051147,
“enable_phase_interpolation”: true,
“bandwidth”: 1000,
“calib_range”: 0.019999999552965164,
“calib_scan_distance”: 50.26548385620117,
“calib_scan_omega”: 12.566370964050293,
“idx_search_unidirectional”: false,
“ignore_illegal_hall_state”: false
}
In addition, I set the encoder to zero with the Arduino command
SPI.begin(); //start transmition
digitalWrite(CS,LOW);
SPI_T(0x70); // set to zero command
digitalWrite(CS,HIGH); //just to make sure
SPI.end(); //end transmition
Below is a part of the code from the .ino file and startup procedure without ENCODER_OFFSET_CALIBRATION
- I’m turning on the Odrive and the Arduino
- then I’m sending a command to initialize the motor
odrive_serial.run_state(0, ODriveArduino::AXIS_STATE_MOTOR_CALIBRATION, true);
- I initialize the encoder via SPI and get its position, let’s say it’s 100 out of 4096
encpos=100
- Writing down linear_count
odrive_serial << "e " << 0 << encpos;
- turning on encoder.is_ready=true
odrive_serial << "w axis" << 0 << ".encoder.is_ready " << 1 << '\n';
- starting CLOSED_LOOP_CONTROL
odrive.run_state(0, ODriveArduino::AXIS_STATE_CLOSED_LOOP_CONTROL, false);
Until I turn off the ODrive, everything works and CLOSED_LOOP_CONTROL keeps the motor in place with sufficient torque
But after switching ODrive off and then on and initializing by these items (1-6)
is_ready is not set immediately = True but only after a few attempts
And the torque on the motor is less than after normal initialization.
I think I forgot to take the offset into account somehow, but I saved the Odrive configuration and it shouldn’t change
And there’s another question. If I know the encoder position and have saved the configuration, can I do without AXIS_STATE_MOTOR_CALIBRATION ?
Thanks in advance