Chegou a hora de começar a conectar algo à nossa placa! Nesta lição, vamos acender e apagar vários LEDs e vamos também aprender a usar as frases condicionais if-else (se-senão). Necessitarás todo o que foi explicado até agora, uma vez que vamos utilizar tudo.
- Comunicação através da porta série
- Funciones e variáveis
Para esta lição necessitarás 1 LED e uma placa controladora tipo ZUM Core (ou compatível Arduino).
Acender e apagar um LED
Acender e apagar um LED é um dos primeiros programas com periféricos que se criam com o Arduino. Por ser o primeiro vamos olhar para ele com um pouco mais de detalhe, mas iremos mais rápidamente nas seguintes lições..
Primeiro: um LED é analógico o digital? Um LED é um componente digital, que apenas pode adquirir dois valores: aceso ou apagado.
Segundo: um LED é um componente de saída ou de entrada? Um LED é um componente de saída, uma vez que devemos comandá-lo, ou seja, devemos dizer-lhe se se deve acender ou apagar, contrariamente a um sensor, que nos dá a leitura de um valor.
Comecemos então por conectar um LED no pino digital 8 da placa, como na figura:
Como explicámos em lições anteriores, existem duas funções fundamentais ao programar em Arduino: setup() e loop(). A função setup() normalmente realiza todas as tarefas de configuração e inicialização, enquanto que a função loop() contém as instruções que serão executadas pelo programa.
void setup()
A única acção de configuração que devemos fazer é indicar que o pino digital 8 é de saída.
1 2 3 4 |
void setup() { pinMode(8,OUTPUT); // configura o pino digital 8 como saída } |
A função pinMode() assume como primeiro parâmetro o número do pino digital, e como segundo, o modo de funcionamento, que pode ser INPUT ou OUTPUT.
void loop()
A seguir, vamos fazer piscar o LED, e para isso vamos acendê-lo, esperamos um segundo, apagamos, e esperamos outro segundo. Dado que a função loop() executa-se continuamente, isto fará com que o LED pisque. Vejamos o código.
1 2 3 4 5 6 |
void loop() { digitalWrite(8, HIGH); //liga o LED delay(1000); //pára a execução 1000 millisegundos digitalWrite(8, LOW); // desliga o LED delay(1000); //pára a execução 1000 millisegundos |
1 |
} |
A función digitalWrite() toma dois parâmetros: o primeiro é o número do pino digital, e o segundo é o estado atribuído: HIGH (Alto) ou LOW (Baixo). Quando o estado é HIGH, serão enviados 5 volts para o pino, enquanto que se for LOW, será ligado à terra (0 volts). Isto causa com que o LED se acenda ou se apague. Para poder realizar uma acção de escrita num pino digital, é necessário que previamente se tenha posto o pinMode em OUTPUT. A função delay() pausa a execução durante o tempo indicado em milissegundos.
Frases condicionais if-else (se-senão)
Uma frase condicional é aquela que modifica o fluxo de execução do programa em função de uma condição. Por exemplo, poderia ser feito um programa que no caso de receber (através da porta série) o carácter H, acenda o LED, e no caso de receber o caractere L, o apague. Vejamos como se faz.
Estructura if-else
A instrucção if-else tem a seguinte estructura:
1 2 3 4 5 6 7 8 9 |
if(condition) { //instruction 1 //instruction 2 }else() { //instruction 3 //instruction 4 } |
Se se cumprir a condição, então as instruções 1 e 2 serão executadas. Em caso contrário, serão executadas as instruções 3 e 4. É preciso salientar que não é necessário existir um senão. Para mais informações, é possível consultar a documentação oficial da instrucção se e da instrucção senão.
Actuando em função de um valor
Vejamos como acender o LED se este receber o caractere H, e apagar se receber o caractere L. Recorda-te da função da lição anterior que pausava a execução do programa, até receber algo pela porta série:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
void waitForInput(){ //Enquanto não existir informação na <em>Serial</em> while(Serial.available()==0){ delay(500); // esperar 500 ms e verificar novamente } // Hey!! Chegou alguma coisa // Enquanto houver informação em espera while(Serial.available()>0){ Serial.read(); //lê e limpa <em>Serial</em> } // quando chegar aqui, <em>Serial</em> está vazio e nós recebemos algo // isso é o que nós queríamos! } |
Modificámos a função para que guarde o caractere que recebeu através da porta série. Esse valor deve ser enviado para outra função (vamos criá-la depois) que gere o que fazer com o caractere lido. Vamos chamá-la manageChar(). Vejamos como ficaria o programa e explicamos logo a seguir:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
int ledPin = 8; //variável global para o número do pino /** * Estas funções recebem os parâmetros como <em>char</em> (caracteres) * e ligam ou desligam o LED, dependendo do seu valor */ void manageChar(char c){ //se o <em>char</em> é igual a <em>H</em> if(c=='H') { digitalWrite(ledPin, HIGH); //liga o LED } //se o <em>char</em> é igual a <em>L</em> if(c=='L') { digitalWrite(ledPin,LOW); //desliga o LED } } /** * Esta função pára a execução do programa até * algo ser recebido através da porta série * Os <em>chars</em> recebidos são enviados para a função <em>manageChar</em> */ void waitForInput(){ //Enquanto existir informação na entrada Serial while(Serial.available()==0){ delay(500); //espera 500 ms e verifica novamente } // Hey!! Chegou alguma coisa // enquanto houver informação em espera while(Serial.available()>0){ char incomingChar = Serial.read(); //lê e limpa Serial manageChar(incomingChar); } // quando chegar aqui, Serial está vazio e nós recebemos alguma coisa // isso era o que nós queríamos! } void setup() { Serial.begin(9600); //inicia a comunicação série a 9600 bauds pinMode(ledPin, OUTPUT); //define o pino do LED como <em>output</em> } void loop() { waitForInput(); //aguarda pela entrada na porta série } |
int ledPin = 8;
Guardámos o número do pino onde está conectado o LED numa variável global. Deste modo evitamos confundir-nos ao escrever-mos nas diversas partes do programa.
void manageChar(char c)
Esta função assume um caractere como parâmetro. Se o valor do dito parâmetro for H (a comparação de igualdade em Arduino escreve-se ==) acende o LED conectado ao pino ledPin (no nosso caso, o 8). Se o parâmetro é L, apaga o LED. Se o parâmetro não for nem H, nem L, esta função não realizará nenhuma acção.
void waitForInput()
Como vimos na lição anterior, esta função espera que cheguem dados através da porta série. Modificámo-la para que armazene o valor lido numa variável tipo char (recordamos que a função Serial.read() devolve um char -byte-)
1 2 |
char incomingChar = Serial.read(); //lê e limpa Serial manageChar(incomingChar); |
Posteriormente, o valor lido é enviado para a função manageChar para que acenda ou apague o LED conforme o valor recebido.
setup()
Define o pino 8 como pino de saída e inicializa as comunicações série a 9600 bauds.
loop()
É a função que se executará continuamente. Neste caso, ela espera até que cheguem dados pela porta série, e quando os recebe, gere esses dados com a função manageChar() e assim por diante.
Exercício
Com tudo o que aprendeste, tenta fazer o seguinte programa: cria um programa que leia a porta série e faça a gestão dos valores lidos do seguinte modo: (A solução será publicada na próxima lição.)
- Primeiro caractere: Indica o número do pino digital, entre 0 e 9
- Segundo caractere: Indica se acender ou apagar o LED, que está conectado ao pino correspondente, pode valer H ou L.
Ou seja, se chegar a sequência 1H4L5H2L pela porta série, deve ser executado o seguinte:
- LEDs conectados aos pinos 1 e 5 acesos
- LEDs conectados aos pinos 4 e 2 apagados
- Os restantes LEDs permanecem no estado em que estavam anteriormente
Vá! Tenta resolver este desafio, partilha o código, e se te atreveres, envia um vídeo do funcionamento.
A solução? Na próxima lição!