wait() with interrupt



  • I have been reading up on this literally all day, yet still can not seem to find the solution.

    I have read million examples of interrupting sleep, but very few where wait() gets interrupted. And the few I did read, got close, but I still did not really explicitly find what I was looking for.

    So, I have an always powered node, with relays, so I don't want it to sleep. I got the 4 relays and a Dallas temp sensor working nice and stable for few days. Today I try to add motion sensor, which of course needs to trigger right away.

    It is this line at the bottom of the motion sensor code that has me perplexed:

      // Sleep until interrupt comes in on motion sensor. Send update every two minute.
      sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
    

    If I could only change that sleep to a wait I think it would be perfect. Maybe I can by now? I saw some old discussions about implementing that maybe, but that was from like 2015...

    Any pointers would be appreciated. I suppose I could just compile and flash and see what happens, but I prefer to know what I am doing rather than just throw darts at the problem guessing.


  • Hardware Contributor

    Hello,
    you could :

    • use attachinterrupt function for your interrupt, and a boolean for your state
    • and in loop(), instead of wait(), make your code async with a state machine

    https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
    https://learn.adafruit.com/multi-tasking-the-arduino-part-1/using-millis-for-timing

    I don't know exactly why you want to use wait(), but I hope this will help



  • Yeah, that is slowly the conclusion I am coming to.

    I tried to give it a whirl with wait instead of sleep, of course that didn't compile. So I just did it with sleep for now. And it is working, at least.

    I am going to take a step back and strategically re-think my options of exactly how I want to implement this, now that I am getting more of a feel for what the options actually are.

    Thanks for the quick answer.


  • Mod

    @TRS-80 why would you use interrupt handling of the trigger, while the mysensors code that actually signals that the sensor fired, runs in the main loop outside the interrupt?
    Sounds to me that you are making things more complex than they should.
    If you just poll your pir sensor from the main loop and don't sleep/wait there, you will be able to quickly react to pir triggers.



  • @Yveaux said in wait() with interrupt:

    why would you use interrupt handling of the trigger, while the mysensors code that actually signals that the sensor fired, runs in the main loop outside the interrupt?

    Thank you for bringing this up, as yes I had actually noticed this too while studying the code. To best answer your question, I suppose there are a number of issues at hand:

    Issues

    1. I was up for two days straight and probably should have just gone to sleep instead of trying to push on. 🙂 I have had a good night's rest now and a nice cup of coffee and am thinking much clearer.

    2. Later I plan on adding additional "inputs" to this node (2 door sensors in addition to the motion, if possible) and as this will exceed the number of hardware interrupt pins available, I started looking at other options and perhaps got ahead of myself.

    3. Even though I did realize the motion sensor code is not interrupt based (running in main loop as you correctly point out), I was trying to reconcile the timing interval of reading/sending the Dallas temperature data with the motion sensor code which can simply run over and over in a tight loop.

    4. All of these "input" (door, motion, etc.) examples default to pin 3, and the motion sensor example code actually states "(Only 2 and 3 generates interrupt!)" which I think added to my confusion.

    [ edit out a bunch of idiotic ramblings where I put 2+2 together ]

    Solutions

    1. Get some sleep. 🙂

    2. Don't get ahead of yourself.

    3. I suppose the answer to that is to do something like note the time when temp reading is taken in some variable, and then not enter Dallas temp sensor reading / sending subroutine again until some condition like millis() > previousTempMillis + TEMP_INTERVAL.

    4. Perhaps consider better wording in code comment?

    Now with a clear head, and putting this all together, I think I have come to the following conclusions thus far:

    Conclusions

    • Hardware interrupts are not even strictly necessary, unless you use sleep() function. Instead, just put your polling into a tight main loop.

    • If you need to do something on an interval (like read temp, etc.) just do it by checking millis() against some interval as I outlined in Solution #3, above.

    Thinking about it now, I suppose it makes sense that there is so much emphasis on sleeping, as often these are battery powered nodes. However I think this led to some confusion in my case where I am not running a battery powered node.

    Finally, I think in all my interrupt reading somewhere (perhaps in Nick Gannon's interrupt notes which are often referenced) that I read tight software loops are actually more reliable anyway. Is this why MySensors was written in this way (with the exception of sleep() which will then require built in hardware functions?

    If I have misunderstood anything, by all means, please chime in.


  • Mod

    @TRS-80 said in wait() with interrupt:

    tight software loops are actually more reliable anyway.

    Not per se, but at least they can be much simpler to comprehend and cause less tricky errors. All in general, of course.....
    Interrupts do have their use cases, but if you're a less experienced software developer they are better ignored.
    Mysensors uses interrupts in sleep, as it is usually the only way to wake a sleeping microcontroller using an external trigger.

    Also, I personally prefer to keep nodes simple and try to not combine too many functions in a single node. Maybe you should also consider creating more nodes.



  • Thanks for the feedback.

    @Yveaux said in wait() with interrupt:

    I personally prefer to keep nodes simple and try to not combine too many functions in a single node. Maybe you should also consider creating more nodes.

    This had also occurred to me. I always tend to bite off more than I can chew at first when learning something new (in this case, Arduino programming). It is painful at first, but I end up learning a lot, and becoming useful in the end. In this case, I feel like I am just beginning to get over the "painful" phase. 😄

    So, is your recommendation based more on me being a beginner, or on the fact that there is only so much the platform can handle? Because those are two very different things. And I am not offended in the least to recognize my own current level of competence in the area (even though I feel I am rapidly "leveling up" so to speak).

    Also, have I got all of the above conclusions (in my longer earlier post) mostly right? I think I am starting to get my head around it, but confirmation of my understanding would be greatly appreciated as I am certainly still learning.


  • Mod

    @TRS-80 I keep my nodes simple, not because any limitations in the hardware or software, but because the number of things that can go wrong increases exponentially when more features are added. Humans are generally not very good at handling exponentially complex stuff.



  • @Yveaux & @mfalkvidd,

    I can't help but make it complicated, I'm descended from Germans! 😄 😄 😄


  • Mod

    @TRS-80 Germans may very well be exempt from that rule😉. Vorsprung durch Technik!



  • @TRS-80 said in wait() with interrupt:

    @Yveaux & @mfalkvidd,

    I can't help but make it complicated, I'm descended from Germans! 😄 😄 😄

    Aber das Traue ich dir.


Log in to reply
 

Suggested Topics

  • 3
  • 2
  • 2
  • 7
  • 20
  • 5
  • 22

271
Online

9.8k
Users

10.3k
Topics

106.8k
Posts