Vamos aprender a usar dois LEDs como interface homem-máquina. Quando se trata de eletrônica, sou minimalista, gosto de circuitos o menor possível. Então, criei uma IHM (interface homem-máquina) que é bem minimalista, capaz de mostrar números com dois dígitos (de 0 a 99) usando apenas dois LEDs.
Pode-se argumentar que apenas o código Morse (em um LED) pode ser menor que isso. A ideia aqui é simples, um LED piscará para as dezenas e outro para as unidades. Então, por exemplo, para o número 28, o LED das dezenas piscará duas vezes e o LED das unidades piscará oito vezes. O mesmo para o número 89, onde o LED das dezenas piscará oito vezes e o LED das unidades piscará nove vezes.
Circuito para teste
Para este experimento, você precisará de um Arduino (na verdade, qualquer um serve), um potenciômetro, dois LEDs e dois resistores (estou usando valor de 1k Ohm). Procure o diagrama esquemático abaixo.


Observe que este potenciômetro é apenas uma das muitas coisas que você pode usar como dados de entrada para esta interface homem-máquina. Você pode, por exemplo, ler dados de um sensor i2c (BMP280, SHT21, etc.), obter dados da internet usando um internet shield ou um ESP32, e muito mais. O importante é que os dados sejam limitados entre inteiros de um e dois dígitos (0-99).
Código para testes
Há algumas etapas necessárias para converter um valor analógico em dois LEDs piscando no padrão correto. Vou explicar isso passo a passo e o código completo final estará no final. Primeiro, você precisa transformar seus dados analógicos em um valor inteiro de 1 a 99; estou usando a função map() para isso:
analoginput= map(analogRead(A1), 0, 1023, 0, 99);
Eu leio a entrada analógica A1 e converto seu valor de 0-1023 para 0-99, então coloco o resultado em “analoginput”. Novamente, alguém poderia ler qualquer valor de qualquer sensor usando qualquer protocolo, sendo suficiente convertê-lo para um valor inteiro de 0-99.
O segundo passo é separar dezenas de unidades, eu faço isso comparando o valor inteiro a pedaços ou partes de inteiros:
if(analoginput < 10){
tens= 0;
unit= analoginput;
}else if(analoginput >= 10 && analoginput < 20){
tens= 1;
unit= analoginput - 10;
}else if(analoginput >= 20 && analoginput < 30){
tens= 2;
unit= analoginput - 20;
}else if(analoginput >= 30 && analoginput < 40){
tens= 3;
unit= analoginput - 30;
}else if(analoginput >= 40 && analoginput < 50){
tens= 4;
unit= analoginput - 40;
}else if(analoginput >= 50 && analoginput < 60){
tens= 5;
unit= analoginput - 50;
}else if(analoginput >= 60 && analoginput < 70){
tens= 6;
unit= analoginput - 60;
}else if(analoginput >= 70 && analoginput < 80){
tens= 7;
unit= analoginput - 70;
}else if(analoginput >= 80 && analoginput < 90){
tens= 8;
unit= analoginput - 80;
}else if(analoginput >= 90 && analoginput < 100){
tens= 9;
unit= analoginput - 90;
}else{
tens= 0;
unit= 0;
}
Poderíamos fazer isso para 0-999 também, aninhando IFs da maneira correta. Observe que isso é muito “trabalhoso”, um monte de IFs um após o outro. Essa é a maneira como eu descobri como resolver o problema, mas não a única maneira que poderia ser feito. Ambos os pedaços de código acima estão dentro de um loop que é executado a cada 50 ms (milissegundos):
if (enterFunction2 == true && waittime == true) { //Enter this function every xx milisseconds and IF LEDs are not blinking
previousTime2 = time2;
Ele também é executado somente quando “waittime” é verdadeiro, o que significa que esses cálculos só acontecem quando os dados não estão sendo mostrados. Agora, para a parte de exibição de dados, a saída digital 6 (dezenas) é alternada (ligada e desligada alternadamente) toda vez que essa função é inserida, se “blinkingtens” for verdadeiro:
if(blinkingtens == true && blinkingunits == false){
digitalWrite(7, LOW);
if(enteredtens == false){
enteredtens = true;
doubletens = 2 * tens;
if(doubletens == 0){
doubletens= 1;
}
}
doubletens --;
if(doubletens != 0){
digitalWrite(6, !digitalRead(6));
}else{
blinkingunits = true;
blinkingtens = false;
}
}
Devido ao uso de alternância, tenho que executar a função duas vezes mais “lentamente”, fazendo:
doubletens = 2 * tens;
Em seguida, faço o mesmo para as unidades (saída digital 7), também dobrando o número de vezes que ele executa, devido à função de alternância:
else if(blinkingunits == true && blinkingtens == false){
digitalWrite(6, LOW);
blinkingtens= false;
if(enteredunit == false){
enteredunit = true;
doubleunit = 2 * unit;
if(doubleunit == 0){
doubleunit= 1;
}
}
doubleunit --;
if(doubleunit != 0){
digitalWrite(7, !digitalRead(7));
}else{
waittime = true;
blinkingunits = false;
startedwait = true;
}
}
Quando mostro dezenas e unidades, faço um atraso de (aproximadamente) 700 ms com tudo desligado, antes de passar para a próxima rodada:
else if(waittime == true){
if(startedwait == true){
digitalWrite(6, LOW);
digitalWrite(7, LOW);
startedwait = false;
elapsedtime = millis();
}
if(millis() - elapsedtime > 698){
waittime = false;
}
}
Então o processo é repetido novamente, apenas com um novo valor analógico que foi lido recentemente da entrada analógica. O código completo pode ser visto abaixo. É NÃO BLOQUEANTE, o que significa que você pode executar outros pedaços de código no meio tempo. Usa apenas 10% do espaço do programa e 10% da memória, programa muito leve.
unsigned long time1;
unsigned long previousTime;
bool enterFunction = true;
unsigned long time2;
unsigned long previousTime2;
bool enterFunction2 = true;
bool blinkingtens= false;
bool enteredtens= false;
int doubletens= 0;
bool blinkingunits = false;
bool enteredunit = false;
int doubleunit = 0;
int unit = 0;
int tens = 0;
bool waittime = true;
bool startedwait = false;
long elapsedtime;
int analoginput;
int digituponentering = 1;
void setup() {
Serial.begin(9600);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
}
void loop() {
time1 = micros();
time2 = micros();
if (enterFunction == true) {
previousTime = time1;
// Start your code below
//-----------------------
if(blinkingtens == true && blinkingunits == false){
digitalWrite(7, LOW);
if(enteredtens == false){
enteredtens = true;
doubletens = 2 * tens;
if(doubletens == 0){
doubletens= 1;
}
}
doubletens --;
if(doubletens != 0){
digitalWrite(6, !digitalRead(6));
}else{
blinkingunits = true;
blinkingtens = false;
}
}else if(blinkingunits == true && blinkingtens == false){
digitalWrite(6, LOW);
blinkingtens= false;
if(enteredunit == false){
enteredunit = true;
doubleunit = 2 * unit;
if(doubleunit == 0){
doubleunit= 1;
}
}
doubleunit --;
if(doubleunit != 0){
digitalWrite(7, !digitalRead(7));
}else{
waittime = true;
blinkingunits = false;
startedwait = true;
}
}else if(waittime == true){
if(startedwait == true){
digitalWrite(6, LOW);
digitalWrite(7, LOW);
startedwait = false;
elapsedtime = millis();
}
if(millis() - elapsedtime > 698){
waittime = false;
}
}else{
blinkingtens= true;
enteredtens = false;
enteredunit = false;
}
//-----------------------
// End of your code
}
if (enterFunction2 == true && waittime == true) { //Enter this function every xx milisseconds and IF LEDs are not blinking
previousTime2 = time2;
// Le o sensor algumas vezes
analoginput= map(analogRead(A1), 0, 1023, 0, 99);
Serial.println(analoginput);
if(analoginput < 10){
tens= 0;
unit= analoginput;
}else if(analoginput >= 10 && analoginput < 20){
tens= 1;
unit= analoginput - 10;
}else if(analoginput >= 20 && analoginput < 30){
tens= 2;
unit= analoginput - 20;
}else if(analoginput >= 30 && analoginput < 40){
tens= 3;
unit= analoginput - 30;
}else if(analoginput >= 40 && analoginput < 50){
tens= 4;
unit= analoginput - 40;
}else if(analoginput >= 50 && analoginput < 60){
tens= 5;
unit= analoginput - 50;
}else if(analoginput >= 60 && analoginput < 70){
tens= 6;
unit= analoginput - 60;
}else if(analoginput >= 70 && analoginput < 80){
tens= 7;
unit= analoginput - 70;
}else if(analoginput >= 80 && analoginput < 90){
tens= 8;
unit= analoginput - 80;
}else if(analoginput >= 90 && analoginput < 100){
tens= 9;
unit= analoginput - 90;
}else{
tens= 0;
unit= 0;
}
}
// The DELAY time is adjusted in the constant below >>
if (time1 - previousTime < 299990) { // 1 million microsencods= 1 second delay
/* I have actually used 0.999990 seconds, in a trial to compensate the time that
this IF function takes to be executed. this is really a point that
need improvement in my code */
enterFunction = false;
}
else {
enterFunction = true;
}
if (time2 - previousTime2 < 49990) { // 1 million microsencods= 1 second delay
/* I have actually used 0.999990 seconds, in a trial to compensate the time that
this IF function takes to be executed. this is really a point that
need improvement in my code */
enterFunction2 = false;
}
else {
enterFunction2 = true;
}
}
Resultado final
Fiz um vídeo mostrando como esse código e protótipo funcionam, confira abaixo. Quer ver como usar outro display com Arduino? veja este artigo.
Deixe um comentário