23 julho 2015

Arduino - Programa 04: Semáforo Interativo com LED

Continuando os tutoriais de arduino, dessa vez trago o código aprimorado do semáforo anterior. A peculiaridade deste código está no fato do usuário poder interagir com o arduino.
Mas, o que estamos a aprender de verdade, é como fazer a leitura de um botão e os tipos de dados e variáveis. Então chega de blá blá, e vamos ao código.



// 04 Semáforo interativo

int carRed = 12; // estabelece o semáforo para carros

int carYellow = 11;

int carGreen = 10;

int pedRed = 9; // estabelece o semáforo para pedestres

int pedGreen = 8;

int button = 2; // pino do botão

int crossTime = 5000; // tempo para que os pedestres atravessem

unsigned long changeTime; // tempo desde que o botão foi pressionado

void setup() {

pinMode(carRed, OUTPUT);

pinMode(carYellow, OUTPUT);

pinMode(carGreen, OUTPUT);

pinMode(pedRed, OUTPUT);

pinMode(pedGreen, OUTPUT);

pinMode(button, INPUT); // botão no pino 2

// acende a luz verde

digitalWrite(carGreen, HIGH);

digitalWrite(pedRed, HIGH);

}

void loop() {

int state = digitalRead(button);

/* verifica se o botão foi pressionado e se transcorreram 5 segundos desde a última vez que

isso ocorreu */

if (state == HIGH && (millis() - changeTime) > 5000) {

delay(1000);

// Chama a função para alterar as luzes

changeLights();

}

}

void changeLights() {

digitalWrite(carGreen, LOW); // apaga o verde

digitalWrite(carYellow, HIGH); // acende o amarelo

delay(2000); // espera 2 segundos

digitalWrite(carYellow, LOW); // apaga o amarelo

digitalWrite(carRed, HIGH); // acende o vermelho

delay(1000); // espera 1 segundo, por segurança

digitalWrite(pedRed, LOW); // apaga o vermelho dos pedestres

digitalWrite(pedGreen, HIGH); // acende o verde dos pedestres

delay(crossTime); // espera por um intervalo de tempo predefinido

// pisca o verde dos pedestres

for (int x=0; x<10; x++) {

digitalWrite(pedGreen, HIGH);

delay(250);

digitalWrite(pedGreen, LOW);

delay(250);

}

// acende o vermelho dos pedestres

digitalWrite(pedRed, HIGH);

delay(500);

digitalWrite(carYellow, HIGH); // acende o amarelo

digitalWrite(carRed, LOW); // apaga o vermelho

delay(1000);

digitalWrite(carGreen, HIGH); // acende o verde

digitalWrite(carYellow, LOW); // apaga o amarelo

// registra o tempo desde a última alteração no semáforo

changeTime = millis();

// depois retorna para o loop principal do programa

}

Como viram acima o código não está completamente comentado, visto que, pelo que já foi apresentado nos tutoriais anteriores, temos condições de olhar e ver o que cada comando no código está executando.Analisando o código, logo temos alguns elementos desconhecidos, e que serão explicados com este tutorial, alguns conceitos que irei descrever aqui poderão ficar vagos, mas em caso de dúvidas deixe seu comentário.

Continuando, a primeira novidade que temos é o tipo de dado "long", até agora só trabalhamos com o tipo de dado inteiro (int). Mas quando falamos em microcontroladores, que possuem pouca memória interna, o tipo e o "tamanho" dos dados que trabalhamos no programa fazem total diferença entre um programa deselegante e lento,  e um programa bem estruturado e ágil. Com o passar do tempo,  cada vez mais seremos capazes de desenvolver programas maiores e mais robustos, o que implica em maior uso da memória, e é ai que importante saber quais os tipos e quanto de memória uma dada variável ocupa.


No programa estamos declarando uma variável do tipo "long", este tipo de variável pode armazenar valores entre -2.137.483.648 e 2.147.483.647. Mas, porém no código foi especificado "unsigned long", o que significa para o arduino que a variável não armazenará números negativos, sendo assim o intervalo para o tipo "long", passa a ir de 0 a 4.294.967.295. Mas, e ai, o que esses números querem dizer ? Isso significa que a nossa variável será capaz de armazenar números racionais, localizados entre o intervalo numérico de 0 a 4.294.967.295. O autor demonstra, o porque de utilizarmos "long" ao invés de "int", ele diz que, uma variável "int" seria capaz de armazenar um intervalo máximo de 32 segundos, sabendo que é improvável um pedestre atrevessar a rua a cada 32 segundos, por isso utilizamos "unsigned long", o que permite trabalharmos com um intervalo de tempo maior. O livro traz alguns números para ajudar-nos a consolidar a ideia.

  • 4.294.967.295 milissegundos = 4.294.967 segundos
  • 4.294.967 segundos = 71.582 minutos
  • 71.582 minutos = 1.193 horas
  • 1.193 horas = 49 dias
Logo, a variável é capaz de armazenar os dados sem "estourar" (termo utilizado quando uma variável excede seu limite) por 49 dias, o que é inevitável que o botão para pedestres seja apertado ao menos uma vez a cada 49 dias. Abaixo temos uma tabela com os tipos de variáveis e o espaço ocupado em memória.


Tabela 1 - Tipos de dados.

Acima podemos conferir os tipos e o tamanho que os dados ocupam na memória do arduino.

Prosseguindo no código, há mais dois comandos novos que vamos conhecer, o "digitalRead" e o "if". O comando digitalRead é bem simples, o que ele faz é ler o que está na porta digital chamada entre os parenteses, este valor é armazenado na variável state como inteiro. Para apresentar o próximo comando, vou apresentar os operadores lógicos. Um operador lógico, é igual a um operador matemático, só que trabalhando em sinais digitais. Para quem não conhece sobre operadores lógicos clique aqui. Se você já é familiarizado com eletrônica digital, isto será mais fácil ainda. Para o arduino e algumas linguagem de programação, os operadores lógicos básicos são descritos abaixo.


  • E lógico => &&;
  • OU lógico => || (barra inclinada para esquerda no teclado);
  • Não Lógico => !
Agora podemos iniciar com o "if", esse comando é chamado de condicional, note que em português "if" significa "se". O comando funcionará sempre que a condição estabelecida for verdadeira. No programa acima o if funcionará sempre que, a variável state for HIGH e a diferença do tempo passado e o tempo definido for maior que 5 segundos. A condição if pode ser aplicada a diversos programas, basta haver a necessidade.
O programa acima ainda destaca uma função chamada de changeLights, ela é criada para realizar uma sub-rotina dentro do programa, é interessante observar neste caso que, se o comando if for falso, em nenhum momento a função changeLights é executada. Como eu utilizo o livro Arduino Básico para me ajudar, mais a frente comentarei de como criar funções. Basicamente o tutorial de hoje termina por aqui, pois a maioria dos comandos acima já foram apresentados nos tutoriais anteriores.

Uma observação importante que faço, é que o código acima é o mesmo do livro, só que, ao fazer os testes em minha bancada, vi que tinha algo errado com o LED verde dos pedestres, ele não acendia muito bem. Então precisei modificar o código e inseri apenas um delay dentro do if antes de executar a função changeLight. O que acontece é que o código evitará erro caso o botão seja pressionado mais de uma vez, e aguardará um determinado tempo para permitir a passagem do restante dos carros. Enfim vamos a melhor parte, a montagem do hardware.


Para este exemplo os seguintes componentes são necessários.

  1. 1 arduino;
  2. 1 protoboard (opcional);
  3. 2 LED verde;
  4. 2 LED vermelho;
  5. 1 LED amarelo;
  6. 5 resistores de 300 Ohm;
  7. 1 resistor de 1K Ohm;
  8. 1 botão do tipo NA (normalmente aberto);
  9. Fios e jumpers;
Figura 1 - Foto dos componentes utilizados.
Abaixo apresento o esquema para montar a parte de hardware.

Figura 2 - Esquema de hardware do programa.

Para ligar o botão, utilize o resistor de 1k Ohm, abaixo a imagem do esquema de ligação do botão.

Figura 3 - Esquema de ligação do botão.
E para finalizar algumas fotos da minha montagem.

Figura 4 - Minha montagem.
Figura 5 - Minha montagem.
Para baixar este e mais programas clique aqui.

Como não pode faltar,  um vídeo demonstrando o funcionamento.



Bom, espero que tenham gostado, qualquer dúvida, deixe seu comentário. Se inscreva no nosso canal do YouTube e fique por dentro das novidades ! 
Até o próximo tutorial !

2 comentários

Bom dia, é possível fazer um exemplo de maquete com duplo sentido e com os mesmos componentes ? Aí tem um exemplo pra 1 sentido e se for colocar no outro sentido ?

Bom dia Ramon! Sim, é possível fazer a maquete com duplo sentido, porém você terá que utilizar o dobro dos componentes para montar um semáforo com dois sentidos.


EmoticonEmoticon