Motor doesn't move properly in closed loop

Hi,
I recently started using the ODrive card and I immediately encountered a problem, namely that the motor does not move as it should.

My motor is the 8308 from EaglePower (I attach photos) with KV=90 and polepairs=20, and as an encoder I use the one integrated into the ODrive board (SPI).

I ran several configuration commands, setting different parameters of the board, encoder and motor.
After saving the configuration and rebooting the ODrive board, I ran the commands to calibrate the motor (odrv0.axis0.requested_state=AXIS_STATE_MOTOR_CALIBRATION) and encoder (odrv0.axis0.requested_state=AXIS_STATE_ENCODER_OFFSET_CALIBRATION).
So far so good, as the motor beeped and started to do a half rotation to the left and right smoothly.

At this point I put the system in closed_loop and from here the problems started.
In fact, if I try to set input_pos=1 the motor tries to rotate clockwise for about 0.2, then it stops, despite the current absorption increasing.
If I try to force the movement manually I feel a lot of resistance, but if I manage to overcome it then the motor makes another turn, reaching around 0.7, if I continue to force it then it moves to the desired position.

I add that the control mode is POSITION_CONTROL and that the input mode is TRAP_TRAJ.
I can confirm that the encoder works properly, because by moving the motor by hand it accurately detects position and speed.
Sometimes, while I try to manually force the movement, the ODrive card goes into error and typing dump_errors(odrv0) gives me AxisError.MOTOR_FAILED, MotorError.CURRENT_LIMIT_VIOLATION (I attach photos).
I tried increasing the current limit up to 20A, but it still gives me the same error.
ODrive Error

Can anyone tell me what the problem could be?

###   odrv0.axis0   ###

clear_errors(obj: object_ref)
config:
  calibration_lockin: ...
  can_heartbeat_rate_ms: 100 (uint32)
  can_node_id: 1 (uint32)
  can_node_id_extended: False (bool)
  dir_gpio_pin: 2 (uint16)
  enable_step_dir: False (bool)
  enable_watchdog: False (bool)
  general_lockin: ...
  sensorless_ramp: ...
  startup_closed_loop_control: True (bool)
  startup_encoder_index_search: False (bool)
  startup_encoder_offset_calibration: True (bool)
  startup_homing: False (bool)
  startup_motor_calibration: False (bool)
  startup_sensorless_control: False (bool)
  step_dir_always_on: False (bool)
  step_gpio_pin: 1 (uint16)
  turns_per_step: 0.0009765625 (float)
  watchdog_timeout: 0.0 (float)
controller:
  anticogging_valid: False (bool)
  config: ...
  error: 0 (int32)
  input_pos: -0.18436723947525024 (float)
  input_torque: 0.0 (float)
  input_vel: 0.0 (float)
  move_incremental(obj: object_ref, displacement: float, from_input_pos: bool)
  pos_setpoint: -0.18436723947525024 (float)
  start_anticogging_calibration(obj: object_ref)
  torque_setpoint: 0.0 (float)
  trajectory_done: True (bool)
  vel_integrator_torque: 0.0 (float)
  vel_setpoint: 0.0 (float)
current_state: 8 (int32)
encoder:
  calib_scan_response: 6146.0 (float)
  config: ...
  count_in_cpr: 13368 (int32)
  error: 0 (int32)
  hall_state: 7 (uint8)
  index_found: False (bool)
  interpolation: 0.5 (float)
  is_ready: True (bool)
  phase: -1.2461192607879639 (float)
  pos_abs: 13371 (int32)
  pos_circular: 0.8158073425292969 (float)
  pos_cpr: 0.8158588409423828 (float)
  pos_cpr_counts: 13368.4375 (float)
  pos_estimate: -0.18417268991470337 (float)
  pos_estimate_counts: -3016.5478515625 (float)
  set_linear_count(obj: object_ref, count: int32)
  shadow_count: -3021 (int32)
  spi_error_rate: 0.0 (float)
  vel_estimate: -0.34332275390625 (float)
  vel_estimate_counts: -2250.0 (float)
error: 0 (int32)
fet_thermistor:
  config: ...
  error: 0 (int32)
  temperature: 32.99772262573242 (float)
is_homed: False (bool)
lockin_state: 0 (int32)
loop_counter: 101607 (uint32)
max_endstop:
  config: ...
  endstop_state: False (bool)
min_endstop:
  config: ...
  endstop_state: False (bool)
motor:
  DC_calib_phB: -1.3841259479522705 (float)
  DC_calib_phC: -0.9646115899085999 (float)
  armed_state: 3 (int32)
  config: ...
  current_control: ...
  current_meas_phB: 0.014435529708862305 (float)
  current_meas_phC: -0.0019727349281311035 (float)
  effective_current_lim: 10.0 (float)
  error: 0 (int32)
  gate_driver: ...
  is_calibrated: True (bool)
  phase_current_rev_gain: 0.02500000037252903 (float)
  timing_log: ...
motor_thermistor:
  config: ...
  error: 0 (int32)
  temperature: 0.0 (float)
requested_state: 0 (int32)
sensorless_estimator:
  config: ...
  error: 0 (int32)
  phase: 3.09071683883667 (float)
  pll_pos: 3.0927751064300537 (float)
  vel_estimate: 0.0016833508852869272 (float)
step_dir_active: False (bool)
trap_traj:
  config: ...
watchdog_feed(obj: object_ref)
###   odrv0.axis0.controller   ###

anticogging_valid: False (bool)
config:
  anticogging: ...
  axis_to_mirror: 255 (uint8)
  circular_setpoint_range: 1.0 (float)
  circular_setpoints: False (bool)
  control_mode: 3 (int32)
  enable_current_mode_vel_limit: True (bool)
  enable_gain_scheduling: False (bool)
  enable_overspeed_error: True (bool)
  enable_vel_limit: True (bool)
  gain_scheduling_width: 10.0 (float)
  homing_speed: 0.25 (float)
  inertia: 0.0 (float)
  input_filter_bandwidth: 2.0 (float)
  input_mode: 1 (int32)
  load_encoder_axis: 0 (uint8)
  mirror_ratio: 1.0 (float)
  pos_gain: 20.0 (float)
  torque_ramp_rate: 0.009999999776482582 (float)
  vel_gain: 0.10000000149011612 (float)
  vel_integrator_gain: 0.0 (float)
  vel_limit: 120.0 (float)
  vel_limit_tolerance: 1.2000000476837158 (float)
  vel_ramp_rate: 1.0 (float)
error: 0 (int32)
input_pos: -0.18436723947525024 (float)
input_torque: 0.0 (float)
input_vel: 0.0 (float)
move_incremental(obj: object_ref, displacement: float, from_input_pos: bool)
pos_setpoint: -0.18436723947525024 (float)
start_anticogging_calibration(obj: object_ref)
torque_setpoint: 0.0 (float)
trajectory_done: True (bool)
vel_integrator_torque: 0.0 (float)
vel_setpoint: 0.0 (float)
###   odrv0.axis0.motor   ###

DC_calib_phB: -1.342707872390747 (float)
DC_calib_phC: -0.958293080329895 (float)
armed_state: 3 (int32)
config:
  acim_autoflux_attack_gain: 10.0 (float)
  acim_autoflux_decay_gain: 1.0 (float)
  acim_autoflux_enable: False (bool)
  acim_autoflux_min_Id: 10.0 (float)
  acim_gain_min_flux: 10.0 (float)
  acim_slip_velocity: 14.706000328063965 (float)
  calibration_current: 10.0 (float)
  current_control_bandwidth: 100.0 (float)
  current_lim: 10.0 (float)
  current_lim_margin: 8.0 (float)
  direction: -1 (int32)
  inverter_temp_limit_lower: 100.0 (float)
  inverter_temp_limit_upper: 120.0 (float)
  motor_type: 0 (int32)
  phase_inductance: 6.308084994088858e-05 (float)
  phase_resistance: 0.10987522453069687 (float)
  pole_pairs: 20 (int32)
  pre_calibrated: True (bool)
  requested_current_range: 60.0 (float)
  resistance_calib_max_voltage: 2.0 (float)
  torque_constant: 0.09188888967037201 (float)
  torque_lim: inf (float)
current_control:
  I_measured_report_filter_k: 1.0 (float)
  Ibus: 0.0003000549622811377 (float)
  Id_measured: -0.033946871757507324 (float)
  Id_setpoint: 0.0 (float)
  Iq_measured: -0.061991192400455475 (float)
  Iq_setpoint: 0.1569238156080246 (float)
  acim_rotor_flux: 0.0 (float)
  async_phase_offset: 0.0 (float)
  async_phase_vel: 0.0 (float)
  final_v_alpha: -0.05308202654123306 (float)
  final_v_beta: -0.0036413802299648523 (float)
  i_gain: 10.98752212524414 (float)
  max_allowed_current: 60.75 (float)
  overcurrent_trip_level: 67.5 (float)
  p_gain: 0.006308084819465876 (float)
  v_current_control_integral_d: -0.01986008509993553 (float)
  v_current_control_integral_q: 0.04878824204206467 (float)
current_meas_phB: 0.017633914947509766 (float)
current_meas_phC: 0.07365173101425171 (float)
effective_current_lim: 10.0 (float)
error: 0 (int32)
gate_driver:
  drv_fault: 0 (int32)
is_calibrated: True (bool)
phase_current_rev_gain: 0.02500000037252903 (float)
timing_log:
  adc_cb_dc: 12874 (uint16)
  adc_cb_i: 3610 (uint16)
  enc_calib: 9330 (uint16)
  foc_current: 10490 (uint16)
  foc_voltage: 9274 (uint16)
  general: 46746 (uint16)
  idx_search: 13453 (uint16)
  meas_l: 1552 (uint16)
  meas_r: 36987 (uint16)
  sample_now: 1778 (uint16)
  spi_end: 5266 (uint16)
  spi_start: 2278 (uint16)

This definitely sounds like encoder issues – could you show how the magnet is mounted to the motor’s shaft, and how the S1 is mounted? Even if it passes calibration and you get valid data back, the field can be too weak or distorted to be used for actual motion control.

1 Like

Thanks for the quick reply.
After your suggestion I checked the encoder and indeed the magnet was slightly off-centre compared to the sensor on the board.
I corrected the problem and also brought the magnet closer to the sensor, now everything works perfectly.
Thanks so much for the tip.



Great to hear that!!!

One note though – I don’t see what’s actually holding this magnet in place? Is there some glue here? You really need some way of securely centering and retaining the magnet, otherwise bad things will happen :slight_smile: I strongly recommend a 3D printed holder and some superglue.

For the moment, under the magnet there is a metal screw that connects to the motor rotation shaft.
The magnet remains in position only thanks to the force the magnet exerts on the screw.
I will create a suitable 3D support and also add a few drops of glue.
Thanks so much again. :innocent: