Project tutorial
Smart Battery Charger Multiplexer with Smart Display

Smart Battery Charger Multiplexer with Smart Display © CC BY-NC

Use a smart battery charger on up to 6 batteries - wave your hand to turn display on and check charging.

  • 1,931 views
  • 4 comments
  • 11 respects

Components and supplies

Necessary tools and machines

09507 01
Soldering iron (generic)

About this project

Living in the North East if you have an older car or a boat, or lawn mower or other vehicle that starts with a battery that you don’t drive or use in bad weather (some call it winter) you have to decide what to do with the batteries each season. If you have one or two it’s pretty easy – you can get a trickle charger. The cheap simple ones are under $15 – but they are simple – no battery feed back or monitoring, they just put just over 13 volts to the battery. A better choice would be one of the smart chargers – they usually have regular higher/faster charge and a snow or trickle charge that adjusts it’s output based on the battery voltage and condition. They work very well – Harbor Freight has one for $39 – of course $29 on sale which is almost always.

Were I got hung up was I have my 1975 MGB (with a 3.5 liter Oldsmobile V8), a 1981 Toyota pickup, a boat and a generator – all with 12 volt batteries. And then if we go away in the winter we leave one of the cars here so there’s another battery. Well I’d have to get 5 battery minders – $150 if I go for the HF one on sale.

While thinking about this I thought I get one for each battery, put it on, it brings the batteries to a level and then it just monitors and trickle charges it for the rest of the time. So the idea comes to my – why couldn’t I hook it up to each battery a few hours a day – wouldn’t that work? Then if I could have it automatically switch between them?

Well I can. I took one of my Arduinos and wrote a program that does just that – and then I got carried away and added a few extra features. So here I present the details on what I ended up with. This version is setup for up to 6 batteries with auto sensing.

It will work with 1 to 6 batteries. The first battery must be hooked up to the number 1 spot – that connection is tied to the voltage regulator that powers the Arduino and other electronics. The 2nd and up can then be connected in any order. When you connect a battery the voltage is sensed in the Read_Show_Volts function and that battery is added to the charging cycle.

How it works – I wanted to accommodate 6 batteries. With an Arduino UNO A4 and A5 analog inputs are needed for the 2 wire LCD control and that leaves 4 analog inputs, too few. So I connected up an MCP-3008 8 channel analog inputs. I use 2 1k resistors as a voltage divider for each input to the MCP-3008.

There are basically 4 functions called in the program.

  • The function read_show_volts checks each connection to see if there is a battery connected by testing for greater than 8 volts available. If there is 8v or more it adds that connection to the charging loop.
  • Function check_relays checks the timer counter and when it reaches the max it moves the charger to the next relay in line.
  • Function update_display does just that – updates the display. First it shows the voltage at connections 1, 2 on line 1 and the voltage of connections 3 and 4 on line 2. Then when the timer tells it it changes and displays the voltage of connections 5 and 6 on line 1 and because I had two extra analog inputs I show the system voltage (hopefully 5 volts) and the iref voltage – 3.3 volts. Those readings are not needed but there was a blank line and I didn’t know what else to show – I’m open to ideas.
  • The final function is read_distance_update. This one is interesting and the most fun playing with. I hooked up an HC-SR04 ultrasonic sonar distance measuring unit. I wanted the lcd to monitor the voltages but I am hardly ever standing there looking at the lcd – most of the time it could be turned off. I could have put a switch – easy way out – but what I did was put the HC-SR04 in and after so many seconds turn the lcd off. Then when I pass my hand closely over the HC-SR04 I turn the lcd back on for x seconds.

There are variables for most everything so you can tailor it too fit you needs. I have set the charging timer to 1 hour per battery. So if there are two batteries connected it will charge each for 1 hour each time 12 times a day. With 4 batteries it would be 1 hour 6 times a day, and so on.

As long as I had the HC-SR04 I added a routine that change the timer loop to a shorter time – a few seconds on each battery. The reason I did this was so I could see that it was switching between the batteries OK and I didn’t have to wait an hour to see it switch. If you hold your hand over the HC-SR04 for a few seconds it flashes the lcd backlight on and off so you know it switched. You’ll then hear the relays switch every few seconds. Hold your hand over the HC-SR04 again and it will switch back.

Here’s a zip of the code: BatteryMultiplexer

Code

Battery Multiplexer Arduino CodeArduino
I used an Arduino Uno.
#include <Wire.h>
#include <LiquidCrystal_I2C.h> // Using version 1.2.1
#include <timer.h>
#include <HCSR04.h>

auto timer = timer_create_default(); // create a timer with default settings

// The LCD constructor - address shown is 0x27 - may or may not be correct for yours
// Also based on YWRobot LCM1602 IIC V1
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

int zcnt = 0;
int acnt = 0; // general purpuse right now
int chargeTime = (10 * 1000); // how much time to spend on each battery
int charge_time_counter = 59; // how many chargetimes were passed?
int charge_time_max = 60; // how many chargetimes were passed?
int relay1 = 3; // each relay on it's own pin
int relay2 = 4;
int relay3 = 5;
int relay4 = 6;
int current_relay = 0; // which relay is the one on now?
int max_relays = 3; // how may relays - 0 based. Start expecting all three.
float volts1; // what's the voltage of each battery
float volts2;
float volts3;
int min_volts = 1; // what is the minimum voltage a batter voltage should be to be charged.
int volts_update_count = 5; // how often to update the voltage reading in seconds
int volts_update_counter = 0; // track the count of seconds gone by
int volts_update = (500);
int read_distance_update = (500); // update the distance reader every millis
int time_on_counter = 0; // counter for the display on/off
int time_on_count = 100; //seconds to be on
int heart_beat = 0; // flip this 0 to 1 to 0 to show the heart beat

UltraSonicDistanceSensor distanceSensor(11, 12);  // Initialize sensor that uses digital pins 13 and 12.
int distance;

int relays[] = { relay1, relay2, relay3 };
int is_live[] = { 0, 0, 0}; // 1 if live, 0 if not. I have only 3

int debug = 5; // set this to the level of debug msgs to go to the serial printer

void all_change_to(int which) { // change all relays to HIGH or LOW, you tell me which:)
  digitalWrite(relay1, which);
  digitalWrite(relay2, which);
  digitalWrite(relay3, which);
}

void toggle_relays(int whichOne) {
  lcd.setCursor(0, 0); // show which relay is the current one on
  lcd.print("Relay on:");
  lcd.print(current_relay + 1); // current_relay is zero based
  all_change_to(HIGH); // turn all off first
  digitalWrite(relays[current_relay], LOW); // and set the one that should be on on
  acnt++; // just a counter to show me it's working
  lcd.print("  ");
  lcd.print(acnt);
}

void checkRelays() {
  // move the current_relay to the next relay
  // if we hit the max, start at 0
  // while you're here, call toggle_relays to make sure we're not charge a blank or dead one
  charge_time_counter++;
  if (charge_time_counter >= charge_time_max) {
    current_relay++;
    if (current_relay >= max_relays) {
      current_relay = 0;
    }
    toggle_relays(current_relay);
    charge_time_counter = 0;
  }
}

void read_distance() {
  // reaad the distance of anything from the HC-S204
  // if it's something within 80cm then turn the display on and reset the display on counter
  // if the counter is reached then nothing is within 80cm so turn the display off
  distance = distanceSensor.measureDistanceCm();
  // uncomment these to see the actual distance measured
  // Serial.print("Distance in CM: ");
  // Serial.println(distance);
  if (distance < 80) { // can be anything under 200 for my system uncomment above and check yours
    lcd.backlight();   // turn display on
    time_on_counter = 0;
  } else { // maybe going off?
    time_on_counter++;
    if (time_on_counter > time_on_count) {
      time_on_counter = 0;
      lcd.noBacklight();
    }
  }
}

void read_show_volts() {
  // read the volts at each battery input
  // then if less then min_volts, there is nothing there worth charging, skip that connection
  // this gets called over and over so if a wire gets knocked off or
  // whatever it won't be in the charge loop
  volts1 = analogRead(0);
  volts1 = (volts1 * 0.016);
  lcd.setCursor(0, 1); lcd.print("                "); // clear the line
  lcd.setCursor(11, 0);
  lcd.print(volts1);
  volts2 = analogRead(1);
  volts2 = (volts2 * 0.0164);
  lcd.setCursor(4, 1);
  lcd.print(volts2);
  volts3 = analogRead(2);
  volts3 = (volts3 * 0.0166);
  lcd.setCursor(11, 1);
  lcd.print(volts3);
  // now test the voltages. If less than 10, then let's assume dead/bad or no battery
  // so take it out of rotation
  // start by clearing all relays out
  int temp_cnt = 0;
  // set all arrays to 0 - that's off
  relays[0] = 0;
  relays[1] = 0;
  relays[2] = 0;
  if (volts1 > min_volts) {
    relays[temp_cnt] = relay1;  // relay 1 is good
    temp_cnt++;
  }
  if (volts2 > min_volts) {
    relays[temp_cnt] = relay2;  // relay 2 is good
    temp_cnt++;
  }
  if (volts3 > min_volts) {
    relays[temp_cnt] = relay3;  // relay 3 is good
    temp_cnt++;
  }
  max_relays = temp_cnt;
  // this is a heart bet on the lcd - just shows me it's running
  lcd.setCursor(0, 1);
  if (heart_beat == 1) {
    lcd.print("<>");
    heart_beat = 0;
  } else {
    lcd.print("><");
    heart_beat = 1;
  }
  lcd.print(charge_time_counter);
  read_distance();
}

void setup()
{
  Serial.begin(19200);
  Serial.println("Starting");
  lcd.begin(16, 2); // sixteen characters across - 2 lines
  lcd.backlight();
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  all_change_to(HIGH);
  // setup timers. 3 timers - the time to turn the charger on each battery,
  // how often to show the voltage update
  // and how often to check for distance read to turn on the display
  read_show_volts(); // do the first time so we don't have to wait for the timer.
  checkRelays();
  timer.every(chargeTime, checkRelays);
  timer.every(volts_update, read_show_volts);
}

void loop()
{
  timer.tick(); // tick the timer
}

Schematics

Battery Multiplexer Schematic
Schematic for multiplexer
Batterymultiplexerschematic g6z5awy6g9

Comments

Similar projects you might like

Battery Charger Monitor

Project tutorial by David Kanceruk

  • 3,744 views
  • 1 comment
  • 18 respects

Smart Suitcase Prototype

Project in progress by Irene Zhang

  • 1,201 views
  • 1 comment
  • 5 respects

Smart Blinds

Project tutorial by Froz3nArcher

  • 13,939 views
  • 3 comments
  • 47 respects

Programmable Pocket Power Supply with OLED Display

Project tutorial by Shahariar

  • 6,862 views
  • 8 comments
  • 36 respects

Grovey sLocks - Access Control Through A Smart Door Lock

Project tutorial by gerrikoio

  • 998 views
  • 0 comments
  • 6 respects

Smart Garden

Project showcase by patel Dipen

  • 25,064 views
  • 15 comments
  • 67 respects
Add projectSign up / Login