This is a screenshot from the serial monitor of a Jeenode (Arduino compatible) connected to my computer. It runs a program that will listen to incoming radio messages through its RFM12B radio transceiver. In this window, you can clearly see too lines that start with “OK”. These are real messages coming from my EM-1 Energy Monitor. The sending Jeenode is busy calculating energy consumption but manages to output a message every 2.5 seconds, on average. Timing is not critical, so I just let the Jeenode crunch numbers at full speed from measurements coming in from 5 current monitors and output a message when it can.
Whats interesting in that window is the rest of the stuff: GARBAGE! The listening Jeenode is very busy printing incoming messages that it can’t understand. JCW, of Jeelabs, wrote a fantastic library that parses incoming messages to identify those that come from other Jeenodes. It uses preamble bytes and CRC to maximize recognition and reduce error rates. But believe me, the ATMega processor (same as the Arduino) is VERY busy parsing these messages to identify valid ones.
If I turn the Q flag on in the RF12_DEMO.ino program showed in this window, only valid packets are displayed. The Q flag instruct the program not to print the messages, but they still have to be parsed for “real” messages.
This would be ok if there wasn’t so much invalid messages flying around. What happens (and what prompted me to study these results), is that I could see that the receiving Jeenode, tied to a PC that does all the energy calculation and data acquisition, was missing messages from the sending unit. I know that the sending unit does indeed send every ~2.5 seconds. I can monitor the blinking LED on it. It never misses a beat. But the receiver will often miss incoming packets. Sometimes for minutes… Sometimes for an hour… But most of the time, it receives most messages. So I decided to run a few tests.
TESTING … 123
First, I walked around the house with a Jeenode attached to a laptop, using the same monitor window. The interference was pretty consistent around the top and main floor. The basement fared a little better. The number of erroneous messages was definitely lower. Maybe half as much. I thought that there could be a rogue emitter in the house: I use 2 wireless weather station, and my alarm system’s 2 door switches, 1 movement detector and 1 smoke detector all use the same 915 Mhz frequency band.
So, I went outside, with the laptop and Jeenode. Interference was just as bad. I even walked away from the house. No change.
We don’t have neighbours! The closest house is more that half a kilometre away. We live isolated in a field, in the country. So if the garbage doesn’t come from my house, it has to come from somewhere else.
But, there is a transmission tower a kilometre away. A big one, with lots of antennas, many of them transmitting cellular signal, and who knows what else.
So I guess that some of the interference must come from the tower. I will have to take the laptop and go away and try again.
The only thing that I can do to improve the apparent reception of valid messages is to use a SEND->ACKnowledge communication protocol. JCW has included the necessary software in the RF12 Library for the Jeenodes.
Basically, the sending unit sets a bit in the message header to requests that the receiving unit sends an ACK message back, confirming reception of the messages. If the sending unit doesn’t get the ACK, it will send the same message again. Transmission should eventually complete.
The ACK strategy is only a patch. If the garbage ratio is too high, it could be minutes before the transmission is considered complete. What happens to the other packets then? How do you process messages coming out of order? What happens to battery operated sending units, that will keep retrying and drain the battery quickly with the emitter at full power?
Radio communication is about compromises: For the energy monitor, the compromise is to ignore lost messages. For other projects, like the MP-1, every packet is important, and some are crucial and cannot be ignored. The next post explores the series of compromises needed to make that work.