LED mit einem Taster Hoch und Runter Dimmen

ardubu:
Zustand und Zeit bei Pegeländerung merken, bei kurzer Zeit Zeit Zustand ändern bei langer Zeit Dimmwert hoch oder runterlaufen lassen.

#define EIN 2
#define DIM 9
#define DRUECKZEIT 300
uint32_t aktMillis, prellMillis, tasterMillis, dimMillis, intervall;
int dimWert, dimDelta = 5;
bool aktTaster, altTaster, pruef, dimmen = true;

void setup() {
  Serial.begin(9600);
  Serial.println("Start");
  pinMode(EIN, INPUT_PULLUP);  // gedrückt ist LOW
}

void dim() {
  dimWert += dimDelta;
  if (dimWert > 255) {
    dimWert = 255;
    dimDelta = -dimDelta;
  }
  if (dimWert < 0) {
    dimWert = 0;
    dimDelta = -dimDelta;
  }
  analogWrite(DIM, dimWert);
}

void loop() {
  aktMillis = millis();
  altTaster = aktTaster;
  if (aktMillis - prellMillis >= 30) {
    prellMillis = aktMillis;
    aktTaster = digitalRead(EIN);
  }
  if (!aktTaster && altTaster) {
    tasterMillis = aktMillis;
    pruef = true;
  }
  if (pruef && aktMillis - tasterMillis >= DRUECKZEIT) {
    pruef = false;
    if (aktTaster) {
      if (dimWert < 11) {
        dimWert = 255;
      } else {
        dimWert = 0;
      }
      analogWrite(DIM, dimWert);
      dimmen = false;
    } else {
      dimmen = true;
    }
  }
  if (dimmen && aktTaster && !altTaster) {
    dimmen = false;
  }
  if (dimmen && aktMillis - dimMillis >= 30) {
    dimMillis = aktMillis;
    dim();
  }
}

combie:
Das ist die erste Grundlage für deinen endlichen Automaten.

#define EIN 2  // Tasterpin
#define DIM 9  // LED-Pin
#define ENTPRELLZEIT 30
#define DRUECKZEIT 300
#define DIMVERZOEGERUNG 100
const byte pwmtable[] PROGMEM = {0, 2, 3, 4, 6, 8, 11, 16, 23, 32, 45, 64, 90, 128, 181, 255};
const byte dimElemente = sizeof(pwmtable);  // Anzahl Elemente der Tabelle
enum {WARTEN, ZEIT, DIMMEN};  // mögliche Zustände des endlichen Automaten
byte zustand = WARTEN;
uint32_t aktMillis,   // Zeit seit Reset in ms
prellMillis,   // relative Entprellzeit in ms
tasterMillis,   // relative Zeit für Tastendruck in ms
dimMillis;   // relative Zeit zum Dimmen in ms
int dimWert,   // Wert für die LED; mit Vorzeichen, damit auch -1 möglich ist
dimIndex; // Feldindex
bool rauf = true, // Dimmrichtung
aktTaster,  // aktueller Zustand Taster
altTaster; // alter Zustand Taster

void setup() {
  pinMode(EIN, INPUT_PULLUP);  // gedrückt ist LOW
}

void dim() {
  if (rauf) {
    dimIndex++;
  } else {
    dimIndex--;
  }
  if (dimIndex >= dimElemente) {
    dimIndex = dimElemente - 2;
    rauf = false; // Richtung ändern
  }
  if (dimIndex < 0) {
    dimIndex = 1;
    rauf = true; // Richtung ändern
  }
  dimWert = pgm_read_byte(&pwmtable[dimIndex]); // Wert aus der Tabelle ausgeben
  analogWrite(DIM, dimWert);
}

void loop() {
  aktMillis = millis(); // eindeutig für diese Schleife
  altTaster = aktTaster; 
  if (aktMillis - prellMillis >= ENTPRELLZEIT) { // Taster nur gelegentlich lesen, dadurch entprellen
    prellMillis = aktMillis;
    aktTaster = digitalRead(EIN);
  }
  switch (zustand) { // endlicher Automat
    case WARTEN:
      if (!aktTaster && altTaster) { // wenn Taster gedrückt (Flanke)
        tasterMillis = aktMillis; // Stoppuhr starten
        zustand = ZEIT;
      }
      break;
    case ZEIT:
      if (aktMillis - tasterMillis >= DRUECKZEIT) {
        zustand = DIMMEN; // nach der DRUECKZEIT, also langer Druck
      }
      if (aktTaster) { // vor der DRUECKZEIT, also kurzer Druck
        if (dimWert < 127) {
          dimWert = 255; // AN
        } else {
          dimWert = 0; // AUS
        }
        analogWrite(DIM, dimWert);
        zustand = WARTEN;
      }
      break;
    case DIMMEN:
      if (aktTaster) { // wenn Taster Losgelassen, dann Dimmwert beibehalten
        zustand = WARTEN;
      }
      if (aktMillis - dimMillis >= DIMVERZOEGERUNG) { // nächster Dimmschritt
        dimMillis = aktMillis;
        dim();
      }
  }
}

Endliche Automaten gefallen mir :slight_smile: