Interruption being triggered when not desired [PHOTON]

I need to activate two relays only on the FALLING signal of two distinct physical pushbuttons (each with a 100 nF capacitor in parallel for hardware debouncing). The buttons are connected to the pins D3 and D4 at one end, and on GND at the other end (together). (might be a problem?)

What I chose to do was to attach two different interruptions (one for each physical button) that would lead to two different functions for toggling the states of the relays.

But what is happening is that I’m getting a very weir behavior. When I activate the pushbutton1, sometimes it triggers the correct interruption attachInterrupt(pushbutton1, toggle_relay1, FALLING);, but sometimes it activates the interruption that it isn’t supposed to activate in any way attachInterrupt(pushbutton2, toggle_relay2, FALLING);, and sometimes it activates both interruptions!

The same happens when activating (pressing) pushbutton2.

Also, when I comment out the second interruption attachInterrupt(pushbutton2, toggle_relay2, FALLING); and still pressing the pushbutton2 it toggles the relay1 ! Remembering that at one end they are connected to different pins on Photon, and at the other they are wired up together and connected to the board GND.

Could somebody help me solving this? Thank you in advance!

Here is my very simple code:

/* RELAYS */
int relay1 = D2;            
int relay2 = D1;  

/* PHYSICAL PUSHBUTTONS */
int pushbutton1 = D3;       
int pushbutton2 = D4;       

volatile int state_relay1 = LOW;       // Initialize the relay 1 as LOW or ON
volatile int state_relay2 = LOW;       // Initialize the relay 2 as LOW or ON

void setup(){

    pinMode(relay1, OUTPUT);                                  //setup of relay1 as output on Photon
    pinMode(pushbutton1, INPUT_PULLUP);
    attachInterrupt(pushbutton1, toggle_relay1, FALLING);   //attach the interruption to toggle the state_relay1 on FALLING of pushbutton1

    pinMode(relay2, OUTPUT);                                 //setup of relay2 as output on Photon
    pinMode(pushbutton2, INPUT_PULLUP);
    attachInterrupt(pushbutton2, toggle_relay2, FALLING);   //attach the interruption to toggle the state_relay2 on FALLING of pushbutton2

}

//Function to toggle_relay1 when the interruption from the falling edge signal from pushbutton1 happens

void toggle_relay1() {
    state_relay1 = !state_relay1;
    digitalWrite(relay1, state_relay1);       //Writes the state_relay1 to relay 1
}

//Function to toggle_relay2 when the interruption from the falling edge signal from pushbutton2 happens

void toggle_relay2() {
    state_relay2 = !state_relay2;
    digitalWrite(relay2, state_relay2);       //Writes the state_relay1 to relay 2
}

Having both switches tied to GND won’t be a problem.
GND is a “strong” enough rail that won’t budge a bit by just connecting 3.3V via a 40k pull-up to it.
But even if you had a realy low value pull-up, the other pin wouldn’t get anything of it since the respective switch would still be open.

Try removing the caps to see if you at least lose the “cross-talk”

I removed the GND cable from the pushbuttons, and I observed a weirder behavior. If I get a wire, that is not connected to anything, and touch it on the GND pin from Photon, the relay switches!

Any idea of why this is happening?

That’s odd indeed.
Any chance to post a photo of your setup.

BTW, how have you wired which relays?
Got fly-back diodes in place?

Here is an Schematic of the wiring I have:

Here is the real setup (sorry it’s a little messy):

In that photo I can’t quite make out where the orange wires of the two switches actually are connected to GND :confused:

1 Like

In real photo they are not yet connected to GND, but afterwards I connected it… I have now some osciloscope pictures of the signals, which I will post it now. It seems a software problem with the interruptions because I removed the buttons and wired the input pins directly with GND, and I still get the same problem.

I have tried your code and didn’t get any cross-talk at all (but I also had no caps in parallel).

But how did you manage to not have the bouncing problem?

Here is the picture of the osciloscope I have. I measured the signals directly on the Photon board pins:

relay1 = D2; (PURPLE)
relay2 = D1; (PINK)
pushbutton1 = D3; (YELLOW)
pushbutton2 = D4; (GREEN)

Hardware debounce is a bit more involved than just a cheap ol’ cap :wink:
You don’t want any signal traversing “back up the cap” to the other pin, which might happen with the combination of your caps and the inductance of your longish wires.

The minimum would also require a resistor.

Some simple thoughts about this can be found there
http://www.zen22142.zen.co.uk/Design/debounce.htm
http://www.labbookpages.co.uk/electronics/debounce.html

And here a somewhat more involved read

Thank you again for the useful information!

Although I still not understand the weird behavior of the interruptions, I could do a workaround to get away with the undesired behavior of the relays and pushbuttons.

here is what I did:

/* RELAYS */
int relay1 = D2;            
int relay2 = D1;  

/* PHYSICAL PUSHBUTTONS */
int pushbutton1 = D3;       
int pushbutton2 = D4;       

volatile int state_relay1 = LOW;       // Initialize the relay 1 as LOW or ON
volatile int state_relay2 = LOW;       // Initialize the relay 2 as LOW or ON

void setup(){

    pinMode(relay1, OUTPUT);                                  //setup of relay1 as output on Photon
    pinMode(pushbutton1, INPUT_PULLUP);
    attachInterrupt(pushbutton1, toggle_relay1, FALLING);   //attach the interruption to toggle the state_relay1 on FALLING of pushbutton1

    pinMode(relay2, OUTPUT);                                 //setup of relay2 as output on Photon
    pinMode(pushbutton2, INPUT_PULLUP);
    attachInterrupt(pushbutton2, toggle_relay2, FALLING);   //attach the interruption to toggle the state_relay2 on FALLING of pushbutton2

}

//Function to toggle_relay1 when the interruption from the falling edge signal from pushbutton1 happens

void toggle_relay1() {
    if(digitalRead(pushbutton1) == LOW && digitalRead(pushbutton2) == HIGH){
        state_relay1 = !state_relay1;
        digitalWrite(relay1, state_relay1);       //Writes the state_relay1 to relay 1
    }
}

//Function to toggle_relay2 when the interruption from the falling edge signal from pushbutton2 happens

void toggle_relay2() {
    if(digitalRead(pushbutton2) == LOW && digitalRead(pushbutton1) == HIGH){
        state_relay2 = !state_relay2;
        digitalWrite(relay2, state_relay2);       //Writes the state_relay2 to relay 2
    }
}

Even though this workaround make the system operates in the way I want to, I would like to understand why different interruptions are being triggered at the same time or when their trigger events are not happening.

If somebody have any clue for this strange behavior, I’m all open to learn :smile:

Thank you!

I am experiencing the same problem on a raspberry pi. I have implemented a full RC circuit PLUS a Schmidt trigger, and yet I still get multiple interrupts being fired on the press of one button only.I am happy to provide further information and images if it would help.

In order to bypass the problem, I am forced to cancel the interrupts when a button is pressed, action the pressed button functions, and then re-instate the interrupts. Not elegant at all.

I will follow this post with interest and will happily provide further input if required.

You don’t need to cancel interrupts, you can keep interrupts coming, just set a blockout flag on first instance that decays over time

Maybe like this


volatile uint32_t msBlockOut;

void ISR()
{
  if (millis() - msBlockOut < 30) return;  // 30ms blockout periode
  msBlockout = millis();
  // do whatever
}

Yes, indeed that is a valid strategy. I have tried it and it works well.

I find however that having interrupts being called incorrectly is a niggle in the back of my mind, and I feel I need a practical answer before letting it go. The behaviour goes against the laws of science, and so I feel the need to press on with my quest to solve this.

A quick question - The multiple trigger problem seems to go away when the relay, together with its load, is not connected - ie. when I physically disconnect the power to the relay switch, everything works fine. When I power up the relay and trigger NO to closed, the problems seem to occur. Could it be that the load creatives some sort of unintended consequence on the micro controller circuit that drives it (magnetic field, big draw resulting in overall voltage dip etc).

It is interesting to note the the many interrupts are triggered even when I use a soft switch (ie a message from a website). This therefore negates the bouncing of a physical switch as a trigger of the other interrupts.

So by deduction, the LOW instruction to the pin, and subsequent change of state in the relay, causes some sort unintended consequence on the other pins against which interrupts are registered.

Thoughts?

I don’t know enough about your setup, but indcutances like your relay coils do cause a kickback when switched off, for that you need kickback or flyback diodes.
If you have your load and the µC powered via the same power supply, any action on the load can feedback to the µC via the power supply.
If you have a very noise load (e.g. a brushed motor with bad brushes) that’ll produce a lot of EM noise
And the list could go on.