Lag issue with NodeMcu and multiple reed switch

Before creating the topic

So I made a simple device that sends the status of one reed switch to Blynk. It uses a NodeMcu. When using one reed switch it works fine, but I tried to add multiple, and it didn’t work as well. It doesnt work all of the time, especially if I close and open the window quickly. It isn’t a big deal as I am only using it for a demonstration, but I would much appreciate any tips on what I could/should change to improve the code.


#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

#define BLYNK_TEMPLATE_ID "..."
#define BLYNK_DEVICE_NAME "..."
#define BLYNK_AUTH_TOKEN "..."

char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "...";  //WIFI name
char pass[] = "...";  //WIFI password

int reedSwitchStateA;
int reedSwitchStateB;
int reedSwitchStateC;

BlynkTimer timer;

void myTimer()
{
  // Read the state of the reed switches
  reedSwitchStateA = digitalRead(D1);
  reedSwitchStateB = digitalRead(D2);
  reedSwitchStateC = digitalRead(D3);
  
  //write the state of the reed to V1 virtual pin
  Blynk.virtualWrite(V1, reedSwitchStateA);
  Blynk.virtualWrite(V2, reedSwitchStateB);
  Blynk.virtualWrite(V3, reedSwitchStateC);
} 

void setup() {

  // Set the reed switch pin to input mode
  pinMode(D1, INPUT_PULLUP);
  pinMode(D2, INPUT_PULLUP);
  pinMode(D3, INPUT_PULLUP);

  //Initialize the Blynk library
  Blynk.begin(auth, ssid, pass, "blynk.cloud", 80);

  // Setting interval to send data to Blynk Cloud to 1000ms. 
  timer.setInterval(1000L, myTimer); 
}

void loop() {
  
  //Run the Blynk library
  Blynk.run();

  // runs BlynkTimer
  timer.run(); 
}


First of all, these three lines of code should be at the VERY TOP of your sketch…

When you do that, it’s not necessary to specify the server url and port in your Blynk.begin command.

Secondly, D3 (GPIO0) is a very bad choice of pin for this type of use. If this pin is pulled LOW at startup the NodeMCU will go into programming mode, preventing your sketch from running.

You should read this for more info…

Now onto your issue…
You are polling your pins eon E every second, and pushing the result to Blynk regardless of whether the pin’s status has changed since the last time or not.
Decreasing the polling time (increasing the frequency) would make the system more responsive to changes in your switch states, but will cause you problems with writing data to Blynk too frequently unless you only update Blynk if the switch status has changed.

A better approach would be to use Interrupts. Attaching an interrupt your each sensor pin will cause a pre-defined function to be called each time a particular pin changes state. You would need some debounce code in these Interrupt Service Routine functions because your reed switches will give a very noisy output rather than s single clean on/off output each time they are activated, but that’s easy enough to do.

Pete.

1 Like

Thanks for the reply Pete! I’m a bit confused on the Interrupts though. How would I implement them? Is it explained somewhere in the Blynk documentation, or online?

Interrupts aren’t a Blynk thing, it’s standard C++/Arduino stuff.
You’ll find some mention of interrupts and denounce routines in this forum, but also via an internet search,

Pete.

1 Like

Oh ok thanks

Check this article

1 Like

Thanks john, will do

Sorry for the extra questions lol but if I’m using interrupts that means I wont need to use Blynk Timer right?

That’s correct. You might need to use BlynkTimer if you want to do other stuff, but if it’s limited to what you’re currently doing then no, you wouldn’t need to use BlynkTimer

Pete.

1 Like

IMO interrupts are usually only necessary when it is a critical timing issue. Like when you need to know that a input was changed almost instantly (thousandths of a second, possibly faster) .

what is this application? You say open/close a window. This sounds like you are possibly just trying to know if something is closed or open. To me this doesn’t sound timing critical, and to me seems like a simple change in code structure would suffice. Like @PeteKnight said in his first reply,

take a look at this example. It monitors the state of a button every 100th of a second (probably faster than you could open/close a window). In practicality this button could be your reed switch (essentially a magnet operated button).

With a few tweaks this example is just one way of doing what you would like to accomplish. That is one of the perks of programming, there are usually many ways to accomplish a task.

1 Like

Here is the example tweaked for your application. This is for 2 reed switches. I will let you add the third. Should be a matter of cut and paste, with changing some variable names.

Hope it helps.

Also, keep looking into interrupts. They are good to know about.


#define BLYNK_TEMPLATE_ID           "TMPLxxxxxx"
#define BLYNK_DEVICE_NAME           "Device"
#define BLYNK_AUTH_TOKEN            "YourAuthToken"


// Comment this out to disable prints and save space
#define BLYNK_PRINT Serial


#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = BLYNK_AUTH_TOKEN;

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";

// Set your reed pins here
const int reedSwitchA = 5;  //D1
const int reedSwitchB = 4;  //D2

BlynkTimer timer;
void checkPhysicalSwitch();

int reedSwitchStateA = LOW;
int reedChangeA = HIGH;

int reedSwitchStateB = LOW;
int reedChangeB = HIGH;


void checkPhysicalSwitch()
{
  if (digitalRead(reedSwitchA) == LOW) {
    // btnState is used to avoid sequential toggles
    if (reedChangeA != LOW) {

      Blynk.virtualWrite(V1, LOW);
      reedChangeA = LOW;
    }
    
  } 
  else {
    if (reedChangeA != HIGH) {

      Blynk.virtualWrite(V1, HIGH);
      reedChangeA = HIGH;
    }
    
  }

   if (digitalRead(reedSwitchB) == LOW) {
    // btnState is used to avoid sequential toggles
    if (reedChangeB != LOW) {

      Blynk.virtualWrite(V2, LOW);
      reedChangeB = LOW;
    }
    
  } 
  else {
    if (reedChangeB != HIGH) {

      Blynk.virtualWrite(V2, HIGH);
      reedChangeB = HIGH;
    }
    
  }
}

void setup()
{
  // Debug console
  Serial.begin(115200);

  Blynk.begin(auth, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "blynk.cloud", 80);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);
  
  pinMode(reedSwitchStateA, INPUT_PULLUP);
  pinMode(reedSwitchStateB, INPUT_PULLUP);
  
  // Setup a function to be called every 100 ms
  timer.setInterval(100L, checkPhysicalSwitch);
}

void loop()
{
  Blynk.run();
  timer.run();
}
1 Like

sorry I didn’t see this, I was asleep. Thank you so much. Also I have a quick q. why does the code say

why doesn’t it just say if (reedChangeA = HIGH).
i just want to have a good understanding of it, thanks

The logical NOT operator ( ! ) checks whether the Statement evaluates to 0 or not. If it is 0 it results in true, otherwise it results false.
You can also use

if (reedChangeA = HIGH);

There’s no problem with that.

ok cool