Geavanceerde slimme batterijlader met multiplexing en digitaal display
Onderdelen en benodigdheden
- 1× Arduino UNO
- 1× Arduino Proto Shield
- 1× Ultrasone sensor HC-SR04
- 1× Adafruit MCP3008 8-kanaals 10-bit ADC
- 3× 5V Relais - 2 kanaals optocoupler
- 1× LM2596 DC/DC Buck-converter 3A instelbaar
- 12× Weerstand 1kΩ
- 1× 6-positie klemstrip
Nodige tools en machines
- Soldeerbout (algemeen)
Over dit project
Als je meerdere voertuigen (oude auto, boot, generator) hebt die in de winter niet gebruikt worden, is het duur om voor elke batterij een slimme lader te kopen. Deze oplossing gebruikt één lader die automatisch schakelt tussen maximaal 6 batterijen.
Hoe het werkt
- read_show_volts: Meet spanning op elke ingang (>8V = batterij aangesloten) en voegt deze toe aan de laadcyclus.
- check_relays: Schakelt de lader elke uur naar de volgende batterij (instelbaar).
- update_display: Toont spanningen van batterij 1-2 op regel 1, 3-4 op regel 2. Na timeout: batterij 5-6, systeemspanning (5V) en referentiespanning (3,3V).
- read_distance_update: HC-SR04 ultrasone sensor schakelt LCD-backlight uit na inactiviteit. Hand voor sensor = backlight aan voor ingestelde tijd.
De MCP3008 ADC biedt 8 analoge ingangen (Arduino UNO heeft er maar 6, waarvan A4/A5 voor I2C LCD). Twee 1kΩ-weerstanden per kanaal vormen een spanningsdeler.
Variabelen zijn aanpasbaar: laadtijd per batterij (standaard 1 uur), display-timeout, debug-niveau. Testmodus via ultrasone sensor: houd hand langere tijd voor sensor om snel te schakelen (seconden ipv uren) voor testdoeleinden.
Code
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <timer.h>
#include <HCSR04.h>
auto timer = timer_create_default();
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
int zcnt = 0;
int acnt = 0;
int chargeTime = (10 * 1000); // 10 seconden voor test, normaal 1 uur = 3600000
int charge_time_counter = 59;
int charge_time_max = 60;
int relay1 = 3;
int relay2 = 4;
int relay3 = 5;
int relay4 = 6;
int current_relay = 0;
int max_relays = 3;
float volts1, volts2, volts3;
int min_volts = 1;
int volts_update_count = 5;
int volts_update_counter = 0;
int volts_update = 500;
int read_distance_update = 500;
int time_on_counter = 0;
int time_on_count = 100;
int heart_beat = 0;
UltraSonicDistanceSensor distanceSensor(11, 12);
int distance;
int relays[] = { relay1, relay2, relay3 };
int is_live[] = { 0, 0, 0 };
int debug = 5;
void all_change_to(int which) {
digitalWrite(relay1, which);
digitalWrite(relay2, which);
digitalWrite(relay3, which);
}
void toggle_relays(int whichOne) {
lcd.setCursor(0, 0);
lcd.print("Relay on:");
lcd.print(current_relay + 1);
all_change_to(HIGH);
digitalWrite(relays[current_relay], LOW);
acnt++;
lcd.print(" ");
lcd.print(acnt);
}
void checkRelays() {
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() {
distance = distanceSensor.measureDistanceCm();
if (distance < 80) {
lcd.backlight();
time_on_counter = 0;
} else {
time_on_counter++;
if (time_on_counter > time_on_count) {
time_on_counter = 0;
lcd.noBacklight();
}
}
}
void read_show_volts() {
volts1 = analogRead(0) * 0.016;
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(11, 0);
lcd.print(volts1);
volts2 = analogRead(1) * 0.0164;
lcd.setCursor(4, 1);
lcd.print(volts2);
volts3 = analogRead(2) * 0.0166;
lcd.setCursor(11, 1);
lcd.print(volts3);
int temp_cnt = 0;
relays[0] = 0; relays[1] = 0; relays[2] = 0;
if (volts1 > min_volts) { relays[temp_cnt] = relay1; temp_cnt++; }
if (volts2 > min_volts) { relays[temp_cnt] = relay2; temp_cnt++; }
if (volts3 > min_volts) { relays[temp_cnt] = relay3; temp_cnt++; }
max_relays = temp_cnt;
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);
lcd.backlight();
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
all_change_to(HIGH);
read_show_volts();
checkRelays();
timer.every(chargeTime, checkRelays);
timer.every(volts_update, read_show_volts);
}
void loop() {
timer.tick();
}
Schema's
Productieproces
- Slimme Jaloezieën: Geautomatiseerd Lichtbeheer met Arduino & Zonne-energie
- Slimme spaarpot bouwen: Muntenacceptor besturen met Arduino Nano
- Arduino Temperatuurbewaking & Realtime Klok met 3.2" TFT-display
- Een LED bedienen via Bluetooth met Arduino – Eenvoudige DIY Handleiding
- Geoptimaliseerde Voedingsoplossingen voor Arduino Projecten
- Interactief Nextion HMI-weerstation met Arduino Mega en sensoren
- Bouw een DIY Voltmeter met Arduino en Nokia 5110 Display – Stap-voor-Stap Handleiding
- Uitgebreide Arduino Trainingskit met Mega 2560, Sensoren, Motoren en Custom PCB
- De Fridgeye-app bouwen met een Nextion-display: stapsgewijze handleiding
- Accurate zonnestralingsmeting met Arduino UNO en Ethernet Shield
- Slimme gebaar-naar-tekst handskoen voor gebarentaal