Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. General Discussion
  3. Pin Change Interrupts debounce

Pin Change Interrupts debounce

Scheduled Pinned Locked Moved General Discussion
16 Posts 3 Posters 2.0k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • alexsh1A Offline
    alexsh1A Offline
    alexsh1
    wrote on last edited by
    #1

    Hi,

    MY GW is flooded with messages as I am using pin change interrupt.
    How do I debounce it please? sleep() does not work

    ISR (PCINT0_vect)
     {
     // handle pin change interrupt for D8 to D13 here
     }  // end of PCINT0_vect
    
    ISR (PCINT1_vect)
     {
     // handle pin change interrupt for A0 to A5 here
     }  // end of PCINT1_vect
    
    ISR (PCINT2_vect)
     {
     // handle pin change interrupt for D0 to D7 here
     }  // end of PCINT2_vect
    
    
    void setup ()
      { 
      // pin change interrupt (example for D9)
      PCMSK0 |= bit (PCINT1);  // want pin 9
      PCIFR  |= bit (PCIF0);   // clear any outstanding interrupts
      PCICR  |= bit (PCIE0);   // enable pin change interrupts for D8 to D13
      }
    
    mfalkviddM 1 Reply Last reply
    0
    • alexsh1A alexsh1

      Hi,

      MY GW is flooded with messages as I am using pin change interrupt.
      How do I debounce it please? sleep() does not work

      ISR (PCINT0_vect)
       {
       // handle pin change interrupt for D8 to D13 here
       }  // end of PCINT0_vect
      
      ISR (PCINT1_vect)
       {
       // handle pin change interrupt for A0 to A5 here
       }  // end of PCINT1_vect
      
      ISR (PCINT2_vect)
       {
       // handle pin change interrupt for D0 to D7 here
       }  // end of PCINT2_vect
      
      
      void setup ()
        { 
        // pin change interrupt (example for D9)
        PCMSK0 |= bit (PCINT1);  // want pin 9
        PCIFR  |= bit (PCIF0);   // clear any outstanding interrupts
        PCICR  |= bit (PCIE0);   // enable pin change interrupts for D8 to D13
        }
      
      mfalkviddM Offline
      mfalkviddM Offline
      mfalkvidd
      Mod
      wrote on last edited by
      #2

      @alexsh1 debounce must be done in the loop. The ISRs must execte quickly, so no debouncing can be done there.

      alexsh1A 1 Reply Last reply
      1
      • mfalkviddM mfalkvidd

        @alexsh1 debounce must be done in the loop. The ISRs must execte quickly, so no debouncing can be done there.

        alexsh1A Offline
        alexsh1A Offline
        alexsh1
        wrote on last edited by
        #3

        @mfalkvidd Ok, thank you. How exactly do I do that? I cannot use sleep() to debounce as it will be interrupted.

        mfalkviddM 1 Reply Last reply
        0
        • alexsh1A alexsh1

          @mfalkvidd Ok, thank you. How exactly do I do that? I cannot use sleep() to debounce as it will be interrupted.

          mfalkviddM Offline
          mfalkviddM Offline
          mfalkvidd
          Mod
          wrote on last edited by
          #4

          @alexsh1 how to do it would depend entirely on how the node is supposed to function. Could you describe what triggers the interrups and how you would like them to be handled?

          1 Reply Last reply
          0
          • alexsh1A Offline
            alexsh1A Offline
            alexsh1
            wrote on last edited by
            #5

            This is the most of the loop function I have apart from sleep.

             if (IRQHigh) {
                send(msg.set("1"));     
                IRQHigh = false; 
              }
            
            mfalkviddM 1 Reply Last reply
            0
            • alexsh1A alexsh1

              This is the most of the loop function I have apart from sleep.

               if (IRQHigh) {
                  send(msg.set("1"));     
                  IRQHigh = false; 
                }
              
              mfalkviddM Offline
              mfalkviddM Offline
              mfalkvidd
              Mod
              wrote on last edited by mfalkvidd
              #6

              @alexsh1 how about adding global variables for all interrups like this

              volatile unsigned long lastInterruptD1 = 0;
              volatile unsigned long lastInterruptD2 = 0;
              ...
              

              and inside the ISRs set the corresponding variable to millis() like this

              lastInterruptD1 = millis();
              

              and in loop have a series of

              if(lastInterruptD1 != 0 && millis()-lastInterruptD1 > DEBOUNCE_MS){
                lastInterruptD1 = 0;
                // Do whatever the interrupt does here
              }
              

              You could use an array instead of individual variables to make the code cleaner, especially if you want to cover a lot of pins. Which board/Arduino are you using?

              alexsh1A 1 Reply Last reply
              0
              • mfalkviddM mfalkvidd

                @alexsh1 how about adding global variables for all interrups like this

                volatile unsigned long lastInterruptD1 = 0;
                volatile unsigned long lastInterruptD2 = 0;
                ...
                

                and inside the ISRs set the corresponding variable to millis() like this

                lastInterruptD1 = millis();
                

                and in loop have a series of

                if(lastInterruptD1 != 0 && millis()-lastInterruptD1 > DEBOUNCE_MS){
                  lastInterruptD1 = 0;
                  // Do whatever the interrupt does here
                }
                

                You could use an array instead of individual variables to make the code cleaner, especially if you want to cover a lot of pins. Which board/Arduino are you using?

                alexsh1A Offline
                alexsh1A Offline
                alexsh1
                wrote on last edited by alexsh1
                #7

                @mfalkvidd it is a custom made board using atmega328p-au with sensebender bootloader running at 8Mhz and 3.3V.
                I'll try the above, however, does millis() work while sleeping?

                mfalkviddM 1 Reply Last reply
                0
                • alexsh1A alexsh1

                  @mfalkvidd it is a custom made board using atmega328p-au with sensebender bootloader running at 8Mhz and 3.3V.
                  I'll try the above, however, does millis() work while sleeping?

                  mfalkviddM Offline
                  mfalkviddM Offline
                  mfalkvidd
                  Mod
                  wrote on last edited by
                  #8

                  @alexsh1 it will return the last value, but it will not increment. That's one of the reasons ISRs should exit quickly.

                  alexsh1A 1 Reply Last reply
                  0
                  • mfalkviddM mfalkvidd

                    @alexsh1 it will return the last value, but it will not increment. That's one of the reasons ISRs should exit quickly.

                    alexsh1A Offline
                    alexsh1A Offline
                    alexsh1
                    wrote on last edited by
                    #9

                    @mfalkvidd
                    Want to share what I found in case others have a similar issue.

                    const unsigned long debounceTime = 50;
                    volatile bool ir_selector_pressed = false;
                    
                    ISR (PCINT2_vect) { // handle pin change interrupt for D0 to D7 here
                      static unsigned long previousStateChangeMillis = 0;
                      static bool previousPinState = HIGH;
                    
                      bool pinState = digitalRead(SELECTOR_BTN);
                      if (pinState != previousPinState) { // ignore pin changes of pins other than SELECTOR_BTN
                        if (pinState == LOW) { // only falling events
                          if ((millis() - previousStateChangeMillis) > debounceTime) { // debounce
                            ir_selector_pressed = true;
                          }
                        }
                        previousPinState = pinState;
                        previousStateChangeMillis = millis();
                      }
                    }```
                    1 Reply Last reply
                    0
                    • alexsh1A Offline
                      alexsh1A Offline
                      alexsh1
                      wrote on last edited by
                      #10

                      Another way to debounce is to stop interrupts in loop, sleep for say 20 seconds and then resume interrupts.

                      YveauxY 1 Reply Last reply
                      0
                      • alexsh1A alexsh1

                        Another way to debounce is to stop interrupts in loop, sleep for say 20 seconds and then resume interrupts.

                        YveauxY Offline
                        YveauxY Offline
                        Yveaux
                        Mod
                        wrote on last edited by
                        #11

                        @alexsh1 this is in general a bad idea, as it will also stop eg reception of serial data and incoming packages (when using message queuing).

                        http://yveaux.blogspot.nl

                        alexsh1A 1 Reply Last reply
                        0
                        • YveauxY Yveaux

                          @alexsh1 this is in general a bad idea, as it will also stop eg reception of serial data and incoming packages (when using message queuing).

                          alexsh1A Offline
                          alexsh1A Offline
                          alexsh1
                          wrote on last edited by
                          #12

                          @yveaux you mean stopping interrupts?

                          YveauxY 1 Reply Last reply
                          0
                          • alexsh1A alexsh1

                            @yveaux you mean stopping interrupts?

                            YveauxY Offline
                            YveauxY Offline
                            Yveaux
                            Mod
                            wrote on last edited by
                            #13

                            @alexsh1 yup

                            http://yveaux.blogspot.nl

                            alexsh1A 1 Reply Last reply
                            0
                            • YveauxY Yveaux

                              @alexsh1 yup

                              alexsh1A Offline
                              alexsh1A Offline
                              alexsh1
                              wrote on last edited by
                              #14

                              @yveaux What is the best way to do it please?

                              YveauxY 1 Reply Last reply
                              0
                              • alexsh1A alexsh1

                                @yveaux What is the best way to do it please?

                                YveauxY Offline
                                YveauxY Offline
                                Yveaux
                                Mod
                                wrote on last edited by
                                #15

                                @alexsh1 The easiest way would probably use a debounce-library.
                                These normally aren't using interrupts, but you have to question yourself if you really need interrupts in your case.

                                I don't have any readymade, tested code which uses interrupts and debounces switches.

                                http://yveaux.blogspot.nl

                                alexsh1A 1 Reply Last reply
                                1
                                • YveauxY Yveaux

                                  @alexsh1 The easiest way would probably use a debounce-library.
                                  These normally aren't using interrupts, but you have to question yourself if you really need interrupts in your case.

                                  I don't have any readymade, tested code which uses interrupts and debounces switches.

                                  alexsh1A Offline
                                  alexsh1A Offline
                                  alexsh1
                                  wrote on last edited by alexsh1
                                  #16

                                  @yveaux said in Pin Change Interrupts debounce:

                                  @alexsh1 The easiest way would probably use a debounce-library.

                                  I'll look into that. Thank you

                                  1 Reply Last reply
                                  0
                                  Reply
                                  • Reply as topic
                                  Log in to reply
                                  • Oldest to Newest
                                  • Newest to Oldest
                                  • Most Votes


                                  21

                                  Online

                                  11.7k

                                  Users

                                  11.2k

                                  Topics

                                  113.1k

                                  Posts


                                  Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                  • Login

                                  • Don't have an account? Register

                                  • Login or register to search.
                                  • First post
                                    Last post
                                  0
                                  • MySensors
                                  • OpenHardware.io
                                  • Categories
                                  • Recent
                                  • Tags
                                  • Popular