mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-04-14 10:07:39 +08:00
ina228/ina238: correctly set ADC range
It turns out that we set the ADC range incorrectly leading to the measured current being capped at a certain level as the ADC on the sensor saturates. Instead, we need to set the range according to the formula given in the interface datasheet.
This commit is contained in:
parent
3af9a3f76e
commit
117f198891
@ -59,8 +59,6 @@ INA228::INA228(const I2CSPIDriverConfig &config, int battery_index) :
|
||||
_max_current = fvalue;
|
||||
}
|
||||
|
||||
_range = _max_current > (MAX_CURRENT - 1.0f) ? INA228_ADCRANGE_HIGH : INA228_ADCRANGE_LOW;
|
||||
|
||||
fvalue = INA228_SHUNT;
|
||||
_rshunt = fvalue;
|
||||
ph = param_find("INA228_SHUNT");
|
||||
@ -69,6 +67,21 @@ INA228::INA228(const I2CSPIDriverConfig &config, int battery_index) :
|
||||
_rshunt = fvalue;
|
||||
}
|
||||
|
||||
// According to page 8.2.2.1, page 36/48 of the INA228 interface datasheet (Rev. A),
|
||||
// the requirement is: R_SHUNT < V_SENSE_MAX / I_MAX
|
||||
// therefore: R_SHUNT * I_MAX < V_SENSE_MAX
|
||||
// and so if V_SENSE_MAX is bigger, we need to use the bigger ADC range to avoid
|
||||
// the device from capping the measured current.
|
||||
|
||||
const float v_sense_max = _rshunt * _max_current;
|
||||
|
||||
if (v_sense_max > INA228_ADCRANGE_LOW_V_SENSE) {
|
||||
_range = INA228_ADCRANGE_HIGH;
|
||||
|
||||
} else {
|
||||
_range = INA228_ADCRANGE_LOW;
|
||||
}
|
||||
|
||||
ph = param_find("INA228_CONFIG");
|
||||
int32_t value = INA228_ADCCONFIG;
|
||||
_config = (uint16_t)value;
|
||||
|
||||
@ -293,6 +293,8 @@ using namespace time_literals;
|
||||
#define INA228_VSCALE 1.95e-04f /* LSB of voltage is 195.3125 uV/LSB */
|
||||
#define INA228_TSCALE 7.8125e-03f /* LSB of temperature is 7.8125 mDegC/LSB */
|
||||
|
||||
#define INA228_ADCRANGE_LOW_V_SENSE 0.04096f // ± 40.96 mV
|
||||
|
||||
#define swap16(w) __builtin_bswap16((w))
|
||||
#define swap32(d) __builtin_bswap32((d))
|
||||
#define swap64(q) __builtin_bswap64((q))
|
||||
|
||||
@ -55,8 +55,6 @@ INA238::INA238(const I2CSPIDriverConfig &config, int battery_index) :
|
||||
_max_current = fvalue;
|
||||
}
|
||||
|
||||
_range = _max_current > (DEFAULT_MAX_CURRENT - 1.0f) ? INA238_ADCRANGE_HIGH : INA238_ADCRANGE_LOW;
|
||||
|
||||
fvalue = DEFAULT_SHUNT;
|
||||
_rshunt = fvalue;
|
||||
ph = param_find("INA238_SHUNT");
|
||||
@ -65,6 +63,21 @@ INA238::INA238(const I2CSPIDriverConfig &config, int battery_index) :
|
||||
_rshunt = fvalue;
|
||||
}
|
||||
|
||||
// According to page 8.2.2.1, page 33/48 of the INA238 interface datasheet (Rev. A),
|
||||
// the requirement is: R_SHUNT < V_SENSE_MAX / I_MAX
|
||||
// therefore: R_SHUNT * I_MAX < V_SENSE_MAX
|
||||
// and so if V_SENSE_MAX is bigger, we need to use the bigger ADC range to avoid
|
||||
// the device from capping the measured current.
|
||||
|
||||
const float v_sense_max = _rshunt * _max_current;
|
||||
|
||||
if (v_sense_max > INA238_ADCRANGE_LOW_V_SENSE) {
|
||||
_range = INA238_ADCRANGE_HIGH;
|
||||
|
||||
} else {
|
||||
_range = INA238_ADCRANGE_LOW;
|
||||
}
|
||||
|
||||
_current_lsb = _max_current / INA238_DN_MAX;
|
||||
_shunt_calibration = static_cast<uint16_t>(INA238_CONST * _current_lsb * _rshunt);
|
||||
|
||||
|
||||
@ -75,6 +75,8 @@ using namespace ina238;
|
||||
#define INA238_VSCALE 3.125e-03f /* LSB of voltage is 3.1255 mV/LSB */
|
||||
#define INA238_TSCALE 7.8125e-03f /* LSB of temperature is 7.8125 mDegC/LSB */
|
||||
|
||||
#define INA238_ADCRANGE_LOW_V_SENSE 0.04096f // ± 40.96 mV
|
||||
|
||||
#define DEFAULT_MAX_CURRENT 327.68f /* Amps */
|
||||
#define DEFAULT_SHUNT 0.0003f /* Shunt is 300 uOhm */
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user