Como criar um semáforo com Arduino Deixe um comentário

Olá amigos! Nesse post vamos fazer algo relativamente simples mas que abre a possibilidade de conversarmos um pouco sobre programação. A ideia é simular o funcionamento de um semáforo com Arduino. Então sem mais delongas vamos lá!

Material Necessário

Para começar vamos montar nosso circuito. Você vai precisar dos seguintes componentes:

Talvez você esteja se perguntando para que tantos resistores de 220 ohm se o semáforo só tem 3 LEDs? Para que o botão? Tenha paciência. Chegaremos lá!

Semáforo com Arduino, versão básica

A lógica do funcionamento de um sinal varia um pouquinho dependendo de onde você mora mas de um modo geral segue sempre o mesmo padrão:

Verde  > Amarelo > Vermelho > Verde

Semáforo

Bem simples, não? Vamos começar com uma montagem fácil e um código bem básico usando a função delay() do Arduino.

Semáforo com Arduino - versão básica

O que vamos fazer nada mais é do que determinar quais leds estarão acesos e quando, bem como a pausa entre as trocas.

Por que você não tenta fazer antes de olhar? É um bom exercício!

Segue o código:

// dando um "nome" para as portas 
int vermelho = 10;
int amarelo = 9;
int verde = 8;

void setup() {
  // indicando para o arduíno quais portas vamos usar
  pinMode(vermelho, OUTPUT);
  pinMode(amarelo, OUTPUT);
  pinMode(verde, OUTPUT);
}

void loop() {
  // vamos começar do amarelo. Estranho não? 
  // você vai entender no próximo exercício!
  digitalWrite(vermelho, LOW);
  digitalWrite(amarelo, HIGH);
  digitalWrite(verde, LOW);

  // esperamos 2s com o sinal no amarelo
  delay(2000);

  // apagamos o amarelo e ligamos o vermelho
  digitalWrite(amarelo, LOW);
  digitalWrite(vermelho, HIGH);
  // Não precisa desse pois o verde já estava apagado
  // digitalWrite(verde, LOW);

  // esperamos 5s com o sinal fechado
  delay(5000);  

  // para finalizar, apagamos o vermelho e ligamos o verde
  digitalWrite(verde, HIGH);
  // não precisa desse pois o amarelo já estava apagado
  // digitalWrite(amarelo, LOW);
  digitalWrite(vermelho, LOW);

  // esperamos 5s com o sinal aberto
  delay(5000);
}

Desse código simples podemos tirar um primeiro exercício. Se onde você mora a lógica não for exatamente essa, porque não tenta fazer algo igual? Talvez o amarelo acenda junto com o verde antes dos dois desligarem e acender o vermelho. Ou talvez o amarelo também acenda um pouco junto com o vermelho antes de mudar para o verde. Eu já vi essas variações.

Semáforo com Arduino, versão com botão para travessia de pedestres

Essa primeira versão é muito básica! Com certeza podemos ir mais longe. E se tivéssemos um sinal daqueles que tem um botão que o pedestre pressiona para que o sinal feche e ele possa atravessar? Como faríamos?

Agora a lógica vai mudar um pouco, já que o semáforo estará sempre aberto e só irá fechar quando o botão for pressionado.  Vamos também usar o botão que estava na nossa lista (junto com a resistência de 10 kΩ).

Como ficaria o circuito? Segue o esquemático abaixo.

Semáforo com Arduino - versão com botão para travessia de pedestres

Vamos aproveitar esse momento para fazer uma reestruturação no nosso código para deixá-lo mais organizado (no mundo da programação isso é chamado de refatoração).

Não é muito bom termos tanto código concentrado somente na nossa função de loop. No momento temos poucas linhas de código mas conforme formos colocando mais componentes no nosso circuito, a tendência é que fique cada vez mais difícil de entender o que está acontecendo.

Imagine que você tenha um projeto com 1000 linhas de código. Como achar onde está um eventual erro? E se for preciso alterar alguma parte? Qualquer mudança será difícil e cansativa.

As boas práticas de programação nos dizem que é melhor criarmos pequenos módulos separados com as lógicas afins. Pense como se você tivesse vários pequenos programinhas que irão trabalhar juntos orquestrados dentro da função loop()E o bom disso é que essa mesma função que você escreveu, como estará “desacoplada” do programa como um todo, poderá ser utilizada em outras aplicações que você fizer.

Essa discussão faz parte do mundo da engenharia de software. Se gostou e quiser saber mais, procure por “separação de conceitos” e “modularidade” na internet. Não basta ser um Maker! Temos que fazer bem feito e de forma eficiente! Seus programas vão ficar muito mais robustos se você começar a pensar assim.

No nosso caso vamos criar uma função que irá conter toda a lógica da mudança do acender/apagar dos leds. Chamei ela de “semáforo” mas você pode dar o nome que quiser. Sugiro que sejam nomes bem explicativos.

Feito isso, é bem simples encaixar a lógica do nosso botão no código. Basta fazer uma verificação do estado desse botão com um “if”. Se ele for pressionado, iniciamos o código do semáforo.

Segue o código:

// dando um "nome" para as portas 
// agora temos o botão também
int vermelho = 10;
int amarelo = 9;
int verde = 8;
int botao = 12;

void setup() {
  // indicando para o arduíno quais portas vamos usar
  pinMode(vermelho, OUTPUT);
  pinMode(amarelo, OUTPUT);
  pinMode(verde, OUTPUT);

  pinMode(botao, INPUT);

  // iniciamos com o verde ligado ...
  digitalWrite(verde, HIGH);

  // .. e o amarelo e vermelho desligados
  digitalWrite(vermelho, LOW);
  digitalWrite(amarelo, LOW);
}

void loop() {
  if (digitalRead(botao) == HIGH) {
      // esperamos um pouco antes de começar a lógica
      delay(2000);
      semaforo();
  }
}

void semaforo() {
  // amarelo logo após o botão ser pressionado!
  // se encaixa perfeitamente na nossa lógica
  // entendeu porque começamos no amarelo no exercício anterior? 🙂
  digitalWrite(vermelho, LOW);
  digitalWrite(amarelo, HIGH);
  digitalWrite(verde, LOW);

  // esperamos 2s com o sinal no amarelo
  delay(2000);

  // apagamos o amarelo e ligamos o vermelho
  digitalWrite(amarelo, LOW);
  digitalWrite(vermelho, HIGH);
  // Não precisa desse pois o verde já estava apagado
  // digitalWrite(verde, LOW);

  // esperamos 5s com o sinal fechado
  delay(5000);  

  // para finalizar, apagamos o vermelho e ligamos o verde
  digitalWrite(verde, HIGH);
  // não precisa desse pois o amarelo já estava apagado
  // digitalWrite(amarelo, LOW);
  digitalWrite(vermelho, LOW);

  // esperamos 5s com o sinal aberto
  delay(5000);
}

Semáforo com Arduino, versão cruzamento

E para finalizar vamos simular agora o funcionamento de semáforos em um cruzamento de ruas. Teremos dois semáforos que atuarão de forma sincronizada. Depois de tudo que já fizemos, não será tão difícil assim. 

Segue o esquemático:

Semáforo com Arduino - versão cruzamento

O código é bem simples, basta apenas usarmos a lógica da nossa primeira construção duas vezes, sincronizando os dois semáforos, ou seja, em quanto um abre, o outro fecha e vice-versa.

Segue o código:

// dando um "nome" para as portas 
int vermelho_1 = 10;
int vermelho_2 = 11;
int amarelo_1 = 9;
int amarelo_2 = 12;
int verde_1 = 8;
int verde_2 = 13;

void setup() {
  // indicando para o arduíno quais portas vamos usar
  pinMode(vermelho_1, OUTPUT);
  pinMode(amarelo_1, OUTPUT);
  pinMode(verde_1, OUTPUT);

  pinMode(vermelho_2, OUTPUT);
  pinMode(amarelo_2, OUTPUT);
  pinMode(verde_2, OUTPUT);
}

void loop() {
   cruzamento();
}

void cruzamento() {
  // sinal 1 - amarelo
  digitalWrite(vermelho_1, LOW);
  digitalWrite(amarelo_1, HIGH);
  digitalWrite(verde_1, LOW);

  // sinal 2 - amarelo também
  digitalWrite(vermelho_2, LOW);
  digitalWrite(amarelo_2, HIGH);
  digitalWrite(verde_2, LOW);

  // esperamos 2s com o sinal no amarelo
  delay(2000);

  // sinal 1
  // apagmos o amarelo e ligamos o vermelho
  digitalWrite(amarelo_1, LOW);
  digitalWrite(vermelho_1, HIGH);
  // digitalWrite(verde_1, LOW);

  // sinal 2
  // apagmos o amarelo e ligamos o verde
  digitalWrite(amarelo_2, LOW);
  // digitalWrite(vermelho_2, LOW);
  digitalWrite(verde_2, HIGH);

  // esperamos 5s com o sinal fechado (1)/ aberto (2)
  delay(5000);  

  // sinal 1
  // apagamos o vermelho e ligamos o verde
  digitalWrite(verde_1, HIGH);
  // digitalWrite(amarelo_1, LOW);
  digitalWrite(vermelho_1, LOW);

  // sinal 2
  // apagamos o verde e ligamos o vermelho
  digitalWrite(verde_2, LOW);
  // digitalWrite(amarelo_2, LOW);
  digitalWrite(vermelho_2, HIGH);

  // esperamos 5s com o sinal aberto
  delay(5000);
}

E para concluir…

Eu não poderia deixar vocês sem um exercício para casa! Afinal é praticando que se aprende!

1) Vamos voltar com o nosso botão para o circuito, só que agora no cruzamento! Assim um sinal ficará sempre aberto e só fechará quando botão for pressionado (e o outro sincronizará com esse).

2) Essa é para quem já domina bem o Arduíno e quer um desafio um pouquinho mais complexo: Vocês já viram aqueles sinais que tem um contador de tempo? Que tal colocarmos um no nosso circuito? Essa tarefa consiste em pegar nossa primeira montagem e colocar um contador do tipo da figura abaixo:

Display de 7 segmentos: 1 dígito

Uma dica: Se você quiser diminuir a quantidade de fios no seu circuito, existe um semáforo já pronto. É só usar esse da figura que vem até com os resistores:

Módulo Semáforo

Espero que vocês tenham se divertido criando o semáforo! Ajude-nos a melhorar o Blog comentando abaixo sobre este tutorial. Não se esqueça de visitar nosso Fórum para dúvidas e compartilhar suas ideias de projetos com a comunidade. Se você ficou “preso” em algum exercício, é lá que você vai conseguir ajuda.

Divirtam-se e nunca parem de criar! É praticando que aprendemos!

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *