Hi guys,
I've been using a bunch of Moteinos lately - great platform! With the first 10 in use as various sensors / controllers throughout the house I got annoyed by having to run around to reprogram them. I also found the programming time of >10s a major turn-off.
So I thought I'd give Felix wireless programming a try and ordered the next 5 Moteinos with flash. Thankfully I live in Germany and any order takes about 14 days to arrive here - so I started to experiment with alternatives.
In the end I put together a wireless bootloader that installs from an Raspberry Pi based install server directly to the atmega328p flash - no extra chip required. I also provide a feature in the bootloader that allows an app to install an updated bootloader - so you really never have to physically get to your nodes again.
Since I wanted it quick I did the following:
- Asynchronous protocol
Latency quickly brings down performance with handshake-heavy protocols. So I'm just streaming over as many packets as fit into the 328p RAM and then wait for one response saying what arrived. That brings you down to ~14 acks for a 20k payload - much better than handshaking each packet
- Higher bandwidth settings
I found a set of RFM69 settings that allow fairly reliable transmission at 200kbit throughout the house. Here are the important parameters:
/* 0x03 */ { REG_BITRATEMSB, RF_BITRATEMSB_200000},
/* 0x04 */ { REG_BITRATELSB, RF_BITRATELSB_200000},
/* 0x05 */ { REG_FDEVMSB, RF_FDEVMSB_300000},
/* 0x06 */ { REG_FDEVLSB, RF_FDEVLSB_300000},
/* 0x19 */ { REG_RXBW, RF_RXBW_DCCFREQ_000 | RF_RXBW_MANT_20 | RF_RXBW_EXP_0 },
- Transmit / Receive without Standby Pauses
If you send multiple packets in a row it is much faster to keep the radio in transmit mode and send one packet after the other than to switch off the transmitter between packets. I rewrote the RFM69 library to support these streaming cases. I also eliminated the interrupt handler since it kept causing me problems. I now poll instead.
When you don't go into Standby on the receiver side you also don't need to set RF_PACKET2_AUTORXRESTART which saves additional time each packet.
- RF_PACKET1_DCFREE_WHITENING
This parameter needs to be switched on to enable whitening of the data packets by the radio. Otherwise empty pages (0xff) will cause lots of dropped packets - it seems the radio needs some change in the data stream to work effectively.
- No busy wait in sendFrame
I've eliminated all the busy waits. No canSend, no busy wait for transmission ready.
----
With these changes (and I'm sure some I'm forgetting) I can transfer 20k of code in about 1.5 seconds. Together with the page erasing and flashing in the bootloader I flash 20k of code wirelessly in 2.5 seconds.
As for size this is now around 3.5k for the bootloader. I'm pretty sure I could get it under 2k with effort but I don't need that yet. I also plan to add serial boot capabilities to the bootloader using the same protocol so I can boot the wired gateway Moteinos from the install server, so will probably end as 4k bootloader anyway.
The bootloader transmits a node ID, CRC of itself and of the application on each boot and the bootserver sends updated versions as needed. Apps are sent directly to the bootloader for flashing. If the bootloader needs updating an app that flashes the new bootloader gets sent. Once that's done the app gets installed again.
For robustness the bootloader / bootserver are completely seperate from RFM69. But I'm using standard RFM69 for apps. Therefore protocol changes can be implemented at the app level without impacting the boot system (in fact I reenabled encryption at the app level again yesterday without a glitch for booting). The boot server uses the same Moteino as the gateway and shares the radio. The bootserver receive gets 15 ms every 500 ms - or a 3% duty cycle of the radio, without impact for sensor data transmissions.
All in all this works reasonably well. I hope this will be helpful to others implementing streaming applications or interested in wireless bootloaders. Let me know what you think.
I'm sure the speed could be tuned quite a bit more - eg by using 255 byte data packets rather than the 64 bytes required by encryption. However I'm now happy with what I have and will focus in the immediate future on putting the next 12 Moteinos which have finally arrived to use
Joe