#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSansBold9pt7b.h>
#include <Fonts/Picopixel.h>
#define ENCODER_CLK 2
#define ENCODER_DT 3
#define ENCODER_SW 4
const int LED=11;
const int MOTOR = 5;
const int LED_gr = 7;
int flag=0;
unsigned long switch0=0;
// Countdown state
#define COUNTDOWN_SETUP 0
#define COUNTDOWN_ACTIVE 1
#define COUNTDOWN_PAUSED 2
#define COUNTDOWN_MOTOR 3
#define COUNTDOWN_END 4
// Timer button
#define BUT_PIN 8 // where is our button connected (other end to ground)
long butLastChange = 0; // when did we last register a state change?
int butLastState = LOW; // what was the last state of the button?
int countdownState = COUNTDOWN_SETUP; // begin with us ready to set a countdown time
long lastCountdownChange = 0;
//long lastCountdownChange1 = 0;
// how long since we adjusted the countdown
long wartezeitstart = 0;
long endzeitcounter = 0;
long int modeLastChanged = 0;
int prevClk = HIGH;
int startzeit = 2;
int wartezeit = 1;
int zustellung = 1;
int hoehe = 40;
int counter;
unsigned long delayEnde = 5000;
int wartezeitcounter;
unsigned long startzeit1 = 0;
const int pushbtn1 = 6;
long Timestamp_Button_Pressed;
unsigned long Countdown_start;
unsigned long currentMillis;
unsigned long currentMillis1 = 0;
unsigned long previousTime = 0;
int period = 3000;
unsigned long time_now = 0;
long ledOffDelay;
long ledOnDelay;
int ledState = 1;
int blinkcounter;
long myLastDisplayTime = 0;
bool myWaitingDurationChanged = false;
typedef enum {
SET_STARTZEIT,
SET_WARTEZEIT,
SET_ZUSTELLUNG,
SET_HOEHE,
prog_GO,
} Mode;
Mode mode = SET_STARTZEIT;
Adafruit_SSD1306 display(128, 64, &Wire, -1);
int State=0;
int btnstate1;
void nextMode() {
switch (mode) {
case SET_STARTZEIT:
mode = SET_WARTEZEIT;
break;
case SET_WARTEZEIT:
mode = SET_ZUSTELLUNG;
break;
case SET_ZUSTELLUNG:
mode = SET_HOEHE;
break;
case SET_HOEHE:
mode = SET_STARTZEIT;
break;
}
}
void updateValue(int delta) {
switch (mode) {
case SET_STARTZEIT:
startzeit = constrain(startzeit + delta, 0, 100);
startzeit1 = startzeit ;
break;
case SET_WARTEZEIT:
wartezeit = constrain(wartezeit + delta, 0, 100);
break;
case SET_ZUSTELLUNG:
zustellung = constrain(zustellung + delta, 0, 1000);
break;
case SET_HOEHE:
hoehe = constrain(hoehe + delta, 0, 1000);
break;
}
}
void updateDisplay() {
display.clearDisplay();
display.setFont();
display.setTextColor(1);
//Startzeit
display.setCursor(10, 2);
display.print("Startzeit");
display.setCursor(80, 2);
display.print(startzeit);
display.setCursor (95, 2);
display.print("Min.");
if (mode == SET_STARTZEIT) {
display.setCursor(2, 2);
display.print(">");
}
//Wartezeit zwischen Schritten
display.setCursor(10, 18);
display.print("Wartezeit");
display.setCursor(80, 18);
display.print(wartezeit);
display.setCursor (95, 18);
display.print("Min.");
if (mode == SET_WARTEZEIT) {
display.setCursor(2, 18);
display.print(">");
}
//Schrittweite
display.setCursor(10, 34);
display.print("Zustellung");
display.setCursor(80, 34);
display.print(zustellung);
display.setCursor (95, 34);
display.print("µm");
if (mode == SET_ZUSTELLUNG) {
display.setCursor(2, 34);
display.print(">");
}
//Höhe
display.setCursor(10, 50);
display.print("Hoehe");
display.setCursor(80, 50);
display.print(hoehe);
display.setCursor (95, 50);
display.print("µm");
if (mode == SET_HOEHE) {
display.setCursor(2, 50);
display.print(">");
}
display.display();
return;
}
void encoder () {
if (digitalRead(ENCODER_SW) == LOW && millis() - modeLastChanged > 300)
{
modeLastChanged = millis();
nextMode();
updateDisplay();
}
int clk = digitalRead(ENCODER_CLK);
if (clk != prevClk && clk == LOW) {
int dt = digitalRead(ENCODER_DT);
int delta = dt == HIGH ? 1 : -1;
updateValue(delta);
updateDisplay();
}
prevClk = clk;
}
void setupBut() {
digitalWrite(BUT_PIN, HIGH);
pinMode(BUT_PIN, INPUT_PULLUP); // Input with a pull-up resistor (so high when not connected to ground physically by the button)
return;
}
void updateBut() {
// This is my simple debouncing code, that will ensure 50ms have passed before
// allowing further state changes
if(millis() - butLastChange > 50)
{
if(digitalRead(BUT_PIN) == LOW)
{
if(butLastState == HIGH)
{
butLastChange = millis();
butLastState = LOW;
butPressed(); // run the function for a button press
}
}
else
{
butLastState = HIGH;
}
}
return;
}
void butPressed(){
// This adjusts the state of our device, which uses a finite state machine with 4 different possible states
if(countdownState == COUNTDOWN_SETUP)
{
// If we are in the setup mode, then set our mode to active so the countdown can begin
countdownState = COUNTDOWN_ACTIVE;
}
else if(countdownState == COUNTDOWN_ACTIVE)
{
// If we are currently in the active countdown mode - move us to the paused state
countdownState = COUNTDOWN_PAUSED;
}
/*else if(countdownState == COUNTDOWN_PAUSED)
{
// If we are currently in the paused countdown mode - move us back to the active state
countdownState = COUNTDOWN_ACTIVE;
}*/
else if(countdownState == COUNTDOWN_END)
{
// If our countdown is already over, then move us back to the setup stage
countdownState = COUNTDOWN_SETUP; // reset values ready for the setup state again
}
return;
}
void updateCountdown(){
Serial.println(startzeit1);
if(millis() - lastCountdownChange >= 1000)
{
lastCountdownChange = millis(); // Record when we made this change
startzeit1--; // Reduce seconds by 1
if(startzeit1 < 1) // If seconds are now -1, then we have to reduce mins
{
motoran();
countdownState = COUNTDOWN_MOTOR;
}
}
display.clearDisplay();
display.setCursor(42, 2);
display.print("Wartezeit");
display.setCursor(50, 20);
printTimeInMinutesSeconds(startzeit1);
display.display();
return;
}
void printTimeInMinutesSeconds(unsigned long milliseconds) {
int seconds = (milliseconds / 1000) % 60;
int minutes = (milliseconds / 1000) / 60;
if(minutes < 10) Serial.print("0");
//Serial.print(minutes);
//Serial.println(":");
display.print(minutes);
display.println(":");
if(seconds < 10) Serial.print("0");
//Serial.print(seconds);
display.print(seconds);
display.display();
}
void fertig()
{
digitalWrite(LED, LOW);
digitalWrite(MOTOR, LOW);
digitalWrite(LED_gr, HIGH);
delay(ledOffDelay);
Serial.println("Fertig");
}
void motoran() {
ledOnDelay = 2000;
ledOffDelay = 100;
counter = hoehe / zustellung;
currentMillis = millis();
while (((currentMillis - previousTime) >= ledOffDelay) && (ledState == 1) )
{
ledState = !ledState; // toggles the ledState between true/false
digitalWrite(LED, ledState); // make the led change
digitalWrite(MOTOR, ledState);
previousTime = millis();
blinkcounter++;
}
if (((currentMillis - previousTime) >= ledOnDelay) && (ledState == 0) && blinkcounter <= counter)
{
ledState = !ledState; // toggles the ledState between true/false
digitalWrite(LED, ledState); // make the led change
digitalWrite(MOTOR, ledState);
//starttimer();
previousTime = millis();
display.clearDisplay();
display.setCursor(30,30);
display.print(counter-blinkcounter);
display.display();
if (blinkcounter >= counter)
{
fertig();
}
}
}
void starttimer() {
long ledOffDisplay = previousTime/100;
if(millis() - wartezeitstart >= 1000)
{
wartezeitstart = millis(); // Record when we made this change
ledOffDisplay--; // Reduce seconds by 1
if(ledOffDisplay < 1) // If seconds are now -1, then we have to reduce mins
{
//countdownState = COUNTDOWN_MOTOR;
//currentMillis = millis();
}
}
display.clearDisplay();
display.setCursor(42, 2);
display.print("Wartezeit Countdown");
display.setCursor(50, 20);
display.print(ledOffDisplay);
display.display();
return;
}
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
pinMode(ENCODER_SW, INPUT_PULLUP);
pinMode(LED, OUTPUT);
pinMode(MOTOR, OUTPUT);
pinMode(LED_gr, OUTPUT);
Serial.begin(9600);
//updateDisplay();
setupBut();
//welcome();
updateDisplay();
}
void loop() {
if (countdownState == COUNTDOWN_SETUP) encoder();
updateBut();
if(countdownState == COUNTDOWN_ACTIVE) updateCountdown();
if(countdownState == COUNTDOWN_MOTOR) motoran();
}