Máquina de Estados do Semáforo
Parte da seção Temporização sem delay do Journey de Arduino da Coddy. Lição 10 de 18.
Um semáforo é uma máquina de estados: ele está sempre em um estado (verde, amarelo ou vermelho), cada estado dura um tempo determinado e cada estado sabe qual vem em seguida:
- GREEN: verde aceso; após 2 s, vá para YELLOW
- YELLOW: amarelo aceso; após 1 s, vá para RED
- RED: vermelho aceso; após 2 s, vá para GREEN
Cada linha se torna um case:
case GREEN:
setLights(HIGH, LOW, LOW);
if (now - lightStart >= 2000) {
light = YELLOW;
lightStart = now;
}
break;Com delay(2000), a luz também funcionaria, mas nada mais poderia ser executado. Com millis(), cada passagem por loop() leva microssegundos, então a placa tem tempo para outras tarefas: aqui, um LED de status que pisca o tempo todo para mostrar que o controlador está ativo.
Desafio
MédioO LED de status no pino 13 já pisca, e o enum e lightStart estão prontos. Escreva o semáforo como um switch (light) com um case para cada luz:
- verde 2 s, amarelo 1 s, vermelho 2 s, depois verde novamente
- um LED por vez, com
setLights() - sem
delay(), para que o LED de status continue piscando
Pressione Run e depois Check.
Experimente você mesmo
const int greenLed = 10;
const int yellowLed = 11;
const int redLed = 12;
const int statusLed = 13; // o LED da própria placa
enum Light { GREEN, YELLOW, RED };
Light light = GREEN;
unsigned long lightStart = 0; // quando a luz atual acendeu
unsigned long statusPrevious = 0;
int statusState = LOW;
void setup() {
pinMode(greenLed, OUTPUT);
pinMode(yellowLed, OUTPUT);
pinMode(redLed, OUTPUT);
pinMode(statusLed, OUTPUT);
}
void setLights(int green, int yellow, int red) {
digitalWrite(greenLed, green);
digitalWrite(yellowLed, yellow);
digitalWrite(redLed, red);
}
void loop() {
unsigned long now = millis();
// o LED de status alterna a cada 250 ms, para mostrar que o controlador está funcionando
if (now - statusPrevious >= 250) {
statusPrevious = now;
if (statusState == LOW) {
statusState = HIGH;
} else {
statusState = LOW;
}
digitalWrite(statusLed, statusState);
}
// o semáforo: um switch (light) com um case para cada luz
// verde por 2 s, amarelo por 1 s, vermelho por 2 s, depois verde novamente
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Temporização sem delay
2Máquinas de Estados
Lembre-se do ModoEscolhendo com switchEstados Nomeados com enumMáquina de Estados do SemáforoAlterne Modos com um BotãoPratique por conta própria: Playground de Arduino