/* Steuerung einer Taschenlampe mit einem Zustandsautomat
* und PWM. Das PWM-Signal wird mit der LEDC-Baugruppe erzeugt,
* 100Hz Frequenz und 12 Bit Auflösung werden gewählt. MAX_PWM = 2^12-1 = 4095
* Da die LED Active-LOW beschaltet ist, muss der PWM-Wert invertiert
* werden => Ausgabe MAX_PWM - Sollwert
*/
//***** Portpins für Ein-/Ausgänge ****************************************
const int Enc_A = 34, Enc_B = 35, Enc_Taster = 0, NEO_Pin=26;
const int LED_rot = 32, LED_gruen = 33, Taster2 = 2, Taster4 = 4;
// ***** Datentyp für Zustände ********************************************
enum Zustaende_t { Aus, Low, Normal, High};
Zustaende_t Taschenlampe; // Variable vom Typ Zustaende_t
// ***** Globale Variablen ************************************************
bool T2_neu, T2_alt, T4_neu, T4_alt; // für Flankenerkennung
unsigned long nextMillis, Zeit;
bool bTaster;
#define PWM_Bits 12
#define MAX_PWM 4095
// ***** Initialisierung **************************************************
void setup() {
// Standard-Initialisierung für die blaue Patine
Serial.begin(115200); // Serielle Schnittstelle mit 115200Bit/s
pinMode(LED_rot, OUTPUT); // die LEDs beginnen danach
pinMode(LED_gruen, OUTPUT); // zu leuchten! (Active-LOW)
digitalWrite(LED_rot, HIGH); // also beide ausschalten
digitalWrite(LED_gruen, HIGH);
pinMode(Taster2, INPUT_PULLUP); // Taster brauchen hier den
pinMode(Taster4, INPUT_PULLUP); // Pullup-Widerstand
// LEDC Initialisieren
ledcAttachChannel ( LED_gruen, 100, 12, 0); // 100Hz und 12 Bit Auflösung
// ODER ledcAttach ( LED_gruen, 100, 12); // Kanalvergabe macht der Compiler
Taschenlampe = Aus;
Serial.printf("Taschenlampe ist aus\n");
Serial.printf("Dimmer-Werte von 0 bis %d\n", MAX_PWM);
}
// ***** Endlosschleife ***************************************************
void loop() {
unsigned long currentMillis = millis( );
if ( currentMillis >= nextMillis ) {
nextMillis = currentMillis + 50; // 20x pro Sekunde
Einlesen( );
Automat( );
Ausgeben( );
}
}
// ***** Eigene Funktionen ************************************************
// ***** Einlesenfunktion: liest alle Eingänge und speichert in globalen Variablen
void Einlesen ( ) {
// Flankenerkennung für beide Taster
T2_neu = digitalRead(Taster2);
T4_neu = digitalRead(Taster4);
if ( T4_neu == 0 && T4_alt == 1) { // fallende Flanke = Tastendruck
bTaster = true;
}
else {
bTaster = false;
}
T2_alt = T2_neu; // für Flankenerkennung
T4_alt = T4_neu; // für Flankenerkennung
}
// ***** Automaten-Funktion ***********************************************
void Automat ( ) {
switch(Taschenlampe) {
case Aus: ledcWrite (LED_gruen, MAX_PWM - 0); // Ausschalten
if (bTaster == true) {
Taschenlampe = Low;
Serial.println("Schalte niedrige Helligkeit ein");
}
break;
case Low: ledcWrite (LED_gruen, MAX_PWM - 1024); // 25%
if (bTaster == true) {
Taschenlampe = Normal;
Serial.println("Schalte mittlere Helligkeit ein");
}
break;
case Normal: ledcWrite (LED_gruen, MAX_PWM - 2048); // 50%
if (bTaster == true) {
Taschenlampe = High;
Zeit = millis( ); // maximale Helligkeit darf nur 5s an sein
Serial.println("Schalte maximale Helligkeit ein");
}
break;
case High: ledcWrite (LED_gruen, MAX_PWM - 4095); // Maximale Helligkeit
if (bTaster == true) {
Taschenlampe = Aus;
Serial.println("Schalte Taschenlampe aus");
}
if (millis()-Zeit >= 5000) { // Zeitsteuerung als Überhitzungsschutz
Taschenlampe = Normal;
Serial.println("Zeit für High abgelaufen, schalte normale Helligkeit ein");
}
break;
default: break;
}
}
// ***** Ausgabe-Funktion *************************************************
// ***** Schreibe den Wert der globalen Variablen an die Ausgänge *********
void Ausgeben( ) {
// hier ist nur eine Ausgabe mit ledcWrite, daher keine extra Funktion
}
Taster2
Taster4
LED32
LED33
ESP32 Schulboard mit LEDs und Tastern, I2C-Bus mit Standard-Belegung
SSD1306 Display
WS2812 an Pin26