Ah, the nRF24L01+. The radio of broken dreams. Cheap. Enticing. Limited. 32-byte MTU and only able to listen for 6 addresses. Now what?
This radio has a native protocol that is good for a single powered listener and up to several battery-powered transmitters, but if you want to do anything more complicated (say, a peer-to-peer network instead of a star topology) you're on your own.
How can we do something more interesting within the limitations of this radio?
The solution I am pursuing is called rebroadcast mesh networking, inspired by some code designed to work over BLE on the newer nRF51 processor https://github.com/NordicSemiconductor/nRF51-ble-bcast-mesh/ . Their code includes an implementation of the trickle algorithm. Listen. Broadcast your message. If you hear your message being broadcast from another mote, quiet down.
In this way all the radios in an area synchronize their state using a density-aware number of broadcasts with no routing tables or addressing.
The original code uses integer keys. It has an instance of the trickle algorithm for each key, controlling how often each is rebroadcast. My innovation is to use string keys for ease of use and better MQTT interoperability, and to suggest, but not require, JSON values. This mesh will also include code to forget older values when a mote's memory is full, to prevent the mesh from becoming too clogged to receive new data.
For example, the message '/rgb,[255,128,192]' is only 18 bytes. A mote's application code could get this message, parse it with a streaming JSON parser, and blink. A door sensor would only have to say 0, or 1 for closed, open. Plenty of room for all the snail mail notifiers we can afford.
And what about the memory capacity of the entire network? It's true that the network will be very inefficient if it is currently retransmitting more individual keys than the individual motes can hold. Imagine I'm using only 1k of memory and I'm using 64 bytes to store my 32-byte packets, including the overhead. That's 1024/64 = 16 keys.
There's some anxiety there; do we need a lot more complexity to build a more scalable network? No. Relax. These controllers run at 48 megahertz. We should be playing Doom on them, but instead we have plenty of cycles to parse and deal with strings. And this mesh network is for my house. I don't think I can afford to buy and build enough nodes to saturate this network even after my coffee maker, dishwasher, mailbox, and alarm clock are online. And the required bandwidth (1 packet per day, for the mailbox) is also extremely low.
These radios use about the same 10mA when transmitting or when just listening. That is too much to allow battery powered routers. For that we need to implement low-power listening. Low powered listening works by putting the radios into receive mode for only an instant at a time, and by making sure a (broadcast) transmission can be heard at that time. For example, to listen, we could wake our radios for 2 milliseconds eight times a second. To be heard we have to repeat the same packet every 1 millisecond during the entire 1/8th of a second. Transmit uses a lot more power than receive, but it's OK, because our sleepy little mesh network will wait up to a minute or two to retransmit values that have not recently changed.
The finished software will be able to be used in a single microcontroller for the motes, without an OS, or as a separate serial to RF module outputting and accepting mesh events on the serial port. The gateway will connect one of the motes in serial mode to a Raspberry Pi to connect the mesh to the internet.