Go Down

Topic: mehrere Relais schalten (Read 1 time) previous topic - next topic

herbk

Nov 06, 2018, 09:49 am Last Edit: Nov 06, 2018, 09:57 am by herbk
Hallo,
ich habe mal wieder Probleme mit einem Sketch, der nicht das macht was ich möchte...

Folgende Situation: Ich habe ein paar LTO Akkus (Enzellzellen) mit welchen ich ein paar Versuche bezüglich der Kapazität usw machen möchte.
Da es keine fertige Schaltung gibt die so flexibel ist wie ich es gerne möchte, wollte ich das mit einem Arduino und dem passenden Sketch machen.

Der Sketch soll eigentlich nichts anderes machen, als bei jeder Zelle die Spannung messen und, so fern die jeweilige Spannung erreicht ist ein Relais schalten.

Die Verwendete Hartware sind ein Nano (Clone) und eine 8er Relaiskarte. Die Stromversorgung des Arduino erfolgt über eine Festspannungsregelung, die Referenzspannung ist also OK.

Im Versuchsaufbau wird jede Zelle für sich (aus einer eigenen Stromquelle) geladen, es soll deshalb auch jede Zelle für sich geschaltet werden. Um die Tiefentladung einer Zelle zu vermeiden, soll beim erreichen der Minimalspannung die komplette Last von der Batterie genommen werden.

Hier der Sketch mit dem ich das erreichen möchte:


Code: [Select]

/*
Experimentelle Laderegelung für "12V" LTO Akkus.
Die Regelung misst jede Zelle einzeln und schaltet den Ladestrom bei Erreichen der Ladeschlussspannung ab.
Es wird jede Zelle separat geladen, weshalb auch die Zellenspannung separat gemessen und der Ladestrom
für jede Zelle separat geschalten wird.


*/

const byte voltin1 = A1; // input Pin für Spannung Zelle 1
const byte voltin2 = A2; // input Pin für Spannung Zelle 2
const byte voltin3 = A3; // input Pin für Spannung Zelle 3
const byte voltin4 = A4; // input Pin für Spannung Zelle 4
const byte voltin5 = A5; // input Pin für Spannung Zelle 5
const byte voltin6 = A6; // input Pin für Spannung Zelle 6

//const byte voltinall = A7; // input Pin für Spannung ganze Batterie

const int lssp = 512; // digitalwert für Ladeschlussspannung
const int lwasp = 480; // digitalwert für wiederaufnahme des Ladevorgangs
const int cutoffsp = 390; // digitalwert für Unterspannungs Abschaltung

int voltzelle1 = 400; // Startwerte setzen
int voltzelle2 = 400;
int voltzelle3 = 400;
int voltzelle4 = 400;
int voltzelle5 = 400;
int voltzelle6 = 400;




void setup() {
  digitalWrite(2, HIGH);
  pinMode(2, OUTPUT);
  digitalWrite(3, HIGH);  
  pinMode(3, OUTPUT);
  digitalWrite(4, HIGH);
  pinMode(4, OUTPUT);
  digitalWrite(5, HIGH);
  pinMode(5, OUTPUT);
  digitalWrite(6, HIGH);
  pinMode(6, OUTPUT);
  digitalWrite(7, HIGH);
  pinMode(7, OUTPUT);

  digitalWrite(10, HIGH);
  pinMode(10, OUTPUT);

  
}



void loop() {

voltzelle1 = analogRead(voltin1); //Spannungs an A 1 auslesen

if (voltzelle1 >= lssp) digitalWrite(2, HIGH); //Schaltet bei Ladeschlussspannung den Ladestrom ab
if (voltzelle1 <= lwasp) digitalWrite(2, LOW); //Schaltet bei Wiederaufnahmespannung den Ladestrom an.
if (voltzelle1 >= cutoffsp) digitalWrite(10, HIGH); //Nimmt bei Unterspannung einer Zelle die Last von der Batterie.

voltzelle2 = analogRead(voltin2); //Spannungs an A 2 auslesen

if (voltzelle2 >= lssp) digitalWrite(3, HIGH); //Schaltet bei Ladeschlussspannung den Ladestrom ab
if (voltzelle2 <= lwasp) digitalWrite(3, LOW); //Schaltet bei Wiederaufnahmespannung den Ladestrom an.
if (voltzelle2 >= cutoffsp) digitalWrite(10, HIGH); //Nimmt bei Unterspannung einer Zelle die Last von der Batterie.

voltzelle3 = analogRead(voltin3); //Spannungs an A 3 auslesen

if (voltzelle3 >= lssp) digitalWrite(4, HIGH); //Schaltet bei Ladeschlussspannung den Ladestrom ab
if (voltzelle3 <= lwasp) digitalWrite(4, LOW); //Schaltet bei Wiederaufnahmespannung den Ladestrom an.
if (voltzelle3 >= cutoffsp) digitalWrite(10, HIGH); //Nimmt bei Unterspannung einer Zelle die Last von der Batterie.

voltzelle4 = analogRead(voltin4); //Spannungs an A 4 auslesen

if (voltzelle4 >= lssp) digitalWrite(5, HIGH); //Schaltet bei Ladeschlussspannung den Ladestrom ab
if (voltzelle4 <= lwasp) digitalWrite(5, LOW); //Schaltet bei Wiederaufnahmespannung den Ladestrom an.
if (voltzelle4 >= cutoffsp) digitalWrite(10, HIGH); //Nimmt bei Unterspannung einer Zelle die Last von der Batterie.

voltzelle5 = analogRead(voltin5); //Spannungs an A 5 auslesen

if (voltzelle5 >= lssp) digitalWrite(6, HIGH); //Schaltet bei Ladeschlussspannung den Ladestrom ab
if (voltzelle5 <= lwasp) digitalWrite(6, LOW); //Schaltet bei Wiederaufnahmespannung den Ladestrom an.
if (voltzelle5 >= cutoffsp) digitalWrite(10, HIGH); //Nimmt bei Unterspannung einer Zelle die Last von der Batterie.

voltzelle6 = analogRead(voltin6); //Spannungs an A 6 auslesen

if (voltzelle6 >= lssp) digitalWrite(7, HIGH); //Schaltet bei Ladeschlussspannung den Ladestrom ab
if (voltzelle6 <= lwasp) digitalWrite(7, LOW); //Schaltet bei Wiederaufnahmespannung den Ladestrom an.
if (voltzelle6 >= cutoffsp) digitalWrite(10, HIGH); //Nimmt bei Unterspannung einer Zelle die Last von der Batterie.

}



Das Messen an sich scheint zu funktionieren, denn die Relaiskarte reagiert auf entsprechende Spannungsänderungen.
Allerdings wirden die Relais nicht einzeln geschaltet, sondern immer "on block".
D.h. wenn ich die Spannung an einem Eingang ändere ziehen die Ralais 1-6 gemeinsm an (oder fallen gemeinsam ab). Relais 8 (welches am A10 hängt) reagiert dagegen überhaupt nicht.

Ich bin recht überzeugt davon, dass meine "if Abfrage" und die daraus resultierenden Befehle nicht richtig sind... aber was falsch ist kann ich nicht erkennen...


michael_x

Quote
was falsch ist kann ich nicht erkennen...
Ich auch nicht.

Verdrahtungsproblem? Zieh mal die Relaiskarte ab und schau dir die Ausgangspins direkt am Nano an.
Oder mach einen Test-Sketch, der definitiv einen Pin nach dem anderen schaltet.

agmue

#2
Nov 06, 2018, 10:58 am Last Edit: Nov 06, 2018, 10:59 am by agmue
Ich kann nirgendwo ein digitalWrite(10, LOW); entdecken.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

michael_x

Das erklärt aber nur einen Teil des Problems
Quote
Relais 8 (welches am A10 hängt) reagiert dagegen überhaupt nicht.
Bleibt die Frage, warum die anderen Relais gemeinsam reagieren...

Rentner

Hallo,

Ich denke diejeweils 3. If Abfrage ist falsch , da ist immer pin 10 angegeben ? sollte abe sicher jeweils 2, 3, 4 usw sein


Code: [Select]
voltzelle1 = analogRead(voltin1); //Spannungs an A 1 auslesen

if (voltzelle1 >= lssp) digitalWrite(2, HIGH); //Schaltet bei Ladeschlussspannung den Ladestrom ab
if (voltzelle1 <= lwasp) digitalWrite(2, LOW); //Schaltet bei Wiederaufnahmespannung den Ladestrom an.
if (voltzelle1 >= cutoffsp) digitalWrite(10, HIGH); //Nimmt bei Unterspannung einer Zelle die Last von der Batterie.







Heinz

michael_x

Die Relais sind wohl LOW aktiv
Ich verstehe das so, dass Pin 10 eine Art Not-Aus darstellen soll, wenn Zellen nicht geladen werden und bei einer der Zellen Tiefentladung droht.

Rücksetzen ist zur Zeit nur mit Reset vorgesehen.

in setup() würde dazu passen
Code: [Select]
  digitalWrite(10, LOW);  // Verbraucher aktiv
  pinMode(10, OUTPUT);


Die anderen beiden if je Analog-Kanal schalten dann mit Hysterese zwischen lssp und lwasp

Sind die Spannungen der Zellen denn überhaupt unterschiedlich, oder sind diese über den Verbraucher parallel geschaltet und alle Analog-Eingänge messen das gleiche?


herbk

Hi und Danke für die schnellen Antworten.

Wenn ich die Relaiskarte abziehe und an den Pins direkt messe habe ich genau das Gleiche. So bald ich einen zu messenden Akku anschließe wechseln die Ausgänge 2 - 7 den Status.

jep, im Setup müsste das LOW heissen...

In der 3 if Abfrage soll schon jeweils das gleiche Relais angesteuert werden.
Pin 10 steuert (soll) ein Relais steuern das den 12V Kreis abstellt, - egal welch Zelle zu wenig Spannung hat. Die Messungen über die Analogeingänge sind aber jeweils an einer einzelnen Zelle.
Wegen der gemeinsamen GND Verbindung (die zum Akku aber mt Diode gesperrt ist) habe ich auch mit nur einen Akku probiert, - genau das Gleiche...

Edit nach Michals 2. Post
ja genau so stelle ich mir das vor.
Die Zellen sind aber nicht parallel sindern in Reihe gescchalten damit ein 12V Block daraus wird.
Hauptziel ist es festzustellen wie viel die einzelnen Zellen von einander Abweichen.

agmue

Die Zellen sind aber nicht parallel sindern in Reihe gescchalten ...
Und dann mißt Du mit dem Arduino gegen GND? Das kann ich mir gerade nicht vorstellen, da wäre ein Schaltbild (Bleistift und Papier genügt) für mich notwendig.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

Katsumi_S

Alle Zellen sind in Reihe geschaltet. Also misst der A1 die 1. Zelle, A2 die 1. und 2. Zelle, A3 die 1., 2. und 3. Zelle oder wie?

Gibt es eventuell einen Schaltplan?


Gruß, Jürgen

michael_x

Quote
Also misst der A1 die 1. Zelle, A2 die 1. und 2. Zelle, A3 die 1., 2. und 3. Zelle oder wie?
Der Arduino ADC misst in jedem Fall eine Spannung relativ zu Arduino-GND.
Alle analogRead-Kanäle brauchen einen gemeinsamen GND.
Mehr als Vcc kann man nicht direkt messen.


qualidat

Ich nenne solche Programme immer "Bandwurm-Codes".

Mach' doch bitte eigene Funktionen mit "sprechenden Namen". Beginne mit Low-Level (z.B. 1 Rel an/aus) und erhöhe durch Zusammenfassen der getesteten (!) Trivial-Funktionen den Abstraktionsgrad stufenweise.

Im Hauptprogramm - respektive "Loop" stehen dann nur noch einige wenige Aufrufe wie "Messen", "Anzeigen" und "Schalten" usw...

Auch Mikrocontroller sind leistungsfähig genug für einen solchen modularen Programmierstil und du guckst, wenn du in einen Jahr den Code nochmal ändern musst, nicht wie ein "Schwein ins Uhrwerk" :-)

Rentner

#11
Nov 06, 2018, 04:21 pm Last Edit: Nov 06, 2018, 04:23 pm by Rentner
Hallo.

Jetzt hab ich's auch begriffen was der eine Ausgang machen soll :-)

Jetzt kannst du noch vor jeden Analogeingang einen Spannungsteiler bauen 1:3 sagen wir mal und Dan die gemessen Spannung voneinander abziehen . Dann ist alles auf Ground bezogen und durch 3 geteilt. Damit ist dann die größte gemessen Spannung bei 12 V am Akku  4Vam Analogeingang, ob dann die Auflösung noch reicht  musst du selbst entscheiden .



Also
U1= Messwert 1
U2 = Messwert 2 - Messwert 1
U3= Messwert 3- Messwert  2

Usw


PS mit dem Handy ist das Mist  :)


michael_x

Quote
Auch Mikrocontroller sind leistungsfähig genug für einen solchen modularen Programmierstil
Ich denke, das wäre sogar ressourcenschonender und damit gerade für einen kleinen µC einfacher.

Andererseits habe ich bewundert, wie ordentlich herbk nach dem c&p alle Variablennamen, Konstanten und sogar Kommentare editiert hat. Das wäre  ja alles umsonst gewesen :(  :P

herbk

#13
Nov 06, 2018, 07:35 pm Last Edit: Nov 06, 2018, 07:39 pm by herbk
@qualidat  ja, das wäre schöner...  aber so verstehe ich wenigstens halbwegs was ich da schreibe...
Platzmangel ist auf dem Nano aber noch keiner.

So ist die Schaltung aufgebaut, ohne Ladeanschlüsse, sind auch noch nicht dran im Moment


postmaster-ino

Hi

Wie schon geschrieben wurde, kann der Arduino nur bis Vdd messen - oberhalb dürften diverse Schutz-Dioden bei dem Versuch sterben, die höhere Spannung nach Vdd abzuleiten.

Selbst, wenn jede Deiner Zellen nur 1,0V voll geladen bringt, bist Du bei Zelle 6 bei 6.0V - ungefähr 1V mehr, als der Arduino 'ab kann'.

Dürfte auch erklären, warum 'Alles am Stück' schaltet - Dein Messpunkt für Zelle 2 sieht die Spannung Zelle 1 + Zelle 2 und ist damit WEIT oberhalb des erlaubten Bereich.

Zelle 3 braucht gar keine eigene Spannung, auch hier bist Du 'so oder so' weit außerhalb - Relais schaltet auch.
... für alle Weiteren.

Du könntest die tatsächliche Spannung runter teilen, musst dann aber mit den berechneten Teil-Spannungen das Minus-Potential der höheren Zellen bestimmen - denke, Da kommen nur Hausnummern bei rum.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Go Up