[Solved] - Encoding hooverboard motors with rotary encoder

Hello world!
Odrive rocks!
Our question is:

Can hooverboard motors be used with standard issue rotary encoder seen below and in Odrive setup guide? We get error = 0x0002 (int) when checking encoder and wheel only calibrates in one direction. We don’t know why yet. Do you?

Our set up method with 48V Odrive v3.5 followed:


We also tried in odrivetool utility to change from hall sensors to rotary encoders with
odrv0.axis0.encoder.config.mode = ENCODER_MODE_INCREMENTAL

The pivot because Hall sensor cpr were too low at 90 counts per rev. However crude, Halls worked ok on both motors. At low speeds low rez halls often produced hunting during static rover position test after right turns. We would like to upgrade to rotary method but not able to get pass calibration for .pos or .vel control test let alone .py scripts for rover path(s).
-Hooverboard motors have 15 pole pairs
-Rotary encoders have 2400 cpr however we have 3D printed planetary gear set to couple rotary shaft with inside of wheel itself as wheel shaft is not accessible. The ratio of inside wall of 10" wheel : rotary encoder shaft is 32:8.

With this gear reduction cpr input into Odrivetool:
odrv0.axis0.encoder.config.cpr = 600

600 pulse per/rev * 4 =2400/(32/8) = 600

This is valid or was there a mistake with cpr setting before Calibration?

After running:
odrv0.axis0.requested_state = AXIS_STATE_MOTOR_CALIBRATION

odrv0.axis0.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION

odrv0.axis0.encoder

count_in_cpr = 352 (int)
pos_cpr = 352.02496337890625 (float)
error = 0x0002 (int)
phase = -1.178095817565918 (float)
index_found = False (bool)
config:
offset_float = 0.0 (float)
use_index = False (bool)
pre_calibrated = False (bool)
idx_search_speed = 10.0 (float)
calib_range = 0.019999999552965164 (float)
bandwidth = 100.0 (float)
zero_count_on_find_idx = True (bool)
offset = 0 (int)
mode = 0 (int)
cpr = 600 (int)
is_ready = False (bool)
shadow_count = 5152 (int)
hall_state = 7 (int)
interpolation = 0.5 (float)
vel_estimate = 0.0 (float)
pos_estimate = 5152.0048828125 (float)

No filter cap are connected to encoder inputs on Odrive controller and all 3.3K pull ups installed.
Thank you kindly for any insights and feedback. We would very much like to get Bucky::Liner up again.
Cheers,
John

Hi

Can you send a picture of you setup please

Cheers

Carelsbergh Stijn


The error still persist
error = 0x0002 (int)
phase = -1.178095817565918 (float)
index_found = False (bool)
config:
offset_float = 0.0 (float) # yet 0.5 typical
Thanks for your input,
John

Hi

Can you also send the wires on the ODrive

Cheers

Carelsbergh Stijn


red >> 5v
green >> A
white >> B
n/a >> Z
black and shield >> gnd

Yep,

There is your problem, I did the same thing

Red and green are A and B, and the white wire is 5V, I took me 6 weeks to figure this out, very confusing

Cheers

Carelsbergh Stijn

1 Like

Hi Carelsbergh and friends,
Thanks for chiming in on your encoder fix with the colors mixed up from vendor. In our case the wires coming from rotary encoder are color coded correctly. When your wire set up was tired odrv0.axis0.encoder.pos_estimate returns 0.0 regardless of manual wheel rotation. The good news using color coded encoder wires to ODrive encoder input is we no longer have any errors during

odrv0.axis0.encoder

However offset float is 0.0 and not ~.5.
Is this a problem?

While encoder now reads positions well without errrors, no position or velocity control yet. Axis0 does not yet spin in either mode and we are still stuck.

count_in_cpr = 228 (int)
hall_state = 6 (int)
pos_cpr = 228.02487182617188 (float)
index_found = False (bool)
vel_estimate = 0.0 (float)
interpolation = 0.5 (float)
is_ready = False (bool)
pos_estimate = -371.9908447265625 (float)
shadow_count = -372 (int)
config:
bandwidth = 100.0 (float)
use_index = False (bool)
offset = 0 (int)
pre_calibrated = False (bool)
idx_search_speed = 10.0 (float)
zero_count_on_find_idx = True (bool)
cpr = 600 (int)
calib_range = 0.019999999552965164 (float)
offset_float = 0.0 (float)
mode = 0 (int)
phase = -1.8064184188842773 (float)
error = 0x0000 (int)

When axis0 was spun by hand the encoder position change

In [109]: odrv0.axis0.encoder.config.mode = ENCODER_MODE_INCREMENTAL

In [110]: odrv0.axis0.encoder.pos_estimate
Out[110]: 0.0

In [111]: odrv0.axis0.encoder.pos_estimate
Out[111]: 3129.99609375

In [112]: odrv0.axis0.encoder.pos_estimate
Out[112]: 5509.9931640625

In [113]: odrv0.axis0.encoder.pos_estimate
Out[113]: -82.9844970703125

Any ideas why the .pos or .vel modes are not workin yet with our hooverboard motors with rotary encoders mounted with planetary gear set? The pull up 3.3K Resistors are still soldered on ODrive.
Thanks,
John

Update on encoder issue
After changing .cpr to 9600 encoder Cal starts up in both directions. This is an improvement after measuring each wheel rev at 9600 counts with .pos_estimate.
No error are thown however offset float is a bit high. After setting velcoity control mode and closing state loop, axis is still without motion. Would upgrading encoder help with this issue?
Here is odrv0.axis0.encoder
is_ready = False (bool)
pos_estimate = 36.97504425048828 (float)
pos_cpr = 36.97504425048828 (float)
index_found = False (bool)
phase = -0.21371173858642578 (float)
vel_estimate = 0.0 (float)
shadow_count = 36 (int)
interpolation = 0.5 (float)
count_in_cpr = 36 (int)
hall_state = 4 (int)
config:
offset_float = 1.2686406373977661 (float)
calib_range = 0.019999999552965164 (float)
idx_search_speed = 10.0 (float)
zero_count_on_find_idx = True (bool)
bandwidth = 100.0 (float)
pre_calibrated = True (bool)
use_index = False (bool)
mode = 0 (int)
offset = 2617 (int)
cpr = 9600 (int)
error = 0x0000 (int)

Offset_float is near .5 now. However motor still not spinning during .vel mode with closed loop and .set_point = 120. We are stuck for now. Thanks for your feedback.
In [13]: odrv0.axis0.encoder
Out[13]:
error = 0x0000 (int)
shadow_count = 9 (int)
phase = 0.16612720489501953 (float)
index_found = False (bool)
config:
zero_count_on_find_idx = True (bool)
pre_calibrated = False (bool)
mode = 0 (int)
offset_float = 0.5787031054496765 (float)
cpr = 9600 (int)
offset = 2552 (int)
bandwidth = 100.0 (float)
calib_range = 0.019999999552965164 (float)
idx_search_speed = 10.0 (float)
use_index = False (bool)
pos_cpr = 9.975061416625977 (float)
is_ready = True (bool)
vel_estimate = 0.0 (float)
interpolation = 0.5 (float)
pos_estimate = 9.975061416625977 (float)
hall_state = 5 (int)
count_in_cpr = 9 (int)

SOLVED -
The gains needed to scaled back due to new encoder resolution. Before with Halls - 90 cpr as seen in Odrive hooverboard Doc. After with rotary encoders - 9600 cpr
.pos_gain = 1, .vel_gain = .0005 and .vel_intergrator_gain = .0025. The current increase from 10 A to 20 A and we are back on the road. Special thanks to all!

2 Likes

Does Red go to A or B? I’m currently trying to connect a rotary encoder to an Odrive, and I’m not sure if this is the issue or not.

Hello

If there a sticker on the side of the encoder? You can use the Google Translate app to translate the writing with your camera if it’s in Chinese.

Cheers

Thanks for the information. It seems that I have a different rotary encoder. I’m also using the 56V ODRIVE V3.6 board. the rotary encoder is telling me to connect the red wire to Vcc, the black one to 0V, the green one to A, the white one to B, and the shield to G. Do you know where I can find these locations (not A or B) on the 56V ODRIVE V3.6 board?

Vcc == 5V, 0V == GND, G == GND. Might have to solder the 0V to the GND shielding to get it to fit in one header receptacle.

Should be able to all connect to the M0/M1 encoder connector

I’ve connected the wires to the right ports. But when I send the command “odrv0.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE” in the anaconda prompt, the motor moves slowly in one direction and then stops. After this, I dump the errors, and for the axis I get “AxisError.ENCODER_FAILED”, and for the encoder I get “EncoderError.NO_RESPONSE”. Do you know if I need to connect the rotary encoder to configure it (by typing commands in the anaconda prompt). Also, do you know the specific commands to configure the rotary encoder in the anaconda prompt? If not, could you tell me how I can put the Odrive into sensorless mode so that I could ditch using the rotary encoder?

Sensorless mode isn’t worth it - it has a minimum speed requirement, so it definitely won’t be suitable to what hoverboard motors are typically used for.

The rotary encoder is a simple passive device - no configuration needed on the encoder itself. You do need to configure the ODrive though, but as long as you set the cpr of the encoder, you’re fine.

Would you mind posting a picture of your wiring and connections? And a picture of the encoder itself?

I did as you said and also sent a photo of the motor I’m using. I hope that helps.

Can you show how the encoder is connected to the motor during calibration?

@A_General Also, where did you get this ODrive? The connectors look different. Did you buy it from our shop page?