I have an Odrive S1 and am controlling it with a Teensy4.1 via CAN. It works fine but when I try to read the current I always get 0 (with the command from the example). When I try to read the current via the odrivetool I get the three phase currents. What is the command in teensy with CAN to get those phase currents?
Kind regards
Hi! How are you trying to read the current? Could you post the code? And what command are you referencing this to in ODrivetool?
Hi, thanks for your answer!
The code I use to read the current on my teensy is the following:
// request bus voltage and current (1sec timeout)
Serial.println(“attempting to read bus voltage and current”);
Get_Bus_Voltage_Current_msg_t vbus;
if (!odrv0.request(vbus, 1)) {
Serial.println(“vbus request failed!”);
while (true); // spin indefinitely
}
Serial.print("DC voltage [V]: ");
Serial.println(vbus.Bus_Voltage);
Serial.print("DC current [A]: ");
Serial.println(vbus.Bus_Current);
With this code the voltage is given correctly but the current gives 0. This code comes from the Arduino CAN example from the odrive website.
To get the phase currents in Odrivetool I type the following:
odrv0.axis0.motor
The following list then appears:
acim_estimator:
phase_offset: 0.0 (float)
rotor_flux: 0.0 (float)
slip_vel: 0.0 (float)
stator_phase: 0.0 (float)
stator_phase_vel: -0.043952636420726776 (float)
alpha_beta_controller:
I_bus: 7.426164665957913e-05 (float)
Ialpha_measured: 0.03540567681193352 (float)
Ibeta_measured: -0.015320459380745888 (float)
current_meas_phA: 0.4792085289955139 (float)
current_meas_phB: 0.11979475617408752 (float)
current_meas_phC: 0.00399807607755065 (float)
current_meas_status_phA: 0 (uint32)
current_meas_status_phB: 0 (uint32)
current_meas_status_phC: 0 (uint32)
max_measurable_current: 60.75 (float)
n_evt_current_measurement: 319639 (uint32)
n_evt_pwm_update: 314731 (uint32)
power: 0.002117239637300372 (float)
dc_calib:
a_0: 8290.9169921875 (float)
a_1: 8329.498046875 (float)
a_2: 8356.3916015625 (float)
b_0: 8217.197265625 (float)
b_1: 8148.61279296875 (float)
b_2: 8188.23486328125 (float)
c_0: 8126.7119140625 (float)
c_1: 8153.84423828125 (float)
c_2: 8087.75830078125 (float)
effective_current_lim: 10.0 (float)
electrical_power: -0.005129098892211914 (float)
fet_thermistor:
temperature: 23.13916015625 (float)
foc:
I_measured_report_filter_k: 1.0 (float)
Id_measured: -0.09298515319824219 (float)
Id_setpoint: 0.0 (float)
Iq_measured: -0.10117678344249725 (float)
Iq_setpoint: -0.008085271343588829 (float)
Vd_setpoint: 0.0 (float)
Vq_setpoint: 0.0017077893717214465 (float)
final_v_alpha: 0.021872656419873238 (float)
final_v_beta: -0.010514095425605774 (float)
i_gain: 91.12201690673828 (float)
mod_d: -0.0008093737997114658 (float)
mod_q: -0.0012635240564122796 (float)
p_gain: 0.05112745612859726 (float)
phase: 0.2356700897216797 (float)
phase_vel: 0.5853233933448792 (float)
v_current_control_integral_d: -0.008094720542430878 (float)
v_current_control_integral_q: -0.03298168256878853 (float)
input_id: 0.0 (float)
input_iq: 0.0 (float)
loss_power: -0.0023755449801683426 (float)
mechanical_power: 0.00029121682746335864 (float)
motor_thermistor:
config: …
temperature: nan (float)
resistance_calibration_I_beta: 0.0 (float)
sensorless_estimator:
phase: -0.35903847217559814 (float)
phase_vel: 0.7761306762695312 (float)
pll_pos: -0.35927531123161316 (float)
torque_estimate: -0.018532948568463326 (float)
Close to the top of the list I then find these three values for the phase currents.
current_meas_phA: 0.4792085289955139 (float)
current_meas_phB: 0.11979475617408752 (float)
current_meas_phC: 0.00399807607755065 (float)
Note that I don’t see a mean value for the three currents together in that list, which is what tha arduino code is trying to get from the odrive. I know from older Odrive that I have used (Odrive v3.6) That it was possible to just get one value for the motor current, which I assume was the mean value of the three phase currents together.
Hmm, so typically you don’t read current_meas_phA/B/C – you’d look at odrv0.axis0.motor.foc.Iq_measured, which is the effective torque producing current in the motor (kind of like the mean, but not quite) – I’m guessing this is what you were reading from the v3.6.
Note in your Teensy code you’re reading the bus current, which is very different from the motor current (this is a good article). Not sure why this is zero, I can look into it, but also if the motor is at low speeds and low loads then the bus current will be very close to zero anyways (I’m assuming the motor is running in this example? because if the ODrive is in idle, it’ll be zero no matter what).
If you want to read the motor current, you need to run:
Get_Iq_msg_t iq_msg;
if (!odrv0.request(iq_msg, 1)) {
Serial.println(“iq message request failed!”);
while (true); // spin indefinitely
}
Serial.print("Iq Setpoint [A]: ");
Serial.println(iq_msg.Iq_Setpoint);
Serial.print("Iq Measured [A]: ");
Serial.println(iq_msg.Iq_Measured);
Hi, thanks for your answer! The code you gave works and gives me the motor current
Kind regards
Great to hear! Please let me know if there’s any other way I can help!
I acctually have one other question, is there a command in CAN to set the Odrive in torque controll mode? I have been looking in the odrive library file for arduino but find no such command.
Absolutely! You can just run setControllerMode(control_mode, input_mode)
where here control_mode
would be CONTROL_MODE_TORQUE_CONTROL
and input_mode
would be INPUT_MODE_PASSTHROUGH
.
Can I find a list anywhere with all the possible CAN commands for arduino?