Hallo Arduino Gemeinde,
läst sich ein LiPo 5S mit einen UNO überwachen? - die einzelnen Zellen haben ja max 4,2V - mein Problem ist dass ich nur ein GND habe - eine Zelle ist kein problem - was mache ich mit den anderen ?
mfg
Alex
Hallo Arduino Gemeinde,
läst sich ein LiPo 5S mit einen UNO überwachen? - die einzelnen Zellen haben ja max 4,2V - mein Problem ist dass ich nur ein GND habe - eine Zelle ist kein problem - was mache ich mit den anderen ?
mfg
Alex
Hallo Alex,
Ich habe mir 2 Möglichkeiten ausgedacht.
Benutze 5 Analogeingänge und messe mit dem 1. die erste Zelle, mit dem 2. die erste und zweite, mit dem 3. die erste zweite und drite und so fort.
dann braucht man nur jeweil die Differenz zwische den Eingängen berechnen.
Frage ist ob die Genauigkeit bei den letzten Zellen reicht. 5*4,2/1024 ergibt ca. 20 mV für die letzte Zelle.
Soll eine Anregung sein
Karl
Hi Alex
Das Problem ist doch das dass bei Allen, außer der Ersten Zelle, die jeweiligen Spannungen nicht auf Masse bezogen sind .
Der Ardu die Spannungsmessung aber gegen Masse macht.
Wenn Du die einzelnen Zellen mittels eines Operationsverstärker misst und den Ausgang dann mit dem Eingängen des Arduinos misst.
Der OPV misst die Differenzspannung zwischen seinen zwei Eingängen und gibt diese Spannung ( wenn seine Verstärkung auf 1 eingestellt ist ) am Ausgang gegen Masse aus.
Es währe auch möglich die Spannung der ersten Zelle gegen Masse messen -> Zellenspannung Zelle 1
die Spannung der ersten und der zweiten Zelle gegen Masse messen und die
Spannung der ersten Zelle abziehen-> Zellenspannung Zelle 2
u.s.w.
Aber Achtung die Spannung am Eingang darf 5V nicht überschreiten also mit Spannungsteilern arbeiten.
Brauchst Du eigentlich die Spannung aller Zellen. Genügt es nicht die erste Zelle bzw des Akkus zu messen da diese ähnlich der anderen sein wird und so auf den Ladungszustand des Akkus schließen.
Bei Ladung macht das ja das Ladegerät und bei Etladung sollten alle Zelen gleichmäßig sich entladen. Ist das nicht der Fall ist der Akku sowieso defekt.
Grüße Uwe
Uwe genau dass interessiert mich - wie der Akku beim entladen beansprucht wir (ich möchte 60-100A Ziechen) dabei treten Schwankungen der einzelnen Zellen im Bereich von 0,15V und mehre auf.
da ich vor kurzen mit Arduino angefangen habe , bitte ich euch mir etwas zu helfen
das währe der Code für eine Zelle - Eingang 0 gegen Masse
const float referenceVolts = 5.0;
const int batteryPin = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
int val = analogRead(batteryPin);
float volts = (val / 1023.0) * referenceVolts;
Serial.println(volts);
}
mfg
Alex
hallo Alex,
ich habe dir mal einen sketch für einen lifepo4 4s2p drangehängt, müsstest deinen Bedürfnissen entsprechend abändern
der sketch ist aufgeteilt in 2 Teile
gruß ardubu
Teil1
/*
8+2 Kanal Spannungesmesser und Strommesser mit SD card Datenlogger
inkl. Kapazitätsberechnung mit Ausgabe auf LCD + SD
Alle Belegungen sind für den Mega 2560, sowie LCD 2004 mit I2C und SD Plus Shield
Dieser Sketch speichert die Daten von 10 analogen Eingängen auf der SD Karte und zeigt sie auf dem LCD an
Die Schaltung:
8 Spannungsteiler an den analogen Pins 8 bis 15
2 ACS 715 an den analogen Pins 2 + 3
Pinbelegung der RTC über I2C
Pinbelgung für die SD Karte:
MOSI - pin 50
MISO - pin 51
CLK - pin 52
CS - pin 53
Die Schaltung für das LCD:
Adresse 27 hex
LCD GND an GND
LCD VCC an 5V
LCD SCL an Pin 21
LCD SDA an Pin 22
Created 6. Juni 2012
geändert 9.März 2013
by B. K.
*/
#include <SD.h>
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h> // benutzt den library code:
LiquidCrystal_I2C lcd(0x27,20,4); // initialisiert die library mit der I2C Adresse 0x27
File datei; // test datei
//const uint8_t SD_CS = 53; // SD chip select
RTC_DS1307 RTC; // define the Real Time Clock object
//------------------------------------------------------------------------------
// call back for datei timestamps
void dateTime(uint16_t* date, uint16_t* time) {
DateTime now = RTC.now();
// return date using FAT_DATE macro to format fields
*date = FAT_DATE(now.year(), now.month(), now.day());
// return time using FAT_TIME macro to format fields
*time = FAT_TIME(now.hour(), now.minute(), now.second());
}
//------------------------------------------------------------------------------
const int chipSelect = 53;
const float mb =16.0; //Messbereich
const int tm = 1023.0; // Teiler Messbereich (10 Bit)
float (strom1)=0;
float (strom2)=0;
float C1=0;
float C2=0;
byte a=0;
byte b=0;
int c=0;
char d;// 8. Buchstabe des Dateinamens
char(dateiname)[13]="datalog0.csv";
//========================================================================================================================================================
void setup() {
Serial.begin(9600);
Wire.begin();
if (!RTC.begin()) {
Serial.println("RTC fehlt");
while(1); }
DateTime now = RTC.now();
lcd.init();
lcd.begin(20,4); // gibt die Zeichenanzahl und Zeilenzahl des LCD's vor:
lcd.backlight();
pinMode(chipSelect, OUTPUT); //CS
// setzt die date time callback function
SdFile::dateTimeCallback(dateTime);
if (!SD.begin(chipSelect)) { // prüft ob die SD Karte eingeschoben ist und initialisiert werden kann
Serial.println();
Serial.print("Karte Fehlt");
Serial.println();
lcd.print("Karte fehlt");
delay(2000);
lcd.clear();
return;}
while (SD.exists(dateiname)) {//püft ob der Datiename schon vergeben ist
c=c++;
if (c >9){Serial.println("Bereits 10 Dateien auf SD Karte");return;}
d= c+'0'; //Umwandlung von int in char
dateiname[7]=d; }
lcd.home();
lcd.print("Hallo ");
lcd.setCursor(0,1);
lcd.print("Messen und loggen");
lcd.setCursor(0,2);
lcd.print("Timestamp + RTC ");
lcd.setCursor(0,3);
lcd.print("U_8 I_2 C_2");
delay(3000);
File datei = SD.open(dateiname, FILE_WRITE);
datei.println();
datei.print(now.day()); datei.print("."); datei.print(now.month()); datei.print("."); datei.print(now.year()); Serial.print(" ");
datei.println();
datei.println("Zeit,U1,U2,U3,U4,U5,U6,U7,U8,I1,I2,C1,C2"); // schreibt eine Kopfzeile auf den seriellen Monitor
datei.close();
Serial.println();
Serial.print(now.day()); Serial.print("."); Serial.print(now.month()); Serial.print("."); Serial.print(now.year()); Serial.print(" ");
Serial.println();
Serial.println("Zeit,U1,U2,U3,U4,U5,U6,U7,U8,I1,I2,C1,C2"); // schreibt eine Kopfzeile auf den seriellen Monitor
}//setup ende
//===============================================================================================================================================================
Teil2
void loop()
{
DateTime now = RTC.now();
int (zeit10) = ((now.second())%10);
int (zeit5) = ((now.second())%5);
a=a++;
b=b++;
float korrFakt[8]= {(1.002725956),(0.998),(1.000068),(0.998),(1.00214),(0.99751),(0.998851),(0.996)}; //Korrekturfaktoren für die 8 Eingänge
float zw;
int mwdu1;
int mwdu2;
if (zeit10==0 && a==1)
{
datei = SD.open(dateiname, FILE_WRITE);
datei.print(now.hour()); datei.print(":");
if (now.minute()<10) {datei.print("0");}
datei.print(now.minute()); datei.print(":");
if (now.second()<10) {datei.print("0");}
datei.print(now.second());
datei.print(",");
Serial.print(now.hour()); Serial.print(":");
if (now.minute()<10) {Serial.print("0");}
Serial.print(now.minute()); Serial.print(":");
if (now.second()<10) {Serial.print("0");}
Serial.print(now.second());
Serial.print(",");
}
for (int analogPin = 8; analogPin < 15; analogPin+=2) {
mwdu1 = analogRead(analogPin); // liest die Eingänge 1, 3, 5, 7
mwdu2 = analogRead(analogPin+1);// liest die Eingänge 2, 4, 6, 8
mwdu1=map(mwdu1,10,1023,12,1023);
mwdu2=map(mwdu2,10,1023,12,1023);
if(mwdu1<=5) {mwdu1=0;}
if(mwdu2<=5) {mwdu2=0;}
float(U1) = (((mwdu1 *mb) / tm ) * korrFakt[analogPin-8]);//wandelt den digitalen Messwert in einen analogen, rechnet den Spannungsteiler und den Korrekturfaktor ein
float(U2) = (((mwdu2 *mb) / tm ) * korrFakt[analogPin-7]);
float u1 = U1;
// float u2 = U2;
if (analogPin == 10 || analogPin == 14) {
U1 = U1 - zw;}// zieht 3. und 7. Messwert den vorherigen ab, wenn eine Spannung anliegt
zw = U2; //Zwischenwert für das Abziehen
U2 = U2 - u1; //zieht vom Messwert den vorherigen ab
//Strommessung
int(mwIu1) = analogRead(2); //liest den 1. Stromeingang
int(mwIu2) = analogRead(3); //liest den 2. Stromeingang
float(Iu1) = (((mwIu1-101.0)*30.4)/750);
float(Iu2) = (((mwIu2-101.0)*30.4)/750);
//Ausgabe
if (zeit10==0 && a<=1) {
Serial.print (U1,5 ); //schreibt den Messwert 6 stellig auf den seriellen monitor
Serial.print (" ");
Serial.print (U2,5 ); //schreibt den Messwert 6 stellig auf den seriellen monitor
Serial.print (" ");
Serial.print (mwdu1 ) ;//schreibt den Messwert 6 stellig auf den seriellen monitor
Serial.print (" ");
Serial.print (mwdu2 ) ;//schreibt den Messwert 6 stellig auf den seriellen monitor
Serial.print (" ");
//Serial.print (zw); //schreibt den Messwert 6 stellig auf den seriellen monitor
//Serial.print (" ");
datei.print(U1);// schreibt den Messwert auf die SD Karte
datei.print (",");// schreibt hinter den Messwert ein Komma
datei.print(U2);
datei.print (",");
if (analogPin==14) {
Serial.print (Iu1,6);
Serial.print (",");
Serial.print (Iu2,6);
Serial.print (",");
Serial.print (mwIu1);
Serial.print (",");
Serial.print (mwIu2);
Serial.print (",");
Serial.print (C1);
Serial.print (",");
Serial.print (C2);
Serial.println();
datei.print(Iu1,1);
datei.print(",");
datei.print(Iu2,1);
datei.print(",");
datei.print(C1,1);
datei.print(",");
datei.print(C2,1);
datei.println();
}
}
// Ausgabe auf LCD
if (zeit10 == 0 && a<=1){
int(zeile);
if (analogPin==8){zeile=0;lcd.clear();}
if (analogPin==10){zeile=1;}
if (analogPin==12){zeile=2;}
if (analogPin==14){zeile=3;}
lcd.setCursor(0,zeile);
lcd.print("U") ;
lcd.print(analogPin-7);// zeigt welche Spannung angezeigt wird;
lcd.print("=");
lcd.print(U1); // zeigt den Messwert;
lcd.print("V ");// zeigt hinter dem Messwert V;
lcd.setCursor(10, zeile);
lcd.print("U") ;
lcd.print(analogPin-6); // zeigt welche Spannung angezeigt wird;
lcd.print("=");
lcd.print(U2); // zeigt den Messwert;
lcd.print("V ");// zeigt hinter dem Messwert V;
}
if (zeit10!=0){a=0;}
if ((zeit5==0) && (zeit10!=0) && (b<=1))
{
if (analogPin==14) {
//-------------------------------------------------------------------------------------
//Kapazitätsberechnung
strom1=strom1+Iu1;
strom2=strom2+Iu2;
C1=(strom1/360); // Berechnung der ge- oder entladenen Amperstunden.
C2=(strom2/360); // Berechnung der ge- oder entladenen Amperstunden.
//--------------------------------------------------------------------------------------
//LCD Ausgabe 2.Seite
lcd.clear(); // löscht das LCD
lcd.print("I1=");
lcd.print(Iu1,1);
lcd.print("A");
lcd.setCursor(10, 0);
lcd.print("I2=");
lcd.print(Iu2,1);
lcd.print("A");
lcd.setCursor(0,1);
lcd.print("C1=");
lcd.print(C1,1);
lcd.print("Ah");
lcd.setCursor(10,1);
lcd.print("C2=");
lcd.print(C2,1);
lcd.print("Ah");
lcd.setCursor(0,3);
lcd.print(now.day());lcd.print(".");lcd.print(now.month());lcd.print(".");lcd.print(now.year());
lcd.setCursor(13,3);
lcd.print(now.hour());lcd.print(":");
if (now.minute() < 10){lcd.print("0");}
lcd.print(now.minute());
}
}
if (zeit5 !=0){b=0;}
}
datei.close();
}//ende loop