[Solved] Virtual LED and Button widget controlling relay

I was trying to put together a simple project to monitor a door. I would like to have a virtual LED widget assigned to monitor the state of a magnetic switch(open or closed) and a button widget to control a relay. I used the ButtonInterrupt.ino example to start with. I checked that I was able to turn the LED on and off by assigning a button widget to D2. Next, I just added another button widget to the dashboard and assigned it to D9.

The final version will use a magnetic switch so I used a physical push button for testing. Then I removed the D2 button widget and the problems started. Pushing the button closed to simulate the door being closed caused the LED to hang and crashed my connection. It has been pointed out to me about using simple timer, however it is not included in the
ButtonInterrupt.ino example so I did not include it. It seems that by adding or removing the button widgets, I am having issues making the thing run. Also, I tried assigning the D2 button widget to other pins, namely D28 and was not able to get it to work. There are only three places where you have to change the pin number!

Anyway, I am not sure what I am missing here. I thought it would be easy to do as I could use an un-edited sample code and then just add a button widget to the dashboard without having to write any code. Couldn’t be easier, even for a green horn.

I am using an Arduino Mega 2560 R3, Arduino ether shield R3 (has PoE but I am not using it) and iOS V9.1

Thanks for reading. I look forward to your ideas and suggestions. I did not post any code because I used the sample code without alteration.

You say you are using button.ino, that sounds really old to me. What version of the IDE are you using? Just to make sure there’s nothing wrong there :slight_smile:

@Lichtsignaal, Thanks for your reply. I am using the example sketch found here
https://github.com/blynkkk/blynk-library/blob/master/examples/More/ButtonInterrupt/ButtonInterrupt.ino
ButtonInterrupt.ino and the IDE I am using for arduino is 1.6.5
Thank you

I think you need to debounce your physical button. Because the readout is not always 100% accurate because of electrical differences in components, magnetic fields etc.

There is a nice article about that over here: https://www.arduino.cc/en/Tutorial/Debounce

ok, I will start with that. Thank you.

I tried using the switch debounce and got some rather strange results. Although my code compiled and ran, it did not run as expected. Anyway, I am a bit confused in that I thought I am not to use delays? But with this debounce example I am using delays.

@mpo881 50 milliseconds is a short delay and required for debounce to work

oh ok, so it is not so much that I cant use a delay, it is more of how long? Man this is really getting confusing. All I started out to do was to have a button widget control a relay (handle a bigger load, light). Then have a magnetic switch to monitor the state of a door (open or closed). I feel like I am throwing darts with a blind fold on! :anguished:

The last official release of Blynk has a 5 second heartbeat timeout (the latest beta is 10 seconds).

If you start adding delay(1000) here and there then you will miss the hearbeat and get disconnected from the server. Very short delays 10, 20 50 milliseconds are ok (but not if you have dozens of them).

The general rule would be to have no delays as they are not normally required (SimpleTimer which works at the same time as your main code should handle all your timing issues). However if you are working with physical buttons and switches, as opposed to Blynk virtual equivalent, then some very short delays are almost inevitable.

Thank you for the explanation. That makes a lot of sense. What I do not understand is that if I use the BlynkBlink example sketch, I can use a button widget on my dashboard and turn a relay on or off without any coding. How do I add the LED which is virtual, to read the state of the pin that the magnetic door switch is on? Seems like that should be pretty easy? But all the examples I have read and I promise you I do not fully understand, deal with inputs and outputs of virtual pins. I am lost!
Thanks

Yes it is pretty easy. See code below and add the normal Blynk stuff to it. See how you go without debounce and if you notice any problems add delay(50) after the digitalRead line. Fairly self explanatory but shout if it doesn’t make sense.

// add all the normal Blynk stuff depending on your hardware setup

#include <SimpleTimer.h>
SimpleTimer timer;

byte val = 0;             // variable to store the button status
byte buttonD5 = 5;        // button / switch on digital pin 5
byte led = 2;             // the pin that the LED is atteched to, digital pin 2

void setup() {
  pinMode(led, OUTPUT);      // initalize LED as an output
  pinMode(buttonD5, INPUT);    // initialize button / switch as an input
  timer.setInterval(3000,  CheckButton);  // check button state every 3 second
}

void CheckButton(){    // done every 3 seconds
  byte val = digitalRead(buttonD5);   // read button value
  if (val == HIGH) {           // check if the switch is HIGH
    Blynk.virtualWrite(V3, 255);  // turn app LED on V3 ON
  } 
  else {
        Blynk.virtualWrite(V3, 0);  // turn app LED on V3 OFF
  }  
}

void loop() {
  Blynk.run();   // need all the regular Blynk stuff in definitions and setup
  timer.run();
}
1 Like

Wow, Thanks very much for the help. Now, as I am looking through the code that you have sent, I see that you have an led on pin 2, is that correct? Have you added that just so as the code is tested you can see something happening?

Thanks again
Ill give this a try

#define BLYNK_PRINT Serial
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "xxxxxxxx";

WidgetLED led1(V1);

void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth);

 
  pinMode(2, INPUT);
   // Attach INT to our handler
  attachInterrupt(digitalPinToInterrupt(2), checkPin, CHANGE);

}

void checkPin()
{
  // Invert state, since button is "Active LOW"
  if (digitalRead(2)) {
      led1.off();
  } else {
      led1.on();
  }
}

void loop()
{
  Blynk.run();
}

So, before I try the one you sent. Have a look at this, which is what I was trying to use. It seems to work EXCEPT I think I am getting bounced because of not having simptimer function. My understanding would be that by pushing the button, I am sending requests for continuous updates, flooding the system and getting bounced. What do you make of that?
Thanks

To answer your first question yes I have a physical LED on pin 2 here and currently no actual switches wired up.

I will take a quick look at your code now.

Well, I tried your code and it works as I would like things to work, so THANK YOU. I am still trying to understand simpletimer and am trying to add it to my code just to see how it works and if I can make the other code work. I look forward to your thoughts on the other code.
:sunglasses:

Well, at least now I think I understand why I could not use pin 28 instead of pin 2 in the buttoninterrupt sketch. Reading about attachinterrupt here;
https://www.arduino.cc/en/Reference/AttachInterrupt
I found that if I am using a Mega, Mega2560, MegaADK, I can only use pins 2, 3, 18, 19, 20, 21

Your code is fine. To test it with my Nano I have made the changes for USB and as I have an LED on pin 2 I have used pin 3 for a momentary switch (int.1 on the Nano). The Blynk app runs fine for me and the virtual LED responds as expected.

Just changed the momentary switch to a regular on / off switch and that too works fine.

Using the interrupt on CHANGE means you shouldn’t be flooding the Blynk server and switch bounce is not normally a significant issue.

I assume you have your switch tied to ground with a 10K resistor.

Some purists might recommend attachInterrupt rather than SimpleTimer but the beauty of SimpleTimer is that you can more easily ensure Blynk’s virtual LED shows the correct state at all times i.e. you are reading the state of a pin at given frequencies. Whereas attachInterrupt is looking for a change (or high or low etc). In your sketch Blynk app on restart will show LED as the last known state and this might not be the actual state which attachInterrupt will only confirm when you start using the switch.

SimpleTimer wins hands down for me.

Thanks for the reply and for checking the code for me. I must tell you that the code you provided runs much better and I have not experienced any hangs or dropped connections to the server. It has been running since you sent it to me without issue.

I have been doing some reading on both simpletimer and attachinterrupt. For now, simple timer works great! Again, thank you very much for your help.

Yes, I do have the switch wired this way.

Maybe you have solved this after almost a year, but if not the way to debounce a button is to use SimpleTimer and adjust the interval until it works the way you want. For example this worked for me to read the value of a pin and set the WidgetLED on/off when either a physical switch or Blynk button turned a light on/off through a relay. This isn’t the complete code, just the SImpleTimer part.

#include <SimpleTimer.h>
SimpleTimer timerR;
WidgetLED Blynkled(V0);
void setup()
(all your variables)
timerR.setInterval(1000L, setled); //setled is the function
void setled()
{
pinValueRed = digitalRead (ledPin);
if (pinValueRed == 1){
Blynkled.on();
}
else {
Blynkled.off();
}
void loop(){
Blynk.run(); // All the Blynk Magic happens here…
timerR.run(); // Initiates SimpleTimer
}

1 Like

With the help of @Costas and @Lichtsignaal I was able to get the code to work as I wanted. More importantly, I was able to understand simple timer for future projects. Thank you very much for your reply.