Switch fires twice when turning off, although hardware debounce attached

I have an on/off switch connected to the D2 pin of the Arduino Nano, and an interrupt on CHANGE on that pin. I also connected a 1µF capactor in parallel. It works perfectly fine when turning the switch on, however, when turning it off again, the interrupt function gets called twice.

Code:

#define START_SWITCH 2

void setup() {
    pinMode(START_SWITCH, INPUT_PULLUP);
    Serial.begin(9600);

    attachInterrupt(digitalPinToInterrupt(START_SWITCH), onStartSwitchChange, CHANGE);
}

void loop() {}

void onStartSwitchChange() {
  Serial.println("CHANGE");
  Serial.println(digitalRead(START_SWITCH));
}

I'm going to guess your code contains the line pinMode(2, INPUT_PULLUP);
I shouldn't have to guess....

I am sorry, I forgot to include that line into my post. You're right, it does! Im gonna edit my post

confirm you did try with the pull-up enabled

it was enabled, i just forgot to copy it into the post. Unfortunatly it is not working.

i also tried to change the switch, the capacitor, the arduino and all the wires, so a hardware problem shouldnt be the cause.

can you show the full circuit?
or can you try to get rid of everything else but the button and capacitor and try again?

this is pretty interesting. I also had two leds connected, to the d4 and d5 pins. Whenever I include them and the activation code, the switch fails. Im gonna post the whole circuit and the full code, however this is quite a bit.

#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <math.h>

#define BMP280_ADDRESS 0x76 // MEMORY ADDRESS OF BMP280, NEEDED FOR I2C Protocol

#define START_SWITCH 2
#define MULTI_SWITCH 3
#define SUCCESS_LED 4
#define ERROR_LED 5
#define SD_MODULE 10 // CS PIN of SD Module

const String FILE_PATH = "log.txt";
File file;

const Adafruit_BMP280 bmp280;

bool isSwitchPressed = false;
bool dataRecordingStarted = false;
bool setupCheckSuccess = false;

unsigned long previousMillis = 0;

float data[3];

void setup() {
  pinMode(START_SWITCH, INPUT_PULLUP);
  pinMode(SUCCESS_LED, OUTPUT);
  pinMode(ERROR_LED, OUTPUT);

  Serial.begin(9600);

  attachInterrupt(digitalPinToInterrupt(START_SWITCH), onStartSwitchChange, CHANGE);
  attachInterrupt(digitalPinToInterrupt(MULTI_SWITCH), onMultiSwitchChange, CHANGE);

  setupCheckSuccess = checkConnections();

  if (setupCheckSuccess) {
    activateLed(SUCCESS_LED);

    file = SD.open(FILE_PATH, FILE_WRITE);
    file.println("------------------ NEUE MESSUNG ------------------");
    file.println("FORMAT: <ZEIT, TEMPERATUR in °C, DRUCK in Pa>");
    file.close();
  } else {
    activateLed(ERROR_LED);
  }
}

void loop() {
  if (!dataRecordingStarted) {
    // CAUSES THE ISSUE:
    //activateLed(setupCheckSuccess ? SUCCESS_LED : ERROR_LED);
    return;
  }

  collectData(data);

  writeDataToFile(data);
  
  // CAUSES THE ISSUE:
  //flashLedAsync(setupCheckSuccess ? SUCCESS_LED : ERROR_LED, 500);
}

void writeDataToFile(float data[3]) {
  String dataString = String("");

  for (int i = 0; i <= sizeof(data); i++) {
    dataString += data[i];
    
    if (i != sizeof(data)) {
      dataString += ", ";
    }
  }

  file = SD.open(FILE_PATH, FILE_WRITE);
  file.println(dataString);
  file.close();
}

// int[] collectData not possible in C, one function cannot return an array
void collectData(float data[]) {
  float temperature = bmp280.readTemperature();
  float pressure = bmp280.readPressure();

  data[0] = millis();
  data[1] = temperature;
  data[2] = pressure;
}

void onMultiSwitchChange() {
  //Serial.println("CHANGE");
}

void onStartSwitchChange() {
  Serial.println("CHANGE");
  Serial.println(digitalRead(START_SWITCH));
  dataRecordingStarted = !dataRecordingStarted;

  deactivateLed(setupCheckSuccess ? SUCCESS_LED : ERROR_LED);
}

bool checkConnections() {
  bool bmp280 = isBMP280Available();
  bool sdModule = isSdModuleAvailable();

  flashLed(bmp280 ? SUCCESS_LED : ERROR_LED, 500);
  delay(500);
  flashLed(sdModule ? SUCCESS_LED : ERROR_LED, 500);
  delay(500);

  return bmp280 && sdModule;
}

bool isBMP280Available() {
  return bmp280.begin(BMP280_ADDRESS);
}

bool isSdModuleAvailable() {
  return SD.begin(SD_MODULE);
}

void flashLedAsync(int pin, int duration) {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= duration) {
    previousMillis = currentMillis;

    if (digitalRead(pin) == HIGH) {
      deactivateLed(pin);
    } else {
      activateLed(pin);
    }
  }
}

void activateLed(int pin) {
  digitalWrite(pin, HIGH);
}

void deactivateLed(int pin) {
  digitalWrite(pin, LOW);
}

void flashLed(int pin, int duration) {
   activateLed(pin);
   delay(duration);
   deactivateLed(pin);
}

No series resistors for the LEDs. Therefore possible damage to the LEDs. Possible damage to the Arduino pins 3 & 4 or other parts of the chip. High currents causing strange side-effects...

both leds are 3.3 to 5V leds, so i dont need a resistor.

Please post a link to these LEDs.

I dont have a link to these, as I bought them from a local shop. But both LEDs are 3.3-5V and 20mA. And I thought with setting the output to HIGH, hence 5V, there shouldnt be a problem with the leds.

At least post a close-up, sharp, bright photo of one of them.

EDIT: wait a minute... Their anodes are connected to ground.

ahh you're right, i wired them wrong in the circuit diagramm. Of course the cathodes are connected to the ground

Ok, so too much current would flow from the Arduino pins, possibly damaging them and the LEDs or at least causing strange side effects. You need those current limiting resistors, and maybe new LEDs and a new Arduino.

As often the route cause is not where you think it is in the first place

What triggered my thought was seeing the LED in your circuit extract but not the resistor (As a rule of thum I would always have a current limiting resistor with LEDs)

So note to take

Don’t post snippets
Post full circuit
Don’t assume the issue is where the consequences are visible

Hi stad_nico
could you try putting an extra pullup resistance, e.g. 2K ? (on D2)

and tell us when turning the switch off again, the interrupt function gets called only once ?.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.