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
#include "log.h"
struct _Batterie
{
float spannung; // die gemessene Spannung
bool ausgetastet; // wird die Spannung gerade angezeigt, oder ausgetastet
float abschaltspannung; // darunter ist die Batterie leer
};
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // initialize the library with the numbers of the interface pins
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 NEIN 0 // Taste nicht gedr�ckt
#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;
for(i=0; i<6 br="" i=""> Batterien[i].abschaltspannung = 0.02F;
}
// -------------------------------
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 };
aval = analogRead(AnalogBatPin1);
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];
if(Batterien[0].ausgetastet)
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);
if(Batterien[3].ausgetastet)
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.setCursor(0, 0);
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;
gedrueckt = digitalRead(TasterPin);
digitalWrite(LEDPin, gedrueckt); // visuelle R�ckmeldung
if (gedrueckt)
{
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
letztes_gedrueckt = gedrueckt;
// SERIAL_PRINT(anfang);
// SERIAL_PRINT(" ");
// SERIAL_PRINT(jetzt);
// SERIAL_PRINT(" ");
// SERIAL_PRINTLN(tasterGedrueckt);
return tasterGedrueckt;
}
// -------------------------------
void PruefeBatterien(void)
{
int i;
int leereBatterie = -1;
for(i=0; i<6 br="" i=""> {
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);
vcc = analogRead(AnalogVCCPin);
SERIAL_PRINT("VCC=");
SERIAL_PRINTLN(vcc); // 1000bit = 5V
kontrastwert += ((800*(vcc/1000))-kont)/7;
if (kontrastwert<0 br=""> kontrastwert = 0;
if (kontrastwert>255)
kontrastwert = 255;
SERIAL_PRINT(" Kout=");
SERIAL_PRINTLN(kontrastwert);
analogWrite(KontrastPWM, 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
jetzt = millis();
taste = LeseTaster();
PruefeBatterien();
if ((jetzt-jedeSekunde) > 1000)
{ // was hier steht, wird zyklisch jede Sekunde ausgef�hrt
MesseBatterien();
StelleKontrast();
SekundenBlinkbit = ~SekundenBlinkbit;
jedeSekunde = jetzt;
}
if ((jetzt-jedeHalbeSekunde) > 500)
{ // was hier steht, wird zyklisch jede halbe Sekunde ausgef�hrt
AusgabeLCD();
Slot++;
if (Slot>5)
Slot=0;
SERIAL_PRINTLN(Slot);
HalbsekundenBlinkbit = ~HalbsekundenBlinkbit;
jedeHalbeSekunde = jetzt;
}
if ((jetzt-jedeViertelSekunde) > 250)
{ // 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>
Keine Kommentare:
Kommentar veröffentlichen