How to prevent controller to respond on multiple button pushes?

I have made my self an garage door opener, and everything works fine, but if i push the button for closing the garage door in the Blynk app more then one time, the buzzer sound (this is just an warning sound that tells that the garage door soon closes) beeps longer, but the garage door closes correct.

I just want the alarm sound to not read accidential putton pushes.

Here is my code:

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


int relay = 16;
int magnet = 4;
int buzzer = 5;
int magnetValue;

char auth[] = "*****";

char ssid[] = "*****";
char pass[] = "*****";

BlynkTimer timer;

void setup() {
  Blynk.begin(auth, ssid, pass);
  digitalWrite(relay, HIGH);
  pinMode(relay, OUTPUT);
  pinMode(magnet, INPUT_PULLUP);
  pinMode(buzzer, OUTPUT);
  timer.setInterval(1000L, magnetSensor);
}

void magnetSensor() {
  magnetValue = digitalRead(magnet);

  if (magnetValue == 1) {
    Blynk.virtualWrite(V2, "GARASJEPORT ÅPEN");
  }
  else {
    Blynk.virtualWrite(V2, "GARASJEPORT STENGT");
  }
}

void buzzerTone(){
  
    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);

    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);

    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);

    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);

    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);
}

BLYNK_WRITE(V1) {
  int pinData = param.asInt();
  magnetValue = digitalRead(magnet);
  
if(pinData == 1 && magnetValue == 1){
    buzzerTone();
    digitalWrite(relay, LOW);
    timer.setTimeout(500L, RELAYoff);
  }
  if(pinData == 1 && magnetValue == 0){
    digitalWrite(relay, LOW);
    timer.setTimeout(500L, RELAYoff);
  }
}

void RELAYoff() {
  digitalWrite(relay, HIGH);
}

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

you have to define another boolean variable named something like "ButtonPressed" that is initially set to value false
first thing that your function buzzerTone () has to do is checking for not ButtonPressed

if (!ButtonPressed) {
  ButtonPressed = true;

and then follows the code to buzz

As you set the variable ButtonPressed true when calling function buzzerTone() for the first time
the condition if not buttonPressed ) evaluates to false the second, thrid press etc.

The variable ButtonPressed is set back to value false when the door has finished its action
best regards Stefan

Thanks :slight_smile:

Can you please give me an example with that code inplemented in my code in first post?

Please attempt to follow the instructions. If it doesn't work, post the result and we can help. To define a boolean variable, you:

bool ButtonPressed = false;

Hi Bjerknez,
first of all that's a nice gesture to say thanks. Thanks to you :slight_smile:
I apologise immetiately if my guessing is wrong. From your new question I estimate that your knowledge-level about coding is improvable. Malicious tongues would say you are a copy&paste-"programmer".

The disadvantage of this way is that you have to ask again and again and again of you want to change tiny things in your code. Of course it takes some time to learn some more about programming but my opinion is it's worth doing it. And I'm willing to explain more. But under one condition: write a first attempt to add the suggested boolean variable to your code. It doesn't matters if it does not compile. Just make a start to think about it on your own. Then post your modificated code.

best regards Stefan

I tried now, and it worked better. I can now press everal times on the button and the alarm just sounds one time, and that whats i want.

But when i try to press another time, i do not hear any alarm. Just the door that opens. Can you please help me with that?

Here is my last code:

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


int relay = 16;
int magnet = 4;
int buzzer = 5;
int magnetValue;

bool buttonPressed = false;

char auth[] = "MBILrCyjdbueVSYavsmS5p45a8hOkSwo";

char ssid[] = "JabediJabedi";
char pass[] = "Birkeb1er";

BlynkTimer timer;

void setup() {
  Blynk.begin(auth, ssid, pass);
  digitalWrite(relay, HIGH);
  pinMode(relay, OUTPUT);
  pinMode(magnet, INPUT_PULLUP);
  pinMode(buzzer, OUTPUT);
  timer.setInterval(1000L, magnetSensor);
}

void magnetSensor() {
  magnetValue = digitalRead(magnet);

  if (magnetValue == 1) {
    Blynk.virtualWrite(V2, "GARASJEPORT ÅPEN");
  }
  else {
    Blynk.virtualWrite(V2, "GARASJEPORT STENGT");
  }
}

void buzzerTone(){
if (!buttonPressed) {
  buttonPressed = true;
  
    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);

    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);

    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);

    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);

    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);
}
}

BLYNK_WRITE(V1) {
  int pinData = param.asInt();
  magnetValue = digitalRead(magnet);
  
if(pinData == 1 && magnetValue == 1){
    buzzerTone();
    digitalWrite(relay, LOW);
    timer.setTimeout(500L, RELAYoff);
  }
  if(pinData == 1 && magnetValue == 0){
    digitalWrite(relay, LOW);
    timer.setTimeout(500L, RELAYoff);
  }
}

void RELAYoff() {
  digitalWrite(relay, HIGH);
}

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

I tried to put in "buttonPressed = false;" on several locations, but i just can't get the code to work perfectly.

I want to hear the warning sound every time the garage door is open before i close it. WHen i push the button i want the sound to appear. When the warning sound is over, the door closes.

When i open the door again i do not want any sounds. Just before i close it.

Hi Bjernez,

very good start, your code has no comments that would explain what a certain command is doing.
This program is small enough to keep these things in mind if you coded it yourself.
But I don't know it.

Does the garagedoor-opener work with a single input? I mean give th input a signal door opens. give the exact same input another signal the door closes? Or does it have to different inputs for open/close?

Somehow your code must distinguisch between opening and closing. However this will be done.
If it is based on one single input to make it work with high reliability you need another sensor that senses the states "door open" and "door closed" .

So at least if you want to go on with programming you should add comments. To your code if you want to change something a year in the future it will be much easier to anaylse your own code, if the code has comments explaining what for example

if(pinData == 1 && magnetValue == 0)

does mean best regards

Stefan

Here is my code with some comments.

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


int relay = 16;
int magnet = 4;
int buzzer = 5;
int magnetValue;

bool buttonPressed = false; // Sets the button state as false

char auth[] = "*****";

char ssid[] = "*****";
char pass[] = "*****";

BlynkTimer timer; // For activating the Blynk Timer

void setup() {
  Blynk.begin(auth, ssid, pass); // Something that Blynk needs to connect to wifi
  digitalWrite(relay, HIGH); // Sets the relay HIGH (that means open circuit)
  pinMode(relay, OUTPUT); // sets the relay as OUTPUT
  pinMode(magnet, INPUT_PULLUP); // Sets the magnet sensor as an INPUT_PULLUP
  pinMode(buzzer, OUTPUT); // Sets the buzzer as an output
  timer.setInterval(1000L, magnetSensor); // Runs the "magnetSensor" function every second
}

void magnetSensor() { // Reads the state of the door (closed or open)
  magnetValue = digitalRead(magnet);

  if (magnetValue == 1) { // If the door is open...
    Blynk.virtualWrite(V2, "GARASJEPORT ÅPEN"); // ...write "garage door is open" (translated to english) to the Blynk app
  }
  else { // If the door is closed...
    Blynk.virtualWrite(V2, "GARASJEPORT STENGT"); // ...write "Garage door is closed" (translated to english) to the Blynk app
  }
}

void buzzerTone(){ // Makes a warning sound before garage door closes after button in Blynk app is pushed
if (!buttonPressed) { // I'm not shure about this...
  buttonPressed = true; // I'm not shure about this...
 
    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);

    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);

    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);

    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);

    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);
}
}

BLYNK_WRITE(V1) { //Blynk app button
  int pinData = param.asInt(); // Some code for sync the Blynk app button
  magnetValue = digitalRead(magnet);
 
if(pinData == 1 && magnetValue == 1){ // If the button is pressed and the door is open...
    buzzerTone(); // Activate the warning sound
    digitalWrite(relay, LOW); //... Close the garage door
    timer.setTimeout(500L, RELAYoff); // Makes the signal to the door last for half second to ensure that it closes
  }
  if(pinData == 1 && magnetValue == 0){ //If the button is pressed and the door is closed...
    digitalWrite(relay, LOW); // ...close the relay circuit and close the door
    timer.setTimeout(500L, RELAYoff); // Gives the garage opener half second of power to ensure that it closes
  }
}

void RELAYoff() { // turns the signal to the gaage opener off
  digitalWrite(relay, HIGH);
}

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

To explain little more...

I have an magnet sensor that reads when door is open or closed. Main purpose for that sensor is to give feedback to the app that shows the door is open or closed.

Someone...?

Somehow my last posting was not stored. In short again.

I want to make some more suggestions how your code can be improved to be easier to maintain.
If you define constants with self-explaining names these self-explaining names replace most of the comments.

There is another advantage of constants. If the vlaue of a constant is used multiple times you just change the value at one place and it will be changed in all places and you can't forgot one.

So I made a codeversion with such constants.
It compiles but as I don't have your hardware I can't really test it.

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


int relay = 16;
int magnet = 4;
int buzzer = 5;
int magnetValue;

bool Flag_buttonPressed = false; // Sets the button state as false

char auth[] = "*****";

char ssid[] = "*****";
char pass[] = "*****";

BlynkTimer timer; // For activating the Blynk Timer
        
#define DoorIsOpened 1
#define DoorIsClosed 0


#define SignalCloseDoor LOW
#define NoSignalCloseDoor HIGH

void setup() {
  Blynk.begin(auth, ssid, pass); // Something that Blynk needs to connect to wifi
  digitalWrite(relay, NoSignalCloseDoor); // Sets the relay HIGH (that means open circuit)
  pinMode(relay, OUTPUT); // sets the relay as OUTPUT
  pinMode(magnet, INPUT_PULLUP); // Sets the magnet sensor as an INPUT_PULLUP
  pinMode(buzzer, OUTPUT); // Sets the buzzer as an output
  timer.setInterval(1000L, magnetSensor); // Runs the "magnetSensor" function every second
}

void magnetSensor() { // Reads the state of the door (closed or open)
  magnetValue = digitalRead(magnet);

  if (magnetValue == DoorIsOpened) { // If the door is open... 
    Blynk.virtualWrite(V2, "GARASJEPORT ÅPEN"); // ...write "garage door is open" (translated to english) to the Blynk app
  }
  else { // If the door is closed...
    Blynk.virtualWrite(V2, "GARASJEPORT STENGT"); // ...write "Garage door is closed" (translated to english) to the Blynk app
    Flag_buttonPressed = false; // reset the flag because door is closed
  }
}

void buzzerTone(){ // Makes a warning sound before garage door closes after button in Blynk app is pushed
if (!Flag_buttonPressed && magnetValue == DoorIsOpened ) { 
  Flag_buttonPressed = true; 
 
    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);

    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);

    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);

    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);

    tone(buzzer, 600);
    delay(500);
    noTone(buzzer);
    delay(500);
}
}

BLYNK_WRITE(V1) { //Blynk app button
  int pinData = param.asInt(); // Some code for sync the Blynk app button
  magnetValue = digitalRead(magnet);
 
if(pinData == 1 && magnetValue == DoorIsOpened){ 
    buzzerTone(); // Activate the warning sound
    digitalWrite(relay, SignalCloseDoor); //... Close the garage door
    timer.setTimeout(500L, RELAYoff); // Makes the signal to the door last for half second to ensure that it closes
  }
  if(pinData == 1 && magnetValue == DoorIsClosed){ 
    digitalWrite(relay, SignalCloseDoor); 
    timer.setTimeout(500L, RELAYoff); // Gives the garage opener half second of power to ensure that it closes
  }
}

void RELAYoff() { // turns the signal to the garage opener off
  digitalWrite(relay, NoSignalCloseDoor);
}

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

best regards Stefan

Thanks. I can take a look at that :slight_smile:

But when i close the door second (or third etc.) i can't hear any warning sound. The door just closes.

I want the buttonstate to go back to false after the door begin to close.

I just don't can figure out how to get this to work properly.

My only problem is that when i press the button several times when the door is open, the alarm sound register the number of pushes and stays on, while the garage door signal is staying high for some time.

So my main problems are the alarm sound that stays on when i accidental push several times and the signal to the door stays on longer.

Does the alarm sound too long only when you tap the button several times before the door begins to open, so the magnet still reads one?

Maybe you only want to sound the buzzer if you read a one after reading a zero when you opened the door.

Not sure I've thought this all the way through, but maybe add a variable named oldMagnetValue to store the previous magnet read when the app button was pressed. Check the following logic.

  // If the button is pressed ...
  if (pinData == 1 )
  {
    // if sensor sees magnet but did not last time button was pressed
    if ( magnetValue == 1) && (oldMagnetValue == 0) )
    {
      buzzerTone(); // Activate the warning sound
    }
    digitalWrite(relay, LOW); //... close the relay circuit
    timer.setTimeout(500L, RELAYoff); // Makes the signal to the door last for half second to ensure that it closes
  }

  oldMagnetValue = magnetValue;  // save value just read

I think i already have that code?

Hi Bjerknez,

the code I posted in post #11 has namechanges and an additional command
else { // If the door is closed...
Blynk.virtualWrite(V2, "GARASJEPORT STENGT"); // ...write "Garage door is closed" (translated to english) to the Blynk app
Flag_buttonPressed = false; // reset the flag because door is closed
}

else { // If the door is closed...
Blynk.virtualWrite(V2, "GARASJEPORT STENGT"); // ...write "Garage door is closed" (translated to english) to the Blynk app
Flag_buttonPressed = false; // reset the flag because door is closed
}

did you really test the code-version from post #11??

My assumption is that function magnetsensor is called once per second
So as soon as the magnet is some centimeters away from the magnetsensor senses a zero
which means door has left completely opened position where magnet is detected.
and then Flag_buttonPressed = false; is set back to false.

If you overlooked this change the whole thing is if you want it fast it turns out to be really slow.

Anyway for an automated door open/close-function that is high reliable and does report malfunctions
you would have to add another sensor that really detects "door closed" and you have to add more code
if door has started moving and after a timeout-time the other sensor does not detect position reached do some kind if error-signaling

best regards Stefan

StefanL38:
Hi Bjerknez,

the code I posted in post #11 has namechanges and an additional command

 else { // If the door is closed...

Blynk.virtualWrite(V2, "GARASJEPORT STENGT"); // ...write "Garage door is closed" (translated to english) to the Blynk app
    Flag_buttonPressed = false; // reset the flag because door is closed
  }

else { // If the door is closed...
    Blynk.virtualWrite(V2, "GARASJEPORT STENGT"); // ...write "Garage door is closed" (translated to english) to the Blynk app
    Flag_buttonPressed = false; // reset the flag because door is closed
  }




did you really test the code-version from post #11??

My assumption is that function magnetsensor is called once per second
So as soon as the magnet is some centimeters away from the magnetsensor senses a zero
which means door has left completely opened position where magnet is detected.
and then Flag_buttonPressed = false; is set back to false.

If you overlooked this change the whole thing is if you want it fast it turns out to be really slow.

Anyway for an automated door open/close-function that is high reliable and does report malfunctions
you would have to add another sensor that really detects "door closed" and you have to add more code
if door has started moving and after a timeout-time the other sensor does not detect position reached do some kind if error-signaling

best regards Stefan

I think you can have a point here :slight_smile:

Sorry, i have not tried the code in post #11. I can try this later today and give you feedback :slight_smile:

btw, i also think it is a good idea to add more sensores for detecting door status. I think i'm going to do that...

YEAH!

The ecode posted in post #11 actually worked! :slight_smile: Thanks alot!

I repost the code here, with a small change i did regards to the buzzer code. I wrote a for loop for the buzzer to save som code space.

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

int relay = 16;
int magnet = 4;
int buzzer = 5;
int magnetValue;

bool Flag_buttonPressed = false; // Sets the button state as false

//Put WiFi cridentials and token here----------------------------------

char auth[] = "*****";
char ssid[] = "*****";
char pass[] = "*****";

//---------------------------------------------------------------------

BlynkTimer timer; // For activating the Blynk Timer

#define DoorIsOpened 1
#define DoorIsClosed 0

#define SignalCloseDoor LOW
#define NoSignalCloseDoor HIGH

void setup() {
  Blynk.begin(auth, ssid, pass); // Something that Blynk needs to connect to wifi
  digitalWrite(relay, NoSignalCloseDoor); // Sets the relay HIGH (that means open circuit)
  pinMode(relay, OUTPUT); // sets the relay as OUTPUT
  pinMode(magnet, INPUT_PULLUP); // Sets the magnet sensor as an INPUT_PULLUP
  pinMode(buzzer, OUTPUT); // Sets the buzzer as an output
  timer.setInterval(1000L, magnetSensor); // Runs the "magnetSensor" function every second
}

void magnetSensor() { // Reads the state of the door (closed or open)
  magnetValue = digitalRead(magnet);

  if (magnetValue == DoorIsOpened) { // If the door is open...
    Blynk.virtualWrite(V2, "GARASJEPORT ÅPEN"); // ...write "garage door is open" (translated to english) to the Blynk app
  }
  else { // If the door is closed...
    Blynk.virtualWrite(V2, "GARASJEPORT STENGT"); // ...write "Garage door is closed" (translated to english) to the Blynk app
    Flag_buttonPressed = false; // reset the flag because door is closed
  }
}

void buzzerTone() { // Makes a warning sound before garage door closes after button in Blynk app is pushed
  if (!Flag_buttonPressed && magnetValue == DoorIsOpened ) {
    Flag_buttonPressed = true;

    for (int i = 0; i < 5; i++) {
      tone(buzzer, 600);
      delay(500);
      noTone(buzzer);
      delay(500);
    }
  }
}

BLYNK_WRITE(V1) { //Blynk app button
  int pinData = param.asInt(); // Some code for sync the Blynk app button
  magnetValue = digitalRead(magnet);

  if (pinData == 1 && magnetValue == DoorIsOpened) {
    buzzerTone(); // Activate the warning sound
    digitalWrite(relay, SignalCloseDoor); //... Close the garage door
    timer.setTimeout(500L, RELAYoff); // Makes the signal to the door last for half second to ensure that it closes
  }
  if (pinData == 1 && magnetValue == DoorIsClosed) {
    digitalWrite(relay, SignalCloseDoor);
    timer.setTimeout(500L, RELAYoff); // Gives the garage opener half second of power to ensure that it closes
  }
}

void RELAYoff() { // turns the signal to the garage opener off
  digitalWrite(relay, NoSignalCloseDoor);
}

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

Heres some pictures of my project and my little friend thats cribbles around in my mancave.