Weird detections of ISR on D3 pin changes on Electron (false positives) (Resolved)


I have an application which uses an ISR to detect changes in D3 (Push Button). I get random hits to the ISR without a common reproducible cause.

The push button is normally open, and I have +v come into D3 when I want to trigger the ISR event. I have the internal pull_down set to the pin.

I am suspecting the pull_downs are not enough or I am receiving interference of some sort, but can’t figured it out if this could also come from a peripheral (Software Timer, PMIC, CEL, FUEL G, etc) firing for some reason. I couldn’t find anything suggesting the latter in the data-sheets but never hurts to ask before making changes.

As far as the code this is what I’ve done: (I simplified the reason to use an ISR to make the code more clear and concise).

int button = D3;
int extLed = A4;
bool systemHasNoticed=false;

void setup() {
    pinMode(button, INPUT_PULLDOWN);
    pinMode(extLed, OUTPUT);
    attachInterrupt(D3, isrEvent, CHANGE);

void loop() { 

void isrEvent() {
    if (digitalRead(D3)==HIGH && systemHasNoticed == false) {
      systemHasNoticed = true;

void checkPressEvents() {
 if(digitalRead(D3)==HIGH && systemHasNoticed == true) {
      Particle.publish("BUTTON PRESSED!");
      systemHasNoticed = false;

Just to understand:

  • Why are you using a CHANGE trigger and not a RISING?
  • How long are your wires to the button?
  • Is you button closing to 3.3V or 5V?
  • What happens in setExternalLed()?

I don’t see a lot of need for noInterrupts() in this case - your systemHasNoticed should provide enough “debounce”, but you should have it volatile!


  1. I replaced it with RISING. Which seems appropriate.
  2. Probably 3cm to 5cm. They run under the lower side of the chip to the end opposite of the USB port.
  3. 3.3v
  4. I set the external led to on or off. See code bellow.

Thanks for the tip. So systemHasNoticed needs to be set to volitile! YES. that’s true. Thanks for the catch.

I will also remove the noInterrupts for simplicity. And I am already thinking on a way to re-code the whole thing without using interrupts so I can calibrate the debounce.

This is what happens on setExternalLed() :

void setExternalLed(bool value) {
  if (value) {
    digitalWrite(A4, LOW);
  } else {
    digitalWrite(A4, HIGH);

With these infos and after applying the changes outlined, I’d not expect to see any triggers of the interrupt unlesss you’ve got a lot of EM noise either directly tripping the device or inducing voltage into your wires (which are not actually that long).

If you still see the false triggers, you could try an external 4k7 pull-down and maybe a 10nF/100nF cap in parallel to “pull off” some high frequency spikes.

Would you recommend a polling mechanism (check digitalRead in loop) or interrupt driven?

You can use polling, but interrupts don’t usually give me troubles.
If I experience troubles I try to find ways to counteract them.


@frlobo, have you looked at the clickButton library on the IDE?


Havent @peekay123 but will do.

Now, here’s an interesting test I have done…

I do think I have either created an antena or something, because I did a polling route with mirror to see what was going on:

void loop() {

void poll_button() {
  bool value = digitalRead(D3);

And what I see is a dimming/pulsing LED :blush:

If I set the SYSTEM_MODE to SEMI_AUTOMATIC… And I only connect to cellular, I don’t see any issues… Even if I transmit to TCPClient continually. However when I also connect to particle : Particle.connect(), I see the oscillating condition. However… It is weird that only when connecting to Particle and not when using the cellular radio.

I will install an external pulldown resistor. I have already re-checked my wiring which is extremely short and well isolated. I installed thermofit (shrink wrap) around all the connections in the switch. I hate that its a Normally Open switch and not a NC so I could check LOW instead of HIGH. But I don’t have another switch with the required LED specs handy. And now its personal!

If that does not work I will try another input PIN that does not share any other function such as SPI3_SS os I2S_WS…

I will see if for some reason there’s not another thing going on. Because I was still getting the misfire on the ISR even in AUTOMATIC mode.

Will keep you posted and if you have any other ideas to explore more than welcome.


Just to update everyone:

The ISR works perfect on my original configuration. It was a mistake I had in my wiring where I was using the common VCC that controls the LED bridged to the switch NO so if the LED was off the switch did not worked as expected.

So in short. My bad :blush:


Glad you were able to get it working!

1 Like