#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSansBold9pt7b.h>
#include <Fonts/Picopixel.h>
// Anschlüsse Encoder
#define ENCODER_CLK 2
#define ENCODER_DT 3
#define ENCODER_SW 5
//Encoder Variablen
long int modeLastChanged = 0;
int prevClk = HIGH;
// Countdown state
#define COUNTDOWN_SETUP 0
#define COUNTDOWN_ACTIVE 1
#define COUNTDOWN_PAUSED 2
#define COUNTDOWN_MOTOR 3
#define COUNTDOWN_END 4
//Variablen Countdown
int countdownState = COUNTDOWN_SETUP; // begin with us ready to set a countdown time
long lastCountdownChange = 0;
//Anschlüsse Motor und Grüne LED
const int MOTOR = 4;
const int LED_gr = 7;
// 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?
long wartezeitstart = 0;
//Werte auf Display hier ändern
long startzeit = 2;
int wartezeit = 1;
int zustellung = 1;
int hoehe = 5;
int counter;
int blinkCounter;
unsigned long currentMillis;
unsigned long previousTime = 0;
unsigned long previousMillis;
unsigned long startCountdownMillis;
unsigned long previousCountdownMillis;
unsigned long printInterval;
unsigned long endDelayStart;
//Werte anpassen (*60 etc.)
long startzeit1 = 120;
long wartezeitrest =1;
long zustellung1 = 100;
long wartezeit1 = 60000; //60000
long ledOffDelay;
long ledOnDelay;
int ledState = 1;
int blinkcounter;
typedef enum {
SET_STARTZEIT,
SET_WARTEZEIT,
SET_ZUSTELLUNG,
SET_HOEHE,
prog_GO,
} Mode;
Mode mode = SET_STARTZEIT;
Adafruit_SSD1306 display(128, 64, &Wire, -1);
//Auswählen der vier einstellbaren Variablen
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;
}
}
//Variable einstellen
void updateValue(int delta) {
switch (mode) {
case SET_STARTZEIT:
startzeit = constrain(startzeit + delta, 0, 100);
// startzeit1 = startzeit * 6; in *60 ändern
startzeit1 = startzeit * 60 ;
Serial.print("Startzeit ");
Serial.println(startzeit1);
break;
case SET_WARTEZEIT:
wartezeit = constrain(wartezeit + delta, 0, 100);
wartezeit1 = wartezeit * 6;
Serial.print("Wartezeit ");
Serial.println(wartezeit1);
break;
case SET_ZUSTELLUNG:
zustellung = constrain(zustellung + delta, 0, 1000);
zustellung1 = zustellung * 100;
break;
case SET_HOEHE:
hoehe = constrain(hoehe + (delta*5), 0, 1000);
break;
}
}
//Display Update
void updateDisplay() {
display.clearDisplay();
display.setFont();
display.setTextColor(1);
//Startzeit
display.setCursor(8, 2);
display.print("Startzeit");
display.setCursor(72, 2);
display.print(startzeit);
display.setCursor (85, 2);
display.print("Min.");
if (mode == SET_STARTZEIT) {
display.setCursor(2, 2);
display.print("-");
}
//Wartezeit zwischen Schritten
display.setCursor(8, 18);
display.print("Wartezeit");
display.setCursor(72, 18);
display.print(wartezeit);
display.setCursor (85, 18);
display.print("Min.");
if (mode == SET_WARTEZEIT) {
display.setCursor(2, 18);
display.print("-");
}
//Schrittweite
display.setCursor(8, 34);
display.print("Zustellung");
display.setCursor(72, 34);
display.print(zustellung);
display.setCursor (85, 34);
display.print("Mikrom.");
if (mode == SET_ZUSTELLUNG) {
display.setCursor(2, 34);
display.print("-");
}
//Höhe
display.setCursor(8, 50);
display.print("Hoehe");
display.setCursor(72, 50);
display.print(hoehe);
display.setCursor (85, 50);
display.print("Mikrom.");
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)
//Serial.println("SetupButton: Check!");
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(){
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;
currentMillis = millis();
//wartezeitstart = millis();
}
}
//Serial.println(startzeit1);
//Serial.println(startzeit1);
display.clearDisplay();
display.setCursor(42, 2);
display.print("Wartezeit");
display.setCursor(50, 20);
printTimeInMinutesSeconds(startzeit1);
display.display();
return;
}
void printTimeInMinutesSeconds(long milliseconds) {
int seconds = (milliseconds % 60);
int minutes = (milliseconds /60);
if(minutes < 10) display.print("0");
display.print(minutes);
display.print(":");
if(seconds < 10) display.print("0");
display.print(seconds);
display.display();
}
void fertig() {
digitalWrite(MOTOR, LOW);
unsigned long startTime = millis();
while (millis() < startTime + wartezeit1); {
Serial.println("Warten");
}
digitalWrite(LED_gr, HIGH);
display.clearDisplay();
display.setCursor(42, 10);
display.print("Fertig");
display.display();
}
void motoran() {
counter = ((hoehe / zustellung));
currentMillis = millis(); // get the current time
if (blinkCounter < counter) {
if (currentMillis - previousMillis >= (ledState ? zustellung1 : wartezeit1)) {
ledState = !ledState; // toggle the state of the LED
digitalWrite(MOTOR, ledState); // set the state of the LED
previousMillis = currentMillis; // update the previous time
if (ledState == LOW) {
blinkCounter++;
startCountdownMillis = currentMillis;
}
}
if(ledState == LOW){
int remainingSeconds = (wartezeit1 - (currentMillis - startCountdownMillis))/1000;
if(ledState == LOW){
if(currentMillis - previousCountdownMillis >= printInterval){
int remainingSeconds = (wartezeit1 - (currentMillis - startCountdownMillis))/1000;
if(remainingSeconds > 0) {
Serial.println(remainingSeconds);
display.clearDisplay();
display.setCursor(1,10);
display.print("Verbl. Schritte");
display.setCursor(1,20);
display.print(counter - blinkCounter);
display.setCursor(1,30);
display.print("Restzeit");
display.setCursor(1, 40);
printTimeInMinutesSeconds(remainingSeconds);
display.display();
previousCountdownMillis = currentMillis;
}
}
}
}
}
else {
endDelayStart = millis();
while (millis() < endDelayStart + wartezeit1) {
}
digitalWrite(LED_gr, HIGH);
display.clearDisplay();
display.setCursor(42, 10);
display.print("Fertig");
display.display();
}
}
void starttimer() {
long ledOffDisplay = previousTime/100;
if(millis() - wartezeitstart >= 1000)
{
wartezeitstart = millis(); // Record when we made this change
ledOffDisplay--; // Reduce seconds by 1
//Serial.println(ledOffDisplay);
/*if(ledOffDisplay < 1) // If seconds are now -1, then we have to reduce mins
{
}*/
}
display.clearDisplay();
display.setCursor(42, 2);
display.print("Wartezeit Countdown");
display.setCursor(50, 20);
display.print(ledOffDisplay);
//printTimeInMinutesSeconds(ledOffDelay);
display.display();
return;
}
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
pinMode(ENCODER_SW, INPUT_PULLUP);
pinMode(MOTOR, OUTPUT);
pinMode(LED_gr, OUTPUT);
Serial.begin(9600);
//updateDisplay();
setupBut();
//welcome();
updateDisplay();
}
void loop() {
//motoran();
if (countdownState == COUNTDOWN_SETUP) encoder();
//Serial.println(startzeit1);
updateBut();
if(countdownState == COUNTDOWN_ACTIVE) updateCountdown();
if(countdownState == COUNTDOWN_MOTOR) motoran();
//if(countdownState == COUNTDOWN_END) fertig();
}