O Problema
Ok, um probleminha que tentei resolver hoje. Em um projeto preciso piscar um LED para indicar a situação de uma conexão ao LoRaWAN da The Things Network. Mas quero fazer isso em um intervalo curto pois o circuito funcionará na bateria. Por isso quero ligar o LED 20ms a cada 3 segundos mais ou menos.
Como estou lidando com conexão LoRa, não é viável utilizar a função delay() para esse controle, pois a biblioteca LMIC é bem exigente quanto aos seus temporizadores internos. O uso da função delay() tem o potencial de atrapalhar bastante.
Para resolver isso me utilizei de uma técnica também bastante difundida, que é a de se usar a função millis() para saber quanto tempo passou desde que uma condição ocorreu, e tomar uma ação apenas se a condição for satisfeita.
Daí eu acabei implementando um código que me permite piscar múltiplos LEDs a intervalos diferentes para cada um. Eu posto o código abaixo caso isso seja de ajuda para alguém.
Eu também testei esse código através do simulador Wokwi, caso você queira dar uma olhada antes:
O Código
/**
* Copyright (c) 2023 - James Owens
*
* Arquivo: 012_PiscarLEDsMillis.ino
* Arquivo: 09/05/2023 15:04:00
* Versão:
* Fonte:
* Website: https://arduando.com.br
*
* DISCLAIMER:
* The author is in no way responsible for any problems or damage caused by
* using this code. Use at your own risk.
*
* LICENSE:
* This code is distributed under the GNU Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
* More details can be found at http://www.gnu.org/licenses/gpl.txt
*/
typedef struct blinkled {
uint16_t on;
uint16_t off;
uint8_t pin;
bool status;
uint32_t millisLED;
} BLINKLED;
BLINKLED initBlink(uint8_t pin, uint32_t on = 500, uint32_t off = 500)
{
BLINKLED myLED;
myLED.on = on;
myLED.off = off;
myLED.pin = pin;
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
myLED.status = LOW;
myLED.millisLED = millis();
return myLED;
}
void blinkLED(BLINKLED *myLED)
{
if (myLED->status == HIGH)
if ((millis() - myLED->millisLED) > myLED->on)
{
digitalWrite(myLED->pin, LOW);
myLED->status = LOW;
myLED->millisLED = millis();
}
if (myLED->status == LOW)
if ((millis() - myLED->millisLED) > myLED->off)
{
digitalWrite(myLED->pin, HIGH);
myLED->status = HIGH;
myLED->millisLED = millis();
}
}
BLINKLED theLED;
BLINKLED theOtherLED;
BLINKLED theOtherOtherLED;
void setup(void)
{
Serial.begin(9600);
while(!Serial);
theLED = initBlink(LED_BUILTIN, 20, 1980);
theOtherLED = initBlink(12, 60, 980);
theOtherOtherLED = initBlink(4, 250, 654);
}
void loop(void)
{
blinkLED(&theLED);
blinkLED(&theOtherLED);
blinkLED(&theOtherOtherLED);
}