Brushless fan heats up too much too quickly

Hello,

I’m trying to control this brushless fan with my ODrive v3.6 (fw: 0.4.12). Previously, I’ve had good luck with other motors but this one keeps giving me problems.

Reading through the forum, I realized that the ODrive is not optimized to drive this motor since it’s a high phase resistance, low current, high speed motor and that probably I have to change the shunts. Before I try to stick my soldering iron anywhere, I want to make sure I have exhausted all possible solutions that are purely software.

Here are the calibration data:
motor:

error = 0x0000 (int)
armed_state = 0 (int)
is_calibrated = True (bool)
current_meas_phB = 0.31261035799980164 (float)
current_meas_phC = 0.02401140332221985 (float)
DC_calib_phB = 0.07030913978815079 (float)
DC_calib_phC = 0.3588608503341675 (float)
phase_current_rev_gain = 0.012500000186264515 (float)
thermal_current_lim = 91.98960876464844 (float)
get_inverter_temp()
current_control:
  p_gain = 0.014318176545202732 (float)
  i_gain = 151.45947265625 (float)
  v_current_control_integral_d = 0.0 (float)
  v_current_control_integral_q = 0.0 (float)
  Ibus = 0.0 (float)
  final_v_alpha = 0.0 (float)
  final_v_beta = 0.0 (float)
  Iq_setpoint = 0.0 (float)
  Iq_measured = 0.0 (float)
  Id_measured = 0.0 (float)
  I_measured_report_filter_k = 1.0 (float)
  max_allowed_current = 30.375 (float)
  overcurrent_trip_level = 33.75 (float)
gate_driver:
  drv_fault = 0 (int)
timing_log:
  TIMING_LOG_GENERAL = 0 (int)
  TIMING_LOG_ADC_CB_I = 2458 (int)
  TIMING_LOG_ADC_CB_DC = 13006 (int)
  TIMING_LOG_MEAS_R = 0 (int)
  TIMING_LOG_MEAS_L = 0 (int)
  TIMING_LOG_ENC_CALIB = 0 (int)
  TIMING_LOG_IDX_SEARCH = 0 (int)
  TIMING_LOG_FOC_VOLTAGE = 0 (int)
  TIMING_LOG_FOC_CURRENT = 0 (int)
config:
  pre_calibrated = True (bool)
  pole_pairs = 2 (int)
  calibration_current = 2.0 (float)
  resistance_calib_max_voltage = 4.0 (float)
  phase_inductance = 0.00014318176545202732 (float)
  phase_resistance = 1.5145947933197021 (float)
  direction = 1 (int)
  motor_type = 0 (int)
  current_lim = 20.0 (float)
  current_lim_tolerance = 5.0 (float)
  inverter_temp_limit_lower = 100.0 (float)
  inverter_temp_limit_upper = 120.0 (float)
  requested_current_range = 25.0 (float)
  current_control_bandwidth = 100.0 (float)

encoder:

error = 0x0000 (int)
is_ready = True (bool)
index_found = False (bool)
shadow_count = -2 (int)
count_in_cpr = 10 (int)
interpolation = 0.5 (float)
phase = 0.36997127532958984 (float)
pos_estimate = -1.9750031232833862 (float)
pos_cpr = 10.024981498718262 (float)
hall_state = 4 (int)
vel_estimate = 0.0 (float)
calib_scan_response = 0.0 (float)
config:
  mode = 1 (int)
  use_index = False (bool)
  find_idx_on_lockin_only = False (bool)
  pre_calibrated = True (bool)
  zero_count_on_find_idx = True (bool)
  cpr = 12 (int)
  offset = 33 (int)
  offset_float = 1.1467031240463257 (float)
  enable_phase_interpolation = True (bool)
  bandwidth = 100.0 (float)
  calib_range = 0.05000000074505806 (float)
  calib_scan_distance = 50.26548385620117 (float)
  calib_scan_omega = 12.566370964050293 (float)
  idx_search_unidirectional = False (bool)
  ignore_illegal_hall_state = False (bool)
set_linear_count(count: int)

controller:

error = 0x0000 (int)
is_ready = True (bool)
index_found = False (bool)
shadow_count = -2 (int)
count_in_cpr = 10 (int)
interpolation = 0.5 (float)
phase = 0.36997127532958984 (float)
pos_estimate = -1.9750031232833862 (float)
pos_cpr = 10.024981498718262 (float)
hall_state = 4 (int)
vel_estimate = 0.0 (float)
calib_scan_response = 0.0 (float)
config:
  mode = 1 (int)
  use_index = False (bool)
  find_idx_on_lockin_only = False (bool)
  pre_calibrated = True (bool)
  zero_count_on_find_idx = True (bool)
  cpr = 12 (int)
  offset = 33 (int)
  offset_float = 1.1467031240463257 (float)
  enable_phase_interpolation = True (bool)
  bandwidth = 100.0 (float)
  calib_range = 0.05000000074505806 (float)
  calib_scan_distance = 50.26548385620117 (float)
  calib_scan_omega = 12.566370964050293 (float)
  idx_search_unidirectional = False (bool)
  ignore_illegal_hall_state = False (bool)
set_linear_count(count: int)

config:

startup_motor_calibration = False (bool)
startup_encoder_index_search = False (bool)
startup_encoder_offset_calibration = False (bool)
startup_closed_loop_control = False (bool)
startup_sensorless_control = False (bool)
enable_step_dir = False (bool)
counts_per_step = 2.0 (float)
watchdog_timeout = 0.0 (float)
step_gpio_pin = 1 (int)
dir_gpio_pin = 2 (int)
calibration_lockin:
  current = 10.0 (float)
  ramp_time = 0.4000000059604645 (float)
  ramp_distance = 3.1415927410125732 (float)
  accel = 20.0 (float)
  vel = 40.0 (float)
sensorless_ramp:
  current = 10.0 (float)
  ramp_time = 0.4000000059604645 (float)
  ramp_distance = 3.1415927410125732 (float)
  accel = 200.0 (float)
  vel = 400.0 (float)
  finish_distance = 100.0 (float)
  finish_on_vel = True (bool)
  finish_on_distance = False (bool)
  finish_on_enc_idx = False (bool)
general_lockin:
  current = 10.0 (float)
  ramp_time = 0.4000000059604645 (float)
  ramp_distance = 3.1415927410125732 (float)
  accel = 20.0 (float)
  vel = 40.0 (float)
  finish_distance = 100.0 (float)
  finish_on_vel = False (bool)
  finish_on_distance = False (bool)
  finish_on_enc_idx = False (bool)

Things I’ve tried/noticed:

  • I’ve tried sensored, sensorless and gimbal without any noticeable difference (maybe sensored was the worst).
  • When the vel_setpoint is 0, the rotor oscillates probably between two poles. Only by changing the mode to idle I can eliminate the oscillation.
  • The max speed is way below what I can get with a cheap drone ESC (cant get pass 4000) although I’ve seen it surpass it from time to time when the controller is not properly tuned. I’ve tried changing the current limit and velocity limit too.
  • Even at low speed operations at no load, the motor heats up fast and even starts to stinks.

Please let me know what should I try next. Any help will be greatly appreciated!

The max current of 0.65A is within the noise floor of the ODrive, I don’t think you can control this motor without changing the shunts. Use the liveplotter and read motor.current_control.Iq_measured - the noise in idle is probably above 0.65A

The blower is rated to 36-42W at 24V so the PSU needs at least 1.5A which the datasheet also states. I think that 0.65A is the current draw at a specific operating point not the actually max rated current. The fan wouldn’t spin up without moving the current limit to 10A, so I guess that either the phases uses higher current than the PSU or I’m overcharging the coils.

Heres the Iq_measured vs Iq_setpoint:

Figure_1

Current limit is 1.5A, the calibration current is 0.5, the speeds were 0, 120, 1000, 1500 and 2000. The set speed of 2000 didn’t cause a change in speed of the fan since it probably was limited by the current, the speed of 1000 and 1500 were oscillating.

So yeah, the current noise is too high for my motor. Whats a good rule to change the resistor values to? Do I need to reflash the odrive once I change this?

Someone started a similar thread here: How sensitive the torque measurement is when using small currents?

I think you’d both want to increase the shunt values by a factor of 10, and yes you would need to modify the firmware in a few places. For example the selectable ranges of the DRV8301 would change, but there may be other places affected. One of the devs might comment here.

Just changing the definition for the shunt resistance in board_config_v3.h should propagate to all math. (Line 18)

Thanks, I will try this next week. Is there a procedure or method to determine whats the ideal shunt resistance? What value would you recommend?