2023-03-06 22:02:49 -04:00
|
|
|
#include "AP_BattMonitor_config.h"
|
|
|
|
|
|
|
|
#if AP_BATTERY_SUM_ENABLED
|
|
|
|
|
2018-11-19 04:59:58 -04:00
|
|
|
#include <AP_HAL/AP_HAL.h>
|
|
|
|
#include <AP_Common/AP_Common.h>
|
|
|
|
#include <AP_Math/AP_Math.h>
|
|
|
|
#include "AP_BattMonitor.h"
|
2023-03-06 22:02:49 -04:00
|
|
|
|
2018-11-19 04:59:58 -04:00
|
|
|
#include "AP_BattMonitor_Sum.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
battery monitor that is the sum of other battery monitors after this one
|
|
|
|
|
|
|
|
This can be used to combined other current/voltage sensors into a
|
|
|
|
single backend
|
|
|
|
*/
|
|
|
|
extern const AP_HAL::HAL& hal;
|
|
|
|
|
2021-10-18 23:04:07 -03:00
|
|
|
const AP_Param::GroupInfo AP_BattMonitor_Sum::var_info[] = {
|
|
|
|
|
2021-11-01 13:23:28 -03:00
|
|
|
// Param indexes must be between 20 and 29 to avoid conflict with other battery monitor param tables loaded by pointer
|
|
|
|
|
2021-10-18 23:04:07 -03:00
|
|
|
// @Param: SUM_MASK
|
|
|
|
// @DisplayName: Battery Sum mask
|
|
|
|
// @Description: 0: sum of remaining battery monitors, If none 0 sum of specified monitors. Current will be summed and voltages averaged.
|
|
|
|
// @Bitmask: 0:monitor 1, 1:monitor 2, 2:monitor 3, 3:monitor 4, 4:monitor 5, 5:monitor 6, 6:monitor 7, 7:monitor 8, 8:monitor 9
|
|
|
|
// @User: Standard
|
2021-11-01 13:23:28 -03:00
|
|
|
AP_GROUPINFO("SUM_MASK", 20, AP_BattMonitor_Sum, _sum_mask, 0),
|
|
|
|
|
|
|
|
// Param indexes must be between 20 and 29 to avoid conflict with other battery monitor param tables loaded by pointer
|
2021-10-18 23:04:07 -03:00
|
|
|
|
|
|
|
AP_GROUPEND
|
|
|
|
};
|
|
|
|
|
2018-11-19 04:59:58 -04:00
|
|
|
/// Constructor
|
|
|
|
AP_BattMonitor_Sum::AP_BattMonitor_Sum(AP_BattMonitor &mon,
|
|
|
|
AP_BattMonitor::BattMonitor_State &mon_state,
|
|
|
|
AP_BattMonitor_Params ¶ms,
|
|
|
|
uint8_t instance) :
|
|
|
|
AP_BattMonitor_Backend(mon, mon_state, params),
|
|
|
|
_instance(instance)
|
|
|
|
{
|
2021-10-18 23:04:07 -03:00
|
|
|
AP_Param::setup_object_defaults(this, var_info);
|
|
|
|
_state.var_info = var_info;
|
2018-11-19 04:59:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// read - read the voltage and current
|
|
|
|
void
|
|
|
|
AP_BattMonitor_Sum::read()
|
|
|
|
{
|
|
|
|
float voltage_sum = 0;
|
2024-09-24 23:11:37 -03:00
|
|
|
float voltage_min = 0;
|
2018-11-19 04:59:58 -04:00
|
|
|
uint8_t voltage_count = 0;
|
|
|
|
float current_sum = 0;
|
|
|
|
uint8_t current_count = 0;
|
|
|
|
|
2024-07-27 11:02:04 -03:00
|
|
|
float temperature_sum = 0.0;
|
|
|
|
uint8_t temperature_count = 0;
|
|
|
|
|
2024-09-24 23:11:37 -03:00
|
|
|
float consumed_mah_sum = 0;
|
|
|
|
float consumed_wh_sum = 0;
|
|
|
|
|
2021-10-18 23:04:07 -03:00
|
|
|
for (uint8_t i=0; i<_mon.num_instances(); i++) {
|
|
|
|
if (i == _instance) {
|
|
|
|
// never include self
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ((_sum_mask == 0) && (i <= _instance)) {
|
|
|
|
// sum of remaining, skip lower instances
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ((_sum_mask != 0) && ((_sum_mask & 1U<<i) == 0)) {
|
|
|
|
// mask param, skip if mask bit not set
|
|
|
|
continue;
|
|
|
|
}
|
2018-11-19 04:59:58 -04:00
|
|
|
if (!_mon.healthy(i)) {
|
|
|
|
continue;
|
|
|
|
}
|
2024-09-24 23:11:37 -03:00
|
|
|
const float voltage = _mon.voltage(i);
|
|
|
|
if (voltage_count == 0 || voltage < voltage_min) {
|
|
|
|
voltage_min = voltage;
|
|
|
|
}
|
|
|
|
voltage_sum += voltage;
|
2018-11-19 04:59:58 -04:00
|
|
|
voltage_count++;
|
2019-07-07 11:34:41 -03:00
|
|
|
float current;
|
|
|
|
if (_mon.current_amps(current, i)) {
|
|
|
|
current_sum += current;
|
2018-11-19 04:59:58 -04:00
|
|
|
current_count++;
|
|
|
|
}
|
2024-07-27 11:02:04 -03:00
|
|
|
|
|
|
|
float temperature;
|
|
|
|
if (_mon.get_temperature(temperature, i)) {
|
|
|
|
temperature_sum += temperature;
|
|
|
|
temperature_count++;
|
|
|
|
}
|
2024-09-24 23:11:37 -03:00
|
|
|
|
|
|
|
float consumed_mah;
|
|
|
|
if (_mon.consumed_mah(consumed_mah, i)) {
|
|
|
|
consumed_mah_sum += consumed_mah;
|
|
|
|
}
|
|
|
|
|
|
|
|
float consumed_wh;
|
|
|
|
if (_mon.consumed_wh(consumed_wh, i)) {
|
|
|
|
consumed_wh_sum += consumed_wh;
|
|
|
|
}
|
2018-11-19 04:59:58 -04:00
|
|
|
}
|
2022-03-22 21:01:25 -03:00
|
|
|
const uint32_t tnow_us = AP_HAL::micros();
|
|
|
|
|
2018-11-19 04:59:58 -04:00
|
|
|
if (voltage_count > 0) {
|
2024-09-24 23:11:37 -03:00
|
|
|
if (option_is_set(AP_BattMonitor_Params::Options::Minimum_Voltage)) {
|
|
|
|
_state.voltage = voltage_min;
|
|
|
|
} else {
|
|
|
|
_state.voltage = voltage_sum / voltage_count;
|
|
|
|
}
|
2018-11-19 04:59:58 -04:00
|
|
|
}
|
|
|
|
if (current_count > 0) {
|
|
|
|
_state.current_amps = current_sum;
|
2024-09-24 23:11:37 -03:00
|
|
|
_state.consumed_mah = consumed_mah_sum;
|
|
|
|
_state.consumed_wh = consumed_wh_sum;
|
2018-11-19 04:59:58 -04:00
|
|
|
}
|
2024-07-27 11:02:04 -03:00
|
|
|
if (temperature_count > 0) {
|
|
|
|
_state.temperature = temperature_sum / temperature_count;
|
|
|
|
_state.temperature_time = AP_HAL::millis();
|
|
|
|
}
|
2022-03-22 21:01:25 -03:00
|
|
|
|
2018-11-19 04:59:58 -04:00
|
|
|
_has_current = (current_count > 0);
|
2024-07-27 11:02:04 -03:00
|
|
|
_has_temperature = (temperature_count > 0);
|
2018-11-19 04:59:58 -04:00
|
|
|
_state.healthy = (voltage_count > 0);
|
2022-03-22 21:01:25 -03:00
|
|
|
|
|
|
|
if (_state.healthy) {
|
|
|
|
_state.last_time_micros = tnow_us;
|
|
|
|
}
|
2018-11-19 04:59:58 -04:00
|
|
|
}
|
2023-03-06 22:02:49 -04:00
|
|
|
|
|
|
|
#endif // AP_BATTERY_SUM_ENABLED
|