Usando o led interno do Arduino para exibir números
Uma função fácil de usar que permite controlar o led interno do Arduino de forma a comunicar rapidamente – e de modo simples de ler – valores ao operador.
Vários modelos de Arduino (incluindo o popular Uno) dispõem de um conveniente led on board conectado ao estado do pino digital 13, de modo que, ao executar o comando digitalWrite(13, HIGH);
1 o led acende e, ao executar o comando digitalWrite(13, LOW);
, ele se apaga.
Ele já é suficientemente útil só executando essa função de acender e apagar, mas que tal usá-lo para exibir números? É só ir um pouco além do método usado há anos pelo kernel Linux para sinalizar um travamento: enquanto o Linux se limita a piscar o LED da tecla Caps Lock em um simples movimento On-Off, nós podemos usar uma função que pisque o led onboard repetitivamente um determinado número de vezes, com pequenas pausas, para comunicar problemas, estados de sensores, etc.
Por que usar o led interno para isso?
Existem várias formas de informar detalhes de situações de erro ou acompanhar estados: um display LCD, leds dedicados, a função Serial.print(), etc. – mas todas elas exigem que algum dispositivo externo de saída esteja conectado ao seu Arduino: o display, um led dedicado, o computador com um monitor serial, etc.
Da minha carreira anterior em desenvolvimento de software, há pelo menos duas lições práticas aplicáveis aqui: a de que incluir elementos (como leds adicionais, comunicação serial ou um display, no nosso exemplo) traz mais complexidade, riscos e potencial de falhas, e a de que geralmente é mais econômico implementar funcionalidades em software do que em dispositivos adicionais.
Assim, para as experiências do meu aprendizado, tenho usado a técnica similar à do Linux: piscar o led interno para me comunicar o andamento dos testes, ao invés de incluir circuitos e componentes adicionais para a mesma finalidade (que eu certamente incluiria se estivesse desenvolvendo um produto para usuários finais).
Uma função de comunicação pelo led, pronta para usar
A função abaixo, que recebe um valor na faixa 0..1023 (a mesma faixa que pode ser lida nos pinos analógicos do Arduino) e aí pisca o led interno indicando um número de 1 a 10, proporcional ao valor recebido (se receber um valor muito baixo pisca uma vez, se estiver bem próximo a 1024 pisca 10 vezes, etc.).
void debugLed(int valorAnalogico) {
// Pisca o led proporcionalmente a um valor analogico
// Augusto Campos 2014 - BR-Arduino.org
int piscas=map(valorAnalogico,0,1023,1,10);
for(int i=0; i<piscas; i++) {
digitalWrite(13, HIGH);
delay(10);
digitalWrite(13, LOW);
delay(250);
}
}
O seu uso é bem simples. Vamos imaginar que eu queira acompanhar as faixas de valores retornadas por um sensor conectado à porta analógica 3 do Arduino. Bastaria incluir o código da função acima ao final do meu programa, e meu loop poderia ficar assim:
void loop() {
int sensor=analogRead(3);
debugLed(sensor);
delay(500);
}
Poderia até ser mais curto que o exemplo acima, mas creio que ele está claro: gravar na variável sensor
o valor lido no pino analógico 3, chamar a função debugLed passando a ela essa variável sensor
, e aguardar meio segundo antes de repetir.
Acima você vê uma animação de um exemplo simples de uso: o Arduino Nano piscando repetidamente o número 4, para indicar que o valor retornado pelo resistor fotossensível conectado à porta analógica é de cerca de 4/10 do máximo. Se eu apagasse a luz do escritório ou apontasse uma lanterna diretamente para o resistor, esse número iria cair ou aumentar (respectivamente) já no próximo ciclo.
Eu já usei várias vezes (inclusive no programa completo acima, que monitorou o sensor de luminosidade), e tem funcionado bem2.
Uma dica que aprendi com o uso é que, para a precisão dos nossos olhos, é melhor fazer os loops de uma forma que o led passe bem mais tempo apagado do que aceso. É igualmente fácil de identificar as piscadas, e a imagem dele não "queima" na nossa visão.
Uma versão mais sofisticada da função
A versão da função vista acima permite acompanhar resultados simplesmente observando as piscadas do led, sem precisar recorrer a outros dispositivos que já não façam parte do projeto.
A versão abaixo tem também suporte a "mensagens" de status simples, piscando de forma diferenciada para indicar situações como "OK", "FALHA", "AGUARDANDO", etc.:
void debugLed(int valorAnalogico) {
// Pisca o led proporcionalmente a um valor analogico
// Se o parametro for negativo, pisca de forma diferenciada, corres-
// pondendo ao numero passado como parametro.
// Augusto Campos 2014 - BR-Arduino.org
int piscas=0;
if (valorAnalogico >= 0) {
piscas=map(valorAnalogico,0,1023,1,10);
} else {
piscas=1+abs(valorAnalogico);
if (piscas>8) piscas=8;
// piscada longa preliminar
for(int i=0; i<6; i++) {
digitalWrite(13, HIGH);
delay(5);
digitalWrite(13, LOW);
delay(30);
}
}
// serie de piscadas
for(int i=0; i<piscas; i++) {
digitalWrite(13, HIGH);
delay(10);
digitalWrite(13, LOW);
delay(250);
}
delay(300);
}
Se ela receber um número positivo como parâmetro, se comporta exatamente como a versão original; mas se o parâmetro for negativo (por exemplo, -1, -3, etc.) ela dá uma piscada longa, seguida de várias piscadas curtas indicando o número recebido como parâmetro.
Aí é só convencionar: -1 pode ser OK, -2 pode ser FALHA, etc. Para usar nos seus programas, é só repetir os comandos dos exemplos acima (quando estiver exibindo o resultado de sensores analógicos), ou usar como neste exemplo, que comunica o parâmetro "-2": debugLed(-2);
.
Quem usou os computadores pessoais do início da década de 80 talvez lembre que era assim (por números, mas não por leds) que alguns deles – como o ZX-81 e seus clones, de onde foi tirada a imagem de tela acima – indicavam o status.
Ficou tão útil, para mim, que talvez eu inclua a função acima em uma biblioteca do Arduino, para facilitar o meu reuso dela. E, futuramente, talvez eu a modifique para que rode em paralelo com o loop, sem que os delays dela atrasem a execução do programa principal.
Se tiver demanda, use à vontade. Se aperfeiçoar, me mande uma cópia ;-)
Comentar