Browse Source

AP_BattMonitor: support other INA2xx battery monitors

added parameters for I2C bus and address. Tested on INA231 and INA226

This allows any 2M flash board to use an INA2xx battery monitor
gps-1.3.1
Andrew Tridgell 3 years ago
parent
commit
75dfa6bae4
  1. 8
      libraries/AP_BattMonitor/AP_BattMonitor.cpp
  2. 6
      libraries/AP_BattMonitor/AP_BattMonitor.h
  3. 63
      libraries/AP_BattMonitor/AP_BattMonitor_INA2xx.cpp
  4. 24
      libraries/AP_BattMonitor/AP_BattMonitor_INA2xx.h
  5. 2
      libraries/AP_BattMonitor/AP_BattMonitor_Params.cpp

8
libraries/AP_BattMonitor/AP_BattMonitor.cpp

@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
#include "AP_BattMonitor_FuelLevel_PWM.h"
#include "AP_BattMonitor_Generator.h"
#include "AP_BattMonitor_MPPT_PacketDigital.h"
#include "AP_BattMonitor_INA231.h"
#include "AP_BattMonitor_INA2xx.h"
#include "AP_BattMonitor_LTC2946.h"
#include "AP_BattMonitor_Torqeedo.h"
@ -276,9 +276,9 @@ AP_BattMonitor::init() @@ -276,9 +276,9 @@ AP_BattMonitor::init()
drivers[instance] = new AP_BattMonitor_MPPT_PacketDigital(*this, state[instance], _params[instance]);
break;
#endif // HAL_MPPT_PACKETDIGITAL_CAN_ENABLE
#if HAL_BATTMON_INA231_ENABLED
case Type::INA231:
drivers[instance] = new AP_BattMonitor_INA231(*this, state[instance], _params[instance]);
#if HAL_BATTMON_INA2XX_ENABLED
case Type::INA2XX:
drivers[instance] = new AP_BattMonitor_INA2XX(*this, state[instance], _params[instance]);
break;
#endif
#if HAL_BATTMON_LTC2946_ENABLED

6
libraries/AP_BattMonitor/AP_BattMonitor.h

@ -46,7 +46,7 @@ class AP_BattMonitor_SMBus_Rotoye; @@ -46,7 +46,7 @@ class AP_BattMonitor_SMBus_Rotoye;
class AP_BattMonitor_UAVCAN;
class AP_BattMonitor_Generator;
class AP_BattMonitor_MPPT_PacketDigital;
class AP_BattMonitor_INA231;
class AP_BattMonitor_INA2XX;
class AP_BattMonitor_LTC2946;
class AP_BattMonitor_Torqeedo;
@ -65,7 +65,7 @@ class AP_BattMonitor @@ -65,7 +65,7 @@ class AP_BattMonitor
friend class AP_BattMonitor_FuelLevel_PWM;
friend class AP_BattMonitor_Generator;
friend class AP_BattMonitor_MPPT_PacketDigital;
friend class AP_BattMonitor_INA231;
friend class AP_BattMonitor_INA2XX;
friend class AP_BattMonitor_LTC2946;
friend class AP_BattMonitor_Torqeedo;
@ -100,7 +100,7 @@ public: @@ -100,7 +100,7 @@ public:
GENERATOR_FUEL = 18,
Rotoye = 19,
MPPT_PacketDigital = 20,
INA231 = 21,
INA2XX = 21,
LTC2946 = 22,
Torqeedo = 23,
};

63
libraries/AP_BattMonitor/AP_BattMonitor_INA231.cpp → libraries/AP_BattMonitor/AP_BattMonitor_INA2xx.cpp

@ -1,8 +1,8 @@ @@ -1,8 +1,8 @@
#include "AP_BattMonitor_INA231.h"
#include "AP_BattMonitor_INA2xx.h"
#include <GCS_MAVLink/GCS.h>
#include <AP_HAL/utility/sparse-endian.h>
#if HAL_BATTMON_INA231_ENABLED
#if HAL_BATTMON_INA2XX_ENABLED
extern const AP_HAL::HAL& hal;
@ -18,9 +18,46 @@ extern const AP_HAL::HAL& hal; @@ -18,9 +18,46 @@ extern const AP_HAL::HAL& hal;
// this should become a parameter in future
#define MAX_AMPS 90.0
void AP_BattMonitor_INA231::init(void)
#ifndef HAL_BATTMON_INA2XX_BUS
#define HAL_BATTMON_INA2XX_BUS 0
#endif
#ifndef HAL_BATTMON_INA2XX_ADDR
#define HAL_BATTMON_INA2XX_ADDR 0
#endif
const AP_Param::GroupInfo AP_BattMonitor_INA2XX::var_info[] = {
// @Param: I2C_BUS
// @DisplayName: Battery monitor I2C bus number
// @Description: Battery monitor I2C bus number
// @Range: 0 3
// @User: Advanced
// @RebootRequired: True
AP_GROUPINFO("I2C_BUS", 25, AP_BattMonitor_INA2XX, i2c_bus, HAL_BATTMON_INA2XX_BUS),
// @Param: I2C_ADDR
// @DisplayName: Battery monitor I2C address
// @Description: Battery monitor I2C address
// @Range: 0 127
// @User: Advanced
// @RebootRequired: True
AP_GROUPINFO("I2C_ADDR", 26, AP_BattMonitor_INA2XX, i2c_address, HAL_BATTMON_INA2XX_ADDR),
AP_GROUPEND
};
AP_BattMonitor_INA2XX::AP_BattMonitor_INA2XX(AP_BattMonitor &mon,
AP_BattMonitor::BattMonitor_State &mon_state,
AP_BattMonitor_Params &params)
: AP_BattMonitor_Backend(mon, mon_state, params)
{
dev = hal.i2c_mgr->get_device(HAL_BATTMON_INA231_BUS, HAL_BATTMON_INA231_ADDR, 100000, false, 20);
AP_Param::setup_object_defaults(this, var_info);
_state.var_info = var_info;
}
void AP_BattMonitor_INA2XX::init(void)
{
dev = hal.i2c_mgr->get_device(i2c_bus, i2c_address, 100000, false, 20);
if (!dev) {
return;
}
@ -31,7 +68,7 @@ void AP_BattMonitor_INA231::init(void) @@ -31,7 +68,7 @@ void AP_BattMonitor_INA231::init(void)
!write_word(REG_CONFIG, REG_CONFIG_DEFAULT) ||
!read_word(REG_CONFIG, config) ||
config != REG_CONFIG_DEFAULT) {
GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "INA231: Failed to find device 0x%04x", unsigned(config));
GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "INA2XX: Failed to find device 0x%04x", unsigned(config));
return;
}
@ -44,20 +81,20 @@ void AP_BattMonitor_INA231::init(void) @@ -44,20 +81,20 @@ void AP_BattMonitor_INA231::init(void)
if (!write_word(REG_CONFIG, REG_CONFIG_RESET) || // reset
!write_word(REG_CONFIG, conf) ||
!write_word(REG_CALIBRATION, cal)) {
GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "INA231: Failed to configure device");
GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "INA2XX: Failed to configure device");
return;
}
GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "INA231: found monitor on bus %u", HAL_BATTMON_INA231_BUS);
GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "INA2XX: found monitor on I2C:%u:%02x", unsigned(i2c_bus), unsigned(i2c_address));
if (dev) {
dev->register_periodic_callback(25000, FUNCTOR_BIND_MEMBER(&AP_BattMonitor_INA231::timer, void));
dev->register_periodic_callback(25000, FUNCTOR_BIND_MEMBER(&AP_BattMonitor_INA2XX::timer, void));
}
}
/// read the battery_voltage and current, should be called at 10hz
void AP_BattMonitor_INA231::read(void)
void AP_BattMonitor_INA2XX::read(void)
{
WITH_SEMAPHORE(accumulate.sem);
_state.healthy = accumulate.count > 0;
@ -88,7 +125,7 @@ void AP_BattMonitor_INA231::read(void) @@ -88,7 +125,7 @@ void AP_BattMonitor_INA231::read(void)
read word from register
returns true if read was successful, false if failed
*/
bool AP_BattMonitor_INA231::read_word(const uint8_t reg, int16_t& data) const
bool AP_BattMonitor_INA2XX::read_word(const uint8_t reg, int16_t& data) const
{
// read the appropriate register from the device
if (!dev->read_registers(reg, (uint8_t *)&data, sizeof(data))) {
@ -105,13 +142,13 @@ bool AP_BattMonitor_INA231::read_word(const uint8_t reg, int16_t& data) const @@ -105,13 +142,13 @@ bool AP_BattMonitor_INA231::read_word(const uint8_t reg, int16_t& data) const
write word to a register, byte swapped
returns true if write was successful, false if failed
*/
bool AP_BattMonitor_INA231::write_word(const uint8_t reg, const uint16_t data) const
bool AP_BattMonitor_INA2XX::write_word(const uint8_t reg, const uint16_t data) const
{
const uint8_t b[3] { reg, uint8_t(data >> 8), uint8_t(data&0xff) };
return dev->transfer(b, sizeof(b), nullptr, 0);
}
void AP_BattMonitor_INA231::timer(void)
void AP_BattMonitor_INA2XX::timer(void)
{
int16_t bus_voltage, current;
if (!read_word(REG_BUS_VOLTAGE, bus_voltage) ||
@ -124,4 +161,4 @@ void AP_BattMonitor_INA231::timer(void) @@ -124,4 +161,4 @@ void AP_BattMonitor_INA231::timer(void)
accumulate.count++;
}
#endif // HAL_BATTMON_INA231_ENABLED
#endif // HAL_BATTMON_INA2XX_ENABLED

24
libraries/AP_BattMonitor/AP_BattMonitor_INA231.h → libraries/AP_BattMonitor/AP_BattMonitor_INA2xx.h

@ -3,17 +3,22 @@ @@ -3,17 +3,22 @@
#include <AP_Common/AP_Common.h>
#include <AP_HAL/I2CDevice.h>
#include "AP_BattMonitor_Backend.h"
#include <AP_Param/AP_Param.h>
#include <utility>
#define HAL_BATTMON_INA231_ENABLED defined(HAL_BATTMON_INA231_BUS) && defined(HAL_BATTMON_INA231_ADDR)
#ifndef HAL_BATTMON_INA2XX_ENABLED
#define HAL_BATTMON_INA2XX_ENABLED (BOARD_FLASH_SIZE > 1024)
#endif
#if HAL_BATTMON_INA231_ENABLED
#if HAL_BATTMON_INA2XX_ENABLED
class AP_BattMonitor_INA231 : public AP_BattMonitor_Backend
class AP_BattMonitor_INA2XX : public AP_BattMonitor_Backend
{
public:
// inherit constructor
using AP_BattMonitor_Backend::AP_BattMonitor_Backend;
/// Constructor
AP_BattMonitor_INA2XX(AP_BattMonitor &mon,
AP_BattMonitor::BattMonitor_State &mon_state,
AP_BattMonitor_Params &params);
bool has_cell_voltages() const override { return false; }
bool has_temperature() const override { return false; }
@ -23,7 +28,9 @@ public: @@ -23,7 +28,9 @@ public:
virtual void init(void) override;
virtual void read() override;
static const struct AP_Param::GroupInfo var_info[];
private:
AP_HAL::OwnPtr<AP_HAL::I2CDevice> dev;
@ -31,6 +38,9 @@ private: @@ -31,6 +38,9 @@ private:
bool write_word(const uint8_t reg, const uint16_t data) const;
void timer(void);
AP_Int8 i2c_bus;
AP_Int8 i2c_address;
struct {
uint16_t count;
float volt_sum;
@ -41,4 +51,4 @@ private: @@ -41,4 +51,4 @@ private:
float voltage_LSB;
};
#endif // HAL_BATTMON_INA231_ENABLED
#endif // HAL_BATTMON_INA2XX_ENABLED

2
libraries/AP_BattMonitor/AP_BattMonitor_Params.cpp

@ -13,7 +13,7 @@ const AP_Param::GroupInfo AP_BattMonitor_Params::var_info[] = { @@ -13,7 +13,7 @@ const AP_Param::GroupInfo AP_BattMonitor_Params::var_info[] = {
// @Param: MONITOR
// @DisplayName: Battery monitoring
// @Description: Controls enabling monitoring of the battery's voltage and current
// @Values: 0:Disabled,3:Analog Voltage Only,4:Analog Voltage and Current,5:Solo,6:Bebop,7:SMBus-Generic,8:UAVCAN-BatteryInfo,9:ESC,10:SumOfFollowing,11:FuelFlow,12:FuelLevelPWM,13:SMBUS-SUI3,14:SMBUS-SUI6,15:NeoDesign,16:SMBus-Maxell,17:Generator-Elec,18:Generator-Fuel,19:Rotoye,20:MPPT,21:INA231,22:LTC2946,23:Torqeedo
// @Values: 0:Disabled,3:Analog Voltage Only,4:Analog Voltage and Current,5:Solo,6:Bebop,7:SMBus-Generic,8:UAVCAN-BatteryInfo,9:ESC,10:SumOfFollowing,11:FuelFlow,12:FuelLevelPWM,13:SMBUS-SUI3,14:SMBUS-SUI6,15:NeoDesign,16:SMBus-Maxell,17:Generator-Elec,18:Generator-Fuel,19:Rotoye,20:MPPT,21:INA2XX,22:LTC2946,23:Torqeedo
// @User: Standard
// @RebootRequired: True
AP_GROUPINFO_FLAGS("MONITOR", 1, AP_BattMonitor_Params, _type, int8_t(AP_BattMonitor::Type::NONE), AP_PARAM_FLAG_ENABLE),

Loading…
Cancel
Save