Battery Monitor

Battery Monitor History

Original release with AeroQuad 2.1 written by Honk, modified by Mikro. Information of the v2.x version can be found here: BatteryMonitor.h v2

For v3 the BatteryMonitor was rewritten from scratch by kha for scalability and new features.

General Information

Battery Monitor support provides a way for the AeroQuad copter to sense its current power level by measuring the battery supply voltage and optionally current drawn from it. When the battery voltage drops below predefined level an alarm state is raised which can provide audible/visual warning and also trigger automatic descent. To measure battery voltage a simple "two resistor voltage divider is needed". For current measurement any current sensor providing analog output can be used.

The Battery Monitor can be configured to monitor multiple batteries when needed.

On a platform with an Atmega328 (or Uno) the battery monitor is simplified so that it will only monitor voltage, this is to save code space.

In general the battery monitor differs between two states - the alarm state and the warning state. The warning stage is triggered at first signaled by the blinking battery monitor LED on the flight controller board. The second stage (alarm stage) is triggered when the battery voltage drops further signaled by the now faster blinking LED. Additionally, if enabled, your AeroQuad will now start to automatically descent.


The Battery Monitor is configured by following section in "UserConfiguration.h":

// *******************************************************************************************************************************
// Battery Monitor Options
// For more information on how to setup Battery Monitor please refer to
// *******************************************************************************************************************************
#define BattMonitor            // Enable Battery monitor
//#define BattMonitorAutoDescent // if you want the craft to auto descent when the battery reach the alarm voltage
//#define POWERED_BY_VIN         // Uncomment this if your v2.x is powered directly by the vin/gnd of the arduino
// Advanced configuration. Please refer to wiki for instructions
//#define BattCustomConfig DEFINE_BATTERY(cellcount,vpin,vscale,vbias,cpin,cscale,cbias) // cpin=BM_NOPIN if no sensor
For basic configuration on "standard" hardware only the first three #defines are needed.
  • BattMonitor -- enable Battery Monitor in general
  • BattMonitorAutoDescent -- enable descent when battery voltage is critical
  • POWERED_BY_VIN -- set this if Arduino is powered via the VIN pin instead of the power jack

Advanced configuration should be used when
  • more than one battery is used
  • custom voltage divider is used
  • current sensor is used (for a variety of different current sensor take a look at the AeroQuad store)
  • a LiPo >4s is used (1s-4s LiPos are detected automatically by the algroithm)
  • or you want to increase the precision of the voltage measurement

Custom configuration guide:
  • cellcount = number of cells on battery, a value of 0 means autodetect (1s-4s)
  • vpin = the analog pin the voltage divider is connected
  • vscale = scale factor to convert the analogread() value to volts
  • vbias = bias value added to the voltage
  • cpin = the pin current sensor is connected
  • cscale = scale factor used to convert analogread() value into amperes
  • cbias = bias value added to the current

Calculation of the scale/bias values:
  • Voltage:
  • VSCALE = AREF * (R1 + R2) / R2
    For example with AQ v2 shield on Arduino Mega 2560 AREF=5.0 R1=15kOhm R2=7.5kOhm -> vscale = 5.0 * (15+7.5) / 7.5 = 15.0
    AQ32 built-in voltage divider: R1 = 10K, R2 = 1.5K, AREF = 3.3V -> vscale = 3.3 * (10 + 1.5) / 1.5 = 25.3
    Some early AQ32 boards came with R1 = 5.6K on accident, in this case, vscale = 3.3 * (5.6 + 1.5) / 1.5 = 15.62
  • VBIAS = (voltage drop on D1) (or 0 if no diode)
    For example on Arduino Mega 2560 the diode drop typically is -> vbias = 0.82
  • CSCALE = (current at which the sensor outputs AREF voltage)
  • CBIAS = 0 for unidirectional sensor or -0.5*CSCALE for bidirectional sensor

    For Flytron 100A (5V@100A) sensor with AREF=5.0V
    CSCALE = 100
    CBIAS = 0

    For ACS756SCA-100B-PFF-T (bidirectional 100A 20mV/A) with AREF=5.0V
    CSCALE = 250
    CBIAS = -125

Custom configuration examples:

// one 2-3S battery on v2 shield, a flytron 100A sensor wired to A1, powered via power jack
#define BattCustomConfig DEFINE_BATTERY(0, A0, 15.0, 0.82,  A1, 100, 0)

// two 3S batteries on A0 and A1, (BATT - 15k - Ain - 7.5k - GND) divider used on both
#define BattCustomConfig DEFINE_BATTERY(3, A0, 15.0, 0.0,  BM_NOPIN, 0, 0),DEFINE_BATTERY(3, A1, 15.0, 0.0,  BM_NOPIN, 0, 0)
Specific AeroQuad32 configurations:

// AQ32 standard (internal voltage divider, no current sensor)
#define BattCustomConfig DEFINE_BATTERY(0, BATT_ANALOG_INPUT, 25.3, 0, BM_NOPIN, 0, 0)

// AQ32 internal voltage divider and Flytron 100A sensor on ADC1 (A1)  ## NOTE: do not exceed 66A
#define BattCustomConfig DEFINE_BATTERY(0, BATT_ANALOG_INPUT, 25.3, 0, A1, 66, 0)

// AQ32 attopilot 90A voltage=A1 current=A2
#define BattCustomConfig DEFINE_BATTERY(0, A1, 51.8, 0, A2, 90.2, 0)

// AQ32 attopilot 180A voltage=A1 current=A2
#define BattCustomConfig DEFINE_BATTERY(0, A1, 51.8, 0, A2, 180.3, 0)

// AQ32 attopilot 45A voltage=A1 current=A2
#define BattCustomConfig DEFINE_BATTERY(0, A1, 13.6, 0, A2, 45.1, 0)

Additionally, the behavior of the battery monitor can be further tweaked in the AeroQuad Configurator. Navigate to the "Battery Monitor" sub-menu found in the "Configuration" drop down menu.

The "Alarm Voltage" value controls the voltage value per cell which triggers the alarm state. Additionally this sets the voltage value which triggers the warning state (voltage for warning = voltage for alarm * 110%). For example, if the "Alarm Voltage" value is set to "3.3V" the warning value is 3.3V * 110% = 3,63V.
The "Throttle Target" and "Going Down Time" values are only relevant if "Auto Descent" is enabled and defines the throttle value which should be reached at lowest and the time how long this process of lowering the throttle to the target value should take.


On the AeroQuad Shields v1.9 and v2.x and the AeroQuad32 flight control board, the voltage divider is already present in the form of the resistors R1 and R2. No further work needs to be done in these cases.

Schematic of voltage divider circuitSchematic of voltage divider circuit

The schematic above is showing how the diode (if required) and resistors are to be wired. Vout should be connected to pin A0 that is present on any Arduino. The diode may be a 1N914 or equivalent. The resistors may be quarter watt. You can affect the accuracy of this monitor in two ways: One of them is to use 1% tolerance resistors, which guarantee the resistance will be within 1% of its nominal value. (Generally, resistors are available in 10%, 5% and 1% tolerance.) These are a bit more expensive, but still not much.
The other way, which is the more accurate way is to measure the actual resistance of both of them (regardless of their tolerance) and declare that value for them in the code. This should be done before they are placed in the circuit. Also, if the diode shown in Fig. 1 is used, you must measure its forward voltage, and declare that in the code as well.
To do this, when the circuit is installed and power applied, measure the voltage across the diode (place the probes on either side of the diode's leads) and declare that value for it in the code. If there is no diode used on your platform (e.g on Mini Shield v1.0), this value must be set to zero. It is referred to as voltage “drop” in the code. If Aref on your platform is well regulated (as is the case on the Mega) then using its nominal value is good; if your platform is not regulated, then measuring this voltage and declaring that value is also a good idea.

Future Development

  • Make LED blinking, "heartbeat" behavior, buzzer operation, and auto descend user configurable combinations from setup.

Additional information

AeroQuad Configurator