1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-30 08:24:11 +01:00
LibrePilot/flight/Modules/Battery/battery.c
James Cotton f8d196ffe8 Added support for board voltage monitor to battery module.
The module can be configured to enable what's needed from board voltage, battery voltage and battery current measurement.
In GCS the POWER box in system healt will show alarm related to the supply voltage to the board.
If a power warning/critical alarm is raised, the warning condition is left even if the board voltage return to an acceptable value.

Conflicts:

	ground/openpilotgcs/share/openpilotgcs/diagrams/default/system-health.svg
	shared/uavobjectdefinition/systemalarms.xml
2012-06-15 19:43:34 -05:00

229 lines
7.5 KiB
C

/**
******************************************************************************
* @addtogroup OpenPilotModules OpenPilot Modules
* @{
* @addtogroup BatteryModule Battery Module
* @brief Measures battery voltage and current
* Updates the FlightBatteryState object
* @{
*
* @file battery.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief Module to read the battery Voltage and Current periodically and set alarms appropriately.
*
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* Output object: FlightBatteryState
*
* This module will periodically generate information on the battery state.
*
* UAVObjects are automatically generated by the UAVObjectGenerator from
* the object definition XML file.
*
* Modules have no API, all communication to other modules is done through UAVObjects.
* However modules may use the API exposed by shared libraries.
* See the OpenPilot wiki for more details.
* http://www.openpilot.org/OpenPilot_Application_Architecture
*
*/
#include "openpilot.h"
#include "flightbatterystate.h"
#include "flightbatterysettings.h"
#include "hwsettings.h"
//
// Configuration
//
#define SAMPLE_PERIOD_MS 500
#define BATTERY_BOARD_VOLTAGE_WARNING 4.5
#define BATTERY_BOARD_VOLTAGE_CRITICAL 3.5
#define BATTERY_BOARD_VOLTAGE_ERROR 1.0
// Private types
// Private variables
static bool batteryEnabled = false;
// Private functions
static void onTimer(UAVObjEvent* ev);
/**
* Initialise the module, called on startup
* \returns 0 on success or -1 if initialisation failed
*/
int32_t BatteryInitialize(void)
{
#ifdef MODULE_BATTERY_BUILTIN
batteryEnabled = true;
#else
uint8_t optionalModules[HWSETTINGS_OPTIONALMODULES_NUMELEM];
HwSettingsOptionalModulesGet(optionalModules);
if (optionalModules[HWSETTINGS_OPTIONALMODULES_BATTERY] == HWSETTINGS_OPTIONALMODULES_ENABLED)
batteryEnabled = true;
else
batteryEnabled = false;
#endif
if (batteryEnabled) {
FlightBatteryStateInitialize();
FlightBatterySettingsInitialize();
static UAVObjEvent ev;
memset(&ev,0,sizeof(UAVObjEvent));
EventPeriodicCallbackCreate(&ev, onTimer, SAMPLE_PERIOD_MS / portTICK_RATE_MS);
}
return 0;
}
MODULE_INITCALL(BatteryInitialize, 0)
#define HAS_SENSOR(x) batterySettings.SensorType[x]==FLIGHTBATTERYSETTINGS_SENSORTYPE_ENABLED
static void onTimer(UAVObjEvent* ev)
{
static FlightBatteryStateData flightBatteryData;
static bool BoardPowerWarning= false;
FlightBatterySettingsData batterySettings;
FlightBatterySettingsGet(&batterySettings);
static float dT = SAMPLE_PERIOD_MS / 1000.0;
float energyRemaining;
if(HAS_SENSOR(FLIGHTBATTERYSETTINGS_SENSORTYPE_BOARDVOLTAGE) )
flightBatteryData.BoardSupplyVoltage=((float)PIOS_ADC_PinGet(4)) * PIOS_ADC_VOLTAGE_SCALE * 6.1;
else
flightBatteryData.BoardSupplyVoltage = -1;
//calculate the battery parameters
if(HAS_SENSOR(FLIGHTBATTERYSETTINGS_SENSORTYPE_BATTERYVOLTAGE) )
flightBatteryData.Voltage = ((float)PIOS_ADC_PinGet(0)) * PIOS_ADC_VOLTAGE_SCALE * batterySettings.SensorCalibrations[FLIGHTBATTERYSETTINGS_SENSORCALIBRATIONS_VOLTAGEFACTOR]; //in Volts
else
flightBatteryData.Voltage = -1;
if(HAS_SENSOR(FLIGHTBATTERYSETTINGS_SENSORTYPE_BATTERYCURRENT))
{
flightBatteryData.Current = ((float)PIOS_ADC_PinGet(1)) * PIOS_ADC_VOLTAGE_SCALE * batterySettings.SensorCalibrations[FLIGHTBATTERYSETTINGS_SENSORCALIBRATIONS_CURRENTFACTOR]; //in Amps
flightBatteryData.ConsumedEnergy += (flightBatteryData.Current * 1000.0f * dT / 3600.0f) ;//in mAh
if (flightBatteryData.Current > flightBatteryData.PeakCurrent)
flightBatteryData.PeakCurrent = flightBatteryData.Current; //in Amps
flightBatteryData.AvgCurrent=(flightBatteryData.AvgCurrent*0.8)+(flightBatteryData.Current*0.2); //in Amps
//sanity checks
if (flightBatteryData.AvgCurrent<0)
flightBatteryData.AvgCurrent=0.0;
if (flightBatteryData.PeakCurrent<0)
flightBatteryData.PeakCurrent=0.0;
if (flightBatteryData.ConsumedEnergy<0)
flightBatteryData.ConsumedEnergy=0.0;
energyRemaining = batterySettings.Capacity - flightBatteryData.ConsumedEnergy; // in mAh
flightBatteryData.EstimatedFlightTime = ((energyRemaining / (flightBatteryData.AvgCurrent*1000.0))*3600.0);//in Sec
}
else
if(flightBatteryData.Current != -1)
{
flightBatteryData.Current = -1;
flightBatteryData.EstimatedFlightTime = 0;
flightBatteryData.AvgCurrent = 0;
flightBatteryData.ConsumedEnergy = 0;
}
//Check for battery inputs disconnection (don't think this really works. Do we need pull down on inputs?).
if (flightBatteryData.Voltage == 0 ||
flightBatteryData.Current == 0 )
{
AlarmsSet(SYSTEMALARMS_ALARM_BATTERY, SYSTEMALARMS_ALARM_ERROR);
AlarmsSet(SYSTEMALARMS_ALARM_FLIGHTTIME, SYSTEMALARMS_ALARM_ERROR);
}
else
{
if(HAS_SENSOR(FLIGHTBATTERYSETTINGS_SENSORTYPE_BATTERYCURRENT))
{
if (flightBatteryData.EstimatedFlightTime < 30)
AlarmsSet(SYSTEMALARMS_ALARM_FLIGHTTIME, SYSTEMALARMS_ALARM_CRITICAL);
else
if (flightBatteryData.EstimatedFlightTime < 60)
AlarmsSet(SYSTEMALARMS_ALARM_FLIGHTTIME, SYSTEMALARMS_ALARM_WARNING);
else
AlarmsClear(SYSTEMALARMS_ALARM_FLIGHTTIME);
}
// FIXME: should make the battery voltage detection dependent on battery type.
if(HAS_SENSOR(FLIGHTBATTERYSETTINGS_SENSORTYPE_BATTERYVOLTAGE)){
if (flightBatteryData.Voltage < batterySettings.VoltageThresholds[FLIGHTBATTERYSETTINGS_VOLTAGETHRESHOLDS_ALARM] )
AlarmsSet(SYSTEMALARMS_ALARM_BATTERY, SYSTEMALARMS_ALARM_CRITICAL);
else
if (flightBatteryData.Voltage < batterySettings.VoltageThresholds[FLIGHTBATTERYSETTINGS_VOLTAGETHRESHOLDS_WARNING])
AlarmsSet(SYSTEMALARMS_ALARM_BATTERY, SYSTEMALARMS_ALARM_WARNING);
else
AlarmsClear(SYSTEMALARMS_ALARM_BATTERY);
}
}
if(HAS_SENSOR(FLIGHTBATTERYSETTINGS_SENSORTYPE_BOARDVOLTAGE) )
{
// power ia disconnected from the board (it is powered by usb)
if(flightBatteryData.BoardSupplyVoltage!= -1 && flightBatteryData.BoardSupplyVoltage < BATTERY_BOARD_VOLTAGE_ERROR)
{
AlarmsSet(SYSTEMALARMS_ALARM_POWER, SYSTEMALARMS_ALARM_ERROR);
BoardPowerWarning=false;
}
else
{
if(flightBatteryData.BoardSupplyVoltage < BATTERY_BOARD_VOLTAGE_CRITICAL)
{
AlarmsSet(SYSTEMALARMS_ALARM_POWER, SYSTEMALARMS_ALARM_CRITICAL);
BoardPowerWarning=true;
}
else if (flightBatteryData.BoardSupplyVoltage < BATTERY_BOARD_VOLTAGE_WARNING)
{
AlarmsSet(SYSTEMALARMS_ALARM_POWER, SYSTEMALARMS_ALARM_WARNING);
BoardPowerWarning=true;
}
else
{
// if there was any previous warning/critical condition, notify the problem leaving the warning
if(BoardPowerWarning)
AlarmsSet(SYSTEMALARMS_ALARM_POWER, SYSTEMALARMS_ALARM_WARNING);
else
AlarmsClear(SYSTEMALARMS_ALARM_POWER);
}
}
}
FlightBatteryStateSet(&flightBatteryData);
}
/**
* @}
*/
/**
* @}
*/