hey @madcowswe,
Hardware looks great! When will you be posting v3.4 schematics?
was wondering if you could glance at my code. I’m trying to spin a turnigy multistar sensorless in velocity control mode. Motor is multistar 4108-380, 11 pole pairs, 19 V
My bench supply is set at 19V, 12A limit (max current supply can do)
#define POLE_PAIRS 11 // This value is correct for N5065 motors and Turnigy SK3 series.
....
// M0
// .control_mode = CTRL_MODE_POSITION_CONTROL, //see: Motor_control_mode_t
.control_mode = CTRL_MODE_VELOCITY_CONTROL,
.enable_step_dir = false, //auto enabled after calibration
.counts_per_step = 2.0f,
.error = ERROR_NO_ERROR,
.drv_fault = DRV8301_FaultType_NoFault,
.pos_setpoint = 0.0f,
.pos_gain = 20.0f, // [(counts/s) / counts]
//.vel_setpoint = 0.0f,
.vel_setpoint = 800.0f, //<sensorless example>
//.vel_gain = 5.0f / 10000.0f, // [A/(counts/s)]
.vel_gain = 15.0f / 200.0f, // [A/(rad/s)] <sensorless example>
//.vel_integrator_gain = 10.0f / 10000.0f, // [A/(counts/s * s)]
.vel_integrator_gain = 0.0f, // [A/(rad/s * s)] <sensorless example>
.vel_integrator_current = 0.0f, // [A]
.vel_limit = 20000.0f, // [counts/s]
.current_setpoint = 0.0f, // [A]
.calibration_current = 10.0f, // [A]
.resistance_calib_max_voltage = 1.0f, // [V] - You may need to increase this if this voltage isn't sufficient to drive calibration_current through the motor.
.dc_bus_brownout_trip_level = 8.0f, // [V]
.phase_inductance = 0.0f, // to be set by measure_phase_inductance
.phase_resistance = 0.0f, // to be set by measure_phase_resistance
.motor_thread = 0,
.thread_ready = false,
// .enable_control = true,
// .do_calibration = true,
// .calibration_ok = false,
.motor_timer = &htim1,
.next_timings = {TIM_1_8_PERIOD_CLOCKS / 2, TIM_1_8_PERIOD_CLOCKS / 2, TIM_1_8_PERIOD_CLOCKS / 2},
.control_deadline = TIM_1_8_PERIOD_CLOCKS,
.last_cpu_time = 0,
.current_meas = {0.0f, 0.0f},
.DC_calib = {0.0f, 0.0f},
.gate_driver = {
.spiHandle = &hspi3,
// Note: this board has the EN_Gate pin shared!
.EngpioHandle = EN_GATE_GPIO_Port,
.EngpioNumber = EN_GATE_Pin,
.nCSgpioHandle = M0_nCS_GPIO_Port,
.nCSgpioNumber = M0_nCS_Pin,
.RxTimeOut = false,
.enableTimeOut = false,
},
// .gate_driver_regs Init by DRV8301_setup
.motor_type = MOTOR_TYPE_HIGH_CURRENT,
// .motor_type = MOTOR_TYPE_GIMBAL,
.shunt_conductance = 1.0f / SHUNT_RESISTANCE, //[S]
.phase_current_rev_gain = 0.0f, // to be set by DRV8301_setup
.current_control = {
// Read out max_allowed_current to see max supported value for current_lim.
// You can change DRV8301_ShuntAmpGain to get a different range.
// .current_lim = 75.0f, //[A]
.current_lim = 10.0f, //[A]
.p_gain = 0.0f, // [V/A] should be auto set after resistance and inductance measurement
.i_gain = 0.0f, // [V/As] should be auto set after resistance and inductance measurement
.v_current_control_integral_d = 0.0f,
.v_current_control_integral_q = 0.0f,
.Ibus = 0.0f,
.final_v_alpha = 0.0f,
.final_v_beta = 0.0f,
.Iq_setpoint = 0.0f,
.Iq_measured = 0.0f,
.max_allowed_current = 0.0f,
},
.rotor_mode = ROTOR_MODE_SENSORLESS,
// .rotor_mode = ROTOR_MODE_RUN_ENCODER_TEST_SENSORLESS,
// .rotor_mode = ROTOR_MODE_ENCODER,
.encoder = {
.encoder_timer = &htim3,
.use_index = false,
.index_found = false,
.calibrated = false,
.idx_search_speed = 10.0f, // [rad/s electrical]
.encoder_cpr = ENCODER_CPR,
.encoder_offset = 0,
.encoder_state = 0,
.motor_dir = 1, // 1 or -1
.encoder_calib_range = 0.02,
.phase = 0.0f, // [rad]
.pll_pos = 0.0f, // [rad]
.pll_vel = 0.0f, // [rad/s]
.pll_kp = 0.0f, // [rad/s / rad]
.pll_ki = 0.0f, // [(rad/s^2) / rad]
},
.sensorless = {
.phase = 0.0f, // [rad]
.pll_pos = 0.0f, // [rad]
.pll_vel = 0.0f, // [rad/s]
.pll_kp = 0.0f, // [rad/s / rad]
.pll_ki = 0.0f, // [(rad/s^2) / rad]
.observer_gain = 1000.0f, // [rad/s]
.flux_state = {0.0f, 0.0f}, // [Vs]
.V_alpha_beta_memory = {0.0f, 0.0f}, // [V]
.pm_flux_linkage = 1.31e-3f, // [V / (rad/s)] { 5.51328895422 / (<pole pairs> * <rpm/v>) }
.estimator_good = false,
.spin_up_current = 10.0f, // [A]
.spin_up_acceleration = 400.0f, // [rad/s^2]
.spin_up_target_vel = 400.0f, // [rad/s]
},
.loop_counter = 0,
.timing_log = {0},
.anticogging = {
.index = 0,
.cogging_map = NULL,
.use_anticogging = false,
.calib_anticogging = false,
.calib_pos_threshold = 1.0f,
.calib_vel_threshold = 1.0f,
},
},
{
Then with demo.py I changed the pos setpoint control to
my_drive.motor0.set_vel_setpoint(800.0, 0.0)
my supply hits 0.7A for a few seconds on power up then goes back down to 50mA
Also, it seems like whenever I run the demo.py file, I need to power cycle the board and run again. I am running within a linux VM so that might be the issue though…
Connecting to device on USB device bus 1 device 13
Traceback (most recent call last):
File "/home/bill/ODrive/tools/odrive/usbbulk_transport.py", line 96, in get_packet
ret = self.epr.read(bufferLen, timeout)
File "/usr/lib/python3/dist-packages/usb/core.py", line 364, in read
return self.device.read(self, size_or_buffer, timeout)
File "/usr/lib/python3/dist-packages/usb/core.py", line 918, in read
self.__get_timeout(timeout))
File "/usr/lib/python3/dist-packages/usb/backend/libusb1.py", line 769, in bulk_read
timeout)
File "/usr/lib/python3/dist-packages/usb/backend/libusb1.py", line 872, in __read
_check(retval)
File "/usr/lib/python3/dist-packages/usb/backend/libusb1.py", line 552, in _check
raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 110] Operation timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "demo.py", line 13, in <module>
my_drive = odrive.core.find_any(consider_usb=True, consider_serial=False, printer=print)
File "/home/bill/ODrive/tools/odrive/core.py", line 304, in find_any
dev = next(find_all(consider_usb, consider_serial, printer=printer), None)
File "/home/bill/ODrive/tools/odrive/core.py", line 288, in find_all
yield object_from_channel(channel, printer)
File "/home/bill/ODrive/tools/odrive/core.py", line 215, in object_from_channel
json_bytes = channel.remote_endpoint_read_buffer(0)
File "/home/bill/ODrive/tools/odrive/protocol.py", line 280, in remote_endpoint_read_buffer
chunk = self.remote_endpoint_operation(endpoint_id, struct.pack("<I", len(buffer)), True, chunk_length)
File "/home/bill/ODrive/tools/odrive/protocol.py", line 254, in remote_endpoint_operation
response = self._input.get_packet(deadline)
File "/home/bill/ODrive/tools/odrive/usbbulk_transport.py", line 104, in get_packet
ret = self.epr.read(bufferLen, timeout)
File "/usr/lib/python3/dist-packages/usb/core.py", line 364, in read
return self.device.read(self, size_or_buffer, timeout)
File "/usr/lib/python3/dist-packages/usb/core.py", line 918, in read
self.__get_timeout(timeout))
File "/usr/lib/python3/dist-packages/usb/backend/libusb1.py", line 769, in bulk_read
timeout)
File "/usr/lib/python3/dist-packages/usb/backend/libusb1.py", line 872, in __read
_check(retval)
File "/usr/lib/python3/dist-packages/usb/backend/libusb1.py", line 552, in _check
raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 110] Operation timed out
Thanks,
Bill