Can any one help?

I have the Odrive 3.6 and some hoverboard motors, all I need it to control the motors from a Rc controller.
But I have tried and tried with no luck.

when I set it to closed loop the motor ramps up in speed to a max and then It breaks and outputs errors, I never manage to controller the motor via pwm but I do see the values change when I look but they don’t impact the rpm or val of the motor.

should be super simple. but not this time

Hi, can you show the errors being output using dump_errors(odrv0) in ODrivetool?

Also, can you post your configuration and wiring?

hall sensor wires, red= 5v black = GND blue = a yellow = b green = z
motor wires, a = green b = yellow c = blue.
gpio pin 3 and 4 set to PWM.
comnd GND to receiver.

breaker resistor 2ohm
Vin 18V
GND from battery.

In [65]: dump_errors(odrv0)

system: no error

axis0

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

axis1

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

In [66]:

errors I saw yesterday

Reconnected to ODrive v3.6 205F39984D4D (firmware v0.5.6) as odrv0
In [26]: dump_errors(odrv0)
system: no error
axis0
axis: Error(s):
AxisError.WATCHDOG_TIMER_EXPIRED
motor: no error
DRV fault: none
sensorless_estimator: no error
encoder: no error
controller: no error
axis1
axis: Error(s):
AxisError.WATCHDOG_TIMER_EXPIRED
motor: no error
DRV fault: none
sensorless_estimator: no error
encoder: no error
controller: no error

In [64]: odrv0
Out[64]:
axis0:
acim_estimator: …
config: …
controller: …
current_state: 1 (uint8)
encoder: …
error: 0 (uint32)
is_homed: False (bool)
last_drv_fault: 0 (uint32)
max_endstop: …
mechanical_brake: …
min_endstop: …
motor: …
requested_state: 0 (uint8)
sensorless_estimator: …
step_dir_active: False (bool)
steps: 0 (int64)
task_times: …
trap_traj: …
watchdog_feed(obj: object_ref)
axis1:
acim_estimator: …
config: …
controller: …
current_state: 1 (uint8)
encoder: …
error: 0 (uint32)
is_homed: False (bool)
last_drv_fault: 0 (uint32)
max_endstop: …
mechanical_brake: …
min_endstop: …
motor: …
requested_state: 0 (uint8)
sensorless_estimator: …
step_dir_active: False (bool)
steps: 0 (int64)
task_times: …
trap_traj: …
watchdog_feed(obj: object_ref)
brake_resistor_armed: True (bool)
brake_resistor_current: -0.0 (float)
brake_resistor_saturated: False (bool)
can:
config: …
error: 0 (uint8)
clear_errors(obj: object_ref)
config:
brake_resistance: 2.0 (float)
dc_bus_overvoltage_ramp_end: 59.92000198364258 (float)
dc_bus_overvoltage_ramp_start: 59.92000198364258 (float)
dc_bus_overvoltage_trip_level: 22.0 (float)
dc_bus_undervoltage_trip_level: 15.0 (float)
dc_max_negative_current: -10.0 (float)
dc_max_positive_current: inf (float)
enable_brake_resistor: True (bool)
enable_can_a: True (bool)
enable_dc_bus_overvoltage_ramp: False (bool)
enable_i2c_a: False (bool)
enable_uart_a: True (bool)
enable_uart_b: False (bool)
enable_uart_c: False (bool)
error_gpio_pin: 0 (uint32)
gpio10_mode: 0 (uint8)
gpio11_mode: 0 (uint8)
gpio12_mode: 12 (uint8)
gpio13_mode: 12 (uint8)
gpio14_mode: 2 (uint8)
gpio15_mode: 7 (uint8)
gpio16_mode: 7 (uint8)
gpio1_mode: 4 (uint8)
gpio1_pwm_mapping: …
gpio2_mode: 4 (uint8)
gpio2_pwm_mapping: …
gpio3_analog_mapping: …
gpio3_mode: 3 (uint8)
gpio3_pwm_mapping: …
gpio4_analog_mapping: …
gpio4_mode: 10 (uint8)
gpio4_pwm_mapping: …
gpio5_mode: 10 (uint8)
gpio6_mode: 0 (uint8)
gpio7_mode: 0 (uint8)
gpio8_mode: 0 (uint8)
gpio9_mode: 0 (uint8)
max_regen_current: 0.0 (float)
uart0_protocol: 3 (uint8)
uart1_protocol: 3 (uint8)
uart2_protocol: 3 (uint8)
uart_a_baudrate: 115200 (uint32)
uart_b_baudrate: 115200 (uint32)
uart_c_baudrate: 115200 (uint32)
usb_cdc_protocol: 3 (uint8)
enter_dfu_mode(obj: object_ref)
erase_configuration(obj: object_ref)
error: 0 (uint8)
fw_version_major: 0 (uint8)
fw_version_minor: 5 (uint8)
fw_version_revision: 6 (uint8)
fw_version_unreleased: 0 (uint8)
get_adc_voltage(obj: object_ref, gpio: uint32) → voltage: float
get_dma_status(obj: object_ref, stream_num: uint8) → status: uint32
get_drv_fault(obj: object_ref) → drv_fault: uint64
get_gpio_states(obj: object_ref) → status: uint32
get_interrupt_status(obj: object_ref, irqn: int32) → status: uint32
hw_version_major: 3 (uint8)
hw_version_minor: 6 (uint8)
hw_version_variant: 56 (uint8)
ibus: 0.0 (float)
ibus_report_filter_k: 1.0 (float)
misconfigured: True (bool)
n_evt_control_loop: 3100175 (uint32)
n_evt_sampling: 3100178 (uint32)
oscilloscope:
get_val(obj: object_ref, index: uint32) → val: float
size: 4096 (uint32)
otp_valid: True (bool)
reboot(obj: object_ref)
save_configuration(obj: object_ref) → success: bool
serial_number: 35593360264525 (uint64)
system_stats:
i2c: …
max_stack_usage_analog: 316 (uint32)
max_stack_usage_axis: 564 (uint32)
max_stack_usage_can: 408 (uint32)
max_stack_usage_startup: 532 (uint32)
max_stack_usage_uart: 292 (uint32)
max_stack_usage_usb: 468 (uint32)
min_heap_space: 47432 (uint32)
prio_analog: -2 (int32)
prio_axis: 3 (int32)
prio_can: 0 (int32)
prio_startup: 0 (int32)
prio_uart: 0 (int32)
prio_usb: 0 (int32)
stack_size_analog: 1024 (uint32)
stack_size_axis: 2048 (uint32)
stack_size_can: 1024 (uint32)
stack_size_startup: 2048 (uint32)
stack_size_uart: 4096 (uint32)
stack_size_usb: 4096 (uint32)
uptime: 387637 (uint32)
usb: …
task_timers_armed: False (bool)
task_times:
control_loop_checks: …
control_loop_misc: …
dc_calib_wait: …
sampling: …
test_function(obj: object_ref, delta: int32) → cnt: int32
test_property: 0 (uint32)
user_config_loaded: 30326 (uint32)
vbus_voltage: 17.8333740234375 (float)

In [43]: dump_errors(odrv0)

system: no error

axis0

axis: Error(s):

AxisError.MOTOR_FAILED

AxisError.CONTROLLER_FAILED

motor: Error(s):

MotorError.UNKNOWN_TORQUE

MotorError.UNKNOWN_VOLTAGE_COMMAND

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: Error(s):

ControllerError.OVERSPEED

axis1

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

In [44]:

I took a new motor, erased the previous config, and followed the hoverboard tut. all looked good until I got to the PWM part. when I config the gpio and save + reboot+ power cycle I still don’t see any pwm signal when looking it up using >drv0.axis1.controller.input_vel< it just out puts 0.0-

https://docs.odriverobotics.com/v/0.5.4/hoverboard.html#pwm-input

That first error, with WATCHDOG_TIMER_EXPIRED – this means you enabled the watchdog, which is a safety measure to disable the ODrive if it doesn’t receive commands periodically, but then you didn’t send pos/vel/torque commands in time, so it disabled out of safety. Read here: Getting Started — ODrive Documentation 0.5.6 documentation

That next error OVERSPEED means that your motor is going faster than vel_limit*vel_limit_tolerance. You should increase vel_limit.

For the PWM setup, can you post some pictures of your wiring? What’s sending the PWM? What should it be set to? Can you post all of your configuration and setup commands?

As i mentioned, i erased all config, and started with a new motor. i did this today =).
This resulted in me having control over set motor using odrv0.axis0.controller.input_vel = (and a value)
that part works fin. here is my most reason config log.
all looks good. now ill try and work with the PWM signal on gpio 3 and 4, and i use one of the dobblt GND to ground my reciver/flightcontroller.

Oh no odrv0 disappeared
Reconnected to ODrive v3.6 205F39984D4D (firmware v0.5.6) as odrv0
In [86]: odrv0
Out[86]:
axis0:
acim_estimator: …
config: …
controller: …
current_state: 1 (uint8)
encoder: …
error: 0 (uint32)
is_homed: False (bool)
last_drv_fault: 0 (uint32)
max_endstop: …
mechanical_brake: …
min_endstop: …
motor: …
requested_state: 0 (uint8)
sensorless_estimator: …
step_dir_active: False (bool)
steps: 25 (int64)
task_times: …
trap_traj: …
watchdog_feed(obj: object_ref)
axis1:
acim_estimator: …
config: …
controller: …
current_state: 1 (uint8)
encoder: …
error: 0 (uint32)
is_homed: False (bool)
last_drv_fault: 0 (uint32)
max_endstop: …
mechanical_brake: …
min_endstop: …
motor: …
requested_state: 0 (uint8)
sensorless_estimator: …
step_dir_active: False (bool)
steps: 0 (int64)
task_times: …
trap_traj: …
watchdog_feed(obj: object_ref)
brake_resistor_armed: True (bool)
brake_resistor_current: -0.0 (float)
brake_resistor_saturated: False (bool)
can:
config: …
error: 0 (uint8)
clear_errors(obj: object_ref)
config:
brake_resistance: 2.0 (float)
dc_bus_overvoltage_ramp_end: 59.92000198364258 (float)
dc_bus_overvoltage_ramp_start: 59.92000198364258 (float)
dc_bus_overvoltage_trip_level: 59.92000198364258 (float)
dc_bus_undervoltage_trip_level: 8.0 (float)
dc_max_negative_current: -10.0 (float)
dc_max_positive_current: inf (float)
enable_brake_resistor: True (bool)
enable_can_a: True (bool)
enable_dc_bus_overvoltage_ramp: False (bool)
enable_i2c_a: False (bool)
enable_uart_a: True (bool)
enable_uart_b: False (bool)
enable_uart_c: False (bool)
error_gpio_pin: 0 (uint32)
gpio10_mode: 0 (uint8)
gpio11_mode: 0 (uint8)
gpio12_mode: 12 (uint8)
gpio13_mode: 12 (uint8)
gpio14_mode: 2 (uint8)
gpio15_mode: 7 (uint8)
gpio16_mode: 7 (uint8)
gpio1_mode: 4 (uint8)
gpio1_pwm_mapping: …
gpio2_mode: 4 (uint8)
gpio2_pwm_mapping: …
gpio3_analog_mapping: …
gpio3_mode: 10 (uint8)
gpio3_pwm_mapping: …
gpio4_analog_mapping: …
gpio4_mode: 10 (uint8)
gpio4_pwm_mapping: …
gpio5_mode: 3 (uint8)
gpio6_mode: 0 (uint8)
gpio7_mode: 0 (uint8)
gpio8_mode: 0 (uint8)
gpio9_mode: 0 (uint8)
max_regen_current: 0.0 (float)
uart0_protocol: 3 (uint8)
uart1_protocol: 3 (uint8)
uart2_protocol: 3 (uint8)
uart_a_baudrate: 115200 (uint32)
uart_b_baudrate: 115200 (uint32)
uart_c_baudrate: 115200 (uint32)
usb_cdc_protocol: 3 (uint8)
enter_dfu_mode(obj: object_ref)
erase_configuration(obj: object_ref)
error: 0 (uint8)
fw_version_major: 0 (uint8)
fw_version_minor: 5 (uint8)
fw_version_revision: 6 (uint8)
fw_version_unreleased: 0 (uint8)
get_adc_voltage(obj: object_ref, gpio: uint32) → voltage: float
get_dma_status(obj: object_ref, stream_num: uint8) → status: uint32
get_drv_fault(obj: object_ref) → drv_fault: uint64
get_gpio_states(obj: object_ref) → status: uint32
get_interrupt_status(obj: object_ref, irqn: int32) → status: uint32
hw_version_major: 3 (uint8)
hw_version_minor: 6 (uint8)
hw_version_variant: 56 (uint8)
ibus: 0.0 (float)
ibus_report_filter_k: 1.0 (float)
misconfigured: False (bool)
n_evt_control_loop: 351743 (uint32)
n_evt_sampling: 351746 (uint32)
oscilloscope:
get_val(obj: object_ref, index: uint32) → val: float
size: 4096 (uint32)
otp_valid: True (bool)
reboot(obj: object_ref)
save_configuration(obj: object_ref) → success: bool
serial_number: 35593360264525 (uint64)
system_stats:
i2c: …
max_stack_usage_analog: 316 (uint32)
max_stack_usage_axis: 564 (uint32)
max_stack_usage_can: 408 (uint32)
max_stack_usage_startup: 532 (uint32)
max_stack_usage_uart: 292 (uint32)
max_stack_usage_usb: 420 (uint32)
min_heap_space: 47432 (uint32)
prio_analog: -2 (int32)
prio_axis: 3 (int32)
prio_can: 0 (int32)
prio_startup: 0 (int32)
prio_uart: 0 (int32)
prio_usb: 0 (int32)
stack_size_analog: 1024 (uint32)
stack_size_axis: 2048 (uint32)
stack_size_can: 1024 (uint32)
stack_size_startup: 2048 (uint32)
stack_size_uart: 4096 (uint32)
stack_size_usb: 4096 (uint32)
uptime: 44085 (uint32)
usb: …
task_timers_armed: False (bool)
task_times:
control_loop_checks: …
control_loop_misc: …
dc_calib_wait: …
sampling: …
test_function(obj: object_ref, delta: int32) → cnt: int32
test_property: 0 (uint32)
user_config_loaded: 30326 (uint32)
vbus_voltage: 17.848682403564453 (float)

Can you show all the commands you entered in ODrivetool to set this ODrive up, starting from the configuration erase?

Last login: Tue Oct 15 12:24:28 on ttys000

michaeljustesen@MacBook-Air-tilhrende-Michael ~ % odrivetool

ODrive control utility v0.6.9.post0

Website: https://odriverobotics.com/

Docs: https://docs.odriverobotics.com/

Forums: https://discourse.odriverobotics.com/

Discord: ODrive

Github: GitHub - odriverobotics/ODrive: High performance motor control

Please connect your ODrive.

You can also type help() or quit().

Connected to ODrive v3.6 205F39984D4D (firmware v0.5.6) as odrv0

In [1]: odrv0.axis0.requested_state = AXIS_STATE_MOTOR_CALIBRATION

In [2]: dump_errors(odrv0)

system: no error

axis0

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

axis1

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

In [3]: odrv0.axis0.motor

Out[3]:

DC_calib_phA: 0.5397038459777832 (float)

DC_calib_phB: -0.6538399457931519 (float)

DC_calib_phC: 0.11340455710887909 (float)

I_bus: 0.0 (float)

config:

I_bus_hard_max: inf (float)

I_bus_hard_min: -inf (float)

I_leak_max: 0.10000000149011612 (float)

R_wL_FF_enable: False (bool)

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)

bEMF_FF_enable: False (bool)

calibration_current: 10.0 (float)

current_control_bandwidth: 100.0 (float)

current_lim: 10.0 (float)

current_lim_margin: 8.0 (float)

dc_calib_tau: 0.20000000298023224 (float)

inverter_temp_limit_lower: 100.0 (float)

inverter_temp_limit_upper: 120.0 (float)

motor_type: 0 (uint8)

phase_inductance: 0.0004092316376045346 (float)

phase_resistance: 0.28006941080093384 (float)

pole_pairs: 15 (int32)

pre_calibrated: True (bool)

requested_current_range: 25.0 (float)

resistance_calib_max_voltage: 4.0 (float)

torque_constant: 0.5168750286102295 (float)

torque_lim: inf (float)

current_control:

I_measured_report_filter_k: 1.0 (float)

Ialpha_measured: 0.0 (float)

Ibeta_measured: 0.0 (float)

Id_measured: 0.0 (float)

Id_setpoint: 0.0 (float)

Iq_measured: 0.0 (float)

Iq_setpoint: 0.0 (float)

Vd_setpoint: 0.0 (float)

Vq_setpoint: 0.0 (float)

final_v_alpha: 0.0 (float)

final_v_beta: 0.0 (float)

i_gain: 28.006938934326172 (float)

p_gain: 0.040923163294792175 (float)

phase: 0.0 (float)

phase_vel: 0.0 (float)

power: 0.0 (float)

v_current_control_integral_d: 0.0 (float)

v_current_control_integral_q: 0.0 (float)

current_meas_phA: -0.5283942818641663 (float)

current_meas_phB: 0.6443180441856384 (float)

current_meas_phC: -0.11448799818754196 (float)

effective_current_lim: 10.0 (float)

error: 0 (uint64)

fet_thermistor:

config: …

temperature: 26.84030532836914 (float)

is_armed: False (bool)

is_calibrated: True (bool)

last_error_time: 0.0 (float)

max_allowed_current: 30.375 (float)

max_dc_calib: 3.0375001430511475 (float)

motor_thermistor:

config: …

temperature: 0.0 (float)

n_evt_current_measurement: 827001 (uint32)

n_evt_pwm_update: 827004 (uint32)

phase_current_rev_gain: 0.012500000186264515 (float)

In [4]: odrv0.axis0.motor.config.pre_calibrated = True

In [5]: odrv0.axis0.requested_state = AXIS_STATE_ENCODER_HALL_POLARITY_CALIBRATI

…: ON

In [6]: dump_errors(odrv0)

system: no error

axis0

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

axis1

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

In [7]: odrv0.axis0.encoder

Out[7]:

calib_scan_response: 0.0 (float)

config:

abs_spi_cs_gpio_pin: 1 (uint16)

bandwidth: 100.0 (float)

calib_range: 0.019999999552965164 (float)

calib_scan_distance: 150.0 (float)

calib_scan_omega: 12.566370964050293 (float)

cpr: 90 (int32)

direction: 0 (int32)

enable_phase_interpolation: True (bool)

find_idx_on_lockin_only: False (bool)

hall_polarity: 0 (uint8)

hall_polarity_calibrated: True (bool)

ignore_illegal_hall_state: False (bool)

index_offset: 0.0 (float)

mode: 1 (uint16)

phase_offset: 0 (int32)

phase_offset_float: 0.0 (float)

pre_calibrated: False (bool)

sincos_gpio_pin_cos: 4 (uint16)

sincos_gpio_pin_sin: 3 (uint16)

use_index: False (bool)

use_index_offset: True (bool)

count_in_cpr: 1 (int32)

delta_pos_cpr_counts: 5.605193857299268e-45 (float)

error: 0 (uint16)

hall_state: 3 (uint8)

index_found: False (bool)

interpolation: 0.5 (float)

is_ready: False (bool)

phase: 0.0 (float)

pos_abs: 0 (int32)

pos_circular: 0.011388901621103287 (float)

pos_cpr_counts: 1.024989366531372 (float)

pos_estimate: 0.011388770304620266 (float)

pos_estimate_counts: 1.024989366531372 (float)

set_linear_count(obj: object_ref, count: int32)

shadow_count: 1 (int32)

spi_error_rate: 0.0 (float)

vel_estimate: 0.0 (float)

vel_estimate_counts: 0.0 (float)

In [8]: odrv0.axis0.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION

In [9]: dump_errors(odrv0)’

Cell In[9], line 1

dump_errors(odrv0)’

^

SyntaxError: unterminated string literal (detected at line 1)

In [10]: dump_errors(odrv0)

system: no error

axis0

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

axis1

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

In [11]: odrv0.axis0.encoder

Out[11]:

calib_scan_response: 143.0 (float)

config:

abs_spi_cs_gpio_pin: 1 (uint16)

bandwidth: 100.0 (float)

calib_range: 0.019999999552965164 (float)

calib_scan_distance: 150.0 (float)

calib_scan_omega: 12.566370964050293 (float)

cpr: 90 (int32)

direction: -1 (int32)

enable_phase_interpolation: True (bool)

find_idx_on_lockin_only: False (bool)

hall_polarity: 0 (uint8)

hall_polarity_calibrated: True (bool)

ignore_illegal_hall_state: False (bool)

index_offset: 0.0 (float)

mode: 1 (uint16)

phase_offset: -67 (int32)

phase_offset_float: -0.46513283252716064 (float)

pre_calibrated: False (bool)

sincos_gpio_pin_cos: 4 (uint16)

sincos_gpio_pin_sin: 3 (uint16)

use_index: False (bool)

use_index_offset: True (bool)

count_in_cpr: 4 (int32)

delta_pos_cpr_counts: -5.605193857299268e-45 (float)

error: 0 (uint16)

hall_state: 4 (uint8)

index_found: False (bool)

interpolation: 0.5 (float)

is_ready: True (bool)

phase: 0.03650856018066406 (float)

pos_abs: 0 (int32)

pos_circular: 0.05524202063679695 (float)

pos_cpr_counts: 4.975038051605225 (float)

pos_estimate: 0.05529564619064331 (float)

pos_estimate_counts: 4.9766082763671875 (float)

set_linear_count(obj: object_ref, count: int32)

shadow_count: 4 (int32)

spi_error_rate: 0.0 (float)

vel_estimate: 0.0 (float)

vel_estimate_counts: 0.0 (float)

In [12]: odrv0.axis0.encoder.config.pre_calibrated = True

In [13]: odrv0.save_configuration()

…: odrv0.reboot()

13:45:45.297064 [LEGACY_OBJ] protocol failed with 3 - propagating error to application

Oh no odrv0 disappeared

Reconnected to ODrive v3.6 205F39984D4D (firmware v0.5.6) as odrv0

In [14]: odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL

…: odrv0.axis0.controller.input_vel = 2

In [15]: odrv0.axis0.controller.input_vel = 0

…: odrv0.axis0.requested_state = AXIS_STATE_IDLE

In [16]: odrv0.config.gpio3_pwm_mapping.min = -2

…: odrv0.config.gpio3_pwm_mapping.max = 2

…: odrv0.config.gpio3_pwm_mapping.endpoint = odrv0.axis0.controller._input_vel_property

…:

…: odrv0.config.gpio4_pwm_mapping.min = -2

…: odrv0.config.gpio4_pwm_mapping.max = 2

…: odrv0.config.gpio4_pwm_mapping.endpoint = odrv0.axis1.controller._input_vel_property

In [17]: odrv0.save_configuration()

…: odrv0.reboot()

13:46:30.946421 [LEGACY_OBJ] protocol failed with 3 - propagating error to application

Oh no odrv0 disappeared

Reconnected to ODrive v3.6 205F39984D4D (firmware v0.5.6) as odrv0

In [18]: odrv0.axis1.controller.input_vel

Out[18]: 0.0

In [19]: odrv0.axis1.controller.input_vel

Out[19]: 0.0

In [20]: odrv0.axis0.controller.input_vel

Out[20]: 0.0

In [21]: odrv0.axis0.encoder.config.bandwidth = 100

…: odrv0.axis0.controller.config.pos_gain = 1

…: odrv0.axis0.controller.config.vel_gain = 0.02 * odrv0.axis0.motor.config.torque_constant * od

…: rv0.axis0.encoder.config.cpr

…: odrv0.axis0.controller.config.vel_integrator_gain = 0.1 * odrv0.axis0.motor.config.torque_con

…: stant * odrv0.axis0.encoder.config.cpr

…: odrv0.axis0.controller.config.vel_limit = 10

…: odrv0.axis0.controller.config.control_mode = CONTROL_MODE_VELOCITY_CONTROL

In [22]: odrv0.save_configuration()

…: odrv0.reboot()

13:50:01.99726 [LEGACY_OBJ] protocol failed with 3 - propagating error to application

Oh no odrv0 disappeared

Reconnected to ODrive v3.6 205F39984D4D (firmware v0.5.6) as odrv0

In [23]: odrv0.axis0.controller.input_vel

Out[23]: 0.0

In [24]: odrv0.axis1.controller.input_vel

Out[24]: 0.0

In [25]: odrv0.axis1.controller.input_vel

Out[25]: 0.0

In [26]: odrv0.axis0.controller.input_vel

Out[26]: 0.0

In [27]: odrv0

Out[27]:

axis0:

acim_estimator: …

config: …

controller: …

current_state: 1 (uint8)

encoder: …

error: 0 (uint32)

is_homed: False (bool)

last_drv_fault: 0 (uint32)

max_endstop: …

mechanical_brake: …

min_endstop: …

motor: …

requested_state: 0 (uint8)

sensorless_estimator: …

step_dir_active: False (bool)

steps: 0 (int64)

task_times: …

trap_traj: …

watchdog_feed(obj: object_ref)

axis1:

acim_estimator: …

config: …

controller: …

current_state: 1 (uint8)

encoder: …

error: 0 (uint32)

is_homed: False (bool)

last_drv_fault: 0 (uint32)

max_endstop: …

mechanical_brake: …

min_endstop: …

motor: …

requested_state: 0 (uint8)

sensorless_estimator: …

step_dir_active: False (bool)

steps: 0 (int64)

task_times: …

trap_traj: …

watchdog_feed(obj: object_ref)

brake_resistor_armed: True (bool)

brake_resistor_current: -0.0 (float)

brake_resistor_saturated: False (bool)

can:

config: …

error: 0 (uint8)

clear_errors(obj: object_ref)

config:

brake_resistance: 2.0 (float)

dc_bus_overvoltage_ramp_end: 59.92000198364258 (float)

dc_bus_overvoltage_ramp_start: 59.92000198364258 (float)

dc_bus_overvoltage_trip_level: 59.92000198364258 (float)

dc_bus_undervoltage_trip_level: 8.0 (float)

dc_max_negative_current: -10.0 (float)

dc_max_positive_current: inf (float)

enable_brake_resistor: True (bool)

enable_can_a: True (bool)

enable_dc_bus_overvoltage_ramp: False (bool)

enable_i2c_a: False (bool)

enable_uart_a: True (bool)

enable_uart_b: False (bool)

enable_uart_c: False (bool)

error_gpio_pin: 0 (uint32)

gpio10_mode: 0 (uint8)

gpio11_mode: 0 (uint8)

gpio12_mode: 12 (uint8)

gpio13_mode: 12 (uint8)

gpio14_mode: 2 (uint8)

gpio15_mode: 7 (uint8)

gpio16_mode: 7 (uint8)

gpio1_mode: 4 (uint8)

gpio1_pwm_mapping: …

gpio2_mode: 4 (uint8)

gpio2_pwm_mapping: …

gpio3_analog_mapping: …

gpio3_mode: 3 (uint8)

gpio3_pwm_mapping: …

gpio4_analog_mapping: …

gpio4_mode: 3 (uint8)

gpio4_pwm_mapping: …

gpio5_mode: 3 (uint8)

gpio6_mode: 0 (uint8)

gpio7_mode: 0 (uint8)

gpio8_mode: 0 (uint8)

gpio9_mode: 0 (uint8)

max_regen_current: 0.0 (float)

uart0_protocol: 3 (uint8)

uart1_protocol: 3 (uint8)

uart2_protocol: 3 (uint8)

uart_a_baudrate: 115200 (uint32)

uart_b_baudrate: 115200 (uint32)

uart_c_baudrate: 115200 (uint32)

usb_cdc_protocol: 3 (uint8)

enter_dfu_mode(obj: object_ref)

erase_configuration(obj: object_ref)

error: 0 (uint8)

fw_version_major: 0 (uint8)

fw_version_minor: 5 (uint8)

fw_version_revision: 6 (uint8)

fw_version_unreleased: 0 (uint8)

get_adc_voltage(obj: object_ref, gpio: uint32) → voltage: float

get_dma_status(obj: object_ref, stream_num: uint8) → status: uint32

get_drv_fault(obj: object_ref) → drv_fault: uint64

get_gpio_states(obj: object_ref) → status: uint32

get_interrupt_status(obj: object_ref, irqn: int32) → status: uint32

hw_version_major: 3 (uint8)

hw_version_minor: 6 (uint8)

hw_version_variant: 56 (uint8)

ibus: 0.0 (float)

ibus_report_filter_k: 1.0 (float)

misconfigured: False (bool)

n_evt_control_loop: 261797 (uint32)

n_evt_sampling: 261801 (uint32)

oscilloscope:

get_val(obj: object_ref, index: uint32) → val: float

size: 4096 (uint32)

otp_valid: True (bool)

reboot(obj: object_ref)

save_configuration(obj: object_ref) → success: bool

serial_number: 35593360264525 (uint64)

system_stats:

i2c: …

max_stack_usage_analog: 268 (uint32)

max_stack_usage_axis: 564 (uint32)

max_stack_usage_can: 408 (uint32)

max_stack_usage_startup: 532 (uint32)

max_stack_usage_uart: 292 (uint32)

max_stack_usage_usb: 420 (uint32)

min_heap_space: 47432 (uint32)

prio_analog: -2 (int32)

prio_axis: 3 (int32)

prio_can: 0 (int32)

prio_startup: 0 (int32)

prio_uart: 0 (int32)

prio_usb: 0 (int32)

stack_size_analog: 1024 (uint32)

stack_size_axis: 2048 (uint32)

stack_size_can: 1024 (uint32)

stack_size_startup: 2048 (uint32)

stack_size_uart: 4096 (uint32)

stack_size_usb: 4096 (uint32)

uptime: 32840 (uint32)

usb: …

task_timers_armed: False (bool)

task_times:

control_loop_checks: …

control_loop_misc: …

dc_calib_wait: …

sampling: …

test_function(obj: object_ref, delta: int32) → cnt: int32

test_property: 0 (uint32)

user_config_loaded: 30326 (uint32)

vbus_voltage: 17.8333740234375 (float)

In [28]: odrv0.config.gpio3_pwm_mapping.min = -2

…: odrv0.config.gpio3_pwm_mapping.max = 2

…: odrv0.config.gpio3_pwm_mapping.endpoint = odrv0.axis0.controller._input_vel_property

…:

…: odrv0.config.gpio4_pwm_mapping.min = -2

…: odrv0.config.gpio4_pwm_mapping.max = 2

…: odrv0.config.gpio4_pwm_mapping.endpoint = odrv0.axis1.controller._input_vel_property

In [29]: odrv0.save_configuration()

…: odrv0.reboot()

13:51:05.939056 [LEGACY_OBJ] protocol failed with 3 - propagating error to application

Oh no odrv0 disappeared

Reconnected to ODrive v3.6 205F39984D4D (firmware v0.5.6) as odrv0

Oh no odrv0 disappeared

Reconnected to ODrive v3.6 205F39984D4D (firmware v0.5.6) as odrv0

In [30]: odrv0.axis1.controller.input_vel

Out[30]: 0.0

In [31]: odrv0.axis0.controller.input_vel

Out[31]: 0.0

In [32]: odrv0.config.gpio4_mode = GPIO_MODE_PWM

…: odrv0.config.gpio4_pwm_mapping.min = -2

…: odrv0.config.gpio4_pwm_mapping.max = 2

…: odrv0.config.gpio4_pwm_mapping.endpoint = odrv0.axis0.controller._input_pos_property

…:

In [33]: odrv0.config.gpio3_mode = GPIO_MODE_PWM

…: odrv0.config.gpio3_pwm_mapping.min = -2

…: odrv0.config.gpio3_pwm_mapping.max = 2

…: odrv0.config.gpio3_pwm_mapping.endpoint = odrv0.axis0.controller._input_pos_property

…:

In [34]: odrv0.save_configuration()

…: odrv0.reboot()

13:53:17.34528 [LEGACY_OBJ] protocol failed with 3 - propagating error to application

Oh no odrv0 disappeared

Reconnected to ODrive v3.6 205F39984D4D (firmware v0.5.6) as odrv0

In [35]: odrv0.axis0.controller.input_vel

Out[35]: 0.0

In [36]: odrv0.axis0.controller.input_vel

Out[36]: 0.0

In [37]: odrv0.axis0.controller.input_vel

Out[37]: 0.0

In [38]: odrv0.axis1.controller.input_vel

Out[38]: 0.0

In [39]: odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL

In [40]: dump_errors(odrv0)

system: no error

axis0

axis: Error(s):

AxisError.MOTOR_FAILED

AxisError.ENCODER_FAILED

AxisError.CONTROLLER_FAILED

motor: Error(s):

MotorError.UNKNOWN_TORQUE

MotorError.UNKNOWN_VOLTAGE_COMMAND

DRV fault: none

sensorless_estimator: no error

encoder: Error(s):

EncoderError.ILLEGAL_HALL_STATE

controller: no error

axis1

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

In [41]: odrv0.axis0.requested_state = AXIS_STATE_IDLE

In [42]:

In [42]: odrv0.clear_errors()

In [43]: dump_errors(odrv0)

system: no error

axis0

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

axis1

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

In [44]: odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL

…: odrv0.axis0.controller.input_vel = 2

In [45]: odrv0.axis0.controller.input_vel = 0.5

In [46]: 0.2

Out[46]: 0.2

In [47]: odrv0.axis0.controller.input_vel = 0.2

In [48]: odrv0.axis0.controller.input_vel = 5

In [49]: odrv0.axis0.controller.input_vel = 10

In [50]: odrv0.axis0.controller.input_vel = 30

In [51]: odrv0.axis0.controller.input_vel = 20

In [52]: odrv0.axis0.controller.input_vel = 11

In [53]: odrv0.axis0.controller.input_vel = 0.4

In [54]: odrv0.axis0.controller.input_vel = 0

In [55]: odrv0.axis0.requested_state = AXIS_STATE_IDLE

In [56]: odrv0.axis0.controller.input_pos = 1

In [57]: odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL

In [58]: odrv0.axis0.controller.input_pos = 1

In [59]: dump_errors(odrv0)

system: no error

axis0

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

axis1

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

In [60]: odrv0.config.gpio4_mode = 3

In [61]: odrv0.config.gpio3_mode = 3

In [62]: odrv0.config.gpio4_mode = GPIO_MODE_PWM

…: odrv0.config.gpio4_pwm_mapping.min = -2

…: odrv0.config.gpio4_pwm_mapping.max = 2

…: odrv0.config.gpio4_pwm_mapping.endpoint = odrv0.axis0.controller._input_pos_property

In [63]: odrv0.config.gpio3_mode = GPIO_MODE_PWM

…: odrv0.config.gpio3_pwm_mapping.min = -2

…: odrv0.config.gpio3_pwm_mapping.max = 2

…: odrv0.config.gpio3_pwm_mapping.endpoint = odrv0.axis0.controller._input_pos_property

In [64]: odrv0.save_configuration()

…: odrv0.reboot()

14:00:06.318109 [LEGACY_OBJ] protocol failed with 3 - propagating error to application

Oh no odrv0 disappeared

Reconnected to ODrive v3.6 205F39984D4D (firmware v0.5.6) as odrv0

In [65]: odrv0.axis1.controller.input_vel

Out[65]: 0.0

In [66]: odrv0.config.gpio4_pwm_mapping.min = -1 # Minimum PWM signal mapped to the control range (e.

…: g., full reverse)

…: odrv0.config.gpio4_pwm_mapping.max = 1 # Maximum PWM signal mapped to the control range (e.

…: g., full forward)

…: odrv0.config.gpio4_pwm_mapping.endpoint = odrv0.axis0.controller.input_vel # Map PWM to velo

…: city control (can be changed to position or torque if needed)


TypeError Traceback (most recent call last)

Cell In[66], line 3

1 odrv0.config.gpio4_pwm_mapping.min = -1 # Minimum PWM signal mapped to the control range (e.g., full reverse)

2 odrv0.config.gpio4_pwm_mapping.max = 1 # Maximum PWM signal mapped to the control range (e.g., full forward)

----> 3 odrv0.config.gpio4_pwm_mapping.endpoint = odrv0.axis0.controller.input_vel # Map PWM to velocity control (can be changed to position or torque if needed)

File /Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/odrive/pyfibre/fibre/libfibre.py:678, in RemoteObject.setattr(self, key, value)

676 if self.sealed and not key in dir(self) and not hasattr(self, key):

677 raise AttributeError(“Attribute {} not found”.format(key))

→ 678 object.setattr(self, key, value)

File /Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/odrive/pyfibre/fibre/libfibre.py:647, in RemoteAttribute.set(self, instance, val)

645 def set(self, instance, val):

646 if self._magic_setter:

→ 647 return self._get_obj(instance).exchange(val)

648 else:

649 raise Exception(“this attribute cannot be written to”)

File /Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/odrive/pyfibre/fibre/libfibre.py:584, in RemoteFunction.call(self, cancellation_token, *args)

574 “”"

575 Starts invoking the remote function. The first argument is usually a

576 remote object.

(…)

580 invokation.

581 “”"

583 if threading.current_thread() != libfibre_thread:

→ 584 return run_coroutine_threadsafe(self._libfibre.loop, lambda: self.call(*args))

586 if (len(self._inputs) != len(args)):

587 raise TypeError(“expected {} arguments but have {}”.format(len(self._inputs), len(args)))

File /Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/odrive/pyfibre/fibre/libfibre.py:299, in run_coroutine_threadsafe(loop, func)

297 future.set_exception(ex)

298 loop.call_soon_threadsafe(asyncio.ensure_future, func_async())

→ 299 return future.result()

File /Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/concurrent/futures/_base.py:456, in Future.result(self, timeout)

454 raise CancelledError()

455 elif self._state == FINISHED:

→ 456 return self.__get_result()

457 else:

458 raise TimeoutError()

File /Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/concurrent/futures/_base.py:401, in Future.__get_result(self)

399 if self._exception:

400 try:

→ 401 raise self._exception

402 finally:

403 # Break a reference cycle with the exception in self._exception

404 self = None

File /Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/odrive/pyfibre/fibre/libfibre.py:294, in run_coroutine_threadsafe..func_async()

292 result = func()

293 if hasattr(result, ‘await’):

→ 294 result = await result

295 future.set_result(result)

296 except Exception as ex:

File /Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/odrive/pyfibre/fibre/libfibre.py:538, in RemoteFunction.async_call(self, args, cancellation_token)

536 tx_buf = bytes()

537 for i, arg in enumerate(self._inputs):

→ 538 tx_buf += arg[2].serialize(self._libfibre, args[i])

539 rx_buf = bytes()

541 agen = Call(self)

File /Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/odrive/pyfibre/fibre/libfibre.py:250, in ObjectPtrCodec.serialize(self, libfibre, value)

248 return struct.pack(“P”, value._obj_handle)

249 else:

→ 250 raise TypeError(“Expected value of type RemoteObject or None but got ‘{}’. An example for a RemoteObject is this expression: odrv0.axis0.controller._input_pos_property”.format(type(value).name))

TypeError: Expected value of type RemoteObject or None but got ‘float’. An example for a RemoteObject is this expression: odrv0.axis0.controller._input_pos_property

In [67]: dump_errors(odrv0)

system: no error

axis0

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

axis1

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

In [68]: odrv0.config.gpio4_pwm_mapping.center = 1500 # Neutral position (e.g., 1500us for zero speed

…: )

…: odrv0.config.gpio4_pwm_mapping.deadzone = 50 # Dead zone for neutral signal to avoid jitter

…: around 1500us


AttributeError Traceback (most recent call last)

Cell In[68], line 1

----> 1 odrv0.config.gpio4_pwm_mapping.center = 1500 # Neutral position (e.g., 1500us for zero speed)

2 odrv0.config.gpio4_pwm_mapping.deadzone = 50 # Dead zone for neutral signal to avoid jitter around 1500us

File /Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/odrive/pyfibre/fibre/libfibre.py:677, in RemoteObject.setattr(self, key, value)

675 def setattr(self, key, value):

676 if self.sealed and not key in dir(self) and not hasattr(self, key):

→ 677 raise AttributeError(“Attribute {} not found”.format(key))

678 object.setattr(self, key, value)

AttributeError: Attribute center not found

In [69]: odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL

In [70]: odrv0.axis1.controller.input_vel

Out[70]: 0.0

In [71]: odrv0.save_configuration()

…: odrv0.reboot()

14:03:41.206704 [LEGACY_OBJ] protocol failed with 3 - propagating error to application

Oh no odrv0 disappeared

Reconnected to ODrive v3.6 205F39984D4D (firmware v0.5.6) as odrv0

In [72]: odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL

…: odrv0.axis0.controller.input_vel = 2

In [73]: odrv0.axis0.controller.input_vel = 10

In [74]: odrv0.axis0.controller.input_vel = 0.4

In [75]: odrv0.axis0.controller.input_vel = 0.4

In [76]: odrv0.axis0.controller.input_vel = 0.6

In [77]: dump_errors(odrv0)

system: no error

axis0

axis: Error(s):

AxisError.MOTOR_FAILED

AxisError.ENCODER_FAILED

AxisError.CONTROLLER_FAILED

motor: Error(s):

MotorError.UNKNOWN_TORQUE

MotorError.UNKNOWN_VOLTAGE_COMMAND

DRV fault: none

sensorless_estimator: no error

encoder: Error(s):

EncoderError.ILLEGAL_HALL_STATE

controller: no error

axis1

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

In [78]: odrv0.clear_errors()

In [79]: odrv0.axis0.controller.input_vel = 0.6

In [80]: odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL

…: odrv0.axis0.controller.input_vel = 2

In [81]: odrv0.axis0.controller.input_vel = 0.6

In [82]: odrv0.axis0.controller.input_vel = 0

In [83]: odrv0.axis0.requested_state = AXIS_STATE_IDLE

In [84]: odrv0.save_configuration()

…: odrv0.reboot()

14:07:49.72952 [LEGACY_OBJ] protocol failed with 3 - propagating error to application

Oh no odrv0 disappeared

Reconnected to ODrive v3.6 205F39984D4D (firmware v0.5.6) as odrv0

In [85]: odrv0.axis1.controller.input_vel

Out[85]: 0.0

Oh no odrv0 disappeared

Reconnected to ODrive v3.6 205F39984D4D (firmware v0.5.6) as odrv0

In [86]: odrv0

Out[86]:

axis0:

acim_estimator: …

config: …

controller: …

current_state: 1 (uint8)

encoder: …

error: 0 (uint32)

is_homed: False (bool)

last_drv_fault: 0 (uint32)

max_endstop: …

mechanical_brake: …

min_endstop: …

motor: …

requested_state: 0 (uint8)

sensorless_estimator: …

step_dir_active: False (bool)

steps: 25 (int64)

task_times: …

trap_traj: …

watchdog_feed(obj: object_ref)

axis1:

acim_estimator: …

config: …

controller: …

current_state: 1 (uint8)

encoder: …

error: 0 (uint32)

is_homed: False (bool)

last_drv_fault: 0 (uint32)

max_endstop: …

mechanical_brake: …

min_endstop: …

motor: …

requested_state: 0 (uint8)

sensorless_estimator: …

step_dir_active: False (bool)

steps: 0 (int64)

task_times: …

trap_traj: …

watchdog_feed(obj: object_ref)

brake_resistor_armed: True (bool)

brake_resistor_current: -0.0 (float)

brake_resistor_saturated: False (bool)

can:

config: …

error: 0 (uint8)

clear_errors(obj: object_ref)

config:

brake_resistance: 2.0 (float)

dc_bus_overvoltage_ramp_end: 59.92000198364258 (float)

dc_bus_overvoltage_ramp_start: 59.92000198364258 (float)

dc_bus_overvoltage_trip_level: 59.92000198364258 (float)

dc_bus_undervoltage_trip_level: 8.0 (float)

dc_max_negative_current: -10.0 (float)

dc_max_positive_current: inf (float)

enable_brake_resistor: True (bool)

enable_can_a: True (bool)

enable_dc_bus_overvoltage_ramp: False (bool)

enable_i2c_a: False (bool)

enable_uart_a: True (bool)

enable_uart_b: False (bool)

enable_uart_c: False (bool)

error_gpio_pin: 0 (uint32)

gpio10_mode: 0 (uint8)

gpio11_mode: 0 (uint8)

gpio12_mode: 12 (uint8)

gpio13_mode: 12 (uint8)

gpio14_mode: 2 (uint8)

gpio15_mode: 7 (uint8)

gpio16_mode: 7 (uint8)

gpio1_mode: 4 (uint8)

gpio1_pwm_mapping: …

gpio2_mode: 4 (uint8)

gpio2_pwm_mapping: …

gpio3_analog_mapping: …

gpio3_mode: 10 (uint8)

gpio3_pwm_mapping: …

gpio4_analog_mapping: …

gpio4_mode: 10 (uint8)

gpio4_pwm_mapping: …

gpio5_mode: 3 (uint8)

gpio6_mode: 0 (uint8)

gpio7_mode: 0 (uint8)

gpio8_mode: 0 (uint8)

gpio9_mode: 0 (uint8)

max_regen_current: 0.0 (float)

uart0_protocol: 3 (uint8)

uart1_protocol: 3 (uint8)

uart2_protocol: 3 (uint8)

uart_a_baudrate: 115200 (uint32)

uart_b_baudrate: 115200 (uint32)

uart_c_baudrate: 115200 (uint32)

usb_cdc_protocol: 3 (uint8)

enter_dfu_mode(obj: object_ref)

erase_configuration(obj: object_ref)

error: 0 (uint8)

fw_version_major: 0 (uint8)

fw_version_minor: 5 (uint8)

fw_version_revision: 6 (uint8)

fw_version_unreleased: 0 (uint8)

get_adc_voltage(obj: object_ref, gpio: uint32) → voltage: float

get_dma_status(obj: object_ref, stream_num: uint8) → status: uint32

get_drv_fault(obj: object_ref) → drv_fault: uint64

get_gpio_states(obj: object_ref) → status: uint32

get_interrupt_status(obj: object_ref, irqn: int32) → status: uint32

hw_version_major: 3 (uint8)

hw_version_minor: 6 (uint8)

hw_version_variant: 56 (uint8)

ibus: 0.0 (float)

ibus_report_filter_k: 1.0 (float)

misconfigured: False (bool)

n_evt_control_loop: 351743 (uint32)

n_evt_sampling: 351746 (uint32)

oscilloscope:

get_val(obj: object_ref, index: uint32) → val: float

size: 4096 (uint32)

otp_valid: True (bool)

reboot(obj: object_ref)

save_configuration(obj: object_ref) → success: bool

serial_number: 35593360264525 (uint64)

system_stats:

i2c: …

max_stack_usage_analog: 316 (uint32)

max_stack_usage_axis: 564 (uint32)

max_stack_usage_can: 408 (uint32)

max_stack_usage_startup: 532 (uint32)

max_stack_usage_uart: 292 (uint32)

max_stack_usage_usb: 420 (uint32)

min_heap_space: 47432 (uint32)

prio_analog: -2 (int32)

prio_axis: 3 (int32)

prio_can: 0 (int32)

prio_startup: 0 (int32)

prio_uart: 0 (int32)

prio_usb: 0 (int32)

stack_size_analog: 1024 (uint32)

stack_size_axis: 2048 (uint32)

stack_size_can: 1024 (uint32)

stack_size_startup: 2048 (uint32)

stack_size_uart: 4096 (uint32)

stack_size_usb: 4096 (uint32)

uptime: 44085 (uint32)

usb: …

task_timers_armed: False (bool)

task_times:

control_loop_checks: …

control_loop_misc: …

dc_calib_wait: …

sampling: …

test_function(obj: object_ref, delta: int32) → cnt: int32

test_property: 0 (uint32)

user_config_loaded: 30326 (uint32)

vbus_voltage: 17.848682403564453 (float)

In [87]: odrv0.axis1.controller.input_vel

Out[87]: 0.0

Oh no odrv0 disappeared

In [88]:

Have you verified the PWM receiver is actually outputting? Can you post an image of the wiring?

i have the flightcontroller connected to my pc and I monitor the receiver from there, and it should output signal. I also have the PWM value change beforehand but it did not affect the motors rpm or anything for that matter.

Thanks for the picture. The setup commands you showed before were quite hard to follow, can you only send the relevant ones for your setup?

Also, where did these come from? These aren’t actual ODrive properties, what documentation are you reading?

Oh - i found it

odrv0.config.gpio4_pwm_mapping.endpoint = odrv0.axis0.controller.input_vel
this is incorrect, please see the docs carefully, it should be
odrv0.config.gpio4_pwm_mapping.endpoint = odrv0.axis0.controller._input_vel_property

im using chat gpt and that does forsure not help, lol…

but here is the “minimum” I think

Motor configuration for axis1

odrv0.axis1.motor.config.pole_pairs = 15
odrv0.axis1.motor.config.resistance_calib_max_voltage = 4
odrv0.axis1.motor.config.requested_current_range = 25 # Requires config save and reboot
odrv0.axis1.motor.config.current_control_bandwidth = 100
odrv0.axis1.motor.config.torque_constant = 8.27 /

Encoder configuration for hall mode

odrv0.axis1.encoder.config.mode = ENCODER_MODE_HALL
odrv0.axis1.encoder.config.cpr = 90
odrv0.axis1.encoder.config.calib_scan_distance = 150
odrv0.config.gpio12_mode = GPIO_MODE_DIGITAL
odrv0.config.gpio13_mode = GPIO_MODE_DIGITAL
odrv0.config.gpio14_mode = GPIO_MODE_DIGITAL

Adjust encoder and controller settings for smooth velocity control

odrv0.axis1.encoder.config.bandwidth = 100
odrv0.axis1.controller.config.pos_gain = 1
odrv0.axis1.controller.config.vel_gain = 0.02 * odrv0.axis1.motor.config.torque_constant * odrv0.axis1.encoder.config.cpr
odrv0.axis1.controller.config.vel_integrator_gain = 0.1 * odrv0.axis1.motor.config.torque_constant * odrv0.axis1.encoder.config.cpr
odrv0.axis1.controller.config.vel_limit = 10
odrv0.axis1.controller.config.control_mode = CONTROL_MODE_VELOCITY_CONTROL

Save and reboot configuration

odrv0.save_configuration()
odrv0.reboot()

Motor calibration for axis1

odrv0.axis1.requested_state = AXIS_STATE_MOTOR_CALIBRATION

Check motor status

odrv0.axis1.motor

Save motor calibration

odrv0.axis1.motor.config.pre_calibrated = True

Hall polarity calibration for axis1

odrv0.axis1.requested_state = AXIS_STATE_ENCODER_HALL_POLARITY_CALIBRATION

Check encoder status

odrv0.axis1.encoder

Encoder offset calibration for axis1

odrv0.axis1.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION

Save encoder calibration

odrv0.axis1.encoder.config.pre_calibrated = True

Save and reboot again

odrv0.save_configuration()
odrv0.reboot()

Enable closed-loop control for axis1

odrv0.axis1.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL
odrv0.axis1.controller.input_vel = 2 # Motor should spin
odrv0.axis1.controller.input_vel = 0
odrv0.axis1.requested_state = AXIS_STATE_IDLE

Configure PWM input for axis1 on GPIO4

odrv0.config.gpio4_pwm_mapping.min = -2
odrv0.config.gpio4_pwm_mapping.max = 2
odrv0.config.gpio4_pwm_mapping.endpoint = odrv0.axis1.controller._input_vel_property

Save and reboot to apply PWM input

odrv0.save_configuration()
odrv0.reboot()

Check input velocity from the PWM

odrv0.axis1.controller.input_vel

Yes, please don’t use chatgpt, it will be completely useless and incorrect. The only resource you should be using is the ODrive documentation: Getting Started — ODrive Documentation 0.5.6 documentation

im following this one. and still stuck at the PWM part .

https://docs.odriverobotics.com/v/0.5.6/hoverboard.html#hoverboard-doc

What about it are you stuck on? Can you show the exact commands you’re using?

i use this to config the gpio for PWM.

Configure PWM input for axis1 on GPIO4

odrv0.config.gpio4_pwm_mapping.min = -2

odrv0.config.gpio4_pwm_mapping.max = 2

odrv0.config.gpio4_pwm_mapping.endpoint = odrv0.axis1.controller._input_vel_property

and this one to see if I get a signal on the gpio
odrv0.axis1.controller.input_vel

any help- after a reboot the errors are gone and I have control for a bit I move my value range from 1000-2000 and near 1500 it “clicks” and breaks. and a soft reboot is needed.

Reconnected to ODrive v3.6 205F39984D4D (firmware v0.5.6) as odrv0

In [308]: dump_errors(odrv0) # This will display all errors for odrv0 including axis0 and axis1

system: no error

axis0

axis: Error(s):

AxisError.MOTOR_FAILED

AxisError.ENCODER_FAILED

AxisError.CONTROLLER_FAILED

motor: Error(s):

MotorError.UNKNOWN_TORQUE

MotorError.UNKNOWN_VOLTAGE_COMMAND

DRV fault: none

sensorless_estimator: no error

encoder: Error(s):

EncoderError.ILLEGAL_HALL_STATE

controller: no error

axis1

axis: no error

motor: no error

DRV fault: none

sensorless_estimator: no error

encoder: no error

controller: no error

In [309]:

The v3.6 has a lot of issues with electrical noise – typically we recommend adding external 22nF capacitors to the hall lines, like so Encoder error ERROR_ILLEGAL_HALL_STATE - #7 by madcowswe. That should help this issue. You can also use ferrite rings on the motor phases, for added benefit.