NodeMCU 8266 While loop delay- problem

Hi I have a problem I’m not able to solve. I’m making my curtain smart. I have two relays, a Bluetooth module (HC-05) and a magnetsensor hooked up to a NodeMCU 8266.

I can control my curtains through my GoogleHome and an app i made. I have placed a magnet inside my curtain, this will send a signal to the magnetsensor and the magnetsensor will close the relays.

THE PROBLEM: I want my magnetsensor to be able to update itself as fast as possible, so it can close the relays at the right place. The While loop has 5000 milliseconds delay wich makes the entire script wait, including my magnetic sensor and app.

To solve the problem i think a have to use the function “millis ();” or “yield ();” but i can’t figure it out!

Thanks in advance

The code:

#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include <SoftwareSerial.h>

#define WIFI_SSID ""
#define WIFI_PASS ""

#define MQTT_SERV "io.adafruit.com"
#define MQTT_PORT 1883
#define MQTT_NAME ""
#define MQTT_PASS ""

SoftwareSerial btSerial(D2, D3); // Rx,Tx

int led = D6;// op= medUr
int modUr = D5;//= ned=modUr
int state = 0;
int stopper = 1;
int magnet =D1;
WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, MQTT_SERV, MQTT_PORT, MQTT_NAME, MQTT_PASS);

Adafruit_MQTT_Subscribe onoff = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME "/f/ONOF");
Adafruit_MQTT_Publish LightsStatus = Adafruit_MQTT_Publish(&mqtt, MQTT_NAME "/f/LightsStatus");
Adafruit_MQTT_Subscribe halvtredsProcent = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME "/f/halvtredsProcent");

void setup()
{
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
   btSerial.begin(9600); 

  //Connect to WiFi
  Serial.print("\n\nConnecting Wifi>");
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  digitalWrite(LED_BUILTIN, LOW);

  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(">");
    delay(50);
  }

  Serial.println("OK!");

  //Subscribe to the onoff topic
  mqtt.subscribe(&halvtredsProcent);
  mqtt.subscribe(&onoff);
 
  pinMode(led, OUTPUT);
  pinMode(modUr, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  digitalWrite(led, LOW);
  digitalWrite(modUr, LOW);
}

void loop()
{
  wifiLoop();
  blueToothLoop();
  magnetLoop();

}
  void magnetLoop ()
  {
    state=digitalRead(magnet);
    if(state==LOW){
      digitalWrite(modUr,LOW);
    }

  }

  void blueToothLoop ()
  {
    if (btSerial.available() > 0) {    // check if bluetooth module sends some data to esp8266
    char data = btSerial.read();  // read the data from HC-05

  // 100% up//////////////////////////////////////////////////////////////////////////////////////////////
  if(data=='1'&& stopper ==1 ){
     digitalWrite(modUr, HIGH); 
    
     /*delay(20250 );
     digitalWrite(modUr, LOW);
     */
     stopper=0;
  }
 
  
 // 100% down///////////////////////////////////////////////////////////////////////
  if(data=='0'&& stopper== 0){
     digitalWrite(led, HIGH); 
     delay(17150);
     digitalWrite(led, LOW);
     stopper= 1;
    }

    /////////////////////////////////////////////////////////////80%up
  if(data=='2'&& stopper==4){
     digitalWrite(modUr, HIGH); 

    /*
     delay(14560);
     digitalWrite(modUr, LOW);
*/
     stopper= 0;
    }

    ///////////////////////////////////////////////////////////80% ned
   if(data=='4'&&  stopper==0){
     digitalWrite(led, HIGH); 
     delay(14560);
     digitalWrite(led, LOW);
     stopper = 4;
    }

    /////////////////////////////////////////////////////50% op
 if(data=='3'&& stopper== 6){
     digitalWrite(led, HIGH); 
  /*  
     delay(9100);
     digitalWrite(modUr, LOW);
*/
     stopper=0;
 }

 ////////////////////////////////////////////////50% ned
 if(data=='6'&& stopper== 0){
     digitalWrite(led, HIGH); 
     delay(9100);
     digitalWrite(led, LOW);

     stopper= 6;
    }

    //////////////////////////////////////////////////////////trim op
 if(data=='8'){
     digitalWrite(modUr, HIGH); 
     delay(250);
     digitalWrite(modUr, LOW);
    }

    //////////////////////////////////////////////////////// trim ned
 if(data=='9'){
     digitalWrite(led, HIGH); 
     delay(250);
     digitalWrite(led, LOW);
    }
   }
}


 void wifiLoop ()
 {
   //Connect/Reconnect to MQTT
  MQTT_connect();

  //Read from our subscription queue until we run out, or
  //wait up to 5 seconds for subscription to update
  Adafruit_MQTT_Subscribe * subscription;
  while ((subscription = mqtt.readSubscription(5000)))
  {
    //If we're in here, a subscription updated...
    if (subscription == &onoff)
    {
      //Print the new value to the serial monitor
      Serial.print("onoff: ");
      Serial.println((char*) onoff.lastread);

      //If the new value is  "ON", turn the light on.
      //Otherwise, turn it off.
      if (!strcmp((char*) onoff.lastread, "ON"))
      {
        //active low logic
        digitalWrite(led, HIGH);
        delay(5000);
        LightsStatus.publish("ON");
        digitalWrite(led,LOW);

      }
      else if (!strcmp((char*) onoff.lastread, "OFF"))
      {
        digitalWrite(led, LOW);
        LightsStatus.publish("OFF");

      }
      else
      {
        LightsStatus.publish("ERROR");
      }
    }
    else
    {
      //LightsStatus.publish("ERROR");
    }




// 50% ned

  //If we're in here, a subscription updated...
    if (subscription == &halvtredsProcent)
    {
      //Print the new value to the serial monitor
      Serial.print("halvtredsProcent: ");
      Serial.println((char*) halvtredsProcent.lastread);

      //If the new value is  "ON", turn the light on.
      //Otherwise, turn it off.
      if (!strcmp((char*) halvtredsProcent.lastread, "ON"))
      {
        //active low logic
        digitalWrite(modUr, HIGH);
        delay(5000);
        digitalWrite(modUr,LOW);
       

      }
      else if (!strcmp((char*) halvtredsProcent.lastread, "OFF"))
      {
        digitalWrite(led, LOW);
        LightsStatus.publish("OFF");

      }
      else
      {
        LightsStatus.publish("ERROR");
      }
    }
    else
    {
      //LightsStatus.publish("ERROR");
    }


  }
  
      



  
  //  if (!mqtt.ping())
  //  {
  //    mqtt.disconnect();
  //  }
}
  
  



void MQTT_connect()
{

  //  // Stop if already connected
  if (mqtt.connected() && mqtt.ping())
  {
    //    mqtt.disconnect();
    return;
  }

  int8_t ret;

  mqtt.disconnect();

  Serial.print("Connecting to MQTT... ");
  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) // connect will return 0 for connected
  {
    Serial.println(mqtt.connectErrorString(ret));
    Serial.println("Retrying MQTT connection in 5 seconds...");
    mqtt.disconnect();
    delay(5000);  // wait 5 seconds
    retries--;
    if (retries == 0)
    {
      ESP.reset();
    }
  }
  Serial.println("MQTT Connected!");
}

Non-blocking timing tutorials:
Several things at a time.
Beginner's guide to millis().
Blink without delay().

Thanks for the reply, I have now read all the links and I’m still not able to figure it out.

The problem is inside this While loop: " while ((subscription = mqtt.readSubscription(5000)))".

I’ve tried things like this: “while ((subscription = mqtt.readSubscription(currentMillis- StartMillis>= Interval)))” but i doesn’t work.

Am i missing something?

Can't you hook-up your magnetsensor to an interrupt pin and make it work so that when the interrupt triggers, it immediately does the thing you want it to do?

Hey, thanks for your reply. It's a nice idea, but it doesn't include my bluetoothapp and my relays are switching on and off every second-the sound gets annoying pretty quick.

If someone knows how to configure this code: "while ((subscription = mqtt.readSubscription(5000)))" without the readSubscription-delay, then please post a link or the code.

First off, the test in that while loop is wrong - it is not testing equality, it is setting subscription to what mqtt.readSubscription(5000) returns, and then also using that as the value it's testing for. If it "works", it's because it is returning 0 in some cases, and a non-zero (which is true) in others. The effect is a busy-wait until that call returns a non-zero value.

= is assignment
== tests equality

I am not familiar with that library though, so you should wait for someone who is familiar with that library for further advise; I don't know offhand what that library call returns under what circumstances, nor how to use it correctly....