#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#define L1_out 9
#define L1_up 8
#define L1_down 7
#define L1_in 6
#define L2_out 5
#define L2_up 4
#define L2_down 3
#define L2_in 2
#define STOP_LED 13
#define BTN_STARTSTOP A0
#define BTN_EEPROM_RESET A1
#define TOUT 10000 //ms
#define TUP 15000
#define TDOWN 15000
#define TIN 10000
LiquidCrystal_I2C lcd(0x27,20,4);
enum States {
STOPPED,
BOTTOM_OUT,
UP,
TOP_IN,
TOP_OUT,
DOWN,
BOTTOM_IN,
};
States state;
bool stateChangedFlag = false;
bool ButtonPressed = false;
uint32_t t_out = TOUT;
uint32_t t_up = TUP;
uint32_t t_down = TDOWN;
uint32_t t_in = TIN;
uint32_t currentTime;
uint32_t stateTime = 0;
float restTime = 0;
uint32_t stateDur;
int counter;
int counterZero = 0;
uint32_t displayRefresh = 200; //ms
uint32_t lastDisplayRefresh = 0;
void setup() {
Serial.begin(9600);
EEPROM.begin();
lcd.init();
lcd.backlight();
pinMode(L1_out, OUTPUT);
pinMode(L1_up, OUTPUT);
pinMode(L1_down, OUTPUT);
pinMode(L1_in, OUTPUT);
pinMode(L2_out, OUTPUT);
pinMode(L2_up, OUTPUT);
pinMode(L2_down, OUTPUT);
pinMode(L2_in, OUTPUT);
pinMode(STOP_LED, OUTPUT);
pinMode(BTN_STARTSTOP, INPUT);
// EEPROM read / reset
if(digitalRead(BTN_EEPROM_RESET) == LOW)
EEPROM.put(1020, counterZero);
else
EEPROM.get(1020, counter);
switchOffRelais();
changeState(STOPPED);
digitalWrite(STOP_LED, HIGH);
}
void loop() {
currentTime = millis();
if (digitalRead(BTN_STARTSTOP) == LOW) {
ButtonPressed = true;
delay(10);
}
if (digitalRead(BTN_STARTSTOP) == HIGH && ButtonPressed == true) {
ButtonPressed = false;
if(state == STOPPED) {
changeState(BOTTOM_OUT);
digitalWrite(STOP_LED, LOW);
Serial.println("Start");
}
else {
changeState(STOPPED);
digitalWrite(STOP_LED, HIGH);
Serial.println("Stopped");
}
}
switch (state) {
case STOPPED:
if(stateChangedFlag) { //Execute once
lcd.setCursor(0,0);
stateChangedFlag = false;
}
break;
case BOTTOM_OUT:
if(stateChangedFlag) { //Execute once
digitalWrite(L1_out, HIGH);
digitalWrite(L2_out, HIGH);
stateDur = t_out;
stateChangedFlag = false;
}
if(currentTime - stateTime >= t_out)
changeState(UP);
break;
case UP:
if(stateChangedFlag) { //Execute once
digitalWrite(L1_up, HIGH);
digitalWrite(L2_up, HIGH);
stateDur = t_up;
stateChangedFlag = false;
}
if(currentTime - stateTime >= t_up)
changeState(TOP_IN);
break;
case TOP_IN:
if(stateChangedFlag) { //Execute once
digitalWrite(L1_in, HIGH);
digitalWrite(L2_in, HIGH);
stateDur = t_in;
stateChangedFlag = false;
}
if(currentTime - stateTime >= t_in)
changeState(TOP_OUT);
break;
case TOP_OUT:
if(stateChangedFlag) { //Execute once
digitalWrite(L1_out, HIGH);
digitalWrite(L2_out, HIGH);
stateDur = t_out;
stateChangedFlag = false;
}
if(currentTime - stateTime >= t_out)
changeState(DOWN);
break;
case DOWN:
if(stateChangedFlag) { //Execute once
digitalWrite(L1_down, HIGH);
digitalWrite(L2_down, HIGH);
stateDur = t_down;
stateChangedFlag = false;
}
if(currentTime - stateTime >= t_down)
changeState(BOTTOM_IN);
break;
case BOTTOM_IN:
if(stateChangedFlag) { //Execute once
digitalWrite(L1_in, HIGH);
digitalWrite(L2_in, HIGH);
stateDur = t_in;
stateChangedFlag = false;
}
if(currentTime - stateTime >= t_in) {
changeState(BOTTOM_OUT);
counter+=2;
writeEEPROM(); // write counter to EEPROM
updateDisplay();
Serial.print("Counter: ");
Serial.println(counter);
}
break;
}
if(millis()-lastDisplayRefresh >= displayRefresh){
lastDisplayRefresh = millis();
updateDisplay();
}
}
void changeState(States nextState) {
// Switch off all relays
switchOffRelais();
state = nextState;
stateTime = currentTime;
stateChangedFlag = true;
updateDisplay();
}
void switchOffRelais() {
digitalWrite(L1_out, LOW);
digitalWrite(L1_up, LOW);
digitalWrite(L1_down, LOW);
digitalWrite(L1_in, LOW);
digitalWrite(L2_out, LOW);
digitalWrite(L2_up, LOW);
digitalWrite(L2_down, LOW);
digitalWrite(L2_in, LOW);
}
void updateDisplay() {
lcd.clear();
//State
lcd.setCursor(0,0);
switch(state) {
case STOPPED:
lcd.print("Stop");
break;
case BOTTOM_OUT:
lcd.print("Raus");
break;
case UP:
lcd.print("Hoch");
break;
case TOP_IN:
lcd.print("Rein");
break;
case TOP_OUT:
lcd.print("Raus");
break;
case DOWN:
lcd.print("Runter");
break;
case BOTTOM_IN:
lcd.print("Rein");
break;
}
switch(state) {
case STOPPED:
lcd.setCursor(7,0);
lcd.print("R:-");
break;
default:
lcd.setCursor(7,0);
lcd.print("R:");
restTime = (stateDur - (currentTime - stateTime))/1000.0;
lcd.setCursor(9,0);
lcd.print(restTime);
lcd.print("s");
break;
}
lcd.setCursor(0,1);
lcd.print("Zaehler: ");
lcd.setCursor(9,1);
lcd.print(counter);
}
void writeEEPROM() {
EEPROM.put(1020, counter);
}