Help with setting up ODrive to work with Magic Pie motor

looks so my odrive lacks power. I get some weird errors.
I get turning off the motor with an error 20 if current_limit more than 10.0f.
Turning off occurs when I trying to apply a force and rotate the motor from set position

It happend with Magic Pie and N5060

Probably somewhere there is a loss of current. How can this be verified?

-------- Magic Pie --------
Here is the video where the motor turns off after a while if i apply a force with error 20 (20A, 2500 ppr encoder .use_index=true) https://youtu.be/EwSUimDZ7oc

Here is the video where the motor turns off almost immediately with error 20 (10A, 2500 ppr encoder .use_index=false) https://youtu.be/PVnwPBquiEU

Here is the video where cur_lim =2.0f and everythig is ok, no errors, the motor doesn’t turns off https://youtu.be/WqJm22GtKGA (2A,2500 ppr, use_index=true)
I can rotate motor as i wish, but if i send SetParameter(…,20f) then it will turn off if i apply a force

Here is the video i made with oscilloscope connected to the bus voltage https://youtu.be/zjvwrl-6fCU
Bus voltage stays about 48 V (20A, default encoder 600 cpr)

Pulleys ratio always 1:9.75

-------- n5060 --------
This also happens with n5060 when cur_lim = 30f, here is the video https://youtu.be/oo6D2SFX8CY (n5060, default encoder 600 cpr, 30A)

In generally, what does mean error 20?

---- My settings in low_level.c:----
.pole_pairs = 28
.resistance_calib_max_voltage = 4.0f
.current_lim = 02.0f - 30.0f

.encoder_cpr = 5850 * 4 for default 600 cpr encoder
.encoder_cpr = 24375 * 4 for 2500 ppr encoder
.use_index=false or true

Сould you tell please how can i check Z index encoder by osciloscope?
Sometimes i get this https://youtu.be/QVcy4Hxtdj8 strange behavour when
.use_index =true, .manually_calibrated = true,
Looks like encoder cant find z pulse, but usually all is normal.

I still doing varios tests… If something clears up, I’ll write more accurately

I am trying to make compact industrial manipulator
I already planned pneamatic and mechanic parts and get ready to assemble their together.
But i can’t start because this weird errors.
here is prototype model


Thanks for the detailed presentation on the issue with error 20.

You can check what the error codes mean by reading the documentation. Error 20 is DRV_FAULT. You are experiencing an hardware bug that is present in ODrive v3.4, and is further explained here. In that post I suggest a mod that you can try. If that mod doesn’t work I can send you an ODrive v3.5 as a replacement: the DRV fault has been tested to be fixed in v3.5.

Cheers.

unfortunately I did not manage to correct the error.
I re-soldered capacitors but now i have this behavior https://youtu.be/kU1QT81mEJo
I tried not to overheat the board and I did it like this

I understand that product development is iterative and I am ready to support the project. Therefore, I am ready to order ODrive 3.5 (i have 3 motors, so i need 2 boards)

One more question
Сould you tell please how can i check Z index encoder (by osciloscope or something else)?
Sometimes i get this https://youtu.be/QVcy4Hxtdj8 strange behavour when
.use_index =true, .manually_calibrated = true,
Looks like encoder cant find z pulse, but usually all is normal.

That is actually because the calibration current is too low and/or the friction is too high and the motor can’t turn.

This happens if the ODrive sees the index pulse in the wrong place, or you write .manually_calibrated = true but didn’t write the correct value in .encoder_offset. You must:

  1. run use_index = true and manually_calibrated false
  2. run calibration
  3. read out .encoder_offset and write into firmware
  4. set also manually_calibrated to true

If you did all this correctly, then it could be electrical. Yes you can check with oscilloscope.

Yes, it was too low calibration current 2.0f, in any case before it was enough to calibrate
After I set .calibration_current=10.0f and .current_lim=30.0f i got the same turning off n5065

I need to clarify one thing
You wrote

Does this mean that I should warm the board so that the solder penetrates through the hole to the back side? Or just solder like I did?

I have one more strange behavior with Z index encoder (i just want to apologize for my English, but I need to solve these problems)
I found this behavior when I tried to reduce the initial motion of the motor to find the index and set the motor already in the position where the index is
I got the same behavior with a big motor (Magic Pie) too.
I have to say that this behavior does not occur in every initial position and I had to look for it.
Also, it does not happen every time when i turn on the power.
I used a non-fixed ODrive 3.4 with no resoldered capasitors c35,c50 with a current =10A.

The behavior shown in the video below, before I did the following:

  1. i rotated the motor so that the mark (cut off part) on the encoder was on top

  2. i set use_index=true and manually_claibrated =false in firmware and flashed the board

  3. after that i turn on power and then motor slighly rotate from position by itself,
    it rotates so that the mark slightly shifted

  4. After initial move finished i run explore_odrive.py get the offset = -6105 and set it and manually_claibrated =true in firmware

  5. Now when i power on with the mark on top then all is normal
    when i power on with shifted mark i get this behavior


On this video

  1. the mark on the top
  2. I rotate the motor to show the position with shifted mark (to that position motor rotates by itself)
  3. i set mark on the top again and turn on the power - there is no error and the motor rotates to the position when the mark is shifted
  4. I turn off the power and turn it on again ( the motor is in exactly the position with shifted mark and this position to which it rotates by itself)
  5. so strange behavior of the motor is obtained.

Settings:
Motor - N5065
Encoder 2500ppr NPN (aliexpress.com/item/GHS3806-pnp-signal-output-2500-PPR-optical-linear-encoder-reflective-optical-speed-encoders-with-cable/32810781565.html)

.pole_pairs = 7,
.calibration_current = 10.0f,
.current_lim = 10.0f,
.use_index =true,
.index_found = false,
.manually_calibrated = true,
.idx_search_speed = 10.0f,
.encoder_cpr = (2500 * 4),
.encoder_offset = -6105,

If z pulse is triggered once per revolution, then why are there several stable motor positions per round?
Here on this video i rotate the motor for some angle and the motor is fixed in the next position as if it made a whole round

I recheked - there is only one Z pulse per round

Settings:
Motor - N5065
Encoder 2500ppr NPN

.pole_pairs = 7,
.calibration_current = 10.0f,
.current_lim = 10.0f,
.use_index =true,
.index_found = false,
.manually_calibrated = true,
.idx_search_speed = 10.0f,
.encoder_cpr = (2500 * 4),
.encoder_offset = -6105,

To test work with another encoder i bought a new Z encoder E6B2CWZ6C (2500 ppr)


But when i connect it to Odrive i always get error 22 (ERROR_ENCODER_CPR_OUT_OF_RANGE)

Via oscilloscope i checked - there are pulses from encoder. Pulses V=~5.4 volts

I counted the number of pulses with the help of an adruino connected to Odrive
when Odrive does initial move there are ~ 2500 counted pulses and after that Odrive stops with error 22.
Can I get Odrive to make a full initial move and not stop with an error so that I can count the real number of pulses?
Because my_odrive.motor0.encoder.encoder_offset returns 0 when motor0.error = 22

Settings:
Motor - N5065

.pole_pairs = 7,
.calibration_current = 10.0f,
.current_lim = 10.0f,
.use_index =false,
.index_found = false,
.manually_calibrated = false,
.idx_search_speed = 10.0f,
.encoder_cpr = (2500 * 4),
.encoder_offset =0,

Soldering like you did should be fine.

What happens if you hold the base down to the table and dampen the oscillations with your hand. Will it start oscillating again, or will it stay stopped?


It looks like you have .encoder.motor_dir set incorrectly. You must be careful to keep the encoder phase wires and the motor phase wires the same from when you do the encoder calibration. And you must also copy .encoder.motor_dir when you copy .encoder_offset and set .manually_calibrated = true.


I would suggest to just turn the motor by hand after it has errored into error 22. It should still be counting pulses. So you can turn the motor and still read with the arduino and you can also still read my_odrive.motor0.encoder.encoder_state.

I did some tests for the Z encoder 2500 changing the starting position and motor_dir and that’s what behavior I was able to detect:

  1. .encoder_offset =-6263, .motor_dir = -1 looks like that it can’t find z pulse
    https://youtu.be/urRpeb1Ho8I

  2. .encoder_offset =-6263, .motor_dir = 1 there are several stable motor positions per round (not by z pulse)
    https://youtu.be/2NyKRk6UsS0

  3. .encoder_offset =-6263, .motor_dir = 1 in some positions there is that strange behavior. I tried to damp the oscillations with my hand
    https://youtu.be/qBpkqKWuDM0

Settings:
Motor - N5065
.calibration_current = 10.0f,
.current_lim = 10.0f,
.use_index =true,
.index_found = false,
.manually_calibrated = true,
.encoder_cpr = (2500 * 4),
.encoder_offset =-6263,


I understand that you may have many other things to do, but may I suggest to send this assembly (encoder,N5065 and Odrive) to you for verification ?
I will not disassemble this assembly so you could see this behavior.
Also i want to send the E6B2CWZ6C encoder with which ODrive does not work either (I ordered 3 such encoders, i checked all of them, and I wan’t to know - the problem is in them or in ODrive).
I can pay some money for checking and setting up.
Anyway, I’m going to order the new version 3.5 and I do not need version 3.4, but I need to be sure that these errors will not be in the new version.
Because this behavior with a large motor and current of 40 A can be dangerous.

It looks to me like the correct setting is motor_dir = -1, but something has changed (a phase wire is plugged in differently, some mechanical coupling has shifted, etc). Can you run the encoder calibration again?

Sure if you like you can send your rig to me and I can set it up correctly for you. You don’t have to pay for the time for me to set it up if everything is wired up and I only have to change firmware settings, just pay for the shipping.

Hello.
I’ve tested the Odrive 3.5 with the Z index encoder OMRON 2500 cpr and motor N5065.

Strange behavior repeats.
startup_motor_calibration - is ok
startup_encoder_index_search - is ok
But if after startup send
odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL
then there is uncontrolled N5065 rotation
And after this odrv0.axis0.error returns code 49

Here is the video

Here is the json i used as backup-config
{
“config”: {
“brake_resistance”: 2,
“enable_uart”: true,
“enable_i2c_instead_of_can”: false,
“enable_ascii_protocol_on_usb”: true,
“dc_bus_undervoltage_trip_level”: 8,
“dc_bus_overvoltage_trip_level”: 51.840003967285156
},
“axis0”: {
“config”: {
“startup_motor_calibration”: true,
“startup_encoder_index_search”: true,
“startup_encoder_offset_calibration”: false,
“startup_closed_loop_control”: false,
“startup_sensorless_control”: false,
“enable_step_dir”: false,
“counts_per_step”: 2,
“ramp_up_time”: 0.4000000059604645,
“ramp_up_distance”: 12.566370964050293,
“spin_up_current”: 10,
“spin_up_acceleration”: 400,
“spin_up_target_vel”: 400
},
“motor”: {
“config”: {
“pre_calibrated”: false,
“pole_pairs”: 7,
“calibration_current”: 10,
“resistance_calib_max_voltage”: 1,
“phase_inductance”: 0,
“phase_resistance”: 0,
“direction”: 1,
“motor_type”: 0,
“current_lim”: 10,
“requested_current_range”: 70
}
},
“controller”: {
“config”: {
“control_mode”: 3,
“pos_gain”: 20,
“vel_gain”: 0.0005000000237487257,
“vel_integrator_gain”: 0.0010000000474974513,
“vel_limit”: 20000
}
},
“encoder”: {
“config”: {
“mode”: 0,
“use_index”: true,
“pre_calibrated”: true,
“idx_search_speed”: 10,
“cpr”: 10000,
“offset”: 0,
“offset_float”: 0,
“calib_range”: 0.019999999552965164
}
}
},
“axis1”: {
“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,
“ramp_up_time”: 0.4000000059604645,
“ramp_up_distance”: 12.566370964050293,
“spin_up_current”: 10,
“spin_up_acceleration”: 400,
“spin_up_target_vel”: 400
},
“motor”: {
“config”: {
“pre_calibrated”: false,
“pole_pairs”: 7,
“calibration_current”: 10,
“resistance_calib_max_voltage”: 1,
“phase_inductance”: 0,
“phase_resistance”: 0,
“direction”: 1,
“motor_type”: 0,
“current_lim”: 10,
“requested_current_range”: 70
}
},
“controller”: {
“config”: {
“control_mode”: 3,
“pos_gain”: 20,
“vel_gain”: 0.0005000000237487257,
“vel_integrator_gain”: 0.0010000000474974513,
“vel_limit”: 20000
}
},
“encoder”: {
“config”: {
“mode”: 0,
“use_index”: false,
“pre_calibrated”: false,
“idx_search_speed”: 10,
“cpr”: 8192,
“offset”: 0,
“offset_float”: 0,
“calib_range”: 0.019999999552965164
}
}
}
}

The problem is the your have set “pre_calibrated”: true, but not written the offset.

If i set
“pre_calibrated”: false,
then
odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL doesn’t work.

I tried folowing:

  1. set in json
    “startup_motor_calibration”: true,
    “startup_encoder_index_search”: true,
    “startup_encoder_offset_calibration”: false,
    “startup_closed_loop_control”: false,
    “startup_sensorless_control”: false,
    “encoder”: {
    “config”: {
    “pre_calibrated”: false

  2. After startup index search run the commands
    1
    AXIS_STATE_CLOSED_LOOP_CONTROL doesn’t work

  3. What is the meaning of offset if after
    odrv0.axis0.requested_state = AXIS_STATE_ENCODER_INDEX_SEARCH offset is always 0
    2
    if in the json set
    "startup_motor_calibration": true,
    "startup_encoder_index_search": true,
    after startup_encoder_index_search offset equals 0 always

  4. What is the meaning of offset_float ?

Please follow the steps in the documentation exactly.
Specifically you need to:

  1. run AXIS_STATE_ENCODER_INDEX_SEARCH
  2. run AXIS_STATE_ENCODER_OFFSET_CALIBRATION

in that order. But yeah just follow all the steps in the docs.

I did as you wrote but there is some strange behavior to me.
If i change the start position of the motor when Odrive is switched on, the motor CLOSED_LOOP is fixed not to the Z index position.
But if in JSON set "startup_encoder_index_search": true then why after found z index motor is shifted and does not remain in the position Z index?

Does this mean that I can’t change the starting position of the motor despite the fact that every time there is a search for z index?

Here is the video

On the video i did folowing

  1. the motor is on in the position in which I calibrated the encoder with index signal. Therefore when i switched on everything is fine and CLOSED_LOOP retains Z index position.
  2. I changed the initial position of the motor and turned on the Odrive - the motor has shifted relative to the Z index and CLOSED_LOOP retains NON Z index position

Here is json

{
“config”: {
“brake_resistance”: 2,
“enable_uart”: true,
“enable_i2c_instead_of_can”: false,
“enable_ascii_protocol_on_usb”: true,
“dc_bus_undervoltage_trip_level”: 8,
“dc_bus_overvoltage_trip_level”: 51.840003967285156
},
“axis0”: {
“config”: {
“startup_motor_calibration”: true,
“startup_encoder_index_search”: true,
“startup_encoder_offset_calibration”: false,
“startup_closed_loop_control”: true,
“startup_sensorless_control”: false,
“enable_step_dir”: false,
“counts_per_step”: 2,
“ramp_up_time”: 0.4000000059604645,
“ramp_up_distance”: 12.566370964050293,
“spin_up_current”: 10,
“spin_up_acceleration”: 400,
“spin_up_target_vel”: 400
},
“motor”: {
“config”: {
“pre_calibrated”: false,
“pole_pairs”: 7,
“calibration_current”: 10,
“resistance_calib_max_voltage”: 1,
“phase_inductance”: 0.000016686473827576265,
“phase_resistance”: 0.03275086358189583,
“direction”: 1,
“motor_type”: 0,
“current_lim”: 10,
“requested_current_range”: 70
}
},
“controller”: {
“config”: {
“control_mode”: 3,
“pos_gain”: 20,
“vel_gain”: 0.0005000000237487257,
“vel_integrator_gain”: 0.0010000000474974513,
“vel_limit”: 20000
}
},
“encoder”: {
“config”: {
“mode”: 0,
“use_index”: true,
“pre_calibrated”: true,
“idx_search_speed”: 10,
“cpr”: 10000,
“offset”: 9519,
“offset_float”: 0.7360302209854126,
“calib_range”: 0.019999999552965164
}
}
},
“axis1”: {
“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,
“ramp_up_time”: 0.4000000059604645,
“ramp_up_distance”: 12.566370964050293,
“spin_up_current”: 10,
“spin_up_acceleration”: 400,
“spin_up_target_vel”: 400
},
“motor”: {
“config”: {
“pre_calibrated”: false,
“pole_pairs”: 7,
“calibration_current”: 10,
“resistance_calib_max_voltage”: 1,
“phase_inductance”: 0,
“phase_resistance”: 0,
“direction”: 1,
“motor_type”: 0,
“current_lim”: 10,
“requested_current_range”: 70
}
},
“controller”: {
“config”: {
“control_mode”: 3,
“pos_gain”: 20,
“vel_gain”: 0.0005000000237487257,
“vel_integrator_gain”: 0.0010000000474974513,
“vel_limit”: 20000
}
},
“encoder”: {
“config”: {
“mode”: 0,
“use_index”: false,
“pre_calibrated”: false,
“idx_search_speed”: 10,
“cpr”: 8192,
“offset”: 0,
“offset_float”: 0,
“calib_range”: 0.019999999552965164
}
}
}
}

We currently only uses Z index to calibrate the commutation of the motor, but not the “home” or 0 position. We intend to use home switches for that instead.

If you want the index to see the home position, You can go to the encoder.cpp and where we do set_circular_count(0), you can also zero the linear count.

Sorry, but i need help with this.
I downloaded the latest version from GitHub master branch.
I see that all Visual Studio tools are still working and I can build and flash ODrive as before by calling task / build and task / flash

How exactly can I zero the linear count?

Here is the function from encoder.cpp

void Encoder::enc_index_cb() {
if (config_.use_index && !index_found_) {
set_circular_count(0);
if (config_.pre_calibrated) {
offset_ = config_.offset;
is_ready_ = true;
}
index_found_ = true;
}
}