Need help w/ sensorless mode board 3.4

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

I had a brief look at your settings, and as far as I can tell it looks ok. Can you check the error code?

You can’t run position control in sensorlsess mode: demo.py uses position control by default. You can try explore_odrive.py instead.