OK, Tapetenkleister wird ja nicht so schnell hart wie Gips, also können die beiden Tapetenbahnen noch warten.
Hier erstmal der FSM Code für eine Finite State Machine mit vier Zuständen:
#define runEvery(t) for (static uint16_t _lasttime;\
(uint16_t)((uint16_t)millis() - _lasttime) >= (t);\
_lasttime += (t))
const byte ledPin=13;
const byte buttonPin=7;
byte currentState;
unsigned long stateActiveSince;
void softPWM(byte fadeVal)
{
digitalWrite(ledPin,HIGH);
delayMicroseconds(fadeVal*10);
digitalWrite(ledPin,LOW);
delayMicroseconds((255-fadeVal)*10);
// Serial.println(fadeVal);
}
enum states {LEDOFF, FADEUP, LEDON, FADEDOWN};
void setState(byte index)
{
currentState=index;
stateActiveSince=millis();
Serial.print("Current state is: ");Serial.println(index);
}
long stateTime()
//returns number of milliseconds since current state was set
{
return millis()-stateActiveSince;
}
typedef void (* stateFuncPtr)(); // declare the prototype of a state function pointer
bool buttonPressed()
{
bool result=false;
static byte oldButtonState;
byte buttonState=digitalRead(buttonPin);
if(buttonState!=oldButtonState&&buttonState==LOW) result=true;
oldButtonState=buttonState;
return result;
}
void funcLedOff()
{
runEvery(3) if(buttonPressed()) setState(FADEUP);
digitalWrite(ledPin,LOW);
}
void funcFadeUp()
{
byte fadeVal=0;
if (stateTime()>5100) setState(LEDON);
else{ fadeVal=stateTime()/20; softPWM(fadeVal);}
return;
}
void funcLedOn()
{
if (stateTime()>10000) setState(FADEDOWN);
digitalWrite(ledPin,HIGH);
}
void funcFadeDown()
{
byte fadeVal=255;
if (stateTime()>5100) setState(LEDOFF);
else {fadeVal=255-stateTime()/20; softPWM(fadeVal);}
return;
}
stateFuncPtr stateFunctions[]= {&funcLedOff,&funcFadeUp,&funcLedOn,&funcFadeDown};
// *currentFunction=funcLedOff;
void setup()
{
Serial.begin(9600);
pinMode(ledPin,OUTPUT);
pinMode(buttonPin,INPUT_PULLUP);
setState(LEDOFF);
}
void loop()
{
stateFunctions[currentState]();
}
Die vier Zustände sind LEDOFF,FADEUP, LEDON und FADEDOWN, und werden immer in dieser Reihenfolge durchgesteuert:
Anfangszustand LEDOFF
-bei Tastendruck== FADEUP(linear, innerhalb 5.1 Sekunden)
-nach dem Hochfaden automatische Umschaltung in LEDON
- dann nach 10 Sekunden automatische Umschaltung in FADEDOWN (linear, innerhalb 5.1 Sekunden)
-nach dem Runterfaden automatische Umschaltung in LEDOFF
Und dann kann per Tastendruck wieder in FADEUP umgeschaltet werden.
Probier's mal aus!
Der Taster muss wie folgt angeschlossen sein: Ein Pol an GND, der andere an den im Code definierten Arduino-Pin (es wird der interne Pull-Up Widerstand verwendet und per INPUT_PULLUP aktiviert).
Die LED kann übrigens an einen beliebigen Pin angeschlossen werden, es muss kein PWM-Pin sein, denn die analogWrite Funktion findet in diesem Beispiel keine Verwendung, sondern es wird eine kleine SoftwarePWM Funktion realisiert, die eine LED an jedem beliebigen Pin faden kann.
Probier's mal aus!
Was meinst Du?
Verstehst Du von dem State-Machine-Code etwas?