Debouncing

Hey guys,
need help to debbounce an input by software. I just did it by hardware with a RC-module, calculated to 1ms but it doesn`t seem to be enough. I only analyze the state of a relay over an interrupt-input which is set to CHANGE. Every time I switch, a loop gets called.The MCU get disconnected from Blynk after a few switches. When I simulate it with a normal LED it works. So there must be a error with the relay toggle, that the loop Func_Raumlicht() gets called 1000-times.

const int WemosPin_D1 = 5;                        //Input Status-Relay          
const int WemosPin_D2 = 4;                        //Output Relay Raumlicht      

void setup() {
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  pinMode (WemosPin_D1, INPUT_PULLUP);
  attachInterrupt(WemosPin_D1, Func_Raumlicht, CHANGE);
}

BLYNK_WRITE(V20) {                                                                
  Push_Raumlicht = param.asInt();
  if (Push_Raumlicht == 1) {
    Raumlicht_ON_OFF();
  }
}
void Raumlicht_ON_OFF() {
  M_Raumlicht = ! M_Raumlicht;
  digitalWrite (WemosPin_D2, M_Raumlicht);
  if (M_Raumlicht == 1) {
    Blynk.virtualWrite(V60, HIGH);
  }
  if (M_Raumlicht == 0) {
    Blynk.virtualWrite(V60, LOW);
  }
}
void Func_Raumlicht() {
  Status_Raumlicht = digitalRead(WemosPin_D1);
  if (Status_Raumlicht == 1) {
    LED_Raumlicht.setColor (NEON_GREEN);
    LED_Raumlicht.setValue (255);
    Blynk.virtualWrite(V20, HIGH);
  }
  if (Status_Raumlicht == 0) {
    LED_Raumlicht.off();
    Blynk.virtualWrite(V20, LOW);
  }
}

I programmed at this way to realize a simple Zentral OFF function where I only have to call once the loop Raumlicht_ON_OFF()
Is there someone how can help me to implement also the software-solution
Twice the impact :laughing:

Could we please see the whole code <3

I don’t the issue is necessarily in the code you gave us :slight_smile:

There’s some debounce code in this sketch:

see the CheckButtonState function.

In theory, millis() shouldn’t be used in an interrupt driven function, as it’s not 100% accurate, but it seems to work.

Pete.

1 Like

Hey Martin, thanks for your answer. Now I edited the sketch above, so that you can comprehend my thinking. The loop Func_Raumlicht gets called every status change. It´s only here to
visualize the current state on Blynk App. When Raumlicht_ON_OFF gets called, a relay changes his current state (HIGH->LOW and LOW->HIGH). So that it works like this it´s necessary that it get called once. Else Func_Raumlicht() get called 1000-times and Blynk disconnects itself.

How often if this happening?

Maybe you could forget the interrupt, and go with a short timer? Then it would only check the relay once during that interval. (kind of like a debounce)

For example:

void setup() {
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  pinMode (WemosPin_D1, INPUT_PULLUP);

// Setup a function to be called every 100 ms
  timer.setInterval(100L, Func_Raumlicht);
}

void Func_Raumlicht() {
  Status_Raumlicht = digitalRead(WemosPin_D1);
  if (Status_Raumlicht == 1) {
    LED_Raumlicht.setColor (NEON_GREEN);
    LED_Raumlicht.setValue (255);
    Blynk.virtualWrite(V20, HIGH);
  }
  if (Status_Raumlicht == 0) {
    LED_Raumlicht.off();
    Blynk.virtualWrite(V20, LOW);
  }
}

Or it’s possible it may have something to do with the syntax.

https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

Maybe try

attachInterrupt(digitalPinToInterrupt(WemosPin_D1), Func_Raumlicht, CHANGE);

Hey Pete,
I think I have to disappoint you and your idea. First of all I would not use a periodically call of the input-state (so I don´t get any fade effects). To prevent that I had to program it with an “attachinterrupt” in setup. So that it would like seen like this

attachInterrupt(WemosPin_D1, CheckButtonState, CHANGE);

Now would come the debouncing but before CheckButtonState() get called also 1000times. So it would be for the trashcan. Am I right or wrong?

Exactly that I want avoid :joy:
If you have other functions with smaller periodically calls, like I need for fade effects, you see every 100ms a short bug :thinking:

Hmm. I am failing to see any “fade” effect.

What I do see is the monitoring of a digital pin and based upon its state turning a virtual led on/off and also setting a virtual pin high/low.

As the title is “debouncing” I was thinking you were looking for ways to debounc the input. Which you mentioned was from a relay.

My sketch contains also functions like this. The whole is lo large to pubblish on Website :joy:

 timerID_Szene = timerSzene.setInterval(10L, Func_Mode_Szene);

BLYNK_WRITE(V28)                                          //Slider Control Szene (1...50)
{
  Control_Szene = param.asInt();
  if ((M_HinterleuchtungBett_Szene == 1) || (M_UnterleuchtungBett_Szene == 1)) {
    timerSzene.deleteTimer(timerID_Szene);
    timerID_Szene = timerSzene.setInterval(500L / Control_Szene, Func_Mode_Szene);
  }
}
void Func_Mode_Szene() {
  if ((M_HinterleuchtungBett_Szene == 1) || (M_UnterleuchtungBett_Szene == 1)) {
    static int SzeneValue = 0;
    SzeneValue = SzeneValue + SzeneSteps;
    if (SzeneValue >= 255 || SzeneValue <= 0) {                             
      SzeneSteps = -SzeneSteps;
    }
    else {
      OutputValue_Szene = SzeneValue;
    }
  }
  if (M_UnterleuchtungBett_Szene == 1) {
    OutputValue_UnterleuchtungBett = OutputValue_Szene;
    analogWrite (WemosPin_D3, OutputValue_Szene) ;
  }
  if (M_HinterleuchtungBett_Szene == 1) {
    OutputValue_HinterleuchtungBett = OutputValue_Szene;
    analogWrite (WemosPin_D4, OutputValue_Szene);
  }
}

It’s just a standard renounce routine, it doesn’t matter if it’s called by polling with a timer it with an interrupt - I use it either way depending on what works best.
As I said earlier, there is in theory an issue with using millis() inside a function called by an interrupt, but in practice it works well.

If it’s not what you’re looking for then don’t use it.
It’s not me that will be disappointed :grinning:

Pete.

Sorry Pete that I called into question your kindly reply. I will try it tomorrow.
It was only my inner logic with wrote my last answer, and I never claimed that it´s usually right :joy: