Stromsparendes Programm - Automatisch UND Manuell wecken

Hallo zusammen,
gleich vorweg, das ist mein erster Beitrag also bitte verzeiht mir wenn etwas nicht gleich perfekt formuliert ist.

Ich bin aktuell dabei, für meinen Outdoor-Hühnerstall ein automatisches Hühnertor zu bauen (ich wollte das Projekt auch gleich nutzen, um mich in die Welt des Arduino programmierens zu stürzen). Grundsäztlich soll das Hühnertor automatisch und manuell zu öffnen/schließen sein - die Umschaltung der Modi erfolgt über einen simplen Kippschalter. Für den Automatischen Modus verwende ich einen Helligkeitssensor, der entweder High oder Low zurückliefert, je nachdem ob der Schwellwert erreicht ist. Im manuellen Modus kann mittels zweier Taster geöffnet oder geschlossen werden. An den jeweiligen Endpunkten habe ich Mikroschalter montiert, welche beim Erreichen den Vorgang (Öffnen oder Schließen) beenden.

Als Hardware dient mir eine 12Vdc Autobatterie welche einen 12V Getriebemotor betreibt.

Das Projekt funktioniert eigentlich schon einwandfrei - nun kommt aber meine eigentliche Frage: ich würde den Arduino gerne auf Standby legen, damit nach z.B. dem Schließvorgang das Programm nicht ständig weiterläuft sonder erst wieder nach einer Zeit/nach erreichen des neuen Zustandes weiterläuft.

Leider bekomme ich das in der Praxis nicht hin. Der Arduino soll dabei auf zwei Arten wieder geweckt werden können:

  1. Falls der Programmwahlschalter (Automatisch/Manuell) umgeschaltet wird, oder
  2. Falls sich im Automatischen Modus der Zustand ändert

Ich hoffe das war nicht zu kompliziert oder zu viel Text. Ich würde mich sehr freuen wenn mir jemand weiterhelfen könnte :wink: Wie gesagt, ich bin neu hier und das ist mein erstes Thema, also bitte um Verzeihung falls es schlecht ausgedrückt war.

(Im Code ist auch die Überprüfung der Batteriespannung bereits umgesetzt, allerdings noch nicht im Loop verwendet, da ich dazu noch den tatsächlichen Grenzwert für meine Batterie herausfinden muss).

Hier mein Code:

/*
Automatisches Hühnertor
1) Manueller Modus: hierbei kann die Hühnertür manuell über 2 Taster geöffnet/geschlossen werden
2) Automatischer Modus: über einen Helligkeitssensor schließt und öffnet die Tür automatisch
*/

//SPANNUNGSMESSUNG (um Tiefenentladung der Batterie zu verhindern)

const int PIN_U = A0;               //Analoger Pin zur Spannungsmessung der Batterie
const float REF_VOLTAGE = 5.0;      
const float PIN_STEPS = 1024.0;

const float diodeVoltage = 0.69;
const float R1 = 99100.0;
const float R2 = 9930.0;

float Vout = 0.0, Vin = 0.0;
int rawValue = 0;

//HARDWAREBELEGUNG DER TASTER UND SCHALTER

const int MOTOR = 3;      //Pin Ausgang Motorgeschwindigkeit
const int ZU = 4;         //Pin Motordriver Drehrichtung ZU
const int AUF = 5;        //Pin Motordriver Drehrichtung AUF
const int LIGHT = 10;     //Pin des Helligkeitssensors zum Erkennen ob HELL oder DUNKEL (0 = Hell 1 = dunkel)

const int MAN_AUF = 6;    //Pin für Manuelles AUF (ROTER TASTER)
const int MAN_ZU = 8;     //Pin für Manuelles ZU (WEISSER TASTER)
const int STOP_U = 12;    //Pin Endtaster UNTEN (LOW wenn offen, HIGH wenn gedrückt)
const int STOP_O = 13;    //Pin Endtaster OBEN (LOW wenn offen, HIGH wenn gedrückt)
const int SWITCH = 11;    //Pin Umschalten Manuell/Automatisch

//WERTE FÜR MOTOR UND ZEITÜBERLÄUFE

const int SPEED_UP = 200;     //Geschwindigkeit Motor rauf (von 0 - 255)
const int SPEED_DOWN = 60;

const int AUSZEIT_UP = 450;   //Zeit nach der automatisch abgebrochen wird falls Fehler mit Endtaster
const int AUSZEIT_DOWN = 420; //Zeit nach der automatisch abgebrochen wird falls Fehler mit Endtaster

const unsigned long period = 1200000;   //  Auszeit, ab der der Lichtsensor wechseln kann, 1200000
unsigned long time_auf = 1200000;  
unsigned long time_zu = 1200000;

int PINMODE_U;            //Status Taster unten
int PINMODE_O;            //Status Taster oben
int PINMODE_AUF;          //Status Schalter Auf
int PINMODE_ZU;           //Status Schalter Zu
int SWITCHSTATE;          //Status Schalter Manuell/Automatisch (1 = AUTOMATISCH   0 = MANUELL)

int ZEIT_AUF = 0;
int ZEIT_ZU = 0;
int NACHT;                // HIGH = NACHT
int FEHLER_AUF;
int FEHLER_ZU;
int FADE = 1;
int SPEED = 60;
int Offen = 1;
int Geschlossen = 1;

void setup() {
  pinMode(STOP_U, INPUT);
  pinMode(STOP_O, INPUT);
  pinMode(MAN_AUF, INPUT);
  pinMode(MAN_ZU, INPUT);
  pinMode(LIGHT, INPUT);
  pinMode(SWITCH, INPUT);
  pinMode(PIN_U, INPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  
  pinMode(MOTOR, OUTPUT);
  pinMode(AUF, OUTPUT);
  pinMode(ZU, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  
digitalWrite(LED_BUILTIN, LOW); //LED auf Pin 13 ausschalten um Akku zu sparen

PINMODE_O=digitalRead(STOP_O);
PINMODE_U=digitalRead(STOP_U);

PINMODE_AUF=digitalRead(MAN_AUF);
PINMODE_ZU=digitalRead(MAN_ZU);
SWITCHSTATE=digitalRead(SWITCH);
NACHT=digitalRead(LIGHT);

//KONTROLLE DER SPANNUNG
rawValue = analogRead(PIN_U);
Vout = (rawValue*REF_VOLTAGE)/PIN_STEPS;
Vin = (Vout / (R2/(R1+R2)))+diodeVoltage;
//Serial.println("U = " + String(Vin) + " V");

//Serial.println(SWITCHSTATE);
//Serial.println(NACHT);
//Serial.println(period);

// 1) MANUELL:

  if (SWITCHSTATE == LOW && PINMODE_AUF == HIGH){
    if (PINMODE_O == LOW){
      OPEN();
      Serial.print("Zeit auf: ");
      Serial.println(ZEIT_AUF);
       if (ZEIT_AUF < AUSZEIT_UP){
         Serial.println("OPEN - aus durch Taster");
          FEHLER_AUF = 0;
       }
       if (ZEIT_AUF >=AUSZEIT_UP){
         Serial.println("OPEN - aus durch Zeitabbruch");
          FEHLER_AUF = 1;
       }
       delay(200);
     }
    }
 
  if (SWITCHSTATE == LOW && PINMODE_ZU == HIGH){
    if (PINMODE_U == LOW){
      CLOSE();
      Serial.print("Zeit zu: ");
      Serial.println(ZEIT_ZU);
      if (ZEIT_ZU < AUSZEIT_DOWN){
        Serial.println("CLOSE - aus durch Taster");
        FEHLER_ZU = 0;  
      }
      if (ZEIT_ZU >= AUSZEIT_DOWN){
        Serial.println("CLOSE - aus durch Zeitabbruch");
        FEHLER_ZU = 1;
      }
      delay(200);
    }
  }
  
// 2) AUTOMATISCH:

//AUF
  if (SWITCHSTATE == HIGH && NACHT == LOW && ((millis()-time_auf) > period) ){
    if (PINMODE_O == LOW && Geschlossen == 1){
      Serial.print("Lichtsensor Value: ");
      Serial.println(NACHT);
      OPEN();
      Offen = 1;
      Geschlossen = 0;
      time_auf = millis();
      Serial.print(ZEIT_AUF);
      if (ZEIT_AUF < AUSZEIT_UP){
        Serial.println("OPEN - aus durch Taster");
        FEHLER_AUF = 0;
      }
      if (ZEIT_AUF >= AUSZEIT_UP){
        Serial.println("OPEN - aus durch Zeitabbruch");
        FEHLER_AUF = 1;
      }
      delay(10);           
    }
  }

//ZU
  if (SWITCHSTATE == HIGH && NACHT == HIGH && ((millis()-time_zu) > period) ){
    if (PINMODE_U == LOW && Offen == 1){
      Serial.print("Lichtsensor Value: ");
      Serial.println(NACHT);
      CLOSE();
      Offen = 0;
      Geschlossen = 1;
      time_zu = millis();
      Serial.println(ZEIT_ZU);
      if (ZEIT_ZU < AUSZEIT_DOWN){
        Serial.println("CLOSE - aus durch Taster");
        FEHLER_ZU = 0;
      }
      if (ZEIT_ZU >= AUSZEIT_DOWN){
        Serial.println("CLOSE - aus durch Zeitabbruch");
        FEHLER_ZU = 1;
      }
      delay(10);          
    }
  }
  
ZEIT_AUF = 0;  
ZEIT_ZU = 0;
SPEED = 60;
}

void OPEN(){
  while (PINMODE_O == LOW && ZEIT_AUF < AUSZEIT_UP){
    digitalWrite(AUF,HIGH);
    if (SPEED < SPEED_UP){
      SPEED = SPEED + FADE;
    } else{
      SPEED = SPEED_UP;
    }
    analogWrite(MOTOR,SPEED);
    ZEIT_AUF ++;
    PINMODE_O=digitalRead(STOP_O);
    delay(10);
  }
  digitalWrite(AUF,LOW);
  return ZEIT_AUF;
}

void CLOSE(){
  while (PINMODE_U == LOW && ZEIT_ZU < AUSZEIT_DOWN){
    digitalWrite(ZU,HIGH);
    analogWrite(MOTOR,SPEED_DOWN);
    ZEIT_ZU ++;
    PINMODE_U=digitalRead(STOP_U);
    delay(10);
  }
  digitalWrite(ZU,LOW);
  return ZEIT_ZU;
}

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.

1 Like

Alles, was auf dem Uno verbaut ist, frisst Dir den Saft auf. Da fällt der AVR nicht ins Gewicht.

Wie soll das der MC merken, wenn er schläft?

Gruß Tommy

Hallo Tommy56,
genau das wäre ja meine Frage ob das möglich ist (also ihn z.B. wieder aufzuwecken wenn sich an einem Eingang etwas ändert).

LG Thomas

An einem digitalen Interrupteingang geht das, an einem Analogeingang nach meinem Wissen nicht.

Gruß Tommy

1 Like

Ich verwende für die Umsetzung nur die digitalen Eingänge des Arduino. Den einzigen analogen Eingang den ich nutze, ist der zur Überprüfung der Batteriespannung.

Auch der Sensor ist an einem digitalen Eingang. Man kann über ein Poti den Grenzwert für die Helligkeit einstellen. Darüber liefert er 1, darunter 0.

Hallo Thomas,

um Strom zu sparen gibt es verschiedene Varianten, oft ist es eine Kombination verschiedener Techniken. Um was für einen Arduino handelt es sich denn? Gibt es einen Schaltplan?
Bei einem UNO hast Du eher schlechte Karten mit dem Stromsparen durch schlafen, da genug andere Bauteile weiter Strom verbrauchen. Dann werden aus ca. 50mA ca. 33mA, der µC selbst könnte aber mit 4-5µA schlafen ...

Gruß André

1 Like

Hallo André,
danke für deine Nachricht. Anbei der Schaltplan meines Projekts (die Batterieüberwachung habe ich später noch ergänzt, da liegt aber einfach die Batteriespannung über eine Brücke an A0 an, also sollte für mein Problem irrelevant sein).

Ich verwende einen Arduino UNO. Aktuell hält meine Autobatterie ca. 10 Tage, was leider nicht sehr lange ist. Der Lichtsensor hat einen LM393 Chip (Lichtsensor).

Mit den 12 V Deiner Taster grillst Du den Arduino.
Ok, Brille putzen.

Gruß Tommy

Deshalb hängen sie auch nur an den 5V des Arduino :wink: Die 12V dienen nur zur Anspeisung des Arduino generell, sowie zur Anspeisung des Motordrivers (siehe Schaltplan).

Du hast Recht, Brille Putzen.

Gruß Tommy

1 Like

Du kannst Dir die Widerstände sparen wenn Du die Taster gegen GND
schaltest. Den Pin 13 wurde frei lassen dort hängt die interne LED

1 Like

Wenn du am Uno einen analogen Eingang verwendest, reich ein LDR plus Widerstand dafür aus. Die zusätzliche Elektronik kannst du dann sparen. Dann sparst du wieder etwas Strom.

1 Like

Hi,

wie von fony schon erwähnt, kann man die Widerstände an den Tastern weglassen, wenn man die internen PullUps benutzt. Dann ist Ruhepegel HIGH, gedrückter Taster LOW. Zum Motortreiber L293 kann ich nicht viel sagen, außer daß dieser von 1986 ist, und sicher jemand einen aktuellen empfehlen kann. Auch dieser wird dauerhaft Strom verbrauchen! Der Lichtsensor lässt sich (wenn man das will) problemlos gegen einen Ambient Light Sensor ersetzen, und an einem analogen Pin auswerten.
Hast Du mal den Ruhestrom gemessen? 10 Tage mit einer Autobatterie ist nicht wirklich viel, und der Motor ist ja nur kurz am laufen.

Gruß André

Alles was den Stromverbrauch deines Uno betrifft, wurde dir doch schon in Post #3 geschrieben.
Da wäre ein Arduino Pro mini deutlich besser.

Man kann mit einem P-Channel MOS-Fet den L293 von der Stromversorgung abklemmen (vor dem Start des Schlafmodus). Das braucht einen zusätzlichen Pin, aber der LM293 verbraucht keinen Strom mehr.

1 Like

Hallo,
eine Solarzelle mit Regler bekommst Du für wenig Geld. Camping Bereich. dann ist Stromverbrauch und nachladen kein Thema mehr.
Heinz

Klar geht das. Trotzdem kommt das Stromsparen an erster Stelle.
Bei meiner Milchmädchenrechnung reichen bei 100µA Ruhestrom und 2x betätigen der Klappe a 1 Minute mit 1A eine Kapazität von 1Ah für 23 Tage.
Auf die ~ 100µA kommt man freilich nur mit einem nacktem µC und WDT-Schlafen mit periodischem abarbeiten der Loop.

Gruß André

1 Like

Auf einem

Niemals.