Toilettenampel mit Tasterhaltung

Hallo Kupper
Was macht das Ampelprojekt?

Ich müsste mal auf den Acker, um die Ampel zu holen und alles im fertigen zustand zu testen.

Es sind auch durch in der Toilette nach Gebrauch verbliebene Durftstoffe hervorgerufene Paniksituationen zu berücksichtigen. Also Sicherheitsschaltungen sind notwendig!!! :wink: :wink:

Grüße Uwe

Wenn jemand bei Rot/Gelb abschließt, leuchtet es noch Rot/Gelb weiter und schaltet erst nach ablaufen der Zeit wieder auf Rot. Normal müsste es, direkt wieder auf Rot schalten und die Zeit dazu addieren. Ist kein Muss,

Na das ist ja nun nichts mit Sicherheitsschaltung, das ist nur die Unterbrechung der StateMachine mit Rückkehr an einen definierten Punkt.

// basiert auf https://forum.arduino.cc/t/toilettenampel-mit-tasterhaltung/914301/45?u=my_xy_projekt
// erweitert um eine Abfragebedingung in ST_REDyellow
const byte    PinLed  [] = { 5, 7, 9 };
const byte    PinBut     =  11;
enum { Off, On };
enum { ST_IDLE, ST_YELLOW, ST_RED, ST_REDwait, ST_REDYellow };  // Das ist eine Aufzaehlung der Stati
byte  state = ST_IDLE;                                          // Erster Status mit Programmstart

const unsigned long PeriodYellow = 1000;                        // Zeit in ms
unsigned long yellowPlus = 0;                                   // Variable zur Berechnung der Verlaengerung der Gelbphase
unsigned long msecLst;                                          // Merker für letzte Zeit
unsigned long msec;                                             // Merker für aktuelle Zeit

// -----------------------------------------------------------------------------
void setLeds ( const bool green,          // Funktion zur Ausgabe der Zustände
               const bool yellow,
               const bool red )
{
  digitalWrite (PinLed [0], green);
  digitalWrite (PinLed [1], yellow);
  digitalWrite (PinLed [2], red);
}

// -----------------------------------------------------------------------------
void kontrol()
{
  byte x = 200;
  static byte y = 0;
  x = (x + digitalRead(5)) << 1;
  x = (x + digitalRead(7)) << 1;
  x = (x + digitalRead(9));
  if (y != x)
  {
    y = x;
    Serial.println(y, BIN);
  }
}
void loop ()
{
  kontrol();
  msec = millis ();                         // merkt sich die aktuelle Zeit
  switch (state)                            // verzweige je nach Zustand
  {
    case ST_YELLOW:                         // Wenn Status gelb
      setLeds (Off, On, Off);               // stelle die Ampel
      if ((msec - msecLst) > PeriodYellow)  // wenn Gelbzeit abgelaufen
        state = ST_RED;                     // wechsle zu rot
      break;
    case ST_RED:                            // wenn Status rot
      setLeds (Off, Off, On);               // stelle Ampel
      msecLst = msec;                       // merke die aktuelle Zeit
      state = ST_REDwait;                   // wechsel Status zu rot_warten
      break;
    case ST_REDwait:                        // wenn Status rot_warten
      if (digitalRead (PinBut))             // wenn Schloss geöffnet
      {
        yellowPlus = (msec - msecLst);      // ermittle die Zeit, die das Schloß zu war
        if (yellowPlus < 60000) yellowPlus = 1000;  // und setze passend dazu die Verlängerungszeit
        if (yellowPlus > 119900) yellowPlus = 119900;
        msecLst = msec;                     // merke die Zeit
        state = ST_REDYellow;               // wechsel Status zu rot_gelb
      }
      break;
    case ST_REDYellow:                      // wenn Status rot_gelb
      if (!digitalRead (PinBut))            // wenn Schloss wieder geschlossen
      {
        state = ST_RED;
      }
      else
      {
        setLeds (Off, On, On);              // stelle die Ampel
        if ((msec - msecLst) > (PeriodYellow + yellowPlus)) // Wenn Zeit abgelaufen
        {
          state = ST_IDLE;                  // wechsel Status zu gruen
        }
      }
      break;
    case ST_IDLE:                           // Wenn Status gruen
    default:                                // oder Status unbekannt
      setLeds (On, Off, Off);               // stelle Ampel
      if (!digitalRead (PinBut))            // Wenn Schloss zu
      {
        state = ST_YELLOW;                  // wechsel zu Status gelb
        msecLst = msec;                     // merke die Zeit
      }
      break;
  }
}
void setup()
{
  Serial.begin (115200);
  Serial.println(F("Start..."));
  for (unsigned n = 0; n < sizeof(PinLed); n++) // Setze alle Pins
  {
    digitalWrite (PinLed [n], Off);             // aus
    pinMode      (PinLed [n], OUTPUT);          // auf Output
  }
  pinMode (PinBut, INPUT_PULLUP);
}

@ all Sicherheits-Skeptiker
Vielleicht die Toilette aus sicherheitsgründen noch vor dem Betreten dauerfaft verriegeln oder am besten gleich zumauern, dann können erst gar keine Gesundhetsschädigende Gase entstehen, ansonsten eine mindestens 5 Din A4 Setitige Sicherheits Anweisung zur Toilettenbenutzung , mit 3-seitiger unterschriftspflichtiger EU konformer Einverständniss-Erklärung aussen und innen an der Toiletten Türe anbringen. (Türe öffnet natürlich nur nach scannen der Unterschriften). :thinking: