Aussetzer der Steuerung nach unbestimmter Zeit

Hallo zusammen,

ich habe einen Arduino Pro Mini zur Hühnerstallsteuerung programmiert und komme leider nicht weiter.

Schaltungsaufbau:
Stromversorgung erfolgt über ein 12V Solarpanel und einer Autobatterie.
Motor und Licht werden mit 12V betrieben und über ein Relais geschaltet.
Der Motor kann über Taster manuell bedient werden.
RTC ist ein DS1307.
Als Endschalter sind Reed-Relais verbaut.

Die Steuerung hat folgenden Ablauf:
7:00 Uhr - Licht an
9:15 Uhr - Licht aus und Klappe auf
20:00 Uhr - Licht an
20:55 Uhr - Licht aus
21:00 Uhr - Klappe zu

Die Steuerung hat auch einige Zeit gut funktioniert. Dann setzt die Klappensteuerung aus, allerdings entweder morgens ODER abends. Manuell lässt sich die Klappe über Taster IMMER bedienen.
Nach erneutem Flashen des Arduino, funktionierte dieser wieder ein paar Tage.

Ich kann mir das Fehlverhalten nicht erklären. Vllt stehe ich auch einfach auf dem Schlauch.
Die Steuerung wurde bereits auf ein Minimum reduziert.

// Zeitschaltung/RTC und Tasterbedienung //

// Include the libraries:
#include <OneWire.h>
#include <Wire.h>
#include "RTClib.h"

// millis
unsigned long previousMillis = 0;
const long interval = 1000;

// Set RTC  ---------------------------------------------------------------------------------------------------
RTC_DS1307 rtc; // SDA A4 - SCL A5
char daysOfTheWeek[7][12] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"};
int counterMorgens = 0; // 0 -> Tür geschlossen , 1 -> Tür geöffnet
int counterAbends = 0; // 0 -> Tür geöffnet , 1 -> Tür geschlossen
int hh_LichtAnM = 7; // 7:xx Uhr
int mm_LichtAnM = 0; // x:00 Uhr
int hh_TuerAuf = 9; // 9:xx Uhr
int mm_TuerAuf = 15; // x:15 Uhr
int hh_CounterM = hh_TuerAuf + 1;
int hh_LichtAnA = 20; // 20:xx Uhr
int mm_LichtAnA = 0; // x:00 Uhr
int hh_LichtAusA = 20; // 20:xx Uhr
int mm_LichtAusA = 55; // x:55 Uhr
int hh_TuerZu = 21; // 21:xx Uhr
int mm_TuerZu = 0; // x:00 Uhr
int hh_CounterA = hh_TuerZu + 1;

int aktuelleStunde = 0;
int aktuelleMinute = 0;

// LDR --------------------------------------------------------------------------------------------------------
int LDRin = A0; // PullDown 2k2
int LDRvalue = 0;

// Relay-Karte ------------------------------------------------------------------------------------------------
int relais1pin = 5; 
int relais2pin = 6; 
int lichtpin = 4; 
int counterLicht = 0;

// Endschalter ------------------------------------------------------------------------------------------------
int SchalterObenPin = 7; // PullDown 2k2
int SchalterUntenPin = 8; // PullDown 2k2
int counterOben = 0; // Rechts
int counterUnten = 0; // Links

// Taster // PullDown 2k2 ------------------------------------------------------------------------------------
int hochpin = 10; // PullDown 2k2
int runterpin = 11; // PullDown 2k2

void initRTC() {
  if (! rtc.begin()) { // Keine Uhr entdeckt
    Serial.println(F("Echtzeituhr fehlt"));
    // Fehlerbehandlung
    while (1); // Fehlerschleife
  }
  if (! rtc.isrunning()) { // Uhr schon gesetzt?
    Serial.println(F("RTC bisher noch nicht gesetzt!"));
    // => Initialisiere Zeit und Datum auf Datum/Zeit des Host-PCs
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // Datum und Uhrzeit manuell eingeben (Jahr, Monat, Tag, Stunde, Minute, Sekunde)
    //rtc.adjust(DateTime(2020, 6, 5, 11, 28, 0));
  }
  else Serial.println(F("Echtzeituhr laeuft bereits."));
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}

void rechtslauf() {
  digitalWrite(relais1pin, HIGH);
  digitalWrite(relais2pin, LOW);
}

void linkslauf() {
  digitalWrite(relais1pin, LOW);
  digitalWrite(relais2pin, HIGH);
}

void keineBewegungHIGH() {
  digitalWrite(relais1pin, HIGH);
  digitalWrite(relais2pin, HIGH);
}

void LichtAn() {
  digitalWrite(lichtpin, LOW);
}

void LichtAus() {
  digitalWrite(lichtpin, HIGH);
}

void MotorRechtsBisEndschalter() {
  //counterUnten = digitalRead(SchalterUntenPin);
  counterUnten = 1; // untere Endschalter überbrückt
  if (counterUnten == 1) {
    Serial.println(F("HOCH SCHLEIFE"));
    rechtslauf();
    int counter15sec = 0;
    do {
      delay(10);
      counter15sec++;
      if (counter15sec > 1250) {
        goto KeinEndschalterRechts;
      }
    } while (digitalRead(SchalterObenPin) != 1);
  }
KeinEndschalterRechts:
  keineBewegungHIGH();
  delay(100);
}

void MotorLinksBisEndschalter() {
  //counterOben = digitalRead(SchalterObenPin);
  counterOben = 1;
  if (counterOben == 1) {
    Serial.println(F("RUNTER SCHLEIFE"));
    int counter15sec = 0;
    do {
      delay(10);
      counter15sec++;
      if (counter15sec > 1250) {
        goto KeinEndschalterLinks;
      }
    } while (digitalRead(SchalterUntenPin) != 1);
  }
KeinEndschalterLinks:
  keineBewegungHIGH();
  delay(100);
}

void MotorRechtslauf05Sek() {
  Serial.println(F("HOCH 0,5 Sekunden"));
  rechtslauf();
  delay(500);
  keineBewegungHIGH();
}

void MotorLinkslauf05Sek() {
  Serial.println(F("RUNTER 0,5 Sekunden"));
  linkslauf();
  delay(500);
  keineBewegungHIGH();
}

void setup() {
  Serial.begin(9600);
  while (!Serial);

  // RTC
  initRTC();
  delay(100);
  DateTime now = rtc.now();
  delay(100);

  // Relay
  digitalWrite(relais1pin, HIGH);
  digitalWrite(relais2pin, HIGH);
  digitalWrite(lichtpin, HIGH);
  delay(500);
  pinMode(relais1pin, OUTPUT);
  pinMode(relais2pin, OUTPUT);
  pinMode(lichtpin, OUTPUT);
  pinMode(SchalterObenPin, INPUT);
  pinMode(SchalterUntenPin, INPUT);
  pinMode(hochpin, INPUT);
  pinMode(runterpin, INPUT);
  pinMode(LDRin, INPUT);
  delay(500);

  // LED
  pinMode(LED_BUILTIN, OUTPUT);
  delay(250);

  // Abschlussblinken des Setups
  int i = 0;
  while (i < 10) {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(250);
    digitalWrite(LED_BUILTIN, LOW);
    delay(250);
    i++;
  }
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    DateTime now = rtc.now();
    Serial.print(F("Aktuelle Uhrzeit: "));
    Serial.print(now.hour(), DEC);
    Serial.print(F(":"));
    Serial.print(now.minute(), DEC);
    Serial.print(F(":"));
    Serial.print(now.second(), DEC);
    Serial.println();
    aktuelleStunde = now.hour();
    aktuelleMinute = now.minute();
    delay(1);
  }

  // Morgens Automatik
  // Licht Automatik
  if ((aktuelleStunde == hh_LichtAnM) && (aktuelleMinute == mm_LichtAnM)) {
    LDRvalue = 0;
    if ((counterLicht == 0) && (LDRvalue == 0)) {
      LichtAn();
      counterLicht = 1;
      Serial.println(F("Auto: Licht an"));
      delay(1000);
    }
  }
  // Tür Automatik Auf und Licht aus
  if ((aktuelleStunde == hh_TuerAuf) && (aktuelleMinute == mm_TuerAuf)) {
    if (counterMorgens == 0) {
      MotorRechtsBisEndschalter();
      counterMorgens = 1;
      Serial.println(F("AUTO: HOCH"));
      delay(1000);
      if (counterLicht == 1) {
        LichtAus();
        counterLicht = 0;
        Serial.println(F("Auto: Licht aus"));
        delay(1000);
      }
    }
  }
  if ((aktuelleStunde >= hh_CounterM) && (counterMorgens == 1)) { // RST des counters
    Serial.println(F("CounterMorgens auf 0."));
    counterMorgens = 0;
    delay(10);
  }

  // Abends Automatik
  // Licht Automatik An
  if ((aktuelleStunde == hh_LichtAnA) && (aktuelleMinute == mm_LichtAnA)) {
    //LDRvalue = digitalRead(LDRin);
    if (counterLicht == 0) {
      LichtAn();
      counterLicht = 1;
      Serial.println(F("Auto: Licht an"));
      delay(1000);
    }
  }
  // Licht Automatik Aus
  if ((aktuelleStunde == hh_LichtAusA) && (aktuelleMinute == mm_LichtAusA)) {
    if (counterLicht == 1) {
      LichtAus();
      counterLicht = 0;
      Serial.println(F("Auto: Licht aus"));
      delay(1000);
    }
  }
  // Tür Automatik Zu
  if ((aktuelleStunde == hh_TuerZu) && (aktuelleMinute == mm_TuerZu)) {
    if (counterAbends == 0) {
      MotorLinksBisEndschalter();
      counterAbends = 1;
      Serial.println(F("AUTO: RUNTER"));
      delay(1000);
    }
  }
  if ((aktuelleStunde >= hh_CounterA) && (counterAbends == 1)) { // RST des counters
    Serial.println(F("CounterAbends auf 0."));
    counterAbends = 0;
    delay(10);
  }

  int hoch = digitalRead(hochpin);
  if (hoch == 1) {
    Serial.println(F("HOCH"));
    //MotorRechtsBisEndschalter();
    MotorRechtslauf05Sek();
  }
  int runter = digitalRead(runterpin);
  if (runter == 1) {
    Serial.println(F("RUNTER"));
    //MotorLinksBisEndschalter();
    MotorLinkslauf05Sek();
  }
 
}

Und warum musste der Pro mini neu geflasht werden ?
Normal hätte ein Reset gereicht.
Der Pro mini verliert ja nicht einfach seinen Sketch.

Jup. würd' mal sagen, du hast ein Problem mit der Spannungsversorgung.

Ja, 12 Volt sehe ich auch zu hoch, wenn die direkt auf dem Controller liegen.

Hi

Read-RELAIS ??

Davon ab - baue Dir eine Diagnose-Funktion ein - Die blinkt Dir dann eine Zahl vor.
Überall im Sketch änderst Du diese Zahl sinnig ab.
So kannst Du ein Byte für 8 Status hernehmen (Bit gesetzt oder nicht gesetzt), oder eine beliebige Zahl 0…255 vorblinken lassen.
Ein Machwerk aus vergangenen Tagen - blinkt aber trotzdem noch.

//----------------------------------------------------------------------------------------
/*
  Funktion gibt den Wert der Variable 'value' 10-stellig in Blinkimpulsen aus (32bit = 10stellig)
  Vor dem Ziffernblinken wird der Ausgang 'ledPin' auf LOW gesetzt
  Vor und Nach dem Ziffernblinken wird eine 'wartezeit' ... gewartet :) - in ms
  Führende Nullen werden ignoriert
  1-9 Blinkimpulse mit gleich langer Pause, Länge 'waitkurz' ms
  0 Blinkimpuls mit 3-facher Länge
  Zwischen den Ziffern Pause in 3-facher Länge
*/
/*
 * const byte ledPin = PC13;  //LED-Pin
 * const bool _AN = LOW;  //BluePill LED ist bei LOW an
 * const bool _AUS = !_AN;
 */
void impulseout(uint32_t blinkwert) {
  const uint16_t waitkurz = 200;   //ms, Die ein Impuls hell bleibt (x3 für Null, x3 für Pause zwischen Ziffern)
  const uint16_t wartezeit = 700;  //ms vor und nach dem Ziffernblinken
  //kurz = 1x
  //lang = 3x
  //Pause zwischen Ziffernblitzer = 1x
  //Pause zwischen Ziffern = 3x

  static byte ziffer[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};    //Merker für due Ziffernzeichen
  static byte blinkstatus = 0;                  //State der Blink-Maschine
  static uint32_t millisstart;                  //Merker für Startzeit
  static byte i, i2;                            //Merker für die aktuelle Ziffer bzw. den darzustellenden Wert
  switch (blinkstatus) {
    case 0:
      //blinkvalue2 = blinkwert;                        //Den aktuellen Zahlenwert übernehmen
      {
        uint32_t zehnerpotenz = 1000000000;             //Berechnung, Start-Zehnerpotenz
        i = 10;                                      //und in das Ziffern-Array packen
        while (i > 0) {       //Die Zahl in Einzelziffern aufteilen, pow versagte mit 999999 für 10^5
          i--;
          ziffer[i] = blinkwert / zehnerpotenz; //Zahl : 100000, 10000, 1000, 100, 10, 1
          //        Serial.print(ziffer[i]);
          //        Serial.print(" ");
          blinkwert -= ziffer[i] * zehnerpotenz;
          zehnerpotenz /= 10;
        }
      }
      //      Serial.println();
      blinkstatus++;      //Weiter mit Status 1
      millisstart = millis(); //merken, wann wir aufgerufen wurden wegen der Start-Pause
      digitalWrite(ledPin, _AUS);      //Pin für Anzeige AUS schalten
      break;
    case 1:
      if (millis() - millisstart >= wartezeit) {      //Anfangs-Wartezeit, damit die LED vor dem Blinken AUS war
        //ziffer[7]...ziffer[0] = Anzahl der Blinkimpulse
        //die erste Ziffer (oder die Null beim Einer) erfassen
        i = 10; //mit 100000er anfangen      //erste Ziffer auslesen, führende Nullen ignorieren, Einer-Null ausgeben
        do {
          i--;
          i2 = ziffer[i];
        } while (i2 == 0 && i != 0);
        blinkstatus++;                //Weiter mit der HIGH-Phase für diese Ziffer
      }
      break;
    case 2:
      digitalWrite(ledPin, _AN);     //LES für Ziffer AN
      millisstart = millis();         //merken, wann die HIGH-Phase gestartet hat
      blinkstatus++;                  //und zur Abschaltung
      break;
    case 3:
      if (millis() - millisstart >= waitkurz * (i2 == 0 ? 3 : 1)) {   //bei einer Null länger bis zum LOW warten
        digitalWrite(ledPin, _AUS);
        millisstart = millis();       //merken, wann wir die LED abgeschaltet haben
        blinkstatus++;                //weiter um neue Ziffer auszulesen oder die Aktuelle fertig zu blinken
      }
      break;
    case 4:
      if (millis() - millisstart >= waitkurz * (i2 <= 1 ? 3 : 1)) {   //nach dem 1er oder 0er Blink-Impuls Pause zwischen den Ziffern
        if (i2 > 1) {
          i2--;             //Ziffer noch nicht fertig, weiteren Blinkzyklus einleiten
          blinkstatus -= 2; //2 hoch zu 'LED AN'
        } else {
          if (i > 0) {      //wenn noch Ziffern auszugeben sind, dann die Nächste auslesen
            i--;
            i2 = ziffer[i];     //die neue Ziffer auslesen
            blinkstatus -= 2;   //weiter mit 'LED AN'
          } else {
            blinkstatus++;      //sonst weiter mit End-Pause
          }
        }
      }
      break;
    case 5:
      if (millis() - millisstart >= wartezeit) {      //Wartezeit nach dem Ziffernblinken
        blinkstatus++;                                //verlassen wir die Blinkerei
      }
      break;
    default:
      blinkstatus = 0;      //für den nächsten Start vorbereiten
  }
}
//========================================================================================

MfG

Davon ab - baue Dir eine Diagnose-Funktion ein - Die blinkt Dir dann eine Zahl vor.
.....

Würde bedeuten, der TO darf Stunden oder Tage vor seinem Projekt verweilen.

Da würde ich eher auf eine Speicherung auf SD-Card tendieren und die auch Zeilenabhängig.

Aehm, was soll er denn auf der SD-Karte speichern, was ihm weiterhilft?

zwieblum:
Aehm, was soll er denn auf der SD-Karte speichern, was ihm weiterhilft?

Z.B. wo er noch zuletzt funktioniert hat.
Ich habe auch nur den Vorschlag von postmaster aufgegriffen.
Grundsätzlich wäre das auch für mich keine Lösung.

Vielen Dank für die schnellen Rückmeldungen.

HotSystems:
Und warum musste der Pro mini neu geflasht werden ?
Normal hätte ein Reset gereicht.
Der Pro mini verliert ja nicht einfach seinen Sketch.

Das stimmt. Ich habe ihn neu geflasht, da ich auch noch die Zeiten der Öffnung und Schließung angepasst habe.

Laut dem Datenblatt des Arduino Por Mini 16Mhz 5V ging ich davon aus das dieser mit den 12V an RAW arbeiten kann, da ‘5V-16V (6V-12V recommended)’ angegeben ist. Werde den Schaltungsaufbau auf 5V ändern und testen.

postmaster-ino:
Davon ab - baue Dir eine Diagnose-Funktion ein - Die blinkt Dir dann eine Zahl vor.
Überall im Sketch änderst Du diese Zahl sinnig ab.
So kannst Du ein Byte für 8 Status hernehmen (Bit gesetzt oder nicht gesetzt), oder eine beliebige Zahl 0…255 vorblinken lassen.
Ein Machwerk aus vergangenen Tagen - blinkt aber trotzdem noch.

Eine Ausgabe hatte ich über den seriellen Monitor gebaut gehabt, als ich die Steuerung an einem 12V Netzteil getestet habe. Dort hat alles funktioniert gehabt. Jedoch war der Testzeitraum anscheinend nicht lang genug, sonst hätte ich das Problem schon früher festgestellt.

12 Volt sind sehr stark an der Grenze.
Der Onboard-Regler wird dann sehr heiß und irgend wann schaltet der ab.

5Volt sind da am 5Volt Pin optimal.

Hi

Mein Vorschlag ging in die Richtung, einen Status mitzuführen.
Wie der TO schreibt, lässt sich die Steuerung ja noch händisch bedienen - der Arduino hat also weder resettet noch Sich irgendwo festgefressen.
Also muß Es irgendwo im Sketch sein, wo eben nicht mehr auf die Sensoren reagiert wird.
Klar wäre eine Sicherung auf SD der 'Aktuelle-Situation-Blinkerei' vorzuziehen - nur wäre Das für mich auch eher ein Grund, die Schwiegermutter zu besuchen, als das SD-File zu analysieren :wink:
(Anmerkung am Rande: keine Schwiegermutter vorhanden - aber nicht, weil Diese (aus welchen Gründen auch immer) nicht mehr wäre - kann Das also locker so behaupten :wink: )

Wen nder Sensor z.B. dauernd NACHT sagt, obwohl's draußen echt hell ist - DAS könnte man anhand eines Status-Bit durchaus der Außenwelt zugänglich machen.

WARUM Das falsch erkannt wird - Das kommt hier nicht raus - dafür muß man ganz oldscool den Code debuggen - aber man hat dann zumindest einen Anhaltspunkt.

Momentan ist's ja nur 'Funktioniert nicht' - und Das ist für die Fehlersuche äußerst mager.

MfG

PS: Für das Vorblinken von Bits ist die oben veröffentliche Blink-Funktion Nichts - Die will schon Zahlen vorblinken (war angedacht für ein Thermometer in Blau/Rot - bei negativen Gradzahlen mit Blau begonnen (sonst Rot) und für die Komma-Stelle auf die andere Farbe gewechselt ... ok, man könnte den Kram auch einfach in den Tiefen des WWW für wenig Geld auf einem ATtiny45 kaufen :wink:

postmaster-ino:
Mein Vorschlag ging in die Richtung, einen Status mitzuführen.

Ok....jeder muss für sich entscheiden, welcher Weg der Fehlersuche der bessere ist.

Allerdings, das mit der Tastenfunktion habe ich tatsächlich falsch verstanden.
Wenn die aus dem Sketch heraus noch funktioniert, kann es durchaus am Sketch liegen.

Dennoch stehe ich dazu, eine Spannungsversorgung mit 12Volt ist hier nicht die beste Lösung.
Der Regler ist sehr klein und kann nicht viel Verlustleistung ab.
Wenn da noch RTC und Sensoren von gespeist werden, hängt der sich schnell ab.

Da ist eine 5V Speisung deutlich besser angebracht.

minionjazzy:
Stromversorgung erfolgt über ein 12V Solarpanel und einer Autobatterie.
Motor und Licht werden mit 12V betrieben und über ein Relais geschaltet.

7:00 Uhr - Licht an
9:15 Uhr - Licht aus und Klappe auf
20:00 Uhr - Licht an
20:55 Uhr - Licht aus
21:00 Uhr - Klappe zu

Die Steuerung hat auch einige Zeit gut funktioniert. Dann setzt die Klappensteuerung aus, allerdings entweder morgens ODER abends. Manuell lässt sich die Klappe über Taster IMMER bedienen.

 //rtc.adjust(DateTime(2020, 6, 5, 11, 28, 0));

Guten Morgen,

ein paar Gedanken dazu.
Das Panel hängt nicht direkt am Akku dran, sondern mit Laderegler?
Im Code ist für die Uhr mal der 5.6.2020 vorgesehen gewesen. Kann man davon ausgehen, das das der erste Einsatztag war (oder sogar noch früher) und ab da lief es störungsfrei? bis wann?

Wenn Du die Schaltung (ARDU/RELAIS) nicht über einen Ladereglerausgang versorgst, bringt der Akku eher 13,xx V als 12.
Wenn die Sonne scheint sind sogar eher 14,xx V drauf.

Wenn Du die Schaltung über einen Laderegler versorgst, und der PWM macht kann Dir das evtl. in die Versorgungsleitung reinstreuen.

Die Frage die sich noch ergibt, ob nur die Klappe "hängt" oder auch das Licht.

Ich hätte - um das einzugrenzen - als erstes das Solarpanel für ein paar Tage abgeklemmt.

Für die 2k2 PULLDown hätte ich eher 5k angesetzt.

Guten Morgen,

my_xy_projekt:
Das Panel hängt nicht direkt am Akku dran, sondern mit Laderegler?

Ja, hängt am Laderegler.

my_xy_projekt:
Im Code ist für die Uhr mal der 5.6.2020 vorgesehen gewesen. Kann man davon ausgehen, das das der erste Einsatztag war (oder sogar noch früher) und ab da lief es störungsfrei? bis wann?

Ja, war der erste Einsatztag der Steuerung. Die Steuerung lief zwischen 5 und 8 Tagen störungsfrei. Wenn diese nicht lief, habe ich die Steuerung resetet oder neu geflasht (beim Flashen wurden auch Zeiten angepasst). Danach lief es erstmal wieder.

my_xy_projekt:
Wenn Du die Schaltung über einen Laderegler versorgst, und der PWM macht kann Dir das evtl. in die Versorgungsleitung reinstreuen.
[...]
Ich hätte - um das einzugrenzen - als erstes das Solarpanel für ein paar Tage abgeklemmt.

Daran habe ich noch gar nicht gedacht. Ich werde das Solarpanel mal abklemmen, bevor ich die Steuerung auf 5V umbaue.

my_xy_projekt:
Die Frage die sich noch ergibt, ob nur die Klappe "hängt" oder auch das Licht.

Es "hängt" nur der Motor. Das Licht schaltet einwandfrei ohne Unterbrechungen.

minionjazzy:
Es "hängt" nur der Motor. Das Licht schaltet einwandfrei ohne Unterbrechungen.

Dann wird's knifflig.
Ich bin mal durch den Code gegangen.
Kannst Du ausschliessen, das Dir evtl. die PIN für die Endschalter HIGH gehen, noch bevor der Motor sich (sichtbar) in Bewegung gesetzt hat? Da reicht nen Wackelkontakt an den PULL_Downs...

Um das zu kontrollieren, wäre evtl. sinnvoll in rechtslauf() / linkslauf() noch serielle Ausgabe einzubauen.
Wenn das nicht geht - weil kein Rechner anbaubar - könntest versuchen mit 2 LED + Widerstand wenigstens zu sehen, ob da überhaupt hingesprungen wird.
Also oben 2 LED initialisieren: LEDPIN1 / LEDPIN2
und dann bei linkslauf() als erstes rein

digitalWrite(LEDPIN1, HIGH);

bei

rechtslauf()
{ digitalWrite(LEDPIN2, HIGH);

und beim manuellen Taster

if (hoch == 1)

als erstes

digitalWrite(LEDPIN1, LOW);

bzw.

if (runter == 1) 
{
digitalWrite(LEDPIN2, LOW);

zum löschen.

Dann ist mir aufgefallen, das Du counterMorgens und counterAbends als INT initialisierst. "counter" ist vielleicht unglücklich gewählt und mach nen bool draus. Dann muss man später im Code nicht nochmal nachdenken.
hh_CounterA (M) benutzt Du nur einmal. Die hätt ich weggelassen und im Code gerechnet.
Da der Fuchs ab 22 Uhr kommt, wird hh_TuerZu sicher nicht 23 werden?. Sonst könnte Dir der Code nen Streich spielen :wink:

Wie wär's mal mit einem Schltplan und ein paar Detailfotos?

Guten Abend,

vielen Dank für eure Hilfe :slight_smile:

Ich habe über die serielle Schnittstelle Ausgaben eingefügt, um mir den aktuellen Zustand auszugeben.
Es war wirklich ein Wackelkontakt beim PullDown, so dass der Endschalter auf 1 gesetzt worden ist.

minionjazzy:
vielen Dank für eure Hilfe :slight_smile:

Ich habe über die serielle Schnittstelle Ausgaben eingefügt, um mir den aktuellen Zustand auszugeben.
Es war wirklich ein Wackelkontakt beim PullDown, so dass der Endschalter auf 1 gesetzt worden ist.

Danke für die Rückmeldung, das es, so wie vermutet, ein Hardwareproblem war.

Hast Du Deinen Code auch sonst noch hinsichtlich der Vorschläge bearbeitet?

my_xy_projekt:
Hast Du Deinen Code auch sonst noch hinsichtlich der Vorschläge bearbeitet?

Ja, ich habe nun eine dauerhafte Ausgabe über die serielle Schnittstelle. Desweiteren sind die Counter für die Tür auf BOOL gesetzt. Und eine Fehlerbehandlung für hh_TuerZu >= 23.

Der Pro Mini läuft weiterhin auf 12VDC, werde dies aber im Auge behalten.

minionjazzy:
Und eine Fehlerbehandlung für hh_TuerZu >= 23.

Da möchte ich noch eingreifen.
Du könntest hh_TuerZu schon noch auf 23 setzen - allerdings ist die weitere Verfahrensweise zu ändern.

Ich schrub:

hh_CounterA (M) benutzt Du nur einmal. Die hätt ich weggelassen und im Code gerechnet.

Dazu stehe ich weiterhin.
Eine Variante für

if ((aktuelleStunde >= hh_CounterA) && (counterAbends == 1)) { // RST des counters

wäre:

if ((aktuelleStunde >hh_TuerZu) || (aktuelleStunde < hh_TuerAuf)) ....

Wobei ich die zeitlichen Regelungen insgesamt noch einer Prüfung unterzogen hätte. Mir fehlt nur leider aktuell die Zeit um da intensiver einzusteigen. Liegt jetzt auf Wiedervorlage für Sonntag.

Was Du bisher gemacht hast ist schick :wink: +1