der Betrieb der V2.0 ist schon sehr komfortabel. Die Spannung der
Batterien wird zuverlässig angezeigt und es kommt eine Meldung, wenn
deren Spannung zu weit absinkt.
Allerdings ist der Kontrast des
Displays noch nicht optimal, da dessen Versorgungsspannung abhängig der
Leere der Batterien im Bereich von 5V bis unter 3V schwankt. Da muss
eine Kontrast-Automatik her! In Anlehnung an diese Webseite, habe ich die Schaltung erweitert: Ich habe noch 2 Analogeingänge frei, mit
der ich sowohl Versorgungsspannung des Displays, als auch die
Kontrastspannung messen kann. Über einen PWM-Ausgang mit
nachgeschaltetem Spannungsteiler, sowie Glättungs-Schaltung kann ich nun
den Kontrast immer im optimalen Bereich halten.
In diesem Zusammenhang habe ich noch ein paar kleine Bugs im Programm beseitigt:
// ———————————————————
// Batteriemessger�t
// es wird die Spannung von 6 Batterien gemessen und gleichzeitig
// auf einem LCD-Display dargestellt.
// ———————————————————
#include #define DEBUG struct _Batterie LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // initialize the library with the numbers of the interface pins #define NEIN 0 // Taste nicht gedr�ckt // ——————————- // ——————————- for(i=0; i<6 br="" i=""> Batterien[i].abschaltspannung = 0.02F; // ——————————- aval = analogRead(AnalogBatPin1); // ——————————- if(Batterien[0].ausgetastet) if(Batterien[3].ausgetastet) lcd.setCursor(0, 0); // ——————————- gedrueckt = digitalRead(TasterPin); if (gedrueckt) letztes_gedrueckt = gedrueckt; // SERIAL_PRINT(anfang); return tasterGedrueckt; // ——————————- for(i=0; i<6 br="" i=""> { // ——————————- vcc = analogRead(AnalogVCCPin); kontrastwert += ((800*(vcc/1000))-kont)/7; SERIAL_PRINT(“ Kout=“); analogWrite(KontrastPWM, kontrastwert); // ——————————- jetzt = millis(); if ((jetzt-jedeSekunde) > 1000) SekundenBlinkbit = ~SekundenBlinkbit; if ((jetzt-jedeHalbeSekunde) > 500) Slot++; SERIAL_PRINTLN(Slot); HalbsekundenBlinkbit = ~HalbsekundenBlinkbit; if ((jetzt-jedeViertelSekunde) > 250)
#include „log.h“
{
float spannung; // die gemessene Spannung
bool ausgetastet; // wird die Spannung gerade angezeigt, oder ausgetastet
float abschaltspannung; // darunter ist die Batterie leer
};
int AnalogBatPin1 = A0;
int AnalogBatPin2 = A1;
int AnalogBatPin3 = A2;
int AnalogBatPin4 = A3;
int AnalogBatPin5 = A4;
int AnalogBatPin6 = A5;
int AnalogKontrastPin = A6; // hier wird die Kontrastspannung gemessen
int AnalogVCCPin = A7; // hier wird die VCC gemessen (für die Kontrastspannungsberechnung)
int KontrastPWM = 6;
int TasterPin = 10;
int SummerPin = 9;
int LEDPin =13;
bool Pieps; // w�hrenddessen wird gepiepst
int Slot; // z�hlt immer durch
struct _Batterie Batterien[6];
bool SekundenBlinkbit; // toggle jede Sekunde
bool HalbsekundenBlinkbit; // toggle jede halbe Sekunde
bool ViertelsekundenBlinkbit; // toggle jede viertel Sekunde
#define KURZ 1 // Taste kurz gedr�ckt
#define LANG 2 // Taste lang gedr�ckt
void setup()
{
SERIAL_BEGIN;
lcd.begin(16, 2); // set up the LCD’s number of columns and rows:
analogReference(INTERNAL);
pinMode(TasterPin, INPUT);
pinMode(SummerPin, OUTPUT);
pinMode(LEDPin, OUTPUT);
InitVariablen();
}
void InitVariablen(void)
{
int i;
}
void MesseBatterien(void)
{
int aval;
float offset[6] = { 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F };
float zaehl[6] = { 1.24F, 1.24F, 1.24F, 1.24F, 1.24F, 1.24F };
float nenner[6] = { 0.83F, 0.83F, 0.83F, 0.83F, 0.83F, 0.83F };
Batterien[0].spannung = (float)aval *zaehl[0] / nenner[0] / 1000.0F + offset[0];
aval = analogRead(AnalogBatPin2);
Batterien[1].spannung =
(float)aval *2.0F * zaehl[1] / nenner[1] / 1000.0F + offset[1];
Batterien[1].spannung -= Batterien[0].spannung;
aval = analogRead(AnalogBatPin3);
Batterien[2].spannung =
(float)aval *3.0F * zaehl[2] / nenner[2] / 1000.0F + offset[2];
Batterien[2].spannung -= Batterien[0].spannung;
Batterien[2].spannung -= Batterien[1].spannung;
aval = analogRead(AnalogBatPin4);
Batterien[3].spannung =
(float)aval *4.0F * zaehl[3] / nenner[3] / 1000.0F + offset[3];
Batterien[3].spannung -= Batterien[0].spannung;
Batterien[3].spannung -= Batterien[1].spannung;
Batterien[3].spannung -= Batterien[2].spannung;
aval = analogRead(AnalogBatPin5);
Batterien[4].spannung =
(float)aval *5.0F * zaehl[4] / nenner[4] / 1000.0F + offset[4];
Batterien[4].spannung -= Batterien[0].spannung;
Batterien[4].spannung -= Batterien[1].spannung;
Batterien[4].spannung -= Batterien[2].spannung;
Batterien[4].spannung -= Batterien[3].spannung;
aval = analogRead(AnalogBatPin6);
Batterien[5].spannung =
(float)aval *6.0F * zaehl[5] / nenner[5] / 1000.0F + offset[5];
Batterien[5].spannung -= Batterien[0].spannung;
Batterien[5].spannung -= Batterien[1].spannung;
Batterien[5].spannung -= Batterien[2].spannung;
Batterien[5].spannung -= Batterien[3].spannung;
Batterien[5].spannung -= Batterien[4].spannung;
}
void AusgabeLCD(void)
{
char buffer1[40], buffer2[40];
char t1[10], t2[10], t3[10], t4[10], t5[10], t6[10];
strcpy(t1, “ „);
else
dtostrf(Batterien[0].spannung, 4, 2, t1);
if(Batterien[1].ausgetastet)
strcpy(t2, “ „);
else
dtostrf(Batterien[1].spannung, 4, 2, t2);
if(Batterien[2].ausgetastet)
strcpy(t3, “ „);
else
dtostrf(Batterien[2].spannung, 4, 2, t3);
sprintf(buffer1, „%s %s %s „, t1, t2, t3);
strcpy(t4, “ „);
else
dtostrf(Batterien[3].spannung, 4, 2, t4);
if(Batterien[4].ausgetastet)
strcpy(t5, “ „);
else
dtostrf(Batterien[4].spannung, 4, 2, t5);
if(Batterien[5].ausgetastet)
strcpy(t6, “ „);
else
dtostrf(Batterien[5].spannung, 4, 2, t6);
sprintf(buffer2, „%s %s %s „, t4, t5, t6);
lcd.print(buffer1);
lcd.setCursor(0, 1);
lcd.print(buffer2);
}
int LeseTaster(void)
{
int tasterGedrueckt; // und hier ist die Taste
static long int anfang; // hier merken wir uns, seit wann der Taster gedr�ckt ist
long int jetzt=millis(); // Millisekunden
long int drueckdauer; // so lange ist der Taster bereits gedr�ckt
bool gedrueckt;
static bool letztes_gedrueckt=0;
digitalWrite(LEDPin, gedrueckt); // visuelle R�ckmeldung
{
drueckdauer = jetzt-anfang;
if (drueckdauer > 1000)
tasterGedrueckt = LANG;
else
{
if (drueckdauer > 500)
tasterGedrueckt = KURZ;
else
tasterGedrueckt = NEIN;
}
if (letztes_gedrueckt == 0)
anfang = jetzt;
}
else
anfang = jetzt; // damit die Tasten-Dr�ck-Dauer kurz ist
// SERIAL_PRINT(“ „);
// SERIAL_PRINT(jetzt);
// SERIAL_PRINT(“ „);
// SERIAL_PRINTLN(tasterGedrueckt);
}
void PruefeBatterien(void)
{
int i;
int leereBatterie = -1;
if (Batterien[i].spannung < Batterien[i].abschaltspannung)
leereBatterie = i+1;
}
// SERIAL_PRINTLN(leereBatterie);
if (leereBatterie > Slot)
{
Pieps = true;
//SERIAL_PRINT(„Slot „);
//SERIAL_PRINTLN(Slot);
}
else
Pieps = false;
}
void StelleKontrast(void)
{
int kont, vcc;
static int kontrastwert=0; // der PWM-Stellwert für den Kontrast
kont = analogRead(AnalogKontrastPin);
SERIAL_PRINT(„Kin=“);
SERIAL_PRINT(kont);
SERIAL_PRINT(„VCC=“);
SERIAL_PRINTLN(vcc); // 1000bit = 5V
if (kontrastwert<0 br=""> kontrastwert = 0;
if (kontrastwert>255)
kontrastwert = 255;
SERIAL_PRINTLN(kontrastwert);
}
void loop()
{
long int jetzt;
int taste;
static long int jedeSekunde=0; // f�r den Timer jeder Sekunde
static long int jedeHalbeSekunde=0; // f�r den Timer jeder halben Sekunde
static long int jedeViertelSekunde=0; // f�r den Timer jeder viertel Sekunde
taste = LeseTaster();
PruefeBatterien();
{ // was hier steht, wird zyklisch jede Sekunde ausgef�hrt
MesseBatterien();
StelleKontrast();
jedeSekunde = jetzt;
}
{ // was hier steht, wird zyklisch jede halbe Sekunde ausgef�hrt
AusgabeLCD();
if (Slot>5)
Slot=0;
jedeHalbeSekunde = jetzt;
}
{ // was hier steht, wird zyklisch jede viertel Sekunde ausgef�hrt
static bool letzte; // nur maximal 1/4 Sek. piepsen
if (Pieps & !letzte)
{
letzte = true;
digitalWrite(SummerPin, HIGH);
}
else
{
letzte = false;
digitalWrite(SummerPin, LOW);
}
ViertelsekundenBlinkbit = ~ViertelsekundenBlinkbit;
jedeViertelSekunde = jetzt;
}
}0>6>6>