Esta é uma solução possível para o problema do Semáforo aqui proposto.
Para além da classe Button anteriormente já apresentada, nesta solução foram criadas 3 outras classes (Semaforo, Normal e Blink), todas definidas no ficheiro semaforo.h:
// Only modify this file to include // - function definitions (prototypes) // - include files // - extern variable definitions // In the appropriate section #ifndef _semaforo_H_ #define _semaforo_H_ #include "Arduino.h" //add your includes for the project semaforo here //end of add your includes here #ifdef __cplusplus extern "C" { #endif void loop(); void setup(); #ifdef __cplusplus } // extern "C" #endif //add your function definitions for the project semaforo here #define Bp 12 #define Bi 11 #define Lg 3 #define Ly 5 #define Lr 6 #define S_NORMAL 0 #define S_BLINK 1 #define S_ON 0 #define S_OFF 1 #define S_LG 0 #define S_LY 1 #define S_LR 2 class Normal { public: void begin(); void proc(); private: int state; long unsigned time; bool flag; }; class Blink { public: void begin(); void proc(); private: int state; long unsigned time; }; class Semaforo { public: Semaforo(); void proc(); private: int state; Normal normal; Blink blink; }; //Do not add code below this line #endif /* _semaforo_H_ */
O ficheiro semaforo.cpp será o seguinte:
// Do not remove the include below #include "semaforo.h" #include "button.h" Semaforo fsm; Button butBi(Bi); Button butBp(Bp); //The setup function is called once at startup of the sketch void setup() { // Add your initialization code here Serial.begin(115200); } // The loop function is called in an endless loop void loop() { butBi.proc(); butBp.proc(); fsm.proc(); } Semaforo::Semaforo() { pinMode(Lr, OUTPUT); pinMode(Ly, OUTPUT); pinMode(Lg, OUTPUT); digitalWrite(Lr, LOW); digitalWrite(Ly, LOW); digitalWrite(Lg, LOW); state = S_NORMAL; normal.begin(); } void Semaforo::proc() { switch (state) { case S_NORMAL: normal.proc(); if (butBi.clicked()) { state = S_BLINK; blink.begin(); } break; case S_BLINK: blink.proc(); if (butBi.clicked()) { state = S_NORMAL; normal.begin(); } break; } } void Normal::begin() { digitalWrite(Lg, HIGH); digitalWrite(Ly, LOW); digitalWrite(Lr, LOW); state = S_LG; flag = false; time = millis(); Serial.println("LG"); } void Normal::proc() { long unsigned t; switch (state) { case S_LG: if (butBp.clicked()) flag = true; t = millis() - time; if ((t > 9000) or (flag and (t > 4000))) { time = millis(); state = S_LY; digitalWrite(Lg, LOW); digitalWrite(Ly, HIGH); Serial.println("LY"); } break; case S_LY: if (millis() - time > 1000) { time += 1000; state = S_LR; digitalWrite(Ly, LOW); digitalWrite(Lr, HIGH); Serial.println("LR"); } break; case S_LR: if (millis() - time > 5000) { time += 5000; state = S_LG; digitalWrite(Lr, LOW); digitalWrite(Lg, HIGH); flag = false; Serial.println("LG"); } break; } } void Blink::begin() { digitalWrite(Lg, LOW); digitalWrite(Ly, HIGH); digitalWrite(Lr, LOW); state = S_ON; time = millis(); Serial.println("ON"); } void Blink::proc() { switch (state) { case S_ON: if (millis() - time > 1000) { time += 1000; state = S_OFF; digitalWrite(Ly, LOW); Serial.println("OFF"); } break; case S_OFF: if (millis() - time > 1000) { time += 1000; state = S_ON; digitalWrite(Ly, HIGH); Serial.println("ON"); } break; } }