/*
Solange in Motion LED = an
Wenn aus Timer Starten
Countdown anzeigen
Wenn wieder in Motion reset
Wenn Timer abgelaufen led = aus
*/
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
#include <TM1637TinyDisplay.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
#define DEF_MODE
#define PIN_MOTION_SENSOR 2
#define PIN_LED 3
// Module connection pins (Digital Pins)
#define CLK 5
#define DIO 6
#define PIN_BUTTON 7
#define TIMER_TIME 30000 // 1000 = 1 Sek
#define PS_INIT 0
#define PS_WAIT_ON 1
#define PS_ACTIVE 2
#define PS_TIMER 3
#define PS_TURN_OFF 4
#define PS_BUTTON_PUSHED 5
#define PS_BUTTON_TURN_OFF 6
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned long PreviousMillis = 0;
const long Interval = 1000;
const long CountdownDuration = TIMER_TIME; // 5 Minuten in Millisekunden
unsigned long CountdownEnd; //end
int ProcessState;
bool MotionSensor;
bool ButtonState;
bool LastButtonState;
TM1637TinyDisplay display(CLK, DIO);
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
String convertTime(int totalSeconds) {
int minutes = totalSeconds / 60;
int seconds = totalSeconds % 60;
String time = "";
if (minutes < 10) {
time += "0";
}
time += String(minutes) + "";
if (seconds < 10) {
time += "0";
}
time += String(seconds);
return time;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
void Init()
{
#ifdef DEF_MODE
Serial.println("PS_INIT");
#endif
ProcessState = PS_WAIT_ON;
}
void WaitOn()
{
// bool MotionSensor = digitalRead(PIN_MOTION_SENSOR);
#ifdef DEF_MODE
Serial.println("PS_WAIT_ON");
#endif
// if(MotionSensor)
// {
// //Serial.println("ON");
// display.showNumber(9999);
// digitalWrite(PIN_LED, HIGH);
// ProcessState = PS_ACTIVE;
// }
// else
if(!MotionSensor)
{
//Serial.println("OFF");
display.clear();
digitalWrite(PIN_LED, LOW);
}
}
void Active()
{
// solange aktiv hier bleiben und wenn aus dann weiter
#ifdef DEF_MODE
Serial.println("PS_ACTIVE");
#endif
if(!MotionSensor)
{
//weiter in timer
display.clear();
CountdownEnd = millis() + CountdownDuration; // timer start
ProcessState = PS_TIMER;
}
}
void Timer()
{
#ifdef DEF_MODE
Serial.println("PS_TIMER");
#endif
//countdown
String tmpOut = "";
unsigned long currentMillis = millis();
if (currentMillis >= CountdownEnd) // Timer ende
{
display.showNumberDec(0000, 0b01000000, true);
ProcessState = PS_TURN_OFF;
return;
}
#ifdef DEF_MODE
tmpOut = "currentMillis=" + String(currentMillis) + " PreviousMillis="+ String(PreviousMillis) +"= Result = "+ String(currentMillis - PreviousMillis) + ">= Interval = " + String(Interval) + "Counddown end=" +String(CountdownEnd);
Serial.println(tmpOut);
#endif
if (currentMillis - PreviousMillis >= Interval) // zeit dazwichen
{
PreviousMillis = currentMillis;
int remaining = (CountdownEnd - currentMillis) / 1000;
String time = convertTime(remaining);
#ifdef DEF_MODE
Serial.println(time);
#endif
// Konvert Str to char array
char charArray[time.length() + 1];
time.toCharArray(charArray, time.length() + 1);
display.showString(charArray, 4, 0, 0b00100000);
}
}
void TurnOff()
{
#ifdef DEF_MODE
Serial.println("PS_TURN_OFF");
#endif
digitalWrite(PIN_LED, LOW);
ProcessState = PS_INIT;
}
void ButtonPushed()
{
#ifdef DEF_MODE
Serial.println("PS_BUTTON_PUSHED");
#endif
display.showString("STAT");
digitalWrite(PIN_LED, HIGH);
}
void ButtonTurnOff()
{
#ifdef DEF_MODE
Serial.println("PS_BUTTON_TURN_OFF");
#endif
digitalWrite(PIN_LED, LOW);
ProcessState = PS_INIT;
}
void setup()
{
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("PIN_MOTION_SENSOR 2");
Serial.println("PIN_LED 3");
Serial.println("DISPLAY CLK 5");
Serial.println("DISPLAY DIO 6");
Serial.println("PIN_BUTTON 7");
display.setBrightness(0x0f);
pinMode(PIN_BUTTON, INPUT);
pinMode(PIN_MOTION_SENSOR, INPUT);
pinMode(PIN_LED, OUTPUT);
//Startup Message
display.clear();
display.showString("SYSTEM START");
display.clear();
ProcessState = PS_INIT;
}
void loop()
{
// put your main code here, to run repeatedly:
ButtonState = digitalRead(PIN_BUTTON);
// if(ButtonState && !LastButtonState) // Steigende Flanke
// {
// #ifdef DEF_MODE
// Serial.println("ButtonActive");
// #endif
// if(ProcessState != PS_BUTTON_PUSHED)
// {
// ProcessState = PS_BUTTON_PUSHED;
// }
// else
// {
// ProcessState = PS_BUTTON_TURN_OFF;
// }
// }
if (ButtonState != LastButtonState)
{
if (ButtonState == HIGH)
{
// ledActive = !ledActive; // toggle the ledActive flag
if(ProcessState != PS_BUTTON_PUSHED)
{
ProcessState = PS_BUTTON_PUSHED;
}
else
{
ProcessState = PS_BUTTON_TURN_OFF;
}
}
LastButtonState = ButtonState;
}
#ifdef DEF_MODE
Serial.println(String(ButtonState) + " " + String(LastButtonState));
#endif
LastButtonState = ButtonState;
MotionSensor = digitalRead(PIN_MOTION_SENSOR);
if(MotionSensor && ProcessState != PS_BUTTON_PUSHED)
{
display.showNumberDec(8888, 0b01000000, true); // turn on colon
digitalWrite(PIN_LED, HIGH);
ProcessState = PS_ACTIVE;
}
// State machine
switch(ProcessState)
{
case PS_INIT: Init(); break;
case PS_WAIT_ON: WaitOn(); break;
case PS_ACTIVE: Active(); break;
case PS_TIMER: Timer(); break;
case PS_TURN_OFF: TurnOff(); break;
case PS_BUTTON_PUSHED: ButtonPushed(); break; // Wurde Gedrückt (Langes Festhalten muss berücksichtigt werden)
case PS_BUTTON_TURN_OFF: ButtonTurnOff(); break; // Wartet bis nochmal gedrückt
}
if(ProcessState == PS_WAIT_ON)
delay(300);//Ruhe
else
delay(100);// Counter
}