diff --git a/README.md b/README.md index aafaa5c..6293943 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ hackerspace-status-arduino ========================== + +see https://www.krautspace.de/hswiki:projekte:elektronikrunde:status_anzeige diff --git a/status/status.ino b/status/status.ino new file mode 100644 index 0000000..20bbf04 --- /dev/null +++ b/status/status.ino @@ -0,0 +1,132 @@ +/* + * es gibt folgende Zustände: + * 0 - Aus + * 1 - An, aber auf dem weg zu aus + * 2 - An + */ +#define STATE_OFF 0 +#define STATE_HALF 1 +#define STATE_ON 2 + +/* + * Zeit wie lange in einem Zustände verharrt werden soll + * bis zum nächsten umgeschaltet wird in Millisekunden. + * TIME_HALF - Zeitspanne von Zustand 2 bis Wechsel zu Zustand 1 + * TIME_OFF - Zeitspanne von Zustand 2 bis Wechsel zu Zustand 0 + */ +#define TIME_HALF 5400000 // 1,5h +#define TIME_OFF 7200000 // 2h + +// für Variablen Überlauf in calcStateTime +#define MAX_LONG 4294967295 + +// Ein-/Ausgänge Bezeichnen +const int BTN_ON = 2; // Einschalter +const int BTN_OFF = 3; // Ausschalter +const int LED_G = 7; // grüne LED +const int LED_Y = 8; // gelbe LED +const int LED_R = 9; // rote LED + +// hier wird der aktuelle Zustand gespeichert +byte state = STATE_OFF; + +// hier wird der Beginn des aktuellen Zustand gespeichert in Millisekunden nach Uptime. +unsigned long stateBegan; + +// Debouncer +class Debounce +{ + public: + Debounce(int pin); + boolean update(); + int read(); + private: + int _pin; + int _state; + int _time; + int _delay; +}; + +Debounce debounceBtnOn(BTN_ON); +Debounce debounceBtnOff(BTN_OFF); + +// wird einmalig beim Start des Arduinos ausgeführt +void setup() { + pinMode(LED_G, OUTPUT); + pinMode(LED_Y, OUTPUT); + pinMode(LED_R, OUTPUT); + Serial.begin(9600); + setStateOnLeds(); +} + +// bildet den aktuellen Zustand auf die LEDs ab +void setStateOnLeds() { + digitalWrite(LED_R, (state == STATE_OFF)); + digitalWrite(LED_Y, (state == STATE_HALF)); + digitalWrite(LED_G, (state == STATE_ON)); +} + +unsigned long calcStateTime() { + // Variablen überlauf von millis erkennen + if (millis() - stateBegan >= 0) { + return millis() - stateBegan; + } else { + return millis() + (MAX_LONG - stateBegan); + } +} + +// wird nach dem Starten dauerhaft ausgeführt +void loop() { + // Einschalter auslesen + if (debounceBtnOn.update() && debounceBtnOn.read()) { + state = STATE_ON; + stateBegan = millis(); + setStateOnLeds(); + } + // Ausschalter auslesen + if (debounceBtnOff.update() && debounceBtnOff.read()) { + state = STATE_OFF; + setStateOnLeds(); + } + + // Auswertung des aktuellen Zustandes + // ggf Zustand wechseln + if (state == STATE_ON) { + if (calcStateTime() >= TIME_HALF) { + state = STATE_HALF; + setStateOnLeds(); + } + } else if (state == STATE_HALF && calcStateTime() >= TIME_OFF) { + state = STATE_OFF; + setStateOnLeds(); + } + + // aktuellen Zustand auf die Serielle Verbindung schreiben + Serial.print((state == STATE_ON || state == STATE_HALF)); +} + +// Debouncer Klasse +Debounce::Debounce(int pin) +{ + pinMode(pin, INPUT); + this->_pin = pin; + this->_time = 0; + this->_state = LOW; + this->_delay = 50; +} +boolean Debounce::update() +{ + if (millis() - this->_time >= this->_delay) { + int reading = digitalRead(this->_pin); + if (reading != this->_state) { + this->_time = millis(); + this->_state = reading; + return true; + } + } + return false; +} +int Debounce::read() +{ + return this->_state; +}