Motor = spring ?how?

Did you set the abs_spi_gpio_pin correctly?
When do you get the error? straight away or only when you try closed loop? If the latter, does the calibration all work OK?

You shouldn’t be using wetmelon’s repo anymore - use Oskar’s repo instead:

When you clone the repo, make sure you then switch (checkout) the rc-v0.5.1 branch

The procedure is the same to build the firmware and flash it

a couple of …weeks ago I didn’t even know how to flash the odrive.
I asked on discord and got a .hex file so I could finally flash it.

i think that the whole wireing was ok. I kept getting error during calibration as far as i remember.

how to do this?
when I execute these commands:
git clone
git branch
I see only *master

You need to set encoder.config.abs_spi_gpio_pin to the number of the GPIO you used for CS.
Also, you need to set encoder.config.cpr to 16384.

git clone
cd ODrive
git checkout rc-v0.5.1

I did it for sure.
(I’ll try again as soon as I compile and flash rc-v0.5.1)


I get “no module named yaml” 4 times :confused:

Ive tried pip3 install PyYAML (raspberry pi)
(thx to @Wetmelon)
this time got “no module named jsonschema”
pip3 install jsonschema
and finally no errors :slight_smile:

after switching to rc-v0.5.1 and connecting SPI interface weird things start to happen :slight_smile:

  1. power supply off, odrivetool quit()

  2. power supply on (not even connected to the odrivetool) => motor shaft is being hled by some current (nice and smooth btw :slight_smile:)

  3. setup:
    (MOSI to MOSI, than switched to 3v3 nothing helps)
    a) abs_spi_cs_gpio_pin=4
    b) encoder.config.mode=257
    c) cpr=2**14
    d) first FULL_CALIB failed somewhere in the middle (forgot to check dump_errors :confused: most prob encoder)
    e) second FULL_CALIB ERROR_MOTOR_FAILED (phase resistance out of range)
    f) reboot - motor shaft released for a second and than held again, wtf?

    g) erase_config(), power supply off…motor shaft released
    h) same setup as above
    i) full calib error: (after ~one turn of the shaft) ENCODER_FAILED, NO_RESPONSE

Hmm, puzzling… No idea why it should be holding the shaft at boot, unless it is configured to do something on startup. Are any of axis.config.startup* set?
Could be time to ask @madcowswe on this one

If you are getting phase_resistance_out_of_range try increasing motor.config.calibration_current although the defaults ought to work with the stock motor, so something strange could be going on.
You do have quite long & narrow gauge wire on the motor phases so that could be pushing the phase resistance up a bit.

Do you get anything out of encoder.shadow_count when you turn it by hand?

What are all those things you have connected to 3.3V?

clean configuration (after erase()),
ive never changed anything in the startup.

i just realized that after boot and after writing the first line:
i can hear a little “tik” and than the motor’s shaft is held by some current (nice and smooth in both direction - looks better than after anticogging :man_shrugging:).
than of course, calibration failed: phase_resistance_out_of_range

second try:
nothing happens (no tik heard, shaft not being held :man_shrugging:)
calibration failed after one turn
dump error = encoder failed, no response

shadow_count = 0 all the time

encoder works in AB mode, so I assume that it is not burnt.
Jumper set to 3v3, R1 and R2 resistors on AS5047p board switched as per

5v,3v3 and MOSI on the encoder side are all connected to 3v3 on the odrive side.
I’ve also put 22ohm/47ohm resistor in series with CLK as per

The phase_resistance_out_of_range is nothing to do with the encoder btw. The encoder is not used for the motor calibration, which is what’s throwing that error. It sounds as if the wire resistance puts it just on the edge of being able to pass the motor calibration at the default current. Did you try increasing calibration_current? That should fix that issue.

Your second issue is the encoder_no_response. It’s unlikely but possible that you destroyed the MISO output of the encoder if you accidentally connected it to 3.3V instead of MOSI.
I don’t suppose you have another one to try?

In my case I didn’t have to modify anything on the AMS board to make it work with 3v3 and it worked great for about 6 months (with both MOSI and MISO connected to MOSI and MISO as normal), but later on it seemed to develop some noise issues that I haven’t got to the bottom of yet. I sometimes get ERROR_ABS_SPI_COM_FAIL as I mentioned in the other thread. But before and during calibration (i.e. untiil closed_loop) it works fine.

this error is very rare. (however never happend in AB mode; same cables etc…)

suprise :slight_smile:
I have 2 of them, will switch to the second board in a sec, however I checked already both.
Ill give it another try.

When you switch over, I’d start by connecting MISO to MISO and MOSI to MOSI.
Also, don’t change the resistors yet. As I say, it worked fine for me.

Also, you don’t need to fit it into your 3d printed housing to test it. Just see if shadow_count is nonzero when you wave a magnet over it…
Speaking of which. That’s an unusual way to mount an encoder, tbh. Normally you want it as tightly coupled to the motor as possible - whereas you have a flexible coupling in the way. This will make it difficult to achieve stability at high gains.
In my case, I attach the magnet directly to the motor shaft with superglue. That way I take maximum advantage of the non-contact encoder (ie zero friction, zero elastic deflection).

OMG!!! :slight_smile: :rofl: :rofl: :man_facepalming: :man_facepalming: :man_facepalming:


save_configuration() !!!

1 Like

both boards are working :slight_smile:
I’ll try anticogging now

1 Like

I think you actually have to reboot to configure the encoders as absolute. This is the configuration I use for the AS5048A:

odrv0.axis0.encoder.config.mode = 257
odrv0.axis0.encoder.config.cpr = 2**14
odrv0.axis0.encoder.config.abs_spi_cs_gpio_pin = 8
odrv0.axis1.encoder.config.mode = 257
odrv0.axis1.encoder.config.cpr = 2**14
odrv0.axis1.encoder.config.abs_spi_cs_gpio_pin = 7

odrv0.axis0.config.startup_closed_loop_control = True
odrv0.axis0.config.startup_encoder_offset_calibration = True
odrv0.axis0.config.startup_motor_calibration = True


I just wrote an anticogging documentation, too, so definitely check that out.


I think that lack of documentation is the weakest part of the ODrive :confused:
Fortunately you guys do a great job on forum and discord chat.

I’ll give a try anticogging later and give a shout how it works with better encoder resolution.

regarding this,
" Now, tune the motor to be very stiff - high pos_gain and relatively high vel_integrator_gain . This will help in calibration."
for people who just started playing with the ODrive it might be hard to guess those parameters.
any hints here?
my default values/gains are:

I’ve tried many different settings/combinations of the above.
Today I tried
and finally my anticogging_calib takes ~1min (previously >5)

odrv0.axis0.controller.config.control_mode = CONTROL_MODE_POSITION_CONTROL
CTRL_… should work?
same here:
INPUT_MODE_PASSTHROUGH (weird, because it is defined in controller.cpp)

in the example (from your docs):
in spi mode, do we have to use
odrv0.axis0.encoder.config.use_index = True
(with the line above, calibration failed, so I guess no index needed in the spi mode)

Perhaps, you could also add to your example a few lines after reboot()
i.e. how to start anticogging and which calibration should be done at the beginning.
(there is a line controller.config.anticogging.pre_calibrated = True to reload it at the beginning, but do I need a full calib always after reboot?)
( The anticogging map can be reloaded automatically at startup by setting controller.config.anticogging.pre_calibrated = True
I think it will be True already;

(Im slightly confused:
In SPI mode, I do anticogging only once, but do I have to do full calib after each reboot?;
my goal is to build a device which will be mechanically blocked at certain position - motor shaft will be able to do ~3 revolutions however it will always be connected to some other mechanics. Will I be able to use the ODrive at all? )

so, here Is my setup for D6374+AS5047p (SPI mode)


odrv0.save_configuration() //YOU MUST SAVE&REBOOT OTHERWISE
odrv0.reboot() //IT WILL NOT WORK ?

odrv0.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE
odrv0.axis0.encoder.config.pre_calibrated = True
odrv0.axis0.motor.config.pre_calibrated = True

#adjust gains here:
#my default gain was 20
#so…default gain x5

#odrv0.axis0.controller.config.vel_gain#leave it
#my default gain was 0.16

#my default gain was 0.33333
#default gain x 10

odrv0.axis0.controller.config.control_mode = CTRL_MODE_POSITION_CONTROL

odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL

#after ~1 minute (the motor shaft slowly moves in one direction. when its finished it spins back to initial position?

#adjust gains back to the default values

odrv0.axis0.controller.config.anticogging.pre_calibrated = True


odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL
odrv0.axis0.controller.config.anticogging.anticogging_enabled=True/False - to check if it works

So, it looks like if you do the above sequence (spi encoder), after every boot you can go straight to closed loop control and everything shoud be done. Theres no need to do the motor and encoder calibration. ?

1 Like

FULL_CALIBRATION_SEQUENCE is just MOTOR_CALIBRATION followed by ENCODER_OFFSET_CALIBRATION in most cases. So you already did it.

And this should be done only once? Than I can attach the rest of mechanics and forget about it?

In SPI mode, yes. Don’t forget to set encoder.config.pre_calibrated=True before you save, though! And motor.config.pre_calibrated=True too

1 Like

It looks like few problems have been solved here :slight_smile: thank you guys!

Im running into a new one related to the power supply here: Power supply + battery?