diff --git a/Makefile b/Makefile deleted file mode 100644 index d74b3d5..0000000 --- a/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -SRC:=$(shell find status -regex '.*\.cpp') -OBJ:=$(patsubst %,%.o,$(SRC)) -DEP:=$(patsubst %,%.d,$(SRC)) - -CC?=avr-gcc - -CFLAGS?= -O2 -ggdb -std=gnu++11 -fomit-frame-pointer -fmerge-all-constants\ --faggressive-loop-optimizations -finline-functions -funsafe-loop-optimizations\ --ffreestanding -Wlogical-op -Wdouble-promotion -Wformat -Winit-self\ --Wmissing-include-dirs -Wswitch-default -Wpadded -Wswitch-enum -Wall\ --Wunused -Winline -Wuninitialized -Wstrict-overflow\ --Wfloat-equal -Wstack-protector -Wundef -Wvla\ --Wshadow -Wcast-align -Wpedantic -Wextra\ --Wpointer-arith -Wwrite-strings -Wtrampolines -Wpacked\ --Wconversion -Wdate-time -Waggregate-return\ --Wvector-operation-performance\ --Wredundant-decls -Wlong-long -Wvariadic-macros\ --Wdisabled-optimization -Wmissing-declarations -Wunsafe-loop-optimizations\ --pipe -Werror -fno-exceptions -fno-rtti\ --I/usr/share/arduino/hardware/arduino/cores/arduino\ --I/usr/share/arduino/hardware/arduino/variants/micro\ --I/usr/lib/avr/include/\ --DF_CPU=16000000L -MMD -DUSB_VID=0x2341 -DUSB_PID=0x8037 -DARDUINO=105 -D__PROG_TYPES_COMPAT__ -mmcu=atmega32u4 - -ARDUINO?= -PROGRAMMER?= - -.PHONY: all clean check install build - -all: build - -# TODO : find a install commandline -#install: build -# avrdude - -clean: - rm $(OBJ) $(DEP) - -check: - $(CC) $(CFLAGS) -fsyntax-only $(SRC) - -build: $(SRC) - $(CC) $(CFLAGS) $(SRC) -MMD -MP -o hackspace-status.sys - --include $(sort $(DEP)) \ No newline at end of file diff --git a/README.md b/README.md index 8f87533..6293943 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ hackerspace-status-arduino ========================== -see https://kraut.space/hswiki:projekte:2014:raumstatus_anzeige +see https://www.krautspace.de/hswiki:projekte:elektronikrunde:status_anzeige diff --git a/status/status.cpp b/status/status.cpp deleted file mode 100644 index 5ef8e79..0000000 --- a/status/status.cpp +++ /dev/null @@ -1,200 +0,0 @@ -#include -#include -#include "Arduino.h" - -void setup(); -void testLeds(); -void loop(); -void changeStateTo(char state_new); -bool transition(); -void sendState(); -unsigned long calcStateTime(); -/* - * es gibt folgende Zustände: - * 0 - Aus - * 1 - An, aber auf dem weg zu aus - * 2 - An - */ -constexpr char STATE_OFF = 3; -constexpr char STATE_HALF = 1; -constexpr char 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 - */ -constexpr int TIME_HALF = 5400000; // 1,5h -constexpr int TIME_OFF = 7200000; // 2h - -// Ein-/Ausgänge Bezeichnen -constexpr int BTN_ON = 2; // Einschalter -constexpr int BTN_OFF = 3; // Ausschalter -constexpr int LED_G = 9; // grüne LED -constexpr int LED_Y = 8; // gelbe LED -constexpr int LED_R = 7; // rote LED - -// hier wird der aktuelle und vorherige Zustand gespeichert -char state_current = STATE_OFF; -char state_previous = STATE_OFF; - -// hier wird der Beginn des aktuellen Zustand gespeichert in Millisekunden nach Uptime. -unsigned long stateBegan; - -// Debouncer -class Debounce -{ - public: - Debounce(int pin); - bool 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); - testLeds(); - changeStateTo(STATE_OFF); -} - -// Schaltet alle LEDs nacheinander an -void testLeds() { - digitalWrite(LED_R, HIGH); - delay(1000); - digitalWrite(LED_Y, HIGH); - delay(1000); - digitalWrite(LED_G, HIGH); - delay(1000); -} - -// wechselt zu neuen Zustand -void changeStateTo(char state_new) { - state_previous = state_current; - state_current = state_new; - transition(); -} - -// behandelt die Zustandübergänge -bool transition() { - if (state_previous == STATE_OFF && state_current == STATE_ON) { - digitalWrite(LED_R, LOW); - digitalWrite(LED_G, HIGH); - stateBegan = millis(); - return true; - } - if (state_previous == STATE_ON && state_current == STATE_ON) { // STATE_ON ist reflexiv - stateBegan = millis(); - return true; - } - if (state_previous == STATE_ON && state_current == STATE_HALF) { - digitalWrite(LED_G, LOW); - digitalWrite(LED_Y, HIGH); - return true; - } - if (state_previous == STATE_ON && state_current == STATE_OFF) { - digitalWrite(LED_G, LOW); - digitalWrite(LED_R, HIGH); - return true; - } - if (state_previous == STATE_HALF && state_current == STATE_OFF) { - digitalWrite(LED_Y, LOW); - digitalWrite(LED_R, HIGH); - return true; - } - if (state_previous == STATE_HALF && state_current == STATE_ON) { - digitalWrite(LED_Y, LOW); - digitalWrite(LED_G, HIGH); - stateBegan = millis(); - return true; - } - if (state_previous == NULL && state_current == STATE_OFF) { - digitalWrite(LED_G, LOW); - digitalWrite(LED_Y, LOW); - digitalWrite(LED_R, HIGH); - return true; - } - return false; -} - -// information über aktuellen Zustand auf die Serielle Verbindung schreiben -void sendState() { - if (state_current == STATE_ON || state_current == STATE_HALF) { - Serial.print("1"); - } else { - Serial.print("0"); - } -} - -unsigned long calcStateTime() { - // Variablen überlauf von millis erkennen - unsigned long current_uptime = millis(); - // kein überlauf - if (current_uptime > stateBegan) { - return current_uptime - stateBegan; - } - return current_uptime + (ULONG_MAX - stateBegan); -} - -// wird nach dem Starten dauerhaft ausgeführt -void loop() { - // Einschalter auslesen - if (debounceBtnOn.update() && debounceBtnOn.read()) { - changeStateTo(STATE_ON); - } - // Ausschalter auslesen - if (debounceBtnOff.update() && debounceBtnOff.read()) { - changeStateTo(STATE_OFF); - } - - // Auswertung des aktuellen Zustandes - // ggf Zustand wechseln - if (state_current == STATE_ON) { - if (calcStateTime() >= TIME_HALF) { - changeStateTo(STATE_HALF); - } - } else if (state_current == STATE_HALF && calcStateTime() >= TIME_OFF) { - changeStateTo(STATE_OFF); - } - - // kommunizieren - sendState(); - delay(10); -} - -// Debouncer Klasse -Debounce::Debounce(int pin) -{ - pinMode(pin, INPUT); - this->_pin = pin; - this->_time = 0; - this->_state = LOW; - this->_delay = 50; -} -bool 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; -} diff --git a/status/status.ino b/status/status.ino new file mode 100644 index 0000000..68f36f5 --- /dev/null +++ b/status/status.ino @@ -0,0 +1,113 @@ +/* + * 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 +#define INTERRUPT_NAME_BTN_ON 0 +const int BTN_OFF = 3; // Ausschalter +#define INTERRUPT_NAME_BTN_OFF 1 +const int LED_G = 9; // grüne LED +const int LED_Y = 8; // gelbe LED +const int LED_R = 7; // rote LED + +// hier wird der aktuelle Zustand gespeichert +volatile byte state = STATE_OFF; + +// hier wird der Beginn des aktuellen Zustand gespeichert in Millisekunden nach Uptime. +volatile unsigned long stateBegan; + +const long debouncing_time = 50; //Debouncing Time in Milliseconds +volatile unsigned long last_buttonOnPressed; +volatile unsigned long last_buttonOffPressed; + +// 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); + attachInterrupt(INTERRUPT_NAME_BTN_ON, buttonOnPressedDebounce, RISING); + attachInterrupt(INTERRUPT_NAME_BTN_OFF, buttonOffPressedDebounce, RISING); +} + +// 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() { + 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 + if (state == STATE_ON || state == STATE_HALF) { + Serial.print("1"); + } else { + Serial.print("0"); + } + delay(10); +} + +void buttonOnPressedDebounce() { + if (millis() - last_buttonOnPressed >= debouncing_time) { + buttonOnPressed(); + last_buttonOnPressed = millis(); + } +} + +void buttonOnPressed() { + state = STATE_ON; + stateBegan = millis(); +} + +void buttonOffPressedDebounce() { + if (millis() - last_buttonOffPressed >= debouncing_time) { + buttonOffPressed(); + last_buttonOffPressed = millis(); + } +} + +void buttonOffPressed() { + state = STATE_OFF; +}