Generic LowBattery warning code

For a 3.3V ProMini running off a 3.7V LiPo cell i wanted a low battery warning indicator. The result is the code below . Guess it can be used for any battery powered Arduino - just make sure the A0 input gets the raw battery voltage ( after scaling if required ) and not from the Vcc on the board !!

This was coded with examples from codingBadly , retrolefty and library from NickGammon. Thanks to all.

#include <LedFlasher.h>

long BaudRate = 9600;
int analog_Ch0Val;
int battVolts; 

unsigned long acquireMillis;
unsigned long acquireInterval = 1000;

LedFlasher lowBatt(13, 500, 50);     // Pin ref, Off time, On time.

//***********************************

void setup()
{
  Serial.begin (BaudRate);
  lowBatt.begin();
  acquireMillis = millis();
}

//***********************************

void loop()
{
  acquireVal();
  if ( analog_Ch0Val < 300 ) lowBatt.update();  // Flash LED if battery voltage falls below 3.0V
} // End of loop

//***********************************

// Function to Acquire the cell voltage

void acquireVal ()
{
  if ( millis() - acquireMillis > acquireInterval )
  {
    acquireMillis = millis();
    for (int i = 0; i <= 3; i++) battVolts = getBandgap(); //4 readings required for best stable value
    analog_Ch0Val = (map(analogRead(0), 0, 1023, 0, battVolts)) * 2 ; // To nullify the potential divider..on 3.3V ProMini

    Serial.print("AI_00 value = ");
    Serial.println(analog_Ch0Val);
  }
}

//***********************************

// Function to get battery voltage based on Internal Refernce..

int getBandgap(void)
{
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  // For mega boards
  const long InternalReferenceVoltage = 1100L;  // For even more accuracy, enter your boards Vref  BG voltage x1000
  ADMUX = (0 << REFS1) | (1 << REFS0) | (0 << ADLAR) | (1 << MUX4) | (1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (0 << MUX0);
#else
  // For 168/328 boards
  const long InternalReferenceVoltage = 1100L;  // For even more accuracy, enter your boards Vref  BG voltage x1000
  ADMUX = (0 << REFS1) | (1 << REFS0) | (0 << ADLAR) | (1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (0 << MUX0);
#endif

  ADCSRA |= _BV( ADSC );    // Start a conversion
  while ( ( (ADCSRA & (1 << ADSC)) != 0 ) ); // Wait for it to complete
  int results = (((InternalReferenceVoltage * 1024L) / ADC) + 5L) / 10L;  // Scale the value
  return results;
}

Nice starting point.

Suggestion - Call acquire less often - as not to slow down everything else with AD conversions. It's unlikely the battery voltage will change much every couple of microseconds!

Perhaps a call every second or less... ?

lastchancename:
Nice starting point.

Suggestion -
Call acquire less often - as not to slow down everything else with AD conversions.
It’s unlikely the battery voltage will change much every couple of microseconds!

Perhaps a call every second or less… ?

Thanks and good suggestion. Actually even now I am calling acquireVal() once every second.