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. Pin change interrupt not firing with MySensors

Pin change interrupt not firing with MySensors

Scheduled Pinned Locked Moved Troubleshooting
39 Posts 7 Posters 11.3k Views 5 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.
  • tekkaT tekka

    @DavidZH IRQ triggers only on LOW level when sleeping (see at328 datasheet) - what happens if you substitute all enableInterrupt(xyz, CHANGE) to enableInterrupt(xyz, LOW)?

    The only funny thing I see is at 2549 !MCO:SND:NODE NOT REG

    this is because you set a 100ms timeout here:

    #define MY_TRANSPORT_WAIT_READY_MS 100 //Start the node even if no connection to the GW could be made
    

    set it to 0 or increase to e.g. 10000...

    D Offline
    D Offline
    DavidZH
    wrote on last edited by
    #30

    @tekka said in Pin change interrupt not firing with MySensors:

    @DavidZH IRQ triggers only on LOW level when sleeping (see at328 datasheet) - what happens if you substitute all enableInterrupt(xyz, CHANGE) to enableInterrupt(xyz, LOW)?

    That is not true! Chapter 13, page 70, second part, first line: The External Interrupts can be triggered by a falling or rising edge or a low level. For completeness I tried, but the outcome is the same; node wakes up immediately.

    The only funny thing I see is at 2549 !MCO:SND:NODE NOT REG

    this is because you set a 100ms timeout here:

    #define MY_TRANSPORT_WAIT_READY_MS 100 //Start the node even if no connection to the GW could be made
    

    set it to 0 or increase to e.g. 10000...

    You're right! My bad. I'll change that to 2700, that's the approximate time the node needs to start up.

    tekkaT 1 Reply Last reply
    0
    • D DavidZH

      @tekka said in Pin change interrupt not firing with MySensors:

      @DavidZH IRQ triggers only on LOW level when sleeping (see at328 datasheet) - what happens if you substitute all enableInterrupt(xyz, CHANGE) to enableInterrupt(xyz, LOW)?

      That is not true! Chapter 13, page 70, second part, first line: The External Interrupts can be triggered by a falling or rising edge or a low level. For completeness I tried, but the outcome is the same; node wakes up immediately.

      The only funny thing I see is at 2549 !MCO:SND:NODE NOT REG

      this is because you set a 100ms timeout here:

      #define MY_TRANSPORT_WAIT_READY_MS 100 //Start the node even if no connection to the GW could be made
      

      set it to 0 or increase to e.g. 10000...

      You're right! My bad. I'll change that to 2700, that's the approximate time the node needs to start up.

      tekkaT Offline
      tekkaT Offline
      tekka
      Admin
      wrote on last edited by tekka
      #31

      @DavidZH

      That is not true! Chapter 13, page 70, second part, first line: The External Interrupts can be triggered by a falling or rising edge or a low level.

      For sleeping MCUs, you may have missed this here:
      http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf

      Chapter 10.1 Sleep Modes (pg 39) => read note 3

      If the node still wakes up, it could be triggered by the radio - this is something we need to investigate further. If you disable all IRQs (on ChanA-D) - does it still wake up?

      1 Reply Last reply
      0
      • D Offline
        D Offline
        DavidZH
        wrote on last edited by
        #32

        I respectfully disagree: That states only INT_0 and INT_1, I am using PCI. Different mechanism and vectors.

        About the radio waking it up: you mean interference? Or the interrupt? I think those are not the case, as he wake reason states -1, by timer. And if I flash the exact same sketch using the 2.0 library, the node stays asleep properly and wakes with the press of a button.
        The thing I ran into when developing this node was that I could use PCI when using deep sleep, but when I wanted to add a timer to send a sensor value periodically as well, the node would only wake up with the timer, and only then register the interrupt events.

        tekkaT 1 Reply Last reply
        0
        • D DavidZH

          I respectfully disagree: That states only INT_0 and INT_1, I am using PCI. Different mechanism and vectors.

          About the radio waking it up: you mean interference? Or the interrupt? I think those are not the case, as he wake reason states -1, by timer. And if I flash the exact same sketch using the 2.0 library, the node stays asleep properly and wakes with the press of a button.
          The thing I ran into when developing this node was that I could use PCI when using deep sleep, but when I wanted to add a timer to send a sensor value periodically as well, the node would only wake up with the timer, and only then register the interrupt events.

          tekkaT Offline
          tekkaT Offline
          tekka
          Admin
          wrote on last edited by
          #33

          @DavidZH Now I see, indeed, missed the PCI part - my bad :) Maybe @Yveaux can chip in here?

          1 Reply Last reply
          0
          • D Offline
            D Offline
            DavidZH
            wrote on last edited by
            #34

            No worries man! We're all learning as we're moving along with this project. And there's so much info in most of the posts that some parts will be missed. Inevitably.

            YveauxY 1 Reply Last reply
            0
            • D DavidZH

              No worries man! We're all learning as we're moving along with this project. And there's so much info in most of the posts that some parts will be missed. Inevitably.

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

              @DavidZH before I dive into this could you please strip your sketch to the bare minimum that demonstrates the problem (mySensors 2.0.0 vs 2.1.1), preferably without using any hardware connections? Thanks!

              http://yveaux.blogspot.nl

              1 Reply Last reply
              0
              • D Offline
                D Offline
                DavidZH
                wrote on last edited by
                #36

                Hi @Yveaux,

                I have stripped it to one button on a RC-net and one led to see what I am doing, without changing the basic flow of the sketch. Also the node has been stripped bare. I have used a DIP version with the same bootloader (8MHz internal, 1V8 BOD by GertSanders, 3V3 power source) and the outcome is exactly the same:

                • directly waking with 2.1.1, sleeping with 2.0.0.
                • In both tests, all button presses are registered without problems.
                • button library has nothing to do with it. When I use a simple digitalRead(), all remains the same.
                • when I comment out the library call for the Interrupt (line 48), nothing changes.
                /***************************************************************************/
                //                    MySensors definitions
                
                #define MY_DEBUG    
                #define MY_CORE_ONLY      
                
                #define MY_BAUD_RATE 57600       // Lower as max because of 8 MHz Arduino
                
                #define EI_NOTEXTERNAL               // Options for the EnableInterrupt library
                #define EI_NOTPORTB                  // to save flash space
                #define EI_NOTPORTD
                #define EI_ARDUINO_INTERRUPTED_PIN
                
                /**************************************************************************/
                
                #include <Button.h>
                #include <EnableInterrupt.h>
                #include <MySensors.h>
                
                #define buttonPin 14            //A0
                #define ledPin 8
                
                #define PULLUP true        
                #define INVERT true        
                #define bounceTime 20            // A debounce time of 20 milliseconds usually works well for tactile button switches.
                #define sleepWait 1000           // Time to wait in ms before node sleeps (to be able to receive notification messages).
                
                volatile uint8_t interruptCount = 0;
                volatile bool buttonChanged;
                volatile bool buttonState;
                long lastButton;
                
                Button BtnA(buttonPin, PULLUP, INVERT, bounceTime); 
                
                /**************************************************************************/
                
                void presentation(void)
                {
                
                }
                
                /**************************************************************************/
                
                void setup(void)
                {
                  Serial.begin(57600);
                  Serial.println("\nStarting test");
                  enableInterrupt(buttonPin, interrupted, CHANGE);
                  pinMode(ledPin, OUTPUT);
                  //pinMode(buttonPin, INPUT_PULLUP);             //uncomment when testing without Button library
                  lastButton = millis();
                }
                
                /**************************************************************************/
                
                void loop(void)
                {
                  if (buttonChanged) {
                    if (buttonState) {
                      Serial.print("\nButton has changed "); Serial.print(interruptCount); Serial.println(" times.");
                      digitalWrite(ledPin, HIGH);
                    }
                    else {
                      Serial.println("\nButton is released.");
                      digitalWrite(ledPin,LOW);
                    }
                    lastButton = millis();
                    buttonChanged = false;
                  }
                
                  if (!buttonChanged) {
                    if (millis() > (lastButton + sleepWait)) {
                      sleepNode();
                    }
                  }
                }
                
                /**************************************************************************/
                
                void interrupted()
                {
                  interruptCount++;
                  buttonChanged = true;
                  //buttonState = !digitalRead(buttonPin);
                  buttonState = BtnA.read();                                      
                }
                
                /**************************************************************************/
                
                void sleepNode()
                {
                  Serial.println("\nSleep...");
                  wait(30);
                  sleep(0xff, 0x00, 0xff, 0x00, 0);
                  wait(30);
                }
                

                Two other things caught my attention:

                • In MY_CORE_ONLY there's no serial.begin(), makes one wait awfully long for debug output...
                • When the node is in PWR_DOWN, my (Chinesium) USB-serial converter is unable to wake the node to upload new code. I have to keep the node awake with the button, and if that fails, shoot the bootloader again. I know the DTS-pin is functional, as the node resets when I start a serial window.
                YveauxY 1 Reply Last reply
                0
                • D DavidZH

                  Hi @Yveaux,

                  I have stripped it to one button on a RC-net and one led to see what I am doing, without changing the basic flow of the sketch. Also the node has been stripped bare. I have used a DIP version with the same bootloader (8MHz internal, 1V8 BOD by GertSanders, 3V3 power source) and the outcome is exactly the same:

                  • directly waking with 2.1.1, sleeping with 2.0.0.
                  • In both tests, all button presses are registered without problems.
                  • button library has nothing to do with it. When I use a simple digitalRead(), all remains the same.
                  • when I comment out the library call for the Interrupt (line 48), nothing changes.
                  /***************************************************************************/
                  //                    MySensors definitions
                  
                  #define MY_DEBUG    
                  #define MY_CORE_ONLY      
                  
                  #define MY_BAUD_RATE 57600       // Lower as max because of 8 MHz Arduino
                  
                  #define EI_NOTEXTERNAL               // Options for the EnableInterrupt library
                  #define EI_NOTPORTB                  // to save flash space
                  #define EI_NOTPORTD
                  #define EI_ARDUINO_INTERRUPTED_PIN
                  
                  /**************************************************************************/
                  
                  #include <Button.h>
                  #include <EnableInterrupt.h>
                  #include <MySensors.h>
                  
                  #define buttonPin 14            //A0
                  #define ledPin 8
                  
                  #define PULLUP true        
                  #define INVERT true        
                  #define bounceTime 20            // A debounce time of 20 milliseconds usually works well for tactile button switches.
                  #define sleepWait 1000           // Time to wait in ms before node sleeps (to be able to receive notification messages).
                  
                  volatile uint8_t interruptCount = 0;
                  volatile bool buttonChanged;
                  volatile bool buttonState;
                  long lastButton;
                  
                  Button BtnA(buttonPin, PULLUP, INVERT, bounceTime); 
                  
                  /**************************************************************************/
                  
                  void presentation(void)
                  {
                  
                  }
                  
                  /**************************************************************************/
                  
                  void setup(void)
                  {
                    Serial.begin(57600);
                    Serial.println("\nStarting test");
                    enableInterrupt(buttonPin, interrupted, CHANGE);
                    pinMode(ledPin, OUTPUT);
                    //pinMode(buttonPin, INPUT_PULLUP);             //uncomment when testing without Button library
                    lastButton = millis();
                  }
                  
                  /**************************************************************************/
                  
                  void loop(void)
                  {
                    if (buttonChanged) {
                      if (buttonState) {
                        Serial.print("\nButton has changed "); Serial.print(interruptCount); Serial.println(" times.");
                        digitalWrite(ledPin, HIGH);
                      }
                      else {
                        Serial.println("\nButton is released.");
                        digitalWrite(ledPin,LOW);
                      }
                      lastButton = millis();
                      buttonChanged = false;
                    }
                  
                    if (!buttonChanged) {
                      if (millis() > (lastButton + sleepWait)) {
                        sleepNode();
                      }
                    }
                  }
                  
                  /**************************************************************************/
                  
                  void interrupted()
                  {
                    interruptCount++;
                    buttonChanged = true;
                    //buttonState = !digitalRead(buttonPin);
                    buttonState = BtnA.read();                                      
                  }
                  
                  /**************************************************************************/
                  
                  void sleepNode()
                  {
                    Serial.println("\nSleep...");
                    wait(30);
                    sleep(0xff, 0x00, 0xff, 0x00, 0);
                    wait(30);
                  }
                  

                  Two other things caught my attention:

                  • In MY_CORE_ONLY there's no serial.begin(), makes one wait awfully long for debug output...
                  • When the node is in PWR_DOWN, my (Chinesium) USB-serial converter is unable to wake the node to upload new code. I have to keep the node awake with the button, and if that fails, shoot the bootloader again. I know the DTS-pin is functional, as the node resets when I start a serial window.
                  YveauxY Offline
                  YveauxY Offline
                  Yveaux
                  Mod
                  wrote on last edited by
                  #37

                  @DavidZH The issue is caused because the way you use the sleep() function.
                  You 'abuse' the sleep() implementation that takes 2 interrupts (this prototype) to be able to sleep 'forever' (timeout 0).
                  However, by passing two invalid interrupt numbers, the MySensors stack translates this into a regular sleep() (this prototype) for which a timeout value of 0 means to return immediately.

                  In the core, calling either sleep(0xff, 0x00, 0xff, 0x00, 0) or sleep(0) will lead to the same call to the hwSleep() implementation, which will return immediately.

                  As a quick test, could you try replacing the code starting here:

                  if (interrupt1 != INTERRUPT_NOT_DEFINED && interrupt2 != INTERRUPT_NOT_DEFINED) {
                      // both IRQs
                      result = hwSleep(interrupt1, mode1, interrupt2, mode2, sleepingTimeMS);
                  } else if (interrupt1 != INTERRUPT_NOT_DEFINED && interrupt2 == INTERRUPT_NOT_DEFINED) {
                      // one IRQ
                      result = hwSleep(interrupt1, mode1, sleepingTimeMS);
                  } else if (interrupt1 == INTERRUPT_NOT_DEFINED && interrupt2 == INTERRUPT_NOT_DEFINED) {
                      // no IRQ
                      result = hwSleep(sleepingTimeMS);
                  }
                  

                  by

                  result = hwSleep(interrupt1, mode1, interrupt2, mode2, sleepingTimeMS);
                  

                  and see if that solves your issue?

                  http://yveaux.blogspot.nl

                  1 Reply Last reply
                  0
                  • D Offline
                    D Offline
                    DavidZH
                    wrote on last edited by DavidZH
                    #38

                    @Yveaux

                    It did! Thanks a bunch! I had a feeling it was to be found in that part of the code.

                    Strange thing is: it still returns -1 as wake up reason. And that brings me back to my original problem.

                    • When I want to add a timed sensor by setting a time as last argument, the node will not wake up when an interrupt takes place. It does register the interrupt, as the counter increases with every press. But it will only wake when the timer expires and only then display the updated counter.

                    I do see use cases for this: like an alarm-base station. With multiple inputs for the various detector loops. When the power fails (either by accident or intentionally) the base should go in low power mode to save the battery. And send a periodical heartbeat.
                    Or a scene controller in an inaccessible spot with a sensor attached.

                    edit: I've been browsing around MyHwAVR.cpp for a while, but my coding is not at that high of a level at this moment, that I can provide any useful input.

                    YveauxY 1 Reply Last reply
                    0
                    • D DavidZH

                      @Yveaux

                      It did! Thanks a bunch! I had a feeling it was to be found in that part of the code.

                      Strange thing is: it still returns -1 as wake up reason. And that brings me back to my original problem.

                      • When I want to add a timed sensor by setting a time as last argument, the node will not wake up when an interrupt takes place. It does register the interrupt, as the counter increases with every press. But it will only wake when the timer expires and only then display the updated counter.

                      I do see use cases for this: like an alarm-base station. With multiple inputs for the various detector loops. When the power fails (either by accident or intentionally) the base should go in low power mode to save the battery. And send a periodical heartbeat.
                      Or a scene controller in an inaccessible spot with a sensor attached.

                      edit: I've been browsing around MyHwAVR.cpp for a while, but my coding is not at that high of a level at this moment, that I can provide any useful input.

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

                      @DavidZH said in Pin change interrupt not firing with MySensors:

                      It did! Thanks a bunch! I had a feeling it was to be found in that part of the code.

                      Great!

                      Strange thing is: it still returns -1 as wake up reason. And that brings me back to my original problem.

                      Well, that function is setup to either return the interrupt number, or -1 if it didn't wake from interrupt.
                      You woke it differently, hence the return code of -1, see here.

                      • When I want to add a timed sensor by setting a time as last argument, the node will not wake up when an interrupt takes place. It does register the interrupt, as the counter increases with every press. But it will only wake when the timer expires and only then display the updated counter.

                      The actual sleep method differs whether a timeout is passed or not, see here.
                      I would have to consult the datasheet and dive into the different sleeping methods, but that probably is the reason of not waking up.

                      Again, you are using the library in an undocumented/untested way, so, unless you're able to read/modify the code yourself, I advise you to stick to the suggested use cases.

                      http://yveaux.blogspot.nl

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


                      19

                      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