liiontester/lipoTester.ino

301 lines
5.2 KiB
C++

#include <LiquidCrystal.h>
#define gatePin 8
#define highPin A5
#define lowPin A4
float mAh = 0.0;
float shuntRes = 5.3;
float voltRef = 4.89; // AREF Spannung
float current = 0.0;
float battVolt = 0.0;
float shuntVolt = 0.0;
float battLow = 2.9;
float battHigh = 4.3;
boolean cellOkay = false;
float sample1 = 0;
float sample2 = 0;
unsigned long previousMillis = 0;
unsigned long millisPassed = 0;
unsigned long started = 0;
unsigned long finished = 0;
unsigned long hour = 0;
unsigned long minute = 0;
unsigned long second = 0;
unsigned long time_target = 0;
char timeBuffer[11];
unsigned int delayTime = 0;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
byte batStat0[8] = {
0b01110,
0b10001,
0b10001,
0b10001,
0b10001,
0b10001,
0b10001,
0b11111
};
byte batStat2[8] = {
0b01110,
0b10001,
0b10001,
0b10001,
0b10001,
0b11111,
0b11111,
0b11111
};
byte batStat4[8] = {
0b01110,
0b10001,
0b10001,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111
};
byte batStat6[8] = {
0b01110,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111
};
byte batWrench[8] = {
0b01110,
0b11111,
0b10101,
0b10001,
0b11011,
0b11011,
0b11111,
0b11111
};
byte batWarning[8] = {
0b01110,
0b10001,
0b10001,
0b10001,
0b11011,
0b11111,
0b11011,
0b11111
};
byte chargeplug[8] = {
0b01010,
0b01010,
0b11111,
0b10001,
0b11111,
0b00100,
0b00100,
0b00011
};
void setup() {
Serial.begin(9600);
Serial.println("Starting...");
pinMode(gatePin, OUTPUT);
digitalWrite(gatePin, LOW);
lcd.begin(16, 2);
lcd.createChar(0, batStat0);
lcd.createChar(1, batStat2);
lcd.createChar(2, batStat4);
lcd.createChar(3, batStat6);
lcd.createChar(4, batWrench);
lcd.createChar(5, batWarning);
lcd.createChar(6, chargeplug);
lcd.setCursor(2, 0);
lcd.print("LiIon Tester");
lcd.setCursor(0, 1);
lcd.print("gurkengewuerz.de");
delay(2000);
lcd.setCursor(0, 1);
lcd.print("Bitte Warten ");
lcd.setCursor(12, 1);
delay(500);
lcd.write(".");
delay(500);
lcd.write(".");
delay(500);
lcd.write(".");
delay(1000);
lcd.clear();
}
void draw() {
lcd.setCursor(0, 0);
char str_battVolt[6];
dtostrf(battVolt, 3, 2, str_battVolt);
lcd.print(str_battVolt);
lcd.print("V ");
if (battVolt < 1 && !cellOkay) {
lcd.setCursor(15, 0);
lcd.write(byte(5));
lcd.setCursor(0, 1);
lcd.print(" KEINE BATTERIE ");
} else if (battVolt > battHigh && !cellOkay) {
lcd.setCursor(15, 0);
lcd.write(byte(6));
lcd.setCursor(0, 1);
lcd.print("MAXIMAL SPANNUNG");
} else if (battVolt < battLow && !cellOkay) {
lcd.setCursor(15, 0);
lcd.write(byte(0));
lcd.setCursor(0, 1);
lcd.print("GERINGE SPANNUNG");
} else {
char str_current[6];
dtostrf(current, 3, 2, str_current);
lcd.print(str_current);
lcd.print("A ");
// Hinweis geben, wenn Zelle leer ist
if (finished > 0)
lcd.write(byte(0));
else
lcd.write(byte(6));
lcd.setCursor(0, 1);
if (finished > 0)
time_target = finished;
else
time_target = (millis() / 1000) - started;
hour = time_target / 3600;
second = time_target % 3600;
minute = second / 60;
second %= 60;
if (hour < 10) {
lcd.print("0");
}
lcd.print(hour);
lcd.print(":");
if (minute < 10) {
lcd.print("0");
}
lcd.print(minute);
lcd.print(":");
if (second < 10) {
lcd.print("0");
}
lcd.print(second);
lcd.write(" ");
char str_mAh[6];
dtostrf(mAh, 4, 0, str_mAh);
lcd.print(str_mAh);
lcd.print("mAh");
}
}
void resetVals() {
mAh = 0.0;
current = 0.0;
battVolt = 0.0;
shuntVolt = 0.0;
cellOkay = false;
finished = 0;
started = 0;
sample1 = 0;
sample2 = 0;
previousMillis = 0;
millisPassed = 0;
}
void loop() {
for (int i = 0; i < 100; i++)
{
sample1 = sample1 + analogRead(highPin);
delay (2);
}
sample1 = sample1 / 100;
battVolt = 2 * sample1 * voltRef / 1024.0;
for (int i = 0; i < 100; i++)
{
sample2 = sample2 + analogRead(lowPin);
delay (2);
}
sample2 = sample2 / 100;
shuntVolt = 2 * sample2 * voltRef / 1024.0;
if ( battVolt > battHigh) {
digitalWrite(gatePin, LOW);
Serial.println("High Voltage");
delayTime = 1000;
} else if (battVolt < 1) {
digitalWrite(gatePin, LOW);
Serial.println("No Battery");
resetVals(); // Nur Resetten der Variabeln, wenn keine Batterie drin ist (sonst wird nach der Messung das Display geleert!)
delayTime = 1000;
} else if (battVolt < battLow) {
digitalWrite(gatePin, LOW);
Serial.println("Low Voltage");
if (cellOkay && finished == 0) {
finished = (millis() / 1000) - started;
}
delayTime = 1000;
} else if (finished == 0) {
digitalWrite(gatePin, HIGH);
if (!cellOkay) {
cellOkay = true;
started = millis() / 1000;
}
millisPassed = millis() - previousMillis;
current = (battVolt - shuntVolt) / shuntRes;
mAh = mAh + (current * 1000.0) * (millisPassed / 3600000.0);
previousMillis = millis();
Serial.print(battVolt);
Serial.print("\t");
Serial.print(current);
Serial.print("\t");
Serial.println(mAh);
delayTime = 4000;
}
draw();
delay(delayTime);
}