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.
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.
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.
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 arduino;
- 1 protoboard (opcional);
- 2 LED verde;
- 2 LED vermelho;
- 1 LED amarelo;
- 5 resistores de 300 Ohm;
- 1 resistor de 1K Ohm;
- 1 botão do tipo NA (normalmente aberto);
- 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