mirror of
https://github.com/odriverobotics/ODrive.git
synced 2026-09-22 16:14:37 +08:00
Moved thermistors from belonging to Axis to being a part of Motor.
Thermistor apply_config now called in Motor::apply_config() Thermistor errors rolled into motor errors odrivetool and GUI updated to handle change Removed CurrentLimiter,Thermistor arrays abstraction
This commit is contained in:
@@ -58,20 +58,26 @@ OnboardThermistorCurrentLimiter fet_thermistors[AXIS_COUNT] = {
|
||||
}
|
||||
};
|
||||
|
||||
OffboardThermistorCurrentLimiter motor_thermistors[AXIS_COUNT];
|
||||
|
||||
Motor motors[AXIS_COUNT] = {
|
||||
{
|
||||
&htim1, // timer
|
||||
TIM_1_8_PERIOD_CLOCKS, // control_deadline
|
||||
1.0f / SHUNT_RESISTANCE, // shunt_conductance [S]
|
||||
m0_gate_driver, // gate_driver
|
||||
m0_gate_driver // opamp
|
||||
m0_gate_driver, // opamp
|
||||
fet_thermistors[0],
|
||||
motor_thermistors[0]
|
||||
},
|
||||
{
|
||||
&htim8, // timer
|
||||
(3 * TIM_1_8_PERIOD_CLOCKS) / 2, // control_deadline
|
||||
1.0f / SHUNT_RESISTANCE, // shunt_conductance [S]
|
||||
m1_gate_driver, // gate_driver
|
||||
m1_gate_driver // opamp
|
||||
m1_gate_driver, // opamp
|
||||
fet_thermistors[1],
|
||||
motor_thermistors[1]
|
||||
}
|
||||
};
|
||||
|
||||
@@ -101,7 +107,6 @@ MechanicalBrake mechanical_brakes[AXIS_COUNT];
|
||||
SensorlessEstimator sensorless_estimators[AXIS_COUNT];
|
||||
Controller controllers[AXIS_COUNT];
|
||||
TrapezoidalTrajectory trap[AXIS_COUNT];
|
||||
OffboardThermistorCurrentLimiter motor_thermistors[AXIS_COUNT];
|
||||
|
||||
std::array<Axis, AXIS_COUNT> axes{{
|
||||
{
|
||||
@@ -112,8 +117,6 @@ std::array<Axis, AXIS_COUNT> axes{{
|
||||
encoders[0], // encoder
|
||||
sensorless_estimators[0], // sensorless_estimator
|
||||
controllers[0], // controller
|
||||
fet_thermistors[0], // fet_thermistor
|
||||
motor_thermistors[0], // motor_thermistor
|
||||
motors[0], // motor
|
||||
trap[0], // trap
|
||||
endstops[0], endstops[1], // min_endstop, max_endstop
|
||||
@@ -132,8 +135,6 @@ std::array<Axis, AXIS_COUNT> axes{{
|
||||
encoders[1], // encoder
|
||||
sensorless_estimators[1], // sensorless_estimator
|
||||
controllers[1], // controller
|
||||
fet_thermistors[1], // fet_thermistor
|
||||
motor_thermistors[1], // motor_thermistor
|
||||
motors[1], // motor
|
||||
trap[1], // trap
|
||||
endstops[2], endstops[3], // min_endstop, max_endstop
|
||||
|
||||
@@ -14,8 +14,6 @@ Axis::Axis(int axis_num,
|
||||
Encoder& encoder,
|
||||
SensorlessEstimator& sensorless_estimator,
|
||||
Controller& controller,
|
||||
OnboardThermistorCurrentLimiter& fet_thermistor,
|
||||
OffboardThermistorCurrentLimiter& motor_thermistor,
|
||||
Motor& motor,
|
||||
TrapezoidalTrajectory& trap,
|
||||
Endstop& min_endstop,
|
||||
@@ -28,25 +26,15 @@ Axis::Axis(int axis_num,
|
||||
encoder_(encoder),
|
||||
sensorless_estimator_(sensorless_estimator),
|
||||
controller_(controller),
|
||||
fet_thermistor_(fet_thermistor),
|
||||
motor_thermistor_(motor_thermistor),
|
||||
motor_(motor),
|
||||
trap_traj_(trap),
|
||||
min_endstop_(min_endstop),
|
||||
max_endstop_(max_endstop),
|
||||
mechanical_brake_(mechanical_brake),
|
||||
current_limiters_(make_array(
|
||||
static_cast<CurrentLimiter*>(&fet_thermistor),
|
||||
static_cast<CurrentLimiter*>(&motor_thermistor))),
|
||||
thermistors_(make_array(
|
||||
static_cast<ThermistorCurrentLimiter*>(&fet_thermistor),
|
||||
static_cast<ThermistorCurrentLimiter*>(&motor_thermistor)))
|
||||
mechanical_brake_(mechanical_brake)
|
||||
{
|
||||
encoder_.axis_ = this;
|
||||
sensorless_estimator_.axis_ = this;
|
||||
controller_.axis_ = this;
|
||||
fet_thermistor_.axis_ = this;
|
||||
motor_thermistor.axis_ = this;
|
||||
motor_.axis_ = this;
|
||||
trap_traj_.axis_ = this;
|
||||
min_endstop_.axis_ = this;
|
||||
@@ -180,9 +168,6 @@ bool Axis::do_checks() {
|
||||
|
||||
// Sub-components should use set_error which will propegate to this error_
|
||||
motor_.effective_current_lim();
|
||||
for (ThermistorCurrentLimiter* thermistor : thermistors_) {
|
||||
thermistor->do_checks();
|
||||
}
|
||||
motor_.do_checks();
|
||||
// encoder_.do_checks();
|
||||
// sensorless_estimator_.do_checks();
|
||||
@@ -201,11 +186,10 @@ bool Axis::do_checks() {
|
||||
// @brief Update all esitmators
|
||||
bool Axis::do_updates() {
|
||||
// Sub-components should use set_error which will propegate to this error_
|
||||
for (ThermistorCurrentLimiter* thermistor : thermistors_) {
|
||||
thermistor->update();
|
||||
}
|
||||
encoder_.update();
|
||||
sensorless_estimator_.update();
|
||||
motor_.fet_thermistor_.update();
|
||||
motor_.motor_thermistor_.update();
|
||||
min_endstop_.update();
|
||||
max_endstop_.update();
|
||||
bool ret = check_for_errors();
|
||||
|
||||
@@ -86,8 +86,6 @@ public:
|
||||
Encoder& encoder,
|
||||
SensorlessEstimator& sensorless_estimator,
|
||||
Controller& controller,
|
||||
OnboardThermistorCurrentLimiter& fet_thermistor,
|
||||
OffboardThermistorCurrentLimiter& motor_thermistor,
|
||||
Motor& motor,
|
||||
TrapezoidalTrajectory& trap,
|
||||
Endstop& min_endstop,
|
||||
@@ -216,19 +214,12 @@ public:
|
||||
Encoder& encoder_;
|
||||
SensorlessEstimator& sensorless_estimator_;
|
||||
Controller& controller_;
|
||||
OnboardThermistorCurrentLimiter& fet_thermistor_;
|
||||
OffboardThermistorCurrentLimiter& motor_thermistor_;
|
||||
Motor& motor_;
|
||||
TrapezoidalTrajectory& trap_traj_;
|
||||
Endstop& min_endstop_;
|
||||
Endstop& max_endstop_;
|
||||
MechanicalBrake& mechanical_brake_;
|
||||
|
||||
// List of current_limiters and thermistors to
|
||||
// provide easy iteration.
|
||||
std::array<CurrentLimiter*, 2> current_limiters_;
|
||||
std::array<ThermistorCurrentLimiter*, 2> thermistors_;
|
||||
|
||||
osThreadId thread_id_;
|
||||
const uint32_t stack_size_ = 2048; // Bytes
|
||||
volatile bool thread_id_valid_ = false;
|
||||
|
||||
@@ -50,8 +50,8 @@ static bool config_read_all() {
|
||||
config_manager.read(&axes[i].max_endstop_.config_) &&
|
||||
config_manager.read(&axes[i].mechanical_brake_.config_) &&
|
||||
config_manager.read(&motors[i].config_) &&
|
||||
config_manager.read(&fet_thermistors[i].config_) &&
|
||||
config_manager.read(&axes[i].motor_thermistor_.config_) &&
|
||||
config_manager.read(&motors[i].fet_thermistor_.config_) &&
|
||||
config_manager.read(&motors[i].motor_thermistor_.config_) &&
|
||||
config_manager.read(&axes[i].config_);
|
||||
}
|
||||
return success;
|
||||
@@ -70,8 +70,8 @@ static bool config_write_all() {
|
||||
config_manager.write(&axes[i].max_endstop_.config_) &&
|
||||
config_manager.write(&axes[i].mechanical_brake_.config_) &&
|
||||
config_manager.write(&motors[i].config_) &&
|
||||
config_manager.write(&fet_thermistors[i].config_) &&
|
||||
config_manager.write(&axes[i].motor_thermistor_.config_) &&
|
||||
config_manager.write(&motors[i].fet_thermistor_.config_) &&
|
||||
config_manager.write(&motors[i].motor_thermistor_.config_) &&
|
||||
config_manager.write(&axes[i].config_);
|
||||
}
|
||||
return success;
|
||||
@@ -90,8 +90,8 @@ static void config_clear_all() {
|
||||
axes[i].max_endstop_.config_ = {};
|
||||
axes[i].mechanical_brake_.config_ = {};
|
||||
motors[i].config_ = {};
|
||||
fet_thermistors[i].config_ = {};
|
||||
axes[i].motor_thermistor_.config_ = {};
|
||||
motors[i].fet_thermistor_.config_ = {};
|
||||
motors[i].motor_thermistor_.config_ = {};
|
||||
axes[i].clear_config();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,12 +10,16 @@ Motor::Motor(TIM_HandleTypeDef* timer,
|
||||
uint16_t control_deadline,
|
||||
float shunt_conductance,
|
||||
TGateDriver& gate_driver,
|
||||
TOpAmp& opamp) :
|
||||
TOpAmp& opamp,
|
||||
OnboardThermistorCurrentLimiter& fet_thermistor,
|
||||
OffboardThermistorCurrentLimiter& motor_thermistor) :
|
||||
timer_(timer),
|
||||
control_deadline_(control_deadline),
|
||||
shunt_conductance_(shunt_conductance),
|
||||
gate_driver_(gate_driver),
|
||||
opamp_(opamp) {
|
||||
opamp_(opamp),
|
||||
fet_thermistor_(fet_thermistor),
|
||||
motor_thermistor_(motor_thermistor) {
|
||||
apply_config();
|
||||
}
|
||||
|
||||
@@ -66,6 +70,9 @@ bool Motor::apply_config() {
|
||||
config_.parent = this;
|
||||
is_calibrated_ = config_.pre_calibrated;
|
||||
update_current_controller_gains();
|
||||
fet_thermistor_.motor_ = this;
|
||||
motor_thermistor_.motor_ = this;
|
||||
motor_thermistor_.apply_config();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -110,7 +117,16 @@ bool Motor::do_checks() {
|
||||
set_error(ERROR_DRV_FAULT);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!motor_thermistor_.do_checks()) {
|
||||
axis_->error_ |= Axis::ERROR_OVER_TEMP;
|
||||
set_error(ERROR_MOTOR_THERMISTOR_OVER_TEMP);
|
||||
return false;
|
||||
}
|
||||
if (!fet_thermistor_.do_checks()) {
|
||||
axis_->error_ |= Axis::ERROR_OVER_TEMP;
|
||||
set_error(ERROR_FET_THERMISTOR_OVER_TEMP);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -124,11 +140,9 @@ float Motor::effective_current_lim() {
|
||||
current_lim = std::min(current_lim, axis_->motor_.current_control_.max_allowed_current);
|
||||
}
|
||||
|
||||
// Apply axis current limiters
|
||||
for (const CurrentLimiter* const limiter : axis_->current_limiters_) {
|
||||
current_lim = std::min(current_lim, limiter->get_current_limit(config_.current_lim));
|
||||
}
|
||||
|
||||
// Apply thermistor current limiters
|
||||
current_lim = std::min(current_lim, motor_thermistor_.get_current_limit(config_.current_lim));
|
||||
current_lim = std::min(current_lim, fet_thermistor_.get_current_limit(config_.current_lim));
|
||||
effective_current_lim_ = current_lim;
|
||||
|
||||
return effective_current_lim_;
|
||||
|
||||
@@ -99,7 +99,9 @@ public:
|
||||
uint16_t control_deadline,
|
||||
float shunt_conductance,
|
||||
TGateDriver& gate_driver,
|
||||
TOpAmp& opamp);
|
||||
TOpAmp& opamp,
|
||||
OnboardThermistorCurrentLimiter& fet_thermistor,
|
||||
OffboardThermistorCurrentLimiter& motor_thermistor);
|
||||
|
||||
bool arm();
|
||||
void disarm();
|
||||
@@ -130,6 +132,8 @@ public:
|
||||
const float shunt_conductance_;
|
||||
TGateDriver& gate_driver_;
|
||||
TOpAmp& opamp_;
|
||||
OnboardThermistorCurrentLimiter& fet_thermistor_;
|
||||
OffboardThermistorCurrentLimiter& motor_thermistor_;
|
||||
|
||||
Config_t config_;
|
||||
Axis* axis_ = nullptr; // set by Axis constructor
|
||||
|
||||
@@ -14,8 +14,7 @@ ThermistorCurrentLimiter::ThermistorCurrentLimiter(uint16_t adc_channel,
|
||||
temperature_(NAN),
|
||||
temp_limit_lower_(temp_limit_lower),
|
||||
temp_limit_upper_(temp_limit_upper),
|
||||
enabled_(enabled),
|
||||
error_(ERROR_NONE)
|
||||
enabled_(enabled)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -27,8 +26,6 @@ void ThermistorCurrentLimiter::update() {
|
||||
|
||||
bool ThermistorCurrentLimiter::do_checks() {
|
||||
if (enabled_ && temperature_ >= temp_limit_upper_ + 5) {
|
||||
error_ = ERROR_OVER_TEMP;
|
||||
axis_->error_ |= Axis::ERROR_OVER_TEMP;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -70,6 +67,12 @@ OffboardThermistorCurrentLimiter::OffboardThermistorCurrentLimiter() :
|
||||
decode_pin();
|
||||
}
|
||||
|
||||
bool OffboardThermistorCurrentLimiter::apply_config() {
|
||||
config_.parent = this;
|
||||
decode_pin();
|
||||
return true;
|
||||
}
|
||||
|
||||
void OffboardThermistorCurrentLimiter::decode_pin() {
|
||||
adc_channel_ = channel_from_gpio(get_gpio(config_.gpio_pin));
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __THERMISTOR_HPP
|
||||
#define __THERMISTOR_HPP
|
||||
|
||||
class Axis; // declared in axis.hpp
|
||||
class Motor; // declared in motor.hpp
|
||||
|
||||
#include "current_limiter.hpp"
|
||||
#include <autogen/interfaces.hpp>
|
||||
@@ -28,8 +28,7 @@ public:
|
||||
const float& temp_limit_lower_;
|
||||
const float& temp_limit_upper_;
|
||||
const bool& enabled_;
|
||||
Error error_;
|
||||
Axis* axis_ = nullptr; // set by Axis constructor
|
||||
Motor* motor_ = nullptr; // set by Motor::apply_config()
|
||||
};
|
||||
|
||||
class OnboardThermistorCurrentLimiter : public ThermistorCurrentLimiter, public ODriveIntf::OnboardThermistorCurrentLimiterIntf {
|
||||
@@ -68,6 +67,8 @@ public:
|
||||
|
||||
Config_t config_;
|
||||
|
||||
bool apply_config();
|
||||
|
||||
private:
|
||||
void decode_pin();
|
||||
};
|
||||
|
||||
@@ -355,7 +355,7 @@ interfaces:
|
||||
bit: 17
|
||||
doc: the min endstop was not enabled during homing
|
||||
OverTemp:
|
||||
doc: Check `fet_thermistor.error` and `motor_thermistor.error` for more information.
|
||||
doc: Check `motor.error` for more details.
|
||||
step_dir_active: readonly bool
|
||||
current_state: readonly AxisState
|
||||
requested_state: AxisState
|
||||
@@ -444,8 +444,6 @@ interfaces:
|
||||
# status_reg_2: readonly uint32
|
||||
# ctrl_reg_1: readonly uint32
|
||||
# ctrl_reg_2: readonly uint32
|
||||
fet_thermistor: OnboardThermistorCurrentLimiter
|
||||
motor_thermistor: OffboardThermistorCurrentLimiter
|
||||
motor: Motor
|
||||
controller: Controller
|
||||
encoder: Encoder
|
||||
@@ -491,7 +489,6 @@ interfaces:
|
||||
ODrive.OnboardThermistorCurrentLimiter:
|
||||
c_is_class: True
|
||||
attributes:
|
||||
error: ThermistorCurrentLimiter.Error
|
||||
temperature: readonly float32
|
||||
config:
|
||||
c_is_class: False
|
||||
@@ -507,7 +504,6 @@ interfaces:
|
||||
ODrive.OffboardThermistorCurrentLimiter:
|
||||
c_is_class: True
|
||||
attributes:
|
||||
error: ThermistorCurrentLimiter.Error
|
||||
temperature: readonly float32
|
||||
config:
|
||||
c_is_class: False
|
||||
@@ -605,6 +601,8 @@ interfaces:
|
||||
DcBusOverRegenCurrent: {doc: too much current pushed into the power supply}
|
||||
DcBusOverCurrent: {doc: too much current pulled out of the power supply}
|
||||
ModulationIsNan:
|
||||
MotorThermistorOverTemp: {doc: The motor thermistor measured a temperature above motor.motor_thermistor.config.temp_limit_upper}
|
||||
FetThermistorOverTemp: {doc: The inverter thermistor measured a temperature above motor.fet_thermistor.config.temp_limit_upper}
|
||||
armed_state:
|
||||
typeargs: {fibre.Property.mode: readonly}
|
||||
values:
|
||||
@@ -619,6 +617,8 @@ interfaces:
|
||||
DC_calib_phC: {type: float32, c_name: DC_calib_.phC}
|
||||
phase_current_rev_gain: float32
|
||||
effective_current_lim: readonly float32
|
||||
fet_thermistor: OnboardThermistorCurrentLimiter
|
||||
motor_thermistor: OffboardThermistorCurrentLimiter
|
||||
current_control:
|
||||
c_is_class: False
|
||||
attributes:
|
||||
@@ -1020,12 +1020,6 @@ valuetypes:
|
||||
doc:
|
||||
Endstops must be enabled to use this feature.
|
||||
|
||||
ODrive.ThermistorCurrentLimiter.Error:
|
||||
nullflag: None
|
||||
flags:
|
||||
OverTemp:
|
||||
doc: The thermistor temperature upper limit was exceeded.
|
||||
|
||||
ODrive.Encoder.Mode:
|
||||
values:
|
||||
Incremental:
|
||||
|
||||
@@ -29,9 +29,6 @@
|
||||
"AXIS_STATE_ENCODER_DIR_FIND" : 10,
|
||||
"AXIS_STATE_HOMING" : 11,
|
||||
|
||||
"THERMISTOR_CURRENT_LIMITER_ERROR_NONE" : 0,
|
||||
"THERMISTOR_CURRENT_LIMITER_ERROR_OVER_TEMP" : 1,
|
||||
|
||||
"ENCODER_MODE_INCREMENTAL" : 0,
|
||||
"ENCODER_MODE_HALL" : 1,
|
||||
"ENCODER_MODE_SINCOS" : 2,
|
||||
@@ -102,6 +99,8 @@
|
||||
"MOTOR_ERROR_DC_BUS_OVER_REGEN_CURRENT" : 16384,
|
||||
"MOTOR_ERROR_DC_BUS_OVER_CURRENT" : 32768,
|
||||
"MOTOR_ERROR_MODULATION_IS_NAN" : 65536,
|
||||
"MOTOR_ERROR_MOTOR_THERMISTOR_OVER_TEMP" : 131072,
|
||||
"MOTOR_ERROR_FET_THERMISTOR_OVER_TEMP" : 262144,
|
||||
|
||||
"ARMED_STATE_DISARMED" : 0,
|
||||
"ARMED_STATE_WAITING_FOR_TIMINGS" : 1,
|
||||
|
||||
@@ -66,6 +66,9 @@ const motorErrors = {
|
||||
0x00002000: "MOTOR_ERROR_BRAKE_DUTY_CYCLE_NAN",
|
||||
0x00004000: "MOTOR_ERROR_DC_BUS_OVER_REGEN_CURRENT",
|
||||
0x00008000: "MOTOR_ERROR_DC_BUS_OVER_CURRENT",
|
||||
0x00010000: "MOTOR_ERROR_MODULATION_IS_NAN",
|
||||
0x00020000: "MOTOR_ERROR_MOTOR_THERMISTOR_OVER_TEMP",
|
||||
0x00040000: "MOTOR_ERROR_FET_THERMISTOR_OVER_TEMP",
|
||||
};
|
||||
|
||||
let encoderErrors = {
|
||||
@@ -125,10 +128,7 @@ export default {
|
||||
errs.push(axisErrors[errKey]);
|
||||
}
|
||||
}
|
||||
retMsg = "";
|
||||
for (const err of errs) {
|
||||
retMsg = retMsg + " " + err;
|
||||
}
|
||||
retMsg = errs.join(', ');
|
||||
}
|
||||
|
||||
return retMsg;
|
||||
@@ -150,10 +150,7 @@ export default {
|
||||
errs.push(motorErrors[errKey]);
|
||||
}
|
||||
}
|
||||
retMsg = "";
|
||||
for (const err of errs) {
|
||||
retMsg = retMsg + " " + err;
|
||||
}
|
||||
retMsg = errs.join(', ');
|
||||
}
|
||||
|
||||
return retMsg;
|
||||
@@ -175,10 +172,7 @@ export default {
|
||||
errs.push(encoderErrors[errKey]);
|
||||
}
|
||||
}
|
||||
retMsg = "";
|
||||
for (const err of errs) {
|
||||
retMsg = retMsg + " " + err;
|
||||
}
|
||||
retMsg = errs.join(', ');
|
||||
}
|
||||
|
||||
return retMsg;
|
||||
@@ -195,10 +189,7 @@ export default {
|
||||
errs.push(controllerErrors[errKey]);
|
||||
}
|
||||
}
|
||||
retMsg = "";
|
||||
for (const err of errs) {
|
||||
retMsg = retMsg + " " + err;
|
||||
}
|
||||
retMsg = errs.join(', ');
|
||||
}
|
||||
|
||||
return retMsg;
|
||||
|
||||
+3
-3
@@ -4,11 +4,11 @@
|
||||
Thermistors are elements that change their resistance based on the temperature. They can be used to electrically measure temperature. The ODrive itself has thermistors on board near the FETs to ensure that they don't burn themselves out. In addition to this it's possible to connect your own thermistor to measure the temperature of the connected motors. There are two types of thermistors, Negative Temperature Coefficient (NTC) and Positive Temperature Coefficient (PTC). This indicates whether the resistance goes up or down when the temperature goes up or down. The ODrive only supports the NTC type thermistor.
|
||||
|
||||
## FET thermistor
|
||||
The temperature of the onboard FET thermistors can be read out by using the `odrivetool` under `<axis>.fet_thermistor.temp`. The odrive will automatically start current limiting the motor when the `<axis>.fet_thermistor.config.temp_limit_lower` threshold is exceeded and once `<axis>.fet_thermistor.config.temp_limit_upper` is exceeded the ODrive will stop controlling the motor and set an error. The lower and upper threshold can be changed, but this is not recommended.
|
||||
The temperature of the onboard FET thermistors can be read out by using the `odrivetool` under `<axis>.motor.fet_thermistor.temperature`. The odrive will automatically start current limiting the motor when the `<axis>.motor.fet_thermistor.config.temp_limit_lower` threshold is exceeded and once `<axis>.motor.fet_thermistor.config.temp_limit_upper` is exceeded the ODrive will stop controlling the motor and set an error. The lower and upper threshold can be changed, but this is not recommended.
|
||||
|
||||
## Connecting motor thermistors
|
||||
|
||||
To use your own thermistors with the ODrive a few things have to be clarified first. The use of your own thermistor requires one analog input pin. Under `<axis>.motor_thermistor.config` the configuration of your own thermistor is available with the following fields:
|
||||
To use your own thermistors with the ODrive a few things have to be clarified first. The use of your own thermistor requires one analog input pin. Under `<axis>.motor.motor_thermistor.config` the configuration of your own thermistor is available with the following fields:
|
||||
|
||||
* `gpio_pin`: The GPIO input in used for this thermistor.
|
||||
* `poly_coefficient_0` to `poly_coefficient_3`: Coefficient that needs to be set for your specific setup more on that in [Thermistor coefficients](#thermistor-coefficients).
|
||||
@@ -25,7 +25,7 @@ The way this works is that the thermistor is connected in series with a known re
|
||||
To use a thermistor with the ODrive a voltage divider circuit has to be made that uses `VCCA` as the power source with `GNDA` as the ground. The voltage divider output can be connected to a GPIO pin that supports analog input.
|
||||
|
||||
## Thermistor coefficients
|
||||
Every thermistor and voltage divider circuit is different and thus it's necessary to let the ODrive know how to relate a voltage it measures at the GPIO pin to a temperature. The `poly_coefficient_0` to `poly_coefficient_3` under `<axis>.motor_thermistor.config` are used for this. The `odrivetool` has a convenience function `set_motor_thermistor_coeffs(axis, Rload, R_25, Beta, Tmin, Tmax)` which can be used to calculate and set these coefficients.
|
||||
Every thermistor and voltage divider circuit is different and thus it's necessary to let the ODrive know how to relate a voltage it measures at the GPIO pin to a temperature. The `poly_coefficient_0` to `poly_coefficient_3` under `<axis>.motor.motor_thermistor.config` are used for this. The `odrivetool` has a convenience function `set_motor_thermistor_coeffs(axis, Rload, R_25, Beta, Tmin, Tmax)` which can be used to calculate and set these coefficients.
|
||||
|
||||
* `axis`: Which axis do set the motor thermistor coefficients for (`odrv0.axis0` or `odrv0.axis1`).
|
||||
* `Rload`: The Ohm value of the resistor used in the voltage divider circuit.
|
||||
|
||||
@@ -37,10 +37,6 @@ AXIS_STATE_LOCKIN_SPIN = 9
|
||||
AXIS_STATE_ENCODER_DIR_FIND = 10
|
||||
AXIS_STATE_HOMING = 11
|
||||
|
||||
# ODrive.ThermistorCurrentLimiter.Error
|
||||
THERMISTOR_CURRENT_LIMITER_ERROR_NONE = 0x00000000
|
||||
THERMISTOR_CURRENT_LIMITER_ERROR_OVER_TEMP = 0x00000001
|
||||
|
||||
# ODrive.Encoder.Mode
|
||||
ENCODER_MODE_INCREMENTAL = 0
|
||||
ENCODER_MODE_HALL = 1
|
||||
@@ -119,6 +115,8 @@ MOTOR_ERROR_BRAKE_DUTY_CYCLE_NAN = 0x00002000
|
||||
MOTOR_ERROR_DC_BUS_OVER_REGEN_CURRENT = 0x00004000
|
||||
MOTOR_ERROR_DC_BUS_OVER_CURRENT = 0x00008000
|
||||
MOTOR_ERROR_MODULATION_IS_NAN = 0x00010000
|
||||
MOTOR_ERROR_MOTOR_THERMISTOR_OVER_TEMP = 0x00020000
|
||||
MOTOR_ERROR_FET_THERMISTOR_OVER_TEMP = 0x00040000
|
||||
|
||||
# ODrive.Motor.ArmedState
|
||||
ARMED_STATE_DISARMED = 0
|
||||
|
||||
@@ -64,10 +64,10 @@ class OperationAbortedException(Exception):
|
||||
|
||||
def set_motor_thermistor_coeffs(axis, Rload, R_25, Beta, Tmin, TMax):
|
||||
coeffs = calculate_thermistor_coeffs(3, Rload, R_25, Beta, Tmin, TMax)
|
||||
axis.motor_thermistor.config.poly_coefficient_0 = float(coeffs[3])
|
||||
axis.motor_thermistor.config.poly_coefficient_1 = float(coeffs[2])
|
||||
axis.motor_thermistor.config.poly_coefficient_2 = float(coeffs[1])
|
||||
axis.motor_thermistor.config.poly_coefficient_3 = float(coeffs[0])
|
||||
axis.motor.motor_thermistor.config.poly_coefficient_0 = float(coeffs[3])
|
||||
axis.motor.motor_thermistor.config.poly_coefficient_1 = float(coeffs[2])
|
||||
axis.motor.motor_thermistor.config.poly_coefficient_2 = float(coeffs[1])
|
||||
axis.motor.motor_thermistor.config.poly_coefficient_3 = float(coeffs[0])
|
||||
|
||||
def dump_errors(odrv, clear=False):
|
||||
axes = [(name, axis) for name, axis in odrv._remote_attributes.items() if 'axis' in name]
|
||||
@@ -80,8 +80,6 @@ def dump_errors(odrv, clear=False):
|
||||
module_decode_map = [
|
||||
(name, odrv, {k: v for k, v in odrive.enums.__dict__ .items() if k.startswith("AXIS_ERROR_")}),
|
||||
('motor', axis, {k: v for k, v in odrive.enums.__dict__ .items() if k.startswith("MOTOR_ERROR_")}),
|
||||
('fet_thermistor', axis, {k: v for k, v in odrive.enums.__dict__ .items() if k.startswith("THERMISTOR_CURRENT_LIMITER_ERROR")}),
|
||||
('motor_thermistor', axis, {k: v for k, v in odrive.enums.__dict__ .items() if k.startswith("THERMISTOR_CURRENT_LIMITER_ERROR")}),
|
||||
('encoder', axis, {k: v for k, v in odrive.enums.__dict__ .items() if k.startswith("ENCODER_ERROR_")}),
|
||||
('controller', axis, {k: v for k, v in odrive.enums.__dict__ .items() if k.startswith("CONTROLLER_ERROR_")}),
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user