Die Sensoren habe ich noch auskommentiert.
#define relaisPin_8 9 // Relais 8
#define relaisPin_7 8 // Relais 7
#define relaisPin_6 7 // Relais 6
#define relaisPin_5 6 // Relais 5
#define relaisPin_4 5 // Relais 4
#define relaisPin_3 4 // Relais 3
#define relaisPin_2 3 // Relais für LED
#define NDS_Pin 2 // Eingang Niederdruckschalter
#define HDS_Pin 11 // Eingang Hochdruckschalter
#define tasterPin 12 // Eingang Tastereingang
#define wasAuchImmer A3 // Eingang Tastereingang
const unsigned long zeit6H = 21600000UL;
typedef enum eLedZustand { Aus, Schnell, Normal, Langsam } ledZustand;
ledZustand lSignal = Aus;
unsigned long ledInterval = 0;
unsigned long lastLedAction;
const byte relayPins[] = { relaisPin_2, relaisPin_3, relaisPin_4, relaisPin_5, relaisPin_6, relaisPin_7, relaisPin_8 };
unsigned long currentMillis;
// Tastenerkennung
enum {NONE, FIRSTDOWN, FIRSTUP, SHORTCLICK, DOUBLECLICK, LONGCLICK};
#define INPUTMODE INPUT_PULLUP
#define PRELLZEIT 5 // Millisekunden
#define SHORTCLICKTIME 250 // Längste Zeit für einen SHORTCLICK
#define DOUBLECLICKTIME 400 // Längste Zeit für den zweiten Klick beim DOUBLECLICK
#define LONGCLICKTIME 800 // Mindestzeit für einen LONGGLICK
byte buttonPins[] = {tasterPin, wasAuchImmer};
#define NUMBUTTONS sizeof(buttonPins)
byte buttonState[NUMBUTTONS]; // HIGH/LOW
byte buttonResult[NUMBUTTONS]; // NONE/SHORTCLICK/LONGCLICK
enum Zustaende {
unbeschaeftigt,
spuelStart, spuelPhase1, spuelPause, spuelPhase2,
shortStart, shortPhase1, shortPause, shortPhase2,
doubleStart, doublePhase1, doublePause, doublePhase2,
longStart, longPhase1, longPause, longPhase2,
};
byte aktuellerZustand = unbeschaeftigt;
unsigned long lastTransition;
unsigned long letzteSpuelung;
void setup() {
Serial.begin(250000);
Serial.println("Button test");
for (byte i = 0; i < NUMBUTTONS; i++) {
pinMode(buttonPins[i], INPUTMODE);
}
for (byte i = 0; i < sizeof(relayPins); i++) {
digitalWrite(relayPins[i], HIGH);
pinMode(relayPins[i], OUTPUT);
}
}
void loop() {
currentMillis = millis();
// if (digitalRead(NDS_Pin) == LOW) { // wenn der Niederdruckschalter aktiv ist
// digitalWrite(relaisPin_6, HIGH); // Ventil zu
// setLedState(Schnell);
// }
// if (digitalRead(HDS_Pin) == LOW) { // wenn der Hochdruckschalter aktiv ist
// digitalWrite(relaisPin_8, HIGH); // Pumpe aus
// setLedState(Langsam);
// }
if (aktuellerZustand == unbeschaeftigt) {
if (eingabe()) {
ausgabe();
} else if (currentMillis - letzteSpuelung >= zeit6H) {
letzteSpuelung = currentMillis;
aktuellerZustand = spuelStart;
}
} else {
switch (aktuellerZustand) {
case spuelStart:
setupAndGoToState(0b0001111, true, spuelPhase1, PSTR("Test")); // mit 8 0b0101111
break;
case spuelPhase1:
switchAndNewStateAfter(0b0001111, false, spuelPause, 20000); // mit 8 0b0101111
break;
case spuelPause:
switchAndNewStateAfter(0b0001001, true, spuelPhase2, 10); // mit 8 0b0101001
break;
case spuelPhase2:
switchAndNewStateAfter(0b0001001, false, unbeschaeftigt, 15000); // mit 8 0b0101001
break;
case shortStart:
setupAndGoToState(0b0101001, true, shortPhase1, PSTR("300 ml"));
break;
case shortPhase1:
switchAndNewStateAfter(0b0101001, false, shortPause, 15000);
break;
case shortPause:
switchAndNewStateAfter(0b0111000, true, shortPhase2, 500);
break;
case shortPhase2:
switchAndNewStateAfter(0b0111000, false, unbeschaeftigt, 20000);
break;
case doubleStart:
setupAndGoToState(0b0101001, true, doublePhase1, PSTR("1000 ml"));
break;
case doublePhase1:
switchAndNewStateAfter(0b0101001, false, doublePause, 15000);
break;
case doublePause:
switchAndNewStateAfter(0b0111000, true, shortPhase2, 500);
break;
case doublePhase2:
switchAndNewStateAfter(0b0111000, false, unbeschaeftigt, 60000UL);
break;
case longStart:
setupAndGoToState(0b0101001, true, longPhase1, PSTR("8000 ml"));
break;
case longPhase1:
switchAndNewStateAfter(0b0101001, false, longPause, 15000);
break;
case longPause:
switchAndNewStateAfter(0b0111000, true, longPhase2, 500);
break;
case longPhase2:
switchAndNewStateAfter(0b0111000, false, unbeschaeftigt, 480000UL);
break;
}
}
if (lSignal != Aus && currentMillis - lastLedAction >= ledInterval) {
lastLedAction = currentMillis;
digitalWrite(relaisPin_2, !digitalRead(relaisPin_2));
}
benchmark();
}
void setLedState(ledZustand lz) {
if (lz == Aus) {
ledInterval = 0;
digitalWrite(relaisPin_2, HIGH);
} else if (lz != lSignal) {
digitalWrite(relaisPin_2, LOW);
ledInterval = lz * 250;
lastLedAction = currentMillis;
}
lSignal = lz;
}
void switchRelaisSet(byte mask, bool toWhat) {
for (byte idx = 1; mask; idx++, mask >>= 1) {
if (mask & 1) {
digitalWrite(relayPins[idx], toWhat ? LOW : HIGH);
}
}
}
void setupAndGoToState(byte mask, bool toWhat, byte newState, char* txt) {
switchRelaisSet(mask, toWhat);
lastTransition = currentMillis;
aktuellerZustand = newState;
Serial.print(F(" "));
Serial.print((__FlashStringHelper*)txt);
Serial.write(' ');
Serial.println(millis());
}
void switchAndNewStateAfter(byte mask, bool toWhat, byte newState, unsigned long duration) {
if (currentMillis - lastTransition >= duration) {
switchRelaisSet(mask, toWhat);
Serial.print(F(" "));
Serial.print(aktuellerZustand);
Serial.print(F(" -> "));
Serial.print(newState);
Serial.print(F(" nach "));
Serial.print(currentMillis - lastTransition);
Serial.println();
lastTransition = currentMillis;
aktuellerZustand = newState;
}
}
boolean eingabe()
// Rückgabewert false ==> Prellzeit läuft, Taster wurden nicht abgefragt
// Rückgabewert true ==> Taster wurden abgefragt und Status gesetzt
{
static unsigned long lastRunTime;
static unsigned long buttonDownTime[NUMBUTTONS];
unsigned long now = millis();
if (now - lastRunTime < PRELLZEIT) return false; // Prellzeit läuft noch
lastRunTime = now;
for (byte i = 0; i < NUMBUTTONS; i++)
{
byte curState = digitalRead(buttonPins[i]);
if (INPUTMODE == INPUT_PULLUP) curState = !curState; // Vertauschte Logik bei INPPUT_PULLUP
if (buttonResult[i] >= SHORTCLICK) buttonResult[i] = NONE; // Letztes buttonResult löschen
if (curState != buttonState[i]) // Flankenwechsel am Button festgestellt
{
if (curState) // Taster wird gedrückt, Zeit merken
{
if (buttonResult[i] == FIRSTUP && now - buttonDownTime[i] < DOUBLECLICKTIME)
buttonResult[i] = DOUBLECLICK;
else
{
buttonDownTime[i] = now;
buttonResult[i] = FIRSTDOWN;
}
}
else // Taster wird losgelassen
{
if (buttonResult[i] == FIRSTDOWN) buttonResult[i] = FIRSTUP;
if (now - buttonDownTime[i] >= LONGCLICKTIME) buttonResult[i] = LONGCLICK;
}
}
else // kein Flankenwechsel, Up/Down Status ist unverändert
{
if (buttonResult[i] == FIRSTUP && now - buttonDownTime[i] > DOUBLECLICKTIME)
buttonResult[i] = SHORTCLICK;
}
buttonState[i] = curState;
} // for
return true;
}
void ausgabe()
// Klickstatus von geklickten Buttons mit Zeitstempel ausgeben
{
for (byte i = 0; i < NUMBUTTONS; i++)
{
if (buttonResult[i] >= SHORTCLICK) {
Serial.print(millis() / 1000.0, 3); // Zeitstempel mit Millisekundenauflösung
Serial.print("\tPin-");
Serial.println(buttonPins[i]);
if (buttonResult[i] == SHORTCLICK) {
aktuellerZustand = shortStart;
} else if (buttonResult[i] == DOUBLECLICK) {
aktuellerZustand = doubleStart;
} else if (buttonResult[i] == LONGCLICK) {
aktuellerZustand = longStart;
}
}
}
}
void benchmark() {
static unsigned long counterStartTime;
static unsigned long counter;
if (++counter >= 1000000L) {
Serial.print("Average Time per loop(): ");
Serial.print((micros() - counterStartTime) / 1000000.0);
Serial.println(" microseconds");
counter = 0;
counterStartTime = micros();
}
}