Computing stuff tied to the physical world

Room Node redesign

In Software on Oct 15, 2010 at 00:00

Room nodes were one of the first reasons I came up with the JeeNode in the first place. It has all evolved a bit since then (and it will evolve further until there is a good enclosure):

Dsc 2134

It’s now time to start redesigning the software for Room Nodes. The main reason being that the code needs to take more advantage of all the low-power savings achievable with JeeNodes. Current battery lifetimes are 1..2 months, using 3x AA alkaline batteries. That’s not nearly good enough – I really do not want to go through the house replacing tons of batteries every month or so (even rechargable ones).

I can think of two reasons why the current rooms.pde sketch isn’t doing that well:

  1. The “easy transmission” mechanism does retries when no ACK is received – this is a good idea in general, but there is no exponential backoff mechanism in place in case the central node is off, mal-functioning, out of range, or if there is simply too much interference at times. What’s even worse is that the node sits there waiting for an ACK for many seconds, guzzling electricity like crazy with the RFM12B and the ATmega full on!

  2. The code sends out a fresh packet on each transition from the PIR motion detector. If the sensor is in a room where motion is very common, then new packets may get sent out far more often than necessary – and quickly drain the battery.

So the question is how to improve on this. One thing I’m going to do is side-step the rf12_easyPoll() etc. interface for the next Room Node implementation, and go back to rf12_recvDone() etc. Coding at this slightly lower level is more work, but also gives me substantially more control in return.

Next, some decisions need to be made about how often and when to send out packets, and when to work with acknowledgements. Here are some of my considerations for that – evidently not everyone will agree with this set of choices, but I think they are sufficiently general to work in many cases:

  • Temperature, humidity, and light levels need only be sent out once per five minutes. Perhaps averaging the values once a minute to smooth out measurement variations.

  • No need to use ACKs for this. Not knowing the exact temperature for the past hour is not the end of the world. The new logic can just send out readings once every five minutes, with the expectation that most of them will usually come in just fine.

  • The PIR motion sensor is a completely different matter: I’d like to be told when new motion is detected as quickly as possible, i.e. within less than a second.

  • Then again, once motion has been detected, I don’t really care too much about frequent vs. infrequent motion. Telling me once a minute whether any motion was detected in that past minute should be enough.

  • Once motion ceases to be detected for a minute, the system goes back into its highly responsive mode, i.e. the moment new motion is detected, I want to hear about it again, right away.

  • The system could send different packets for different triggers, but I don’t want to complicate things unnecessarily. My expectation is that in a room with no motion, there will be one packet going out every 5 minutes, with one “wasted” bit for the motion detector state. In a busy room, there will be a packet going out up to once a minute due to the motion detector firing all the time. The number of bytes saved is probably not worth the extra trouble of having to deal with different types of packets at the receiving end.

  • The last reason to send out packets, is when the battery voltage of the sensor node is getting low. This can be checked once a minute, along with the temp/humid/light cycle.

  • Changes in motion or battery level are important events. These should use the acknowledge mechanism to make sure the event gets to its destination even with occasional packet loss.

  • The mechanism for acks needs to be more sophisticated than it is now. The first big optimization is to only wait a few milliseconds for the ACK. If it doesn’t come in, go back to sleep, and try again a second later. That should by itself reduce the current worst-case current draw by two orders of magnitude.

  • Refinements such as exponential back-off would be nice, but I don’t expect them to make that much of a difference, in a home monitoring setup where all serious failures are likely to be noticed and resolved within a day.

  • Another refinement I don’t care too much about, is to adjust the 5-minute reporting interval depending on the measured light levels. Note that this does not apply to motion (which must always remain alert) – it’s just a way to reduce packet transmissions even further at times when very little happens anyway. I’m not sure it will increase battery life that much, though: brief packet transmissions are not the main power drain, the always-on PIR is the main determinant for battery life, as far as I can tell.

The highest packet frequency for this new approach is almost two packets per minute: motion is detected, then one minute later a packet comes in reporting that it is no longer being detected, and then immediately after that new motion is detected again.

So if you sit still in front of a Room Node, and move exactly once every 61 seconds, you’ll get extra brownie points and trigger twice as many packets as when you move around all the time. I’m willing to dismiss that scenario as being almost hypothetical :) – I can’t prove it, but my hunch is that this worst-case scenario will always exist, no matter what the algorithm is.

  1. Hello!

    It is very god that you found time to rework the code for rooms.pde. I (and many others a guess) have implemented part of what you list above and etch time something change in the original rooms.pde we have to carefully merge our code wide yours. This rewrite will make our solutions obsolete and the rooms.pde more competent.

    Suggestion 1: Could you write a couple of #define:s at the beginning of the code for configuring all time intervals, activate/deactivate averaging activate/deactivate debugging etc?

    Suggestion 2: Could you try to make the code ready (= easy to adapt) for more/less sensors (eg. pressure sensor).

    • Good points, thx. I’ve gone into something related in my Modular nodes post about a month ago.

      It’d be great to have some sort of modularity at the ports level, so that you can pick a couple of devices to attach, choose ports and per-device settings, and then end up with a sketch which does exactly as requested. There will be some issues when the device readout periods differ, and it may require sending different types of packets.

      I’ll think a bit more about this. Above all, I want things to remain simple.

Comments are closed.