Funduino Nano R3 Sleep Mode für stromsparenden Relaisbetrieb

Hallo ins Forum,

zunächst: ich bin neu in der Arduino-Welt, habe ein paar kleinere Gehversuche mit Funduino gemacht und versuche mich jetzt an einem etwas kleineren Anwendungsprojekt.

Ich steuere bereits mit einer 12V-Quelle einen Futterautomaten per sms. Dazu dient derzeit ein GSM-Relais und eine Batterie (9.000mAh). Mit einem zusätzlichen kleinen Relais kann ich derzeit den Stromverbrauch zwar bereits deutlich reduzieren, die Batterie muss dennoch alle 7-10 Tage geladen/getauscht werden. Dies möchte ich mit einem Microcontroller (Nano R3) und einfachem Relais so verändern, dass die Batterie möglichst lange hält. Nano R3 und Relais sind bereits vorhanden. Dies möchte ich per sleep mode umsetzen. Das GSM-Relais für den Futterautomaten soll einmal täglich kurz (15-20min) hochfahren und bei Empfang einer sms den Automaten in der im GSM-Relais eingestellten Zeit starten.

Ich habe dazu im Forum bereits z.B. hier oder hier ähnliche Projekte gefunden, aus denen ich für mich den folgenden code zusammengestellt habe:

#include <avr/wdt.h> //watchdog timer library
#include <util/atomic.h> //atomic library
// Set variables, VCC as 5V continuous output and RELAIS as switch
constexpr unsigned int VCC=3;
constexpr unsigned int RELAIS=4;
constexpr unsigned int WAKEUP_TIME {1 * 10 * 1000}; // Be awake for 10s (960s equals e16min)
constexpr unsigned int WDT_CYCLE {4 * 1};  // Sleep for 4 * 8 = 32s (10680 * 8 = 85.440s equals 23h 44min)
constexpr unsigned int BREAK_TIME=500;
// Watchdog Interrupt Service Routine (ISR)
ISR(WDT_vect) {
  // Nothing to do here, just wake up!
}
void enableWatchdog() {
  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
    MCUSR &= ~_BV(WDRF);              // clear the reset flag
    WDTCSR |= _BV(WDCE) | _BV(WDE);   // set WDCE to be able to change/set WDE
    // WDTCSR = _BV(WDP1) | _BV(WDP2);             // Set timer to 1 sec
    // WDTCSR = _BV(WDP0) | _BV(WDP1) | _BV(WDP2); // Set timer to 2 sec
    // WDTCSR = _BV(WDP3);                         // Set timer to 4 sec
    WDTCSR = _BV(WDP0) | _BV(WDP3);   // Set timer to 8sec (max).
    WDTCSR |= (1 << WDIE);            // enable the WD interrupt to get an interrupt instead of a reset
  }
}
// function to go to sleep
void enterSleep(void) {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();   // Now enter sleep mode.
  // The program will continue from here after the WDT timeout
  sleep_disable();   // First thing to do is disable sleep.
}
// Setup PINs and enable WatchDog
void setup() {
//Save Power by writing all Digital IO LOW
for(int i=0; i<20; i++) {
  pinMode(i, OUTPUT);
}
enableWatchdog();
}
// Work loop
void loop() {
digitalWrite(VCC, HIGH);
digitalWrite(RELAIS, HIGH);
delay(WAKEUP_TIME); // keep the relais pulled
digitalWrite(RELAIS, LOW);
delay(BREAK_TIME); // short break
digitalWrite(VCC, LOW);
Serial.println("Goto Sleep");
for (int i=0; i<WDT_CYCLE; i++) { 
  enterSleep(); 
}
Serial.println("Waked up");
//println(WDT_CYCLE);
// Controller is awake
}

Mein Ziel ist es, das GSM-Relais einmal am Tage für etwa 16 Minuten laufen zu lassen um zu prüfen, ob eine SMS eingegangen ist und für diesen Fall den Futterautomaten für die in diesem Relais eingestellte Zeit laufen zu lassen. Alternativ geht das ganze nach den 16 Minuten wieder 23h und 44min in den Sleep Modus.

Ich habe den code soweit auf den Nano R3 aufspielen können, das Relais geht im Testmodus auch für etwa 31s aus und dann für 10s wieder an. Habe derzeit leider noch kein Multimeter, um den realen Stromverbrauch zu messen (ist noch auf dem Postweg :wink:).

Ich würde mich freuen, wenn jemand einen Blick über den code werfen könnte (habe ich das so grundsätzlich zweckmäßig bzw. richtig verstanden/umgesetzt?). Ich nehme natürlich auch gern Hinweise zu meinem gesamten Ansatz.

Vielen Dank vorab!
Andreas

Ihr habt im englischsprachigen Bereich des Forums gepostet. Bitte schreibt auf Englisch oder postet im deutschen Bereich des Forums.

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden.
Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

Ein Nano R3 im Sleep Mode ist eine schlechte Kombination, da das Board weitere Bauteile drauf hat, die nicht in den Sleep Modus gehen.
Nimm dazu besser einen ATmega328P-AU und ein eigenes Board auf Lochraster oder einen Arduino Pro mini.
Da wird dann kein weiterer Strom verbraucht. Eine evtl. vorhanden Led kannst du auslöten.

in so einem Fall würde ich einfach eine 12V Schaltuhr jeden Tag 16 Minuten einschalten und damit das Komplette System ein/ausschalten.

Hallo, danke!

Es müsste 12V vertragen, daher hatte ich von dem Mini Abstand genommen. Aber das teste ich dann mal mit einer extra Batterie.

Danke, da habe ich bisher keine wirklich stromsparende Variante (<10 mAh im idle) gefunden, daher der Versuch, dass über ein Arduino-Projekt zu realisieren.

Für Stromsparanwendungen verwende ich meist nackte m328p mit Uhren Quarz.
Die laufen mehrere Monate an einer CR2032 Zelle.
Viele Jahre an 2*AAA

Der Regler auf dem Pro Mini kann doch 12V, oder?

there is a voltage regulator on board so it can accept voltage up to 12VDC.

Aus: https://docs.arduino.cc/retired/boards/arduino-pro-mini/

Naja bei derartigen Projekten muss man halt flexibel sein und sich passende Hardware aussuchen, die auch den Anforderungen entsprechen. Und der Nano passt da nunmal nicht.
Passende Vorschläge hast du ja erhalten.

Der Nano ist halt eh schon da, wenn man den unter 10mAh bekäme, würde ich nicht extra was neues kaufen.

Danke für den Hinweis, das hatte ich nicht gesehen. Das werde ich probieren, sollte ich den Nano nicht weit genug herunter bekommen. Danke!

Gutes Argument. :sweat_smile:

Danke, das probiere ich mal aus!

Das mit dem ATmega probiere ich ebenfalls, danke für den Hinweis!

@andi_011

Welche Module hat du?
Welche Betriebszustände haben diese Module?
Wie viel Strom wird in einem Betriebszustand verbraucht?
Wie viel Zeit braucht ein Betriebszustand?

Sehr ich das richtig dass du per SMS die Schaltzeiten ändern kannst? Wie kommt dieser Änderung von GSM-Relais zum Arduino?

Übergeordnetes Ziel ist es, eine ferngesteuerte Möglichkeit der Auslösung eines Futterautomaten möglichst stromsparend umzusetzen. Der Automat selbst wird dabei mit einer 12V-Batterie (ähnlich einer Motorradbatterie) betrieben. Der Automat selbst soll möglichst lange ohne Ladung der Batterie betrieben werden. Vorhanden und betrieben wird er mit einem GSM-Modul, dass per SMS die Fernsteuerung auslöst. Der Automat selbst soll lediglich einmal täglich kurze Zeit (wenige Minuten) prüfen, ob eine sms zur Auslösung vorliegt und dann zur etwa gleichen Tageszeit auslösen. Das Ganze funktioniert auch soweit, in Ruhe verbraucht dieses Modul allerdings so viel, dass die Batterie insbesondere in kalter Jahreszeit nur etwa eine Woche durchhält.

Ergo möchte ich mit einem kleinen Stromsparmodul ein Relais schalten, dass den Stromkreis für das GSM-Modul und den Automaten unterbricht und täglich nur wenige Minuten schließt. Dazu habe ich mich jetzt - wie angeraten - eines Pro Mini bedient und diesen nun über eine zweite, separate Stromquelle (5V) betrieben. Die 12V der Batterie (voll vml mehr als das) waren auf jeden Fall zu viel für einen nano und pro mini (raw pin).

Den Pro Mini habe ich per WatchDogTimer nun die meiste Zeit schlafen gelegt und nur für 8min täglich zur Schliesung des Relais “oben”. Wermutstropfen dabei: der WDT ist gemessen etwa 10% “off”, es bedurfte einiger Testungen, um die Anzahl an Zyklen für die verbleibenden 23h 52min täglich zu ermitteln. Im u.a. code ist das soweit gelungen. Derzeit macht der Pro Mini bzw. das Modul was er/es soll.

#include <avr/sleep.h>    //sleep modus library
#include <avr/wdt.h> //watchdog timer library
#include <util/atomic.h> //atomic library
// Set variables, VCC as 5V continuous output and RELAIS as switch
constexpr unsigned int VCC=3;
constexpr unsigned int RELAIS=4;
constexpr unsigned long int WAKEUP_TIME=480000; // Miliseconds. Change here to adjust awake time (testing: 10s) (4800/9600s equal 8/16min)
constexpr unsigned long int WDT_CYCLE=10286;  // Change here to adjust sleep time, watchdog timer works according to enableWatchdog() 
// (10680/11160 * 8 = 85.440/89.280s equals 23h+44/52min)--> final test results show WDT is off factor +1,06x -> set to 10286 for about 23hrs+52min.
constexpr unsigned int BREAK_TIME=500;
// Watchdog Interrupt Service Routine (ISR)
ISR(WDT_vect) {
  // Nothing to do here, just wake up!
}
void enableWatchdog() {
  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
    MCUSR &= ~_BV(WDRF);              // clear the reset flag
    WDTCSR |= _BV(WDCE) | _BV(WDE);   // set WDCE to be able to change/set WDE
    // WDTCSR = _BV(WDP1) | _BV(WDP2);             // Set timer to 1 sec
    // WDTCSR = _BV(WDP0) | _BV(WDP1) | _BV(WDP2); // Set timer to 2 sec
    // WDTCSR = _BV(WDP3);                         // Set timer to 4 sec
    WDTCSR = _BV(WDP0) | _BV(WDP3);   // Set timer to 8sec (max).
    WDTCSR |= (1 << WDIE);            // enable the WD interrupt to get an interrupt instead of a reset
  }
}
// function to go to sleep
void enterSleep(void) {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();   // Now enter sleep mode.
  // The program will continue from here after the WDT timeout
  sleep_disable();   // First thing to do is disable sleep.
}
// Setup PINs and enable WatchDog
void setup() {
//Save Power by writing all Digital IO LOW
for(int i=0; i<20; i++) {
  pinMode(i, OUTPUT);
}
enableWatchdog();
}
// Work loop routine, adjust to change daily routine
void loop() {
digitalWrite(VCC, HIGH); // power relais
delay(BREAK_TIME); // short break
digitalWrite(RELAIS, HIGH); // pull relais
delay(WAKEUP_TIME); // keep the relais pulled
digitalWrite(RELAIS, LOW); // release relais
delay(BREAK_TIME); // short break
digitalWrite(VCC, LOW);
Serial.println("Goto Sleep");
for (int i=0; i<WDT_CYCLE; i++) { 
  enterSleep(); 
}
Serial.println("Waked up");
//println(WDT_CYCLE);
// Controller is awake
}

a) Kapazität der Stromquellen
Als Stromquellen dienen eine 12V Batterie mit 9.000 mAh und eine 5V Powerbank mit (nominell) 12.000 mAh Kapazität. Für die Batterie werden 10%, für die Powerbank 30% Kapazitätsverluste angenommen. Ferner sollen beide Quellen je Ladezyklus 20% Restenergie aufweisen. Es ergeben sich folgender nutzbarer Strom:

  • 12V-Quelle: 9.000 * 0,90 * 0,8 = 6.480mAh
  • 5V-Quelle: 12.000 * 0,70 * 0,8 = 6.720mAh
    b) Verbrauchsmesswerte
  • 5V Pro Mini: 0.133h (8min) unter Last= 62.5mAh; (23.8667h) Ruhe = 3 mAh: 79.933 mAh, ˜80 mAh/d -> 6.720mAh/80mAh/d = 84d.
  • 12V: GSM-Relais 8min Last = 18-20mAh zzgl. Motor 1s Last = >600mAh, vmtl ~1Ah
     2,533 mAh/d zzgl. 0,278 -> 2,81 mAh/d -> 6480mAh/2,81mAh/d = 2306d.

Damit wäre ein Wechsel der 5V-SV nach etwa zweieinhalb bis drei Monaten notwendig.

Offen bleibt für mich die Frage, ob der WDT durch Kälte beeinflusst wird. Versuche für mehr Genauigkeit derzeit den Interrupt zum Wecken über ein PCF8653 RTC zu realisieren. Zudem bleibt für mich offen zu testen, ob ggf. über ein Step-Down-Modul auf die zweite SV verzichtet werden könnte.

Dank und Grüße!
Andreas

Ja, der ist aber auch alles andere als Stromsparend.
ein LM1117, wie oft verwendet braucht selbst 5 bis 10mA,

Wenn man Stromsparend bauen will muß man jede elektronische Komponente einzeln , manchmal auch miteinander betrachten und oft nicht die üblichen Verdächtigen nehmen sondern bedacht gewählte Teile nehmen.

Ist da nicht eine Lademöglichkeit der Batterie zielführender? zB Solarzellen. Als Stromsparmodi ausreizen.

Bezüglich SMS Zustellung mußt Du schauen, ob der Provider wirklich so schnell unversannte SMS zustellt, sobald das Telefon wieder online ist, oder es wie meiner Macht daß ich nach etlichen Stunden SMS bekomme die nicht zustellbar waren.

Grüße Uwe

Das mit der SMS passt gut, bis zu 24h werden diese auch nachträglich zugestellt. Das klappte bisher immer - das Modul (einfacher GSM Gate opener) liefert (bei Bedarf) auch eine kurze Bestätigung per SMS. Empfang ist auch gut.

Laden der Batterie mit Solar hatte ich auch bereits überlegt. Ist aber glaube ich keine geeignete Möglichkeit, da die betreffenden Stellen der Automaten meist deutlich Verschattung aufweisen. Mit drei Monaten Stehzeit wäre das Ziel aber bereits deutlich übertroffen, da ja auch Futter hin und wieder mal nachgefüllt werden muss :wink:.

Derzeit läuft der Einsatztest des Moduls, wenn die Berechnung stimmt, ist auch nicht die 12V-Quelle der limitierende Faktor, sondern die 5V-Quelle. Und da ist noch ein Step-Down-Modul auf dem Versandweg, mit dem ich die Kombination der beiden SV testen möchte. Dann ggf. mit Solarmodul zum Laden. Ggf. kann man auch die derzeitige Einsatzzeit von 8min noch deutlich nach unten schrauben, um mehr aus dem Setup herauszubekommen.

Für das Step/Down/Modul dachte ich an ein LM317

oder alternativ dieses hier:

Ich hatte irgendwo gelesen, dass der LM317 als recht stromsparend gilt. Bei dem zweiten Regler nehme ich mal an, dass dies weniger der Fall sein wird.

Nein

doppelt Nein

Der LM317 ist uralt und verbraucht selber mindestens 1,5mA. Dazu noch 6mA auf dem gezeigten Modul (Spannungsteiler zur Setzen der Ausgangsspannung laut Schaltbild im verlinkten Angebt) .

Zum DC/DC Wandler: einen 25W Wandler für 2W Spitzenleistung zu verwenden ist kontraproduktiv. Der Max Wirkungsgrad ligt meist bei 70-0 % der Nennleistung und ist besonder schlecht wenn der Wandler wenig belastet ist.
Außerdem suchst Du Dir einen aus, der einen Microcontroller zum Einstellen der Ausgangsspannung drauf hat)

Grüße Uwe