Using Sensebender gateway MYSX_D3_INT Interrupts



  • I do have difficulties using MYSX_D3|D4_INT Interrupts.
    I'm using the sensebender Gateway as a Gateway with local sensors that does require interrupt ...

    Neither MySensor int8_t sleep (const uint8_t interrupt, const uint8_t mode, const uint32_t sleepingMS = 0, const bool smartSleep = false ) which is not supposed to catch interrupts in Gateway mode or native Arduino AttachInterrupt does catch interrupts on these Pins.

    Is there any trick or turn around about that issue ?



  • @didou I have also noticed that in the MyHwSAMD.cpp there are some functions like hwSleep(....) that are in "ToDo" state. Is that related ?


  • Admin

    @didou

    I sort of decided that a GW never has to sleep, as it is usually connected to a good powersource (usb, wallplug etc), so we do not need to conserve power by going into sleep..


  • Hardware Contributor

    Hello,

    • if you're planning to use it as a gateway, then don't use sleep function else it will miss messages..it won't wake up on receive like you said.

    • as you noticed sleep is not implemented for SAMD mcus, like sensebendergw

    • mapping of SAMD does not work like well known avr8 328p for example. Did you use digitalPinToInterrupt ?
      https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
      like attachInterrupt(digitalPinToInterrupt(3), myisr, CHANGE ) for your "D3.



  • @tbowmo I have seen that no issue but it still should be able to catch interrupt when in wait state ?


  • Mod

    @didou could you clarify what you mean by "wait state"?



  • @scalz Yes I did try even with something different as CHANGE like FALLING

    But seems I was tracking the debug message ☹ which it is never displayed in that case !
    But the Serial message is sent (0;255;3;0;5;1)

    It is working only one time after a GW reset, further test do not fire up the interruption

    loop()
    {
    attachInterrupt(digitalPinToInterrupt(MYSX_D4_INT), myInterrupt , FALLING);
    wait(60*1000); // Wait one minute between each probe (60 * 1000)
    }

    void myInterrupt()
    {
    detachInterrupt(digitalPinToInterrupt(MYSX_D4_INT));
    #ifdef MY_DEBUG
    Serial.println("Motion Interrupt");
    #endif
    send(MotionMsg.set("1"));
    attachInterrupt(digitalPinToInterrupt(MYSX_D4_INT), myInterrupt , FALLING);
    }



  • @didou I have also noticed thta I have to wait for a (0;255;3;0;5;0) reset message to be able to capture a new interrupt. I do not send it I guess it is sent by the core ?



  • @didou It is reset after 2 minutes then I can send a new interrupt. Where does come from the 120 sec hold time ?


  • Hardware Contributor

    seems arduino learning related 😉

    you mentioned sleep in your first post, and I think wait might delay your irq processing too

    • is it your full loop() function ? if so, why do you place attachinterrupt inside of it? looks weird, it would be better in setup for instance
    • "ok" for debug but serial.print in isr is bad.. ideally, it's better to trigger a boolean (volatile) and process its value in loop() . Same for sending msg from isr, not good..
    • are you saying that you get one interrupt at least? which would mean the attachinterrupt(digitalpintointerrupt...) mapping is working, and your sketch logic is wrong (like above mentioned points)

    just in case, in theory (no time for testing), D3=PA05(gpio name under the hood)=IRQNUM is 5 so you could replace the digitalTointerrupt function by the irq mapping name; 5 for D3, or 7 for D4.

    so just as an example, revamping your example, the logic should look something like this

    volatile bool myIsrTriggerVar = false
    
    setup() {
    	attachInterrupt(digitalPinToInterrupt(MYSX_D4_INT), myInterrupt , FALLING); // means attachInterrupt(7, myInterrupt , FALLING);	
    }
    
    loop() {	
    	if (myIsrTriggerVar) {
    		// process your irq here
    		#ifdef MY_DEBUG
    		Serial.println("Motion Interrupt");
    		#endif
    		send(MotionMsg.set("1"));
    		
    		// reset flag
    		myIsrTriggerVar = false
    	}
    	
    	// wait(60*1000); // Wait one minute between each probe (60 * 1000)
    }
    
    void myInterrupt()
    {
    	detachInterrupt(digitalPinToInterrupt(MYSX_D4_INT));
    	myIsrTriggerVar = true
    	attachInterrupt(digitalPinToInterrupt(MYSX_D4_INT), myInterrupt , FALLING);
    }
    


  • @scalz Great help yes I get one at least but need to wait 120 sec to get an other one ?

    Agree for the attachInterrupt in setup

    My loop does also have few sensors read every minutes so I need to both wait for one minute and also been able to catch interrupts


  • Hardware Contributor

    @didou
    then check your sensors in an async way, far better than using wait.
    there are different way of writing this, but here an example, maybe easier to read when new to programming : https://www.arduino.cc/en/tutorial/BlinkWithoutDelay
    In this example, instead of toggling leds, process your sensors.
    Also, maybe start simple, like a sketch processing your sensors as you wish, then once it's working well, add MySensors lib



  • @scalz will try that as proposed ovoiding wait and let you know. Thanks again.



  • @didou Tryed it today with no luck.

    The behavior is globally simillar

    loop()
    {
    unsigned long currentMillis = millis();

    // Check Sensors global timer
    if (currentMillis - previousMillis >= intervalMillis)
    {
    previousMillis = currentMillis;
    readSensors();
    }

    // Check Triggers
    if (myIsrTriggerVar1)
    {
    #ifdef MY_DEBUG
    Serial.println("Motion Interrupt");
    #endif
    send(MotionMsg.set("1"));
    // reset flag
    myIsrTriggerVar1 = false;
    }
    }

    I got the interrupt then mysensor message -> 13:13:07.719 -> 0;255;3;0;5;1 (Motion/V_trigger -> 1)
    Then I have to wait for 120 seconds before being able to do an other interrup
    Not before I have this message 13:15:07.621 -> 0;255;3;0;5;0 (Motion/V_trigger -> 0) which is not in my own code

    How often i do read the sensors do ot have any impact within the 120 seconds or outside of them.
    I have roufly checked the mysensor code and haven't seen any such define behavior for Motion/V_trigger)


 

207
Online

8.7k
Users

9.5k
Topics

99.5k
Posts