Weird Microswitch Behaviour

Hi,
first of all, this is my code:

#include <SoftwareSerial.h>
#include <avr/sleep.h>

# define interruptPin 2

int time_stayreading=0;


void setup() {  
  Serial.begin(19200); 
}

void loop() {
 wakeUp();
 Serial.println("POWER ON");
 int buttonstate=digitalRead(interruptPin);
 bool stayreading=true;
 Serial.println(buttonstate);
 while(stayreading==true){
  int buttonstate=digitalRead(interruptPin);
  Serial.println(buttonstate);
    if(millis() - time_stayreading > 50){
        time_stayreading = millis();
        stayreading=false;
     }
   }    
 Serial.println("POWER OFF");
 delay(50);
 sleep();
}


void sleep(){
    sleep_enable();
    EIFR = bit (INTF0);
    attachInterrupt(0, wakeUp, FALLING);
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_cpu();
  }

void wakeUp(){
  sleep_disable();
  detachInterrupt(0);
}

On Pin 2 I got a Microswitch that puts +5V on the Pin when it is pushed, I got Pin 2connected to ground with a 120kOhm resistor to denoise it (is this the correct term?). I want to achieve a sleeping arduino that wakes up on a button push and is able to stay awake as long as the button is pushed. I tried this using a while loop that is triggered by the button state - but as you see from the output below (I kept pushing the button again and again) this is nothing but a random number generator in the best case.

11:40:55.715 -> POWER OFF
11:40:58.393 -> POWER ON
11:40:58.393 -> 0
11:40:58.393 -> 0
11:40:58.393 -> POWER OFF
11:40:59.202 -> POWER ON
11:40:59.202 -> 0
11:40:59.235 -> 0
11:40:59.235 -> POWER OFF
11:40:59.609 -> POWER ON
11:40:59.644 -> 1
11:40:59.644 -> 1
11:40:59.644 -> POWER OFF
11:41:00.017 -> POWER ON
11:41:00.017 -> 0
11:41:00.017 -> 0
11:41:00.017 -> POWER OFF
11:41:01.160 -> POWER ON
11:41:01.160 -> 0
11:41:01.160 -> 0
11:41:01.160 -> POWER OFF
11:41:01.261 -> POWER ON
11:41:01.261 -> 1
11:41:01.261 -> 1
11:41:01.261 -> 1
11:41:01.261 -> POWER OFF
11:41:01.464 -> POWER ON
11:41:01.464 -> 0
11:41:01.464 -> 0
11:41:01.464 -> 0
11:41:01.464 -> 0
11:41:01.464 -> POWER OFF
11:41:01.599 -> POWER ON
11:41:01.599 -> 0
11:41:01.633 -> 0
11:41:01.633 -> 0
11:41:01.633 -> 0
11:41:01.633 -> 0
11:41:01.633 -> POWER OFF

What did I do wrong? This seems like a very common usecase for me, but I did not really know what to search for, I'm sorry. I'm aware of the bouncing problem, I've tried using the Bounce2 Library but this changed absolutely nothing.

Hi,
Can you post a copy of your circuit please, showing how you have connected everything, including the microswitch?

You haven't assigned the microswitch pin as an input in your setup().

Tom... :slight_smile:

TomGeorge:
You haven't assigned the microswitch pin as an input in your setup().

Does it matter?

  1. Use the digitalPinToInterrupt() function instead of the magic zero.

  2. Why is SoftwareSerial included? That does a lot of things with interrupts and may be incompatible with sleep.

  3. Your output looks like it came from a different program or maybe something other than the serial monitor.

  4. It is good practice to pinMode() inputs just to show future you which pins are used, even though all pins are inputs by default.

11:40:55.715 -> POWER OFF

Where did this come from (not the serial monitor, obviously)?

I suspect this is a result of switch bounce.

The early bouncing will cause the loop to break: to the Arduino it seems as if the switch was released (even though it was just contacts bouncing).

The 50 ms delay after the "power off" will ensure the switch is done bouncing, and no further interrupts arrive to wake up your device again. So even if you keep the switch pressed, it will go to sleep.

Solutions:

  • hardware debounce (small cap in parallel with your pull-down resistor) - usually not the preferred solution but in this case it may be as you're dealing with sleep.
  • software debounce (start checking for the switch release only some 50 ms after the first press was recorded)

120k is a pretty weak pulldown, try something in the 30 ~ 50k range.

JCA79B:
120k is a pretty weak pulldown, try something in the 30 ~ 50k range.

Even better, connect the switch to ground and use a pull-up.