Liebes Forum!
Ich wäre für eure Hilfe sehr dankbar, eine einfache Schaltung für meine kleine Insel-Solaranlage (Solarpanel über Laderegler an Batterie ohne Anschluss an das Stromnetz im Haus) in meiner Garage zu verbessern. Vorweg: Ich bin Anfänger ohne Vorkenntnisse (siehe Nikname)!
Mein bisheriger Code funktioniert bereits mit der folgenden Logik:
Garagentor auf + es ist dunkel = Licht über Relais an.
Garagentor zu = Licht wieder aus
Garagentor auf = kleiner Wechselrichter über Relais an
Garagentor zu = Wechselrichter wieder aus
Alles auf einem Uno, demnächst aber zum Strom sparen auf einen Nano.
Hier der Code, dann meine Fragen:
int Lichtsensor= A0; // Variabel für den Lichtsensor an A0, Lichtsensor mit 1 K Pulldown an Ground und an A0 verbinden, 2. Bein an 5V
int lichtValue = 0; // Variabel für die Messung des Lichtsensor
int RelaisPin1 = 2; int RelaisPin2 = 3; // Variabeln für die Relais (Lichtschalter auf Pin 2, kleiner Wechselrichter auf Pin 3)
int triggerPin=8; int echoPin=7;// Variabel für den Trigger-Pin des Ultraschallsensors - an Pin7, Variabel für den Echo-Pim des Ultraschallsensors; an Pin6
long dauerValue=0; // Variabel für die Dauer, unter der die Zeit gespeichert wird, die eine Schallwelle bis zur Reflektion und zurück benötigt. Startwert ist hier 0.
long entfernungsValue=0; // Variabel für die Entfernung unter der die berechnete Entfernung gespeichert wird.
void setup() {
Serial.begin (9600); // startet serielle Verbindung
pinMode(triggerPin, OUTPUT);pinMode(echoPin, INPUT); // Trigger-Pin ist ein Ausgang,Echo-Pin ist ein Eingang
pinMode (RelaisPin1, OUTPUT); pinMode (RelaisPin2, OUTPUT);} // beide Relais werden auf Ausgang gesetzt
void loop() {
// Entfernungsmesser
digitalWrite(triggerPin, LOW); delay(5); //Hier nimmt man die Spannung für 5 Millisekunden vom Trigger-Pin, damit man später beim senden des Trigger-Signals ein rauschfreies Signal hat.
digitalWrite(triggerPin, HIGH); delay(10); //Jetzt sendet man eine Ultraschallwelle los. Dieser „Ton“ erklingt für 10 Millisekunden.
digitalWrite(triggerPin, LOW);//Dann wird der „Ton“ abgeschaltet.
dauerValue = pulseIn(echoPin, HIGH); //Mit dem Befehl „pulseIn“ zählt der Mikrokontroller die Zeit in Mikrosekunden, bis der Schall zum Ultraschallsensor zurückkehrt.
entfernungsValue = (dauerValue/2) * 0.03432; //Nun berechnet man die Entfernung in Zentimetern.
Serial.print ("Entfernung:"); Serial.print (entfernungsValue); // Serielle Ausgabe des Entfernungswertes
if (entfernungsValue >= 22 || entfernungsValue <= 0) {//Wenn die gemessene Entfernung über 500cm oder unter 0cm liegt,…
Serial.print (" kein Messwert");}
// Lichtsensor
lichtValue =analogRead(Lichtsensor); // ließt Wert des Lichtsensors aus
Serial.print(" Lichtsensorwert ="); Serial.print(lichtValue); // gibt Wert des Lichtsensors auf den seriellen Monitor aus
delay (311); // Wartezeit für den Sensor
// if-Schleife für Licht und Wechselrichter
if ((lichtValue <= 300) && (entfernungsValue <=20)&&(entfernungsValue >= 1)){ // Wenn Tor auf:
digitalWrite (RelaisPin1, HIGH);Serial.println (" Licht AN");} // Licht geht an
else {digitalWrite (RelaisPin1, LOW); Serial.println (" Licht AUS");} // wenn Tor (wieder) zu: List aus
if ((entfernungsValue <=20) && (entfernungsValue >=1)) { // Wenn Tor auf:
digitalWrite (RelaisPin2, HIGH);Serial.println (" Wechselrichter AN");} // Wechselricter an
else {digitalWrite (RelaisPin2, LOW); Serial.println (" Wechselrichter AUS");} // sonst Wechselrichter aus
}
Wie gesagt: Im Grunde läuft es, ich will aber Folgendes verbessern und weiß nicht recht wie.
Ein Delay-Befehl einbauen, der den Wechselrichter noch für 1-6 Stunden laufen lässt (zum ebike-laden), dann aber abschaltet (zu Schutz der Batterie). Soll ich hier mit einem Delay arbeiten? Wie vermeide ich, dass der Befehl dann die andere If-Schleife stört, wenn ich z.B. wieder rein gehe und Licht brauche.
Vielleicht wäre es auch schön, die Laufzeit des Delays mit einem Poti zu kombinieren im Sinne einer Zeitvorwahl (Poti kleiner Wert = 1 Std., Poti aufgedreht = 6 Std,)
Kann ich Befehlt einbauen, um den Arduino schlafen zu schicken, zum Strom zu sparen (Deepsleep, Verringerung Taktfrequenz), ohne die Funktionalität in der Zeit einzuschränken?
Oder habt ihr andere Ideen, um die Anforderung eleganter zu lösen. Insgesamt geht es mir in dem Projekt nur um´s lernen "am Model". Also bin ich sehr dankbar für Tipps, wenn es ganz andere Lösungswege gibt.
Dein Code ist - für meine Augen jedenfalls - recht ungewöhnlich formatiert. Normalerweise verzichte (nicht nur) ich darauf, mehrere Anweisungen in eine Zeile zu schreiben.
Alle Pin-Definitionen sind nicht variabel, sondern konstant. Statt 'int' besser ein 'const byte' verwenden (die Werte sind auch alle kleiner als 256).
Bei den digitalen Eingängen solltest Du prüfen, ob nicht INPUT_PULLUP die bessere Einstellung ist um einen definierten Pegel zu haben. Das liegt aber auch an dem, was da jeweils angeschlossen ist.
Ein Delay-Befehl einbauen, der den Wechselrichter noch für 1-6 Stunden laufen lässt (zum ebike-laden), dann aber abschaltet (zu Schutz der Batterie). Soll ich hier mit einem Delay arbeiten?
Nein, auf keinen Fall delay(). Such-Stichwort: BlinkWithoutDelay
Vielleicht wäre es auch schön, die Laufzeit des Delays mit einem Poti zu kombinieren im Sinne einer Zeitvorwahl (Poti kleiner Wert = 1 Std., Poti aufgedreht = 6 Std,)
Das sollte ohne Probleme möglich sein. Stichwort: Map-Funktion.
Kann ich Befehlt einbauen, um den Arduino schlafen zu schicken, zum Strom zu sparen (Deepsleep, Verringerung Taktfrequenz), ohne die Funktionalität in der Zeit einzuschränken?
Nein, mit der Nachbedingung geht das nicht. Entweder Funktion oder schlafen. Wenn ich schnarchend im Bette liege, kann ich auch nicht gleichzeitig Beiträge für das Forum verfassen
Und noch zum Schluß die obligatorische Anmerkung zur if-Schleife.
drück mal strg-t in der Arduino IDE damit die Eirnückungen passen
schreibe nicht so viele Anweisungen in eine Zeile. Zeilen kosten nichts. Eine Programmzeile - eine Codezeile dann wirds auch mit den Kommentaren besser
zu 3)
du hast ein Garagentor, du hast ein Ladegerät fürs eBike, da spielt imho der Verbrauch vom Arduino überhaupt keine Rolle in der 24h Bilanz. Auch der Nano ist kein Stromsparer. Deepsleep macht nur dann wirklich Sinn, wenn du dir deinen puren ATmega selber baust. Aber wenn du eh andere wirkliche Verbraucer hast, ist es imho gelinde gesagt WURST ob dein Controller 200mA, 10mA oder 50µA verbraucht..
Kann ich Befehlt einbauen, um den Arduino schlafen zu schicken, zum Strom zu sparen (Deepsleep, Verringerung Taktfrequenz), ohne die Funktionalität in der Zeit einzuschränken?
Da bist du weder mit dem UNO, noch mit dem Nano gut bedient.
Das sind beides keine Stromsparwunder.
Recht exakte Zeiten liefert dir ein Uhrenquarz an einem nackten ATMega328P.
Auch wenn sich dieser in einem der tiefen Schlafmodi befindet.
Jetzt habe ich (wiederhole: als Neuling und offenbar ausgesprochen talentlos) eine Woche rumprobiert und bin zu folgender Lösung gekommen:
//int Lichtsensor = A0; // Variabel für den Lichtsensor an A0, Lichtsensor mit 1 K Pulldown an Ground und an A0 verbinden, 2. Bein an 5V
//int lichtValue = 0; // Variabel für die Messung des Lichtsensor
const byte RelaisPin1 = 2;
const byte RelaisPin2 = 3; // Variabeln für die Relais (Lichtschalter auf Pin 2, kleiner Wechselrichter auf Pin 3)
const byte triggerPin = 8;
const byte echoPin = 7; // Variabel für den Trigger-Pin des Ultraschallsensors - an Pin7, Variabel für den Echo-Pim des Ultraschallsensors; an Pin6
long dauerValue = 0; // Variabel für die Dauer, unter der die Zeit gespeichert wird, die eine Schallwelle bis zur Reflektion und zurück benötigt. Startwert ist hier 0.
long entfernungsValue = 0; // Variabel für die Entfernung unter der die berechnete Entfernung gespeichert wird.
unsigned long TorOeffnung = 0;
byte Tor = 0;
void setup() {
Serial.begin (9600); // startet serielle Verbindung
pinMode(triggerPin, OUTPUT);
pinMode(echoPin, INPUT); // Trigger-Pin ist ein Ausgang,Echo-Pin ist ein Eingang
pinMode (RelaisPin1, OUTPUT);
pinMode (RelaisPin2, OUTPUT);
} // beide Relais werden auf Ausgang gesetzt
void loop() {
// Entfernungsmesser
digitalWrite(triggerPin, LOW);
delay(5); //Hier nimmt man die Spannung für 5 Millisekunden vom Trigger-Pin, damit man später beim senden des Trigger-Signals ein rauschfreies Signal hat.
digitalWrite(triggerPin, HIGH);
delay(10); //Jetzt sendet man eine Ultraschallwelle los. Dieser „Ton“ erklingt für 10 Millisekunden.
digitalWrite(triggerPin, LOW);//Dann wird der „Ton“ abgeschaltet.
dauerValue = pulseIn(echoPin, HIGH); //Mit dem Befehl „pulseIn“ zählt der Mikrokontroller die Zeit in Mikrosekunden, bis der Schall zum Ultraschallsensor zurückkehrt.
entfernungsValue = (dauerValue / 2) * 0.03432; //Nun berechnet man die Entfernung in Zentimetern.
Serial.print ("Entfernung:"); Serial.print (entfernungsValue); // Serielle Ausgabe des Entfernungswertes
if (entfernungsValue >= 2222 || entfernungsValue <= 0) {//Wenn die gemessene Entfernung über 500cm oder unter 0cm liegt,…
Serial.print (" kein Messwert");
}
// Lichtsensor
// lichtValue = analogRead(Lichtsensor); // ließt Wert des Lichtsensors aus
// Serial.print(" Lichtsensorwert ="); Serial.print(lichtValue); // gibt Wert des Lichtsensors auf den seriellen Monitor aus
delay (311); // Wartezeit für den Sensor
// if-Schleife für Licht und Wechselrichter
if (/*(lichtValue <= 300) &&`*/ (entfernungsValue <= 22) && (entfernungsValue >= 1)) { // Wenn Tor auf:
digitalWrite (RelaisPin1, HIGH);
Serial.println (" Licht AN");// Licht geht an
digitalWrite (RelaisPin2, HIGH);
Serial.println (" Wechselrichter AN");// Wechselrichter geht an
TorOeffnung = millis ();
}
else {
digitalWrite (RelaisPin1, LOW);
Serial.println (" Licht AUS");// wenn Tor (wieder) zu: Licht aus
}
if (millis () - TorOeffnung > 5000) { //Wenn das Tor mal auf war, aber jetzt wieder zu ist...
digitalWrite (RelaisPin2, LOW);
Serial.print (" Wechselricter wieder aus");
}
Serial.print ("___TorOeffnung");
Serial.print (TorOeffnung);
}
Ich hoffe, die Lösung ist einigermaßen elegant und funktional.
Als nächstes fuchs ich mich mal in die Maps-Funktionalität.
Bzgl. Stromsparen: Es ginge mir um das Prinzip, auch wenn ich nur mA spare.
Was wäre mit einer Reduktion der Taktfrequenz?
In dem Sinne: "CLKPR = 0x80;
CLKPR = 0x04;"?
Würde den Nano auch nur nutzen, weil ich ihn habe und mir dann eine kleine Platine löten will (löten kann ich übrigens auch nicht! - siehe Forumsname).
Naja, mal sehen...