Absolute Encoder pos_abs Not Consistent After Power Cycle

I am using the following items in my setup:

  • ODRIVE PRO — All flashed to latest firmware using odrive dfu
  • DUAL SHAFT MOTOR - D6374 150KV
  • 16384 CPR ABSOLUTE RS485 ENCODER WITH CABLE FOR ODRIVE PRO OR S1

All purchased from ODrive.

Each unit has two drives, two motors, and two encoders. I have 6 units, so a total of 12 drives, 12 motors, and 12 encoders. This is just to share my sample size of data collection.

I have followed the instructions for putting the ODrive in absolute encoder mode found in Absolute Encoder Reference Frame here.

The exact commands I am using from this section are:
odrv0.axis0.pos_vel_mapper.config.offset_valid = True
odrv0.axis0.pos_vel_mapper.config.approx_init_pos_valid = True
odrv0.axis0.controller.config.absolute_setpoints = True

I receive a valid response from odrv0.axis0.pos_vel_mapper.pos_abs, which I am using to poll for position data from the drives.

Both drives only move approximately 1/4 of a rotation at the motor shaft output, and the encoder is directly coupled to the rear motor shaft.

When I initialize a unit for the first time, I have the motors move in both directions and record the max and min of the position data collected during the moves. This recorded data is kept in a json file which is used on subsequent startups to send the motors to an initial position (think max/min/center with a startup at center).

The code I have written does a check on startup to make sure the current position is between the max and min of the values stored in the json before arming the drive to ensure safe startup. Randomly or sometimes always, this check fails only after a full power cycle. Checking current pos_abs verses the previously recorded pos_abs values stored in the json file, the values are definitely inconsistent. pos_abs and pos_rel return different values as expected. Some units last months before showing this behavior, some of them do it all the time.

Going through an entire ODrive setup from scratch can sometimes fix this behavior, but since this system is a closed system inside of a larger system, removing and re-configuring a unit is getting old fast.

Any thoughts on this would be greatly appreciated since I have tried everything including replacing drives, motors and encoders. I have replaced 4 ODrive Pros, 2 motors, and 2 encoders at this point attempting to see if they were defective, but I still get the same results.

From this description, the first two things that come to mind are:

  • Encoder slip or any other drift/slip between what the encoder sees and where the end effector is.
  • Encoder “forgets” or resets its own zero position. The AMT21 sold by CUI does have the capability to move its zero-position, but the version that we sell on the shop does not have any way to trigger this function. So it seems very unlikely, but something to keep in mind.

Some more things you can try to help debugging:

  • Look at rs485_encoder_group0.raw. This is the direct value coming from the encoder, scaled to a range 0…1. Move the actuator to the center and note down the raw value. Once the failure happens, move it to the center again and check if the value is still the same.

  • Take a sharpie and mark the center position on the encoder by drawing a straight line across encoder, sleeve and shaft, while the end effector is in the center position. Next time the failure happens, move it to the center again and see if the line segments still align.

    This approach is sometimes used on fasteners and can indicate if they moved:

    image

I tested the rs_485_encoder_group0.raw values and here was the result:

ODrive board on but only powered by USB: pos_abs and .raw agree

ODrive board powered via power supply: pos_abs and .raw agree

Move the axis while still powered on: pos_abs and .raw agree

Drive out in closed loop control state: pos_abs and .raw agree

Turn power off, but leave drive attached to the USB: pos_abs and .raw agree

Disconnect USB to allow full power down, then reconnect to USB power only: pos_abs and .raw are ~0.2 off

Power down fully again, and only use USB power: pos_abs and .raw are ~-.5 off

I lost my terminal history from this test event, so I can’t give the exact values. I will try and run the tests again today to get some exact values if that will help any.

Edit: I forgot to mention that the encoder is attached quite rigidly to the rear shaft, and I did not see any slippage using a method similar to what you suggested for checking.

Hmm sounds strange. I tried to reproduce the issue but didn’t manage yet, maybe you can repeat the same minimal experiment and see if you still see the issue, and if not try to find out which additional configuration is needed for it to happen.

Setup: ODrive Pro, Firmware v0.6.9-1, encoder AMT21xB-V-OD (same as yours)

Configuration:

odrv0.erase_configuration()
odrv0.rs485_encoder_group0.config.mode = Rs485EncoderMode.AMT21_EVENT_DRIVEN
odrv0.axis0.config.load_encoder = EncoderId.RS485_ENCODER0
odrv0.axis0.pos_vel_mapper.config.offset_valid = True
odrv0.axis0.pos_vel_mapper.config.approx_init_pos_valid = True
odrv0.axis0.controller.config.absolute_setpoints = True
odrv0.save_configuration()

With this config, pos_abs should always starts in a range of -0.5 ... 0.5 and is expected to match raw in “circular space of size 1.0”, aka “modulo 1.0”. So for example 0.595 and -0.405 are the same, because -0.405 + 1.0 = 0.595.

So I did several reboots and turned the encoder by hand, and in my case, raw and pos_abs always matched up (in circular space):

In [7]: odrv0.rs485_encoder_group0.raw, odrv0.axis0.pos_vel_mapper.pos_abs
Out[7]: (0.45172119140625, 0.45172119140625)
In [8]: odrv0.rs485_encoder_group0.raw, odrv0.axis0.pos_vel_mapper.pos_abs
Out[8]: (0.45172119140625, 0.45172119140625)
In [9]: odrv0.rs485_encoder_group0.raw, odrv0.axis0.pos_vel_mapper.pos_abs
Out[9]: (0.59527587890625, 0.5952758193016052)
In [10]: odrv0.reboot()

In [11]: odrv0.rs485_encoder_group0.raw, odrv0.axis0.pos_vel_mapper.pos_abs
Out[11]: (0.59527587890625, -0.40467655658721924)
In [12]: odrv0.rs485_encoder_group0.raw, odrv0.axis0.pos_vel_mapper.pos_abs
Out[12]: (0.8130491375923157, -0.18694937229156494)
In [13]: odrv0.rs485_encoder_group0.raw, odrv0.axis0.pos_vel_mapper.pos_abs
Out[13]: (0.9530029296875, -0.046997129917144775)
In [14]: odrv0.rs485_encoder_group0.raw, odrv0.axis0.pos_vel_mapper.pos_abs
Out[14]: (0.09503173828125, 0.09503173828125)
In [15]: odrv0.rs485_encoder_group0.raw, odrv0.axis0.pos_vel_mapper.pos_abs
Out[15]: (0.17755126953125, 0.17755126953125)
In [16]: odrv0.reboot()

In [17]: odrv0.rs485_encoder_group0.raw, odrv0.axis0.pos_vel_mapper.pos_abs
Out[17]: (0.177490234375, 0.177490234375)

I see, I misunderstood you the first time. I was expecting the values to be the same.

This arguably confuses me more on my issue, then. With my system, I have no slippage, but I am getting full power cycles where the encoder has values that aren’t in the same range as the last time it ran.

While I could write code to handle this, the end result is one of three issues if I ignore the digital slippage and run the closed loop control mode:

  1. The axis uncontrollably moves in one direction
  2. The axis uncontrollably moves in one direction or the other like an over center mechanism
  3. The axis has little to no power and has a strong cogging feel

To address the slippage in the system, I have a keyed and rigid mounted mechanism on these motors, and I have scratched the encoder rings similar to how you marked yours and I see no movement on any of them even after several months of testing this issue.

The only temporary fix I have found to any of the above three issues is swapping the sign on the axis.config.motor.direction value. This only works for one run, and I only do it experimentally because stability is an issue after making this change. If I want to actually fix any of these problems, I have to calibrate from scratch which requires me to completely disassemble the mechanism.

Just to confirm, what are the following?
odrv0.axis0.pos_vel_mapper.config.approx_init_pos
odrv0.axis0.pos_vel_mapper.config.offset
odrv0.axis0.controller.config.circular_setpoints

You may want to join our discord server – that will make faster support easier.

I tried posting in the discord and did not get a response after six days. I think this format works better for me anyways for the visibility and documentation of my project.

Here are some information I have found since last post:

Odrv0.axis0.pos_vel_mapper.config.offset = 0
Odrv0.axis0.pos_vel_mapper.config.approx_init_pos = 0
Odrv0.axis0.controller.config.circular_setpoints = False

Here are some numbers that I have received from displaying the (po_abs, raw) as pairs

I turned the drive on and the position was: (0.229733, 0.229733)

I spun the motor by hand until I got as close to zero as possible
(0.193277, 0.193277)
(0.170283, 0.170283)
(0.111336, 0.111336)
(0.061144, 0.061144)
(0.027868, 0.027868)
(-0.043846, 0.956176)

Everything seems ok there, except according to the documentation, I should be able to move between (-0.5, 0.5) and the encoder should agree with the pos_abs (assuming I understood the documentation)

Now that it’s passed zero, and the encoder and the drive disagree on position, I power cycles the drive.

After power cycling, without moving the motor, I get the following position:

(0.393639, 0.393639)

This position is not the same value as it was when it shut off. What is causing this behavior?

I have tried moving the approx_init_pos and offset to compensate for different start positions, and they still seem to give me the same behavior.

Sorry we must have overlooked your question on Discord.

Yes, so far everything looks good. Note that -0.043846 and 0.956176 are approximately equivalent in modulo 1 (circular space of size 1), because -0.043846 + 1 = 0.956154. The slight inaccuracy can be because the values are not sampled at the exact same time.

In that case the documentation must be misleading. Could you quote the corresponding sentence that seems to contradict your observation?

Now this is very unexpected. That would mean that the encoder somehow shifts its own zero-position (and maybe even direction?) across a power cycle.

And sorry to ask but just to be sure: are you sure there wasn’t any copying error? Because the values you pasted have fewer digits than in my example, so my guess is you copied the values by hand from another computer, in which case an error could have sneaked in?

But assuming there was no copying error, this means we can concentrate on odrv0.rs485_encoder_group0.raw. All other settings and values are on a higher layer, so we can ignore them for a moment and try to find out why raw shifts between power cycles.

  1. Can you confirm that this shift happens with a completely erased ODrive. The only minimal setting you have to configure after erasing is odrv0.rs485_encoder_group0.config.mode, so that a value gets reported on raw. I get that erasing might be a bit intrusive to your application but you can back up the old config before and it would help a lot to bisect the issue.
  2. Does this only happen on full power cycles, or even if you just reboot the ODrive (via odrv0.reboot())?

In that case the documentation must be misleading. Could you quote the corresponding sentence that seems to contradict your observation?

That was my buildup to the rationalization of why I thought the results from the power cycle were inconsistent. (-0.043846, 0.956176) was within the +/-0.5 range and then after power cycle I received the values: (0.393639, 0.393639) after no movement.

And sorry to ask but just to be sure: are you sure there wasn’t any copying error? Because the values you pasted have fewer digits than in my example, so my guess is you copied the values by hand from another computer, in which case an error could have sneaked in?

Sorry for the confusion. I use my personal ODrive and Discord account to communicate with you, but all of this work is completed on a work laptop. It is a bit of a hassle for me to transfer materials from work computer to personal device, so I took the lazy route and typed the values in. While I may not have the whole value present, I typed in what I thought was a reasonable balance between validation of the values and saving my thumbs the workout of typing all those numbers in on my phone. They are the correct values, though.

Here is some data where I reproduced similar results that I transferred over for a copy/paste to clear things up, because I do understand the desire for clean data.

Reconnected to ODrive Pro 346D364E3330 (firmware v0.6.9) as odrv0
In [40]: odrv0.axis0.pos_vel_mapper.pos_abs
Out[40]: 0.18913604319095612

In [41]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[41]: (0.18909414112567902, 0.18914794921875)

In [42]: odrv0.axis0.requested_state = AxisState.CLOSED_LOOP_CONTROL

In [43]: odrv0.axis0.requested_state = AxisState.IDLE

# Moving the device around to validate values before reboot

In [44]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[44]: (0.18761280179023743, 0.18756103515625)

In [45]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[45]: (0.21916009485721588, 0.21917724609375)

In [46]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[46]: (0.11248677223920822, 0.11248779296875)

In [47]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[47]: (-0.0052558183670043945, 0.99468994140625)

# No movement reboot to validate that it kept position correctly

In [48]: odrv0.reboot()
Oh no odrv0 disappeared

Reconnected to ODrive Pro 346D364E3330 (firmware v0.6.9) as odrv0
In [49]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[49]: (-0.00524979829788208, 0.9947509765625)

# Moving the device around to validate values before power cycle

In [50]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[50]: (0.14578865468502045, 0.14581298828125)

In [51]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[51]: (-0.23104363679885864, 0.76898193359375)

In [52]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[52]: (0.14623048901557922, 0.146240234375)

# Full power cycle, no motor movement

Oh no odrv0 disappeared
In [53]: 13:36:17.149573900 [USB] Could not open USB device: -4
13:36:18.150632400 [USB] Could not open USB device: -4
13:36:19.151790000 [USB] Could not open USB device: -4
Reconnected to ODrive Pro 346D364E3330 (firmware v0.6.9) as odrv0
In [53]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[53]: (0.4587399363517761, 0.458740234375)

# Rebooted with a completely new set of values

In [54]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[54]: (0.45872727036476135, 0.458740234375)

# Try with reboot instead of power cycle

In [55]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[55]: (0.4587182104587555, 0.45867919921875)

In [56]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[56]: (0.0789739191532135, 0.0789794921875)

# No movement reboot

In [57]: odrv0.reboot()
Oh no odrv0 disappeared

Reconnected to ODrive Pro 346D364E3330 (firmware v0.6.9) as odrv0
In [58]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[58]: (0.08125362545251846, 0.08123779296875)

# Values changed slightly, maybe acceptable error?

# No movement reboot

In [59]: odrv0.reboot()
Oh no odrv0 disappeared

Reconnected to ODrive Pro 346D364E3330 (firmware v0.6.9) as odrv0
In [60]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[60]: (0.08127433061599731, 0.081298828125)

# Values changed slightly, maybe acceptable error?

# Moved the mechanism a little to test a different value

In [61]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[61]: (0.45707666873931885, 0.45709228515625)

# No movement reboot

In [62]: odrv0.reboot()
Oh no odrv0 disappeared

Reconnected to ODrive Pro 346D364E3330 (firmware v0.6.9) as odrv0
In [63]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[63]: (0.4569932818412781, 0.45697021484375)

# Values changed slightly, maybe acceptable error?
  1. Can you confirm that this shift happens with a completely erased ODrive. The only minimal setting you have to configure after erasing is odrv0.rs485_encoder_group0.config.mode, so that a value gets reported on raw. I get that erasing might be a bit intrusive to your application but you can back up the old config before and it would help a lot to bisect the issue.

I attempted to replicate this behavior, however, I was a bit short on time, and did not find a way to replicate the shifted values in this setup.

  1. Does this only happen on full power cycles, or even if you just reboot the ODrive (via odrv0.reboot())?

I have not observed it on a reboot(), but I have observed it on a save_config() in the past when I was testing settings. In the above code you can see that the reboot()s that I do, the raw value changes slightly almost every time. That may be acceptable error, but I would say I don’t have enough data to prove much as-is.

Testing more today it seems that there may be an issue with ungraceful USB disconnect that could force this behavior. See below:

In [7]: odrv0.erase_configuration()
Oh no odrv0 disappeared

# I forgot to initialize the encoder settings here

Reconnected to ODrive Pro 346D364E3330 (firmware v0.6.9) as odrv0
In [8]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[8]: (nan, 0.0)

In [9]: odrv0.reboot()
Oh no odrv0 disappeared

Reconnected to ODrive Pro 346D364E3330 (firmware v0.6.9) as odrv0
In [10]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[10]: (nan, 0.0)

In [11]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[11]: (nan, 0.0)

Oh no odrv0 disappeared
In [12]: 12:27:50.174759600 [USB] Could not open USB device: -4
12:27:51.178438100 [USB] Could not open USB device: -4
12:27:52.192875900 [USB] Could not open USB device: -4
Reconnected to ODrive Pro 346D364E3330 (firmware v0.6.9) as odrv0
In [12]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[12]: (nan, 0.0)

In [13]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[13]: (nan, 0.0)

In [14]: odrv0.rs485_encoder_group0.config.mode = Rs485EncoderMode.AMT21_POLLING

In [15]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[15]: (nan, 0.1849365234375)

In [16]: odrv0.reboot()
Oh no odrv0 disappeared

Reconnected to ODrive Pro 346D364E3330 (firmware v0.6.9) as odrv0
In [17]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[17]: (nan, 0.0)

In [18]: odrv0.rs485_encoder_group0.config.mode = Rs485EncoderMode.AMT21_POLLING

In [19]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[19]: (nan, 0.18499755859375)

# I remembered to save the configuration this time!

In [20]: odrv0.save_configuration()
Oh no odrv0 disappeared

Reconnected to ODrive Pro 346D364E3330 (firmware v0.6.9) as odrv0
In [21]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[21]: (nan, 0.18499755859375)

In [22]: odrv0.reboot()
Oh no odrv0 disappeared

Reconnected to ODrive Pro 346D364E3330 (firmware v0.6.9) as odrv0
In [23]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[23]: (nan, 0.18499755859375)

# I pulled the USB plug to turn all power off to the board
# No motor movement during reboot

Oh no odrv0 disappeared
In [24]: 12:29:23.950561500 [USB] Could not open USB device: -4
12:29:24.956380200 [USB] Could not open USB device: -4
12:29:25.969851200 [USB] Could not open USB device: -4
Reconnected to ODrive Pro 346D364E3330 (firmware v0.6.9) as odrv0
In [24]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[24]: (nan, 0.18499755859375)

# I moved the motor around by hand to see what might happen during a reboot near zero

In [25]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[25]: (nan, 0.252685546875)

In [26]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[26]: (nan, 0.11151123046875)

In [27]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[27]: (nan, 0.96240234375)

In [28]: odrv0.reboot()
Oh no odrv0 disappeared

Reconnected to ODrive Pro 346D364E3330 (firmware v0.6.9) as odrv0
In [29]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[29]: (nan, 0.96240234375)

# I pulled the USB plug to turn all power off to the board
# No motor movement during reboot

Oh no odrv0 disappeared
In [30]: 12:30:20.399479000 [USB] Could not open USB device: -4
12:30:21.399903200 [USB] Could not open USB device: -4
Reconnected to ODrive Pro 346D364E3330 (firmware v0.6.9) as odrv0
In [30]: (odrv0.axis0.pos_vel_mapper.pos_abs, odrv0.rs485_encoder_group0.raw)
Out[30]: (nan, 0.52490234375)

This is not the first time I have observed an ungraceful USB disconnect right before this issue, but it does not prove that the ungraceful USB disconnect is the cause.

Thanks for the additional data! This helps a lot with isolating the issue.

From this it seems that large unexpected position shifts happen only during full power cycles, and even with an erased ODrive. So far this confirms the suspicion that it’s the encoder that loses position, and it does so during a power cycle. (I don’t think it’s due to the USB disconnect specifically, but because it power-cycles/reboots the encoder)

Regarding the small changes during odrv.reboot()s: These are indeed still a bit large if there’s really no motion. Maybe cogging torque or other non-stiffness led to small motion. Anyway, I would say we can focus on the large changes first and come back to this later if it proves relevant.

I can still not reproduce the issue with my local AMT21, but we’re getting closer. So here are some additional questions:

  • In the first post you wrote “16384 CPR ABSOLUTE RS485 ENCODER WITH CABLE FOR ODRIVE PRO OR S1”, which would correspond to Rs485EncoderMode.AMT21_EVENT_DRIVEN. However in your experiments you used Rs485EncoderMode.AMT21_POLLING, which corresponds to the CUI AMT21 encoder sold in all other places. The distinction is important because they have slightly different firmware, and a different protocol. In fact, Rs485EncoderMode.AMT21_POLLING is not expected to work with the AMT21xB-V-OD from the ODrive shop. Can you confirm which one you’re using, or if you’ve tried both variants and saw the issue on both?

  • If you unplug and replug the encoder cable instead of the USB cable, does the problem still occur? Basically this would power cycle the encoder, but not the ODrive. From what we’ve seen so far, my expectation is that you can indeed trigger the issue this way.

  • It sounded you have multiple AMT21 encoders. Can you confirm that this happens on some of them, but not others? Ideally, you would try multiple ones on the same setup (i.e. only swap the encoder), and see if you can separate them into “good” and “bad”.

  • Is the bootloader installed on this ODrive? I’m asking because this will influence startup time and could be relevant if it’s some communication weirdness. You can check how long the LED is orange on start-up.

Ultimately we might need to exchange this encoder so I can take a closer look at the particular one that’s misbehaving. But beforehand we should just confirm that the issue is indeed localized to the encoder, and not influenced by other factors.

  • In the first post you wrote “16384 CPR ABSOLUTE RS485 ENCODER WITH CABLE FOR ODRIVE PRO OR S1”, which would correspond to Rs485EncoderMode.AMT21_EVENT_DRIVEN. However in your experiments you used Rs485EncoderMode.AMT21_POLLING, which corresponds to the CUI AMT21 encoder sold in all other places. The distinction is important because they have slightly different firmware, and a different protocol. In fact, Rs485EncoderMode.AMT21_POLLING is not expected to work with the AMT21xB-V-OD from the ODrive shop. Can you confirm which one you’re using, or if you’ve tried both variants and saw the issue on both?

Good catch, I missed this myself. We purchased our encoders on Sept 2022, back then the item we purchased from ODrive was listed as: Encoder AMT212B-V. The item we received from ODrive was an AMT212B-V. I have been using the Rs485EncoderMode.AMT21_POLLING API because I have an AMT212B-V.

When I wrote this post, I took the most recent purchase request and grabbed the part number off of it.
The purchaser said they bought the same item as last time, so the part numbers should be the same. That was on me for not checking, but since you don’t seem to sell the AMT212B-V anymore, our most recent purchase was actually AMT212B-D.

Knowing this, I swapped the AMT212B-V with the AMT212B-D and used Rs485EncoderMode.AMT21_EVENT_DRIVEN today and tested with no power cycle related issues.

  • If you unplug and replug the encoder cable instead of the USB cable, does the problem still occur? Basically this would power cycle the encoder, but not the ODrive. From what we’ve seen so far, my expectation is that you can indeed trigger the issue this way.

I will test this when I have time again.

  • It sounded you have multiple AMT21 encoders. Can you confirm that this happens on some of them, but not others? Ideally, you would try multiple ones on the same setup (i.e. only swap the encoder), and see if you can separate them into “good” and “bad”.

I have in “service” 12 AMT212-V encoders. Approximately 50% of them behave this way regularly, and 50% of them have been champs. Of the two that I have on my desk, one has given me no issues, the other fails about 80% of the time. All the provided data has been from that one encoder. I can look into doing a more sterile test when I get back from travel like one odrive vs multiple encoders.

  • Is the bootloader installed on this ODrive? I’m asking because this will influence startup time and could be relevant if it’s some communication weirdness. You can check how long the LED is orange on start-up.

I’m not familiar with the bootloader. I don’t normally see an orange LED on start-up. It powers on to a blue light usually if I recall correctly. When I receive my ODrives, I leave them in their configuration, use Zadig to update the USB driver, run odrivetool dfu, then push my settings to it, and run my code.

Ultimately we might need to exchange this encoder so I can take a closer look at the particular one that’s misbehaving. But beforehand we should just confirm that the issue is indeed localized to the encoder, and not influenced by other factors.

When I return from travel I can send this encoder off to be checked if it would help.

Ok good to know that the problem seems indeed localized to the encoder. I assume by “AMT212B-D” you mean “AMT212B-V-OD” (the OD stands for ODrive). But all the “-OD” encoders you have are newer, right? So the fact that all “AMT212B-V-OD” work well and some “AMT212B-V” don’t, could be either due to the variant differences or due to age.

So yeah when you’re back from travels, maybe do a quick check to confirm (maybe just check 2 good encoders and 2 bad encoders, all with the same ODrive - no need to do anything mechanically, just connect the cables). And you can send an email info@odriverobotics.com with your order number (that contained the encoders) so we can get a swap set up for inspection. Since we don’t stock AMT212B-V anymore, would AMT212B-V-OD work as a substitute?