Guidance Needed for Battery Backup System

Hello Guys,

I’m working on a project where I check the health of a battery. The battery is connected to a charger that keeps the battery charged at all times. However, it does not check if the battery is bad (i.e. unable to hold a charge), because the battery is too old or has another fault. To check the battery health, I’ve come up with some code to disconnect the charger from the battery every day for about 1 hour. The battery will be charged at 13 V. If the voltage drops below 12.5 V within that hour, an email will be sent notifying me that, indeed, it is a bad battery. Otherwise, If the battery is below this voltage value to begin with, the code won’t execute, because it means that the battery was recently used or is still charging.

The code below works just like I want it to work, but I think is a little rough and could be improved. I’m asking all the genius coders out there for help. Can I improve this code?

// On and Off Times 
const unsigned long timeOn = 1000UL*30; // This will be set to 23 hrs
const unsigned long timeOff = 1000UL*5; // This will be set to 1 hr
// Tracks the last time event
unsigned long startMillis = 0;
// Waiting time
unsigned long period = timeOn;
// Tracks if Relay is  on or off
boolean relayState = true;

// Variables for the voltage sensor
int offset = 8; // Offset value
float average = 0;

void setup() 
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH); // We want the relay on
void loop() 
  int volt = analogRead(A3); 
  double voltage = map(volt,0,1023, 0, 2500) + offset; // map 0-1023 to 0-2500 and add correction offset
  voltage /=100;// divide by 100 to get the decimal values
  if(voltage > 13 || relayState == LOW) // Do this only if voltage is below 13V and Relay is LOW
  // relayState value will change only if the relay state changes
  digitalWrite(13, relayState);
  // CurrentMills will take keep track of the milliseconds
  unsigned long currentMillis = millis();
    // Compare to previous capture to see if enough time has passed
    if ((unsigned long)(currentMillis - startMillis) >= period) 
      // Change the period value depending on current relay state
      if (relayState) 
        // Relay is currently on, set time to stay off
        period = timeOff;
        Serial.println("Relay off");
        // Relay is currently off, set time to stay on
        period = timeOn;
        Serial.println("Relay on");

        if (voltage < 12.5) // If voltage is less than 12.5 send email
          Serial.println("Send bad battery email"); // Send me an email!

          digitalWrite(13, HIGH); // Check is done! Turn relay back on
      // Toggle the Relay's state
      relayState = !(relayState);
      // Restarts the time
      startMillis = currentMillis;

You did not tell us what type of battery you are using. Perhaps a lead-acid battery. The truth is the voltage read on the battery terminals are strictly based on the CHEMISTRY of the battery, and give NO indication of the current a battery can supply.

A completely dead lead-acid battery will still show about 12 volts, but cannot light a light bulb.
To ascertain the 'health" of a lead-acid battery, you must discharge it at a substantial rate for a fixed period of time, and measure the terminal voltage while discharging. If the voltage has a substantial drop, then the internal resistnce of the battery is high, indicating poor health.


I aslo would not be so sure that the open circuit voltage of a battery, under no load, is a good indicator as to its state of charge.

What test evidence do you have to the contary ?

I recommend measuring during load. That's what's interesting, that the battery manage to keep the project running.