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
).
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
