Blink without Delay Once!

Hola hoy quiero compartirles un pequeño codigo que tuve que modificar yo mismo, ya que no consegui en los foros algo que me sirviera, pero antes que nada les explico el antecedente que me llevo a hacer la modificacion.

Estoy trabajando con la Placa NodeMcu en un proyecto de IoT para hacer mi propia SmartHome, estoy usando una mezcla de WIFI con modulos RF por medio de los modulos HT12E/D y controlandolo por medio de mi tlf con MQTT. La logica del sistema es enviar la direccion de 8bits + los 4bits de estado por medio de MQTT lo recibe el NodeMCU, el los traduce y activa la transmision de datos por medio del HT12E, el detalle es que esta transferencia por Rf solo se realizaba cuando se enviara la direccion por medio de MQTT y requeria que se tuviera que apagar el pin de transmision (TE) del integrado para que no quedara siempre enviando el comando de encendido y apagado. Por supuesto que la primera opcion fue encender el pin y luego usar un delay() a 1 segundo para que apagara la transmision.

Sabia que el delay suele dar problemas, pero hasta ese momento no sabia el wifi y el MQTT no toleraban en lo absoluto los delay, entonces me di en la tarea de conseguir un codigo (siempre es mas facil copiar y pegar, jajaja) que hiciera que el pin se apagara sin delay despues de un tiempo definido.

Pues no consegui dicho codigo asi que les comparto a continuacion el que yo modifique adaptado que en vez de recibir un dato por MQTT se reactivara el contador al presionar un boton.

/*
  Blink without Delay Once!

  Turns on and off a light emitting diode (LED) connected to a digital pin,
  without using the delay() function, but just once. This means that other code can run at
  the same time without being interrupted by the LED code, and change the led state onece.
  To reactive the counter you have to put the Flag into TRUE state (you can use a button or
  another thats chance the Flag), in this example i use a button to change the state.
  **i didn't use a bounce to the button because it isn´t the point in this code**

  The circuit:
  - Use the onboard LED.
  - Note: Most Arduinos have an on-board LED you can control. On the UNO, MEGA
    and ZERO it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN
    is set to the correct LED pin independent of which board is used.
    If you want to know what pin the on-board LED is connected to on your
    Arduino model, check the Technical Specs of your board at:
    https://www.arduino.cc/en/Main/Products

The Original code is Blink without Delay, This example code is in the public domain.
  http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
  
  created 2005
  by David A. Mellis
  modified 8 Feb 2010
  by Paul Stoffregen
  modified 11 Nov 2013
  by Scott Fitzgerald
  modified 9 Jan 2017
  by Arturo Guadalupi

 This mod (Blink without Delay Once!)
 created 2018
 by Luis A. Franco M.
*/

// constants won't change. Used here to set a pin number:
const int ledPin =  LED_BUILTIN;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED
int btnPin = 2;                 // the pin where the button is connect
bool flag=true;                 // Flag that manage when turn on the counter
bool btnState;                 // hold the button state
// You should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previoustime = 0;        // will store last time LED was updated
unsigned long counter = 0;             // will manage the millis funcion
// constants won't change:
const long interval = 5000;           // Interval at which to blink (milliseconds)
 
  
void setup() {
  
  pinMode(ledPin, OUTPUT);            // set the ledPin as output:
  pinMode(btnPin,INPUT);              // set the Button pin as Input
  flag = true;                        // set the Flag on!
  digitalWrite(ledPin,LOW);           // set the led off

}

void loop() {
counter = millis();                   // Start the couter with the millis funcion
btnState=digitalRead(btnPin);         // Read the button state
  if(btnState){  flag=true;                // if the button is HIGH the Flag get on and
  previoustime = counter;             // this reset the timer saving the current time
  digitalWrite(ledPin,LOW); }         // Set the led off 
  // the next funcion evalute if the flag is on and if is time to blink
  if (counter - previoustime >= interval && flag==true) {
    previoustime = counter;           // save the last time you blinked the LED
    flag=false;                       // set the Flag Off to stop blinking

    // if the LED is off turn it on and vice-versa:
    digitalWrite(ledPin, !digitalRead(ledPin));
    
  }
}

Les explico se basa en el clasico codigo de ejemplo llamado Blink without Delay Once, de http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay dicho codigo como ya sabran hace que un led parpadee en en intervalos, pero lo hace indefinidamente, el codigo que comparto usa una bandera (Flag) que se controla con el boton que una vez presionado el boton 5 segundos despues hara que el led cambie de estado una sola vez.

Espero sus comentarios y retroalimentacion…y realemte espero que les sirva este codigo…

tambien recomiendo a nosotros los novatos leer el post de UKHeliBob que muestra varias adaptaciones tambien. UKHeliBob post!

BlinkWithoutDelayOnce.ino (3.18 KB)

luisfranco1990 te comento que este código Blink whithour delay = millis() es un código presente en el IDE de tu Arduino asi que no hay mucho que buscar para usarlo. En Documentación hay un Indice de temas tutoriales que te permite leer a millis() como uno de los primeros títulos disponibles y las máquinas de estados como la herramienta necesaria para programar usándolo a media y gran escala.

Mientras tanto, el hecho que lo descubrieras del modo que lo has hecho y que pudieras adaptarlo es otro buen aporte para la comunidad.

Por otro lado yendo a tu sistema de dispositivos RF + HT12E no entiendo que es eso de mi

controlandolo por medio de mi tlf con MQTT

Es un nodemcu?

hola surbyte, si estoy usando un nodeMCU que lo comunico con mi smartphone por medio del protocolo MQTT que es comunicacion maquina-maquina (Message Queuing Telemetry Transport)

por otro lado me refiro a RF + HT12E, a un modulo transmisonr RF433mhz (FS1000A) conectado a un integrado HT12E (que es un encode) para enviar un comando a su pareja receptor RF433mhz (XY-MK-5V) conectado HT12D (que es el decoder) para que encienda o apague un relay.

Si conozco cada elemento que has descripto.

Entonces cual es el siguiente paso en el que estas atascado? reemplazar delay?

luisfranco1990 me parece realmente muy interesante tu implementacion del conocido blink without delay a traves de rf y usando el protocolo MQTT, felicidades.

muchas gracias kajanutrio, espero que a alguien le sea util...