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. Troubleshooting
  3. Getting Pin Change Interrupts working together with Timer interrupts / sleep(XX ms) on Arduino Pro Mini

Getting Pin Change Interrupts working together with Timer interrupts / sleep(XX ms) on Arduino Pro Mini

Scheduled Pinned Locked Moved Troubleshooting
23 Posts 9 Posters 196 Views 8 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.
  • J Offline
    J Offline
    Joost
    wrote on last edited by Joost
    #13

    How does MySensors accomplish long sleep() times? Is it like
    sleep() with Watchdog Timer set for 8s -> calculate remainder -> sleep() again?
    If so, I could maybe find the var in which MySensors itself keeps track of sleep time.

    BearWithBeardB YveauxY 2 Replies Last reply
    0
    • J Joost

      How does MySensors accomplish long sleep() times? Is it like
      sleep() with Watchdog Timer set for 8s -> calculate remainder -> sleep() again?
      If so, I could maybe find the var in which MySensors itself keeps track of sleep time.

      BearWithBeardB Offline
      BearWithBeardB Offline
      BearWithBeard
      wrote on last edited by
      #14

      @Joost There has been an attempt to do this a few years ago. I don't know if they ever got it working though: https://forum.mysensors.org/topic/7197/sleep-time-and-external-interrrupts

      Besides that, you could request the current time from the controller on interrupts and calculate the remaining sleep duration from there or, as mentioned before, use an external RTC.

      1 Reply Last reply
      0
      • J Joost

        How does MySensors accomplish long sleep() times? Is it like
        sleep() with Watchdog Timer set for 8s -> calculate remainder -> sleep() again?
        If so, I could maybe find the var in which MySensors itself keeps track of sleep time.

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

        @Joost I implemented a way to get the remaining sleep time, albeit only roughly on AVR: https://forum.mysensors.org/topic/9595/interrupted-sleep/11

        http://yveaux.blogspot.nl

        J 1 Reply Last reply
        1
        • J Joost

          @zboblamont Ah, ok.
          To be honest, I had hoped there'd be a counter/register (for the timer interrupt - how does the Arduino keep track of itself otherwise?) I could read and then sleep() for the remainder...

          I'll browse around later and see if I can dig up something on the web.
          Thanks!

          zboblamontZ Offline
          zboblamontZ Offline
          zboblamont
          wrote on last edited by
          #16

          @Joost My only thought on the RTC is separation of the timing aspect allowing the processor to go deep-sleep forever until Interrupt. I have one set up to hourly scan my water tank, but I can press a button in parallel with the interrupt to ground for ad-hoc update.

          J 1 Reply Last reply
          0
          • zboblamontZ zboblamont

            @Joost My only thought on the RTC is separation of the timing aspect allowing the processor to go deep-sleep forever until Interrupt. I have one set up to hourly scan my water tank, but I can press a button in parallel with the interrupt to ground for ad-hoc update.

            J Offline
            J Offline
            Joost
            wrote on last edited by
            #17

            @zboblamont Thanks, will think about that if a pure software approach fails! Though I'd really like to keep complexity down; I'm planning on fabricating at least 10-20 nodes of that kind (by hand).

            1 Reply Last reply
            0
            • YveauxY Yveaux

              @Joost I implemented a way to get the remaining sleep time, albeit only roughly on AVR: https://forum.mysensors.org/topic/9595/interrupted-sleep/11

              J Offline
              J Offline
              Joost
              wrote on last edited by
              #18

              @Yveaux Thanks, very cool and promising, will take a more in depth look tomorrow!
              I just threw that in my code quickly tonight, so far I got a 5 digit number back, but that was always the same also with different wake up delays via PCInt after going to sleep().

              YveauxY 1 Reply Last reply
              0
              • J Joost

                @Yveaux Thanks, very cool and promising, will take a more in depth look tomorrow!
                I just threw that in my code quickly tonight, so far I got a 5 digit number back, but that was always the same also with different wake up delays via PCInt after going to sleep().

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

                @Joost as documented it can be roughly 8 seconds off on avr. When an avr is set to sleep for 8 seconds (the maximum watchdog sleep time) and it is woken by an interrupt, it will not know how much time is remaining and always return the same time remaining.
                Try sleeping for a minute, then interrupt after 1 second and after half a minute. The remaining time should be different.

                http://yveaux.blogspot.nl

                J 2 Replies Last reply
                0
                • YveauxY Yveaux

                  @Joost as documented it can be roughly 8 seconds off on avr. When an avr is set to sleep for 8 seconds (the maximum watchdog sleep time) and it is woken by an interrupt, it will not know how much time is remaining and always return the same time remaining.
                  Try sleeping for a minute, then interrupt after 1 second and after half a minute. The remaining time should be different.

                  J Offline
                  J Offline
                  Joost
                  wrote on last edited by Joost
                  #20

                  @Yveaux said in Getting Pin Change Interrupts working together with Timer interrupts / sleep(XX ms) on Arduino Pro Mini:

                  @Joost as documented it can be roughly 8 seconds off on avr. When an avr is set to sleep for 8 seconds (the maximum watchdog sleep time) and it is woken by an interrupt, it will not know how much time is remaining and always return the same time remaining.
                  Try sleeping for a minute, then interrupt after 1 second and after half a minute. The remaining time should be different.

                  @Yveaux Hi, yeah, I was already expecting the 8s inaccuracy (which is no problem at all, I am planning to cover intervals of several hours).
                  I tried yesterday night with sleep times of 1-5 minutes and could not get it to work at that point (always receiving identical numbers though the time to awakening the node with PCInt differed), but this might be because I just hacked it in an otherwise more complicated sketch.

                  I'll start now with making up a minimal test sketch to get the hang of it!
                  Thanks, J

                  1 Reply Last reply
                  0
                  • YveauxY Yveaux

                    @Joost as documented it can be roughly 8 seconds off on avr. When an avr is set to sleep for 8 seconds (the maximum watchdog sleep time) and it is woken by an interrupt, it will not know how much time is remaining and always return the same time remaining.
                    Try sleeping for a minute, then interrupt after 1 second and after half a minute. The remaining time should be different.

                    J Offline
                    J Offline
                    Joost
                    wrote on last edited by Joost
                    #21

                    @Yveaux & others:
                    So this works great! Here is an example sketch to get Pin Change Interrupts working together with timer-based sleep(). There will be identification of the triggered pin as well as discrimination between rising and falling edge. To test, just add a jumper wire to pin A1 or/and A2 to a Arduino Pro Mini and short it to Ground to wake the Arduino out of a timed sleep() (a connected Radio, here a RFM95, is needed to get the sketch started).

                    #include <Arduino.h>
                    
                    #define MY_RADIO_RFM95
                    #include <MySensors.h>
                    
                    volatile int isrcounter = 0, timercounter=0;
                    volatile char PinRegLast, ChangedPin, PinRegister;
                    volatile boolean isr_interrupted;
                    uint32_t remainingSleepTime = 0;
                    
                    ISR(PCINT1_vect)
                    {
                        PinRegister = PINC;
                        ChangedPin = PinRegister ^ PinRegLast;
                        PinRegLast = PinRegister;
                        _wokeUpByInterrupt = 0xFE;
                        isr_interrupted=true;
                        isrcounter++;
                    }
                    
                    void setup()
                    {
                    noInterrupts();
                    PCICR |= 0b00000011; // Enables Ports B and C Pin Change Interrupts
                    PCMSK1 |= 0b00000110; //PCINT9 & PCINT10 = A1 & A2
                    PCIFR  = B00000001; // Reset Interruptflag
                    pinMode(A1, INPUT_PULLUP); pinMode(A2, INPUT_PULLUP);
                    PinRegister = PINC;
                    interrupts();
                    Serial.begin(38400);
                    }
                    
                    void presentation() {}
                    
                    void loop()
                    {
                      noInterrupts();
                      if ( isr_interrupted ) {
                        isr_interrupted = false;
                        switch (ChangedPin){
                        case (1 << PINC1):
                          if (~PinRegister & (1 << PINC1)) { 
                            Serial.print("Interrupted / Woken up by Pin A1, remaining sleep() time: ");  
                            remainingSleepTime = getSleepRemaining();
                            Serial.println( remainingSleepTime );}
                          else { 
                            Serial.println("Falling edge of Pin A1"); 
                           } 
                          break;
                        case (1 << PINC2):
                          if (~PinRegister & (1 << PINC2)) { 
                            Serial.print("Interrupted / Woken up by Pin A2, remaining sleep() time: "); 
                            remainingSleepTime = getSleepRemaining();
                            Serial.println( remainingSleepTime );}
                          else { 
                            Serial.println("Falling edge of Pin A2"); 
                           }
                          break;
                        default:
                          break;
                        interrupts();
                        }
                      }
                      else  { 
                        interrupts();
                        Serial.println("Timer wake up / Loop"); 
                        timercounter++; 
                        }
                    
                      Serial.print("  ");  Serial.print(" ISR Counter: ");Serial.print(isrcounter);  Serial.print("   Timer counter: "); Serial.println(timercounter);
                      sleep((uint32_t) 60*1000);
                    }
                    

                    Thanks a lot! Joost

                    1 Reply Last reply
                    2
                    • E Offline
                      E Offline
                      evb
                      wrote on last edited by
                      #22

                      @Joost I like your solution to be able to use other pins as pin change interrupts together with Timer interrupts in the MySensors library.

                      I did use the default sleep function of MySensors with the foreseen D1 and D2 pins where D1 is already taken by the radio, so only D2 is usable for custom use.
                      See https://www.mysensors.org/download/sensor_api_20#sleeping

                      1 Reply Last reply
                      0
                      • R Offline
                        R Offline
                        r-nox
                        wrote on last edited by r-nox
                        #23

                        I think this is the same thing as you were trying to accomplish.

                        Sleep for 6 minutes or when interrupted. I have a reed switch on pin 2

                        pinMode(REED_SWITCH, INPUT);   // set the reed switch digital pin as input
                        //digitalWrite(REED_SWITCH, HIGH);
                        pinMode(REED_SWITCH, INPUT_PULLUP);
                        
                        
                        sleep(digitalPinToInterrupt(REED_SWITCH), CHANGE, 360000); //3600000 hour
                        
                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        12

                        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