I've got an application in which I'd like to stream a live feed from a 9DOF IMU from a Moteino node to a Moteino gateway. Each IMU sample is represented as a 39-byte struct. I've got the IMU wired up over I2C and can confirm that I can blast data back from it as fast as I please over serial.
Over the radio, however, I'm having some issues. I'm using the stock RFM69 library from LowPowerLabs, with encryption off. sendWithRetry() was taking way too long to send, so I replaced it with a regular send(). That seems to send quickly enough, with my main sample+send loop taking about 10-12ms. Main loop is pretty dead simple: read IMU, pack structure, send, throttle to 60Hz.
On the receive side, though, I'm getting dropped packets, despite an RSSI between -26dbm and -50dbm. They appear to drop at random. Even if I throttle my main loop back to 10Hz, I'll still get dropped packets. I know they are dropping because they are timestamped at send, and part of the packet is how long since the last packet was sent, so if I see a 30ms gap in timestamps when the packet says the previous one was sent 15ms ago, I know I dropped a packet. I've not seen it drop two packets in a row, interestingly enough.
39bytes * 60Hz is only 2340bytes/s or 18720bps, and I'm running at Felix's stock 55.5kbps, so there should be plenty of headroom, as far as data bandwidth goes. The two Moteinos are in the same room, and RSSI is never less than -50dbm.
Any ideas? Should I lower my bitrate and narrow the bandwidth to see if that helps? Am I asking too much of the Moteino radio or library? Is there a better approach?
Thanks in advance!
Hmm, 60hz might be too much for the stock settings.
SendWithRetry() is for redundancy and will resend up to 3 times by default and wait up to 30ms each time for an ACK so that's why that was not working fast enough.
I think you could try to increase the bitrate and narrow bandwidth as you said. There are some posts in the forum where people describe some of that and the settings they used.
Let us know how it goes. I think 60hz should be achievable, even though 39bytes is a pretty sizeable packet. Getting that through faster means higher bitrate. 55.5kbps was set to be the middle of the road, all around out of box working setting with decent range for 90% of cases.
Fooling with it some more, I increased the bitrate to 115200 and TX deviation to 300000. On the RX end, I opened the bandwidth all the way up to 500kHz. I drop about the same frequency of packets as before. Sending goes more quickly, though :P.
Should I have narrowed the bandwidth, instead? My RF knowledge is rather poor. At 115200, where would I want my RXBW to be, ballpark? Would a 200m range with half-wave monopole still be feasible (hopefully going to test that today or tomorrow)?
Great board, BTW; I'm really enjoying working with it.
Cool. According to the DS : (BitRate < 2 x RxBw)
You might want to check the formulas in the DS: http://www.hoperf.cn/upload/rf/RFM69-V1.3.pdf
I had looked at the spec sheet, but only found the formula to which you alluded, which yields: RxBw > (BitRate/2)
However, that doesn't seem to tell the whole story. Following that guideline, at a bitrate of 115.2kbps, a RxBw of 62.5kHz should be sufficient. However, if I set my RxBw to 62.5kHz (RF_RXBW_MANT_16 | RF_RXBW_EXP_3), I get absolutely no reception. Did I overlook something?
I did achieve better RSSI swapping out my ballparked half-wave monopole antenna to a quarter wave length wire soldered to ANT and another quarter wave length of wire soldered to the GND pad near the ANT pad... I guess that's close to a half wave dipole? Still didn't help with the packet dropping, though... doesn't seem terribly dependent on RSSI.
Also, interestingly, I seem to be experiencing some sort of packet corruption, which I find odd since these are supposed to be run through a CRC, right? It is always the last bytes of the payload, and every corrupted byte is set to 0x40.
E.g:
3,I,691701,58,-74,-38,4164,-14894,-300,4164,5114,-3196,691571,80403,65,4030,1934,-8651,4505,1,8,0,38,215,17,280614,2,9,5,-27,2
3,I,691712,52,-105,9,4127,-14967,-263,4127,5114,-3196,691571,80403,65,4030,1934,-8651,153,16448,16448,16448,16448,16448,16448,1077952576,64,64,1077952576,-84,2
3,I,691721,88,-106,-36,4212,-14895,-309,4212,5114,-3196,691571,80403,65,4030,1934,-8651,4505,1,8,0,38,215,17,280614,2,9,7,-21,2
The first and last lines are good packets. The middle line gets corrupted. The "3,I," are header bytes tacked on by the receiver before being sent over serial to the host PC, so the radio packet data starts at "691712," which is the millis() reading right before the radio.send() call. 38 bytes in, the value of "16448 (0x4040)" starts showing up, marking the beginning of the corruption, followed by 1077952576 (0x40404040), followed by two 64s (0x40). The "-84,2" are the RSSI and the length of my receive queue, respectively, which also get tacked on by the receiver before being sent to the host PC.
You'll note the RSSI takes a dip to -84, the previous and subsequent RSSIs being -27 and -21, respectively... that's typical of the corruption showing up. The RSSI will either be reported as 0 or -80 or below for just the bad packet.
Any idea what might be causing that? Serial output on the transmitting mote says the data going to radio.send() is not corrupted, so it must be happening somewhere downstream.
Are you using a LowPowerLab Moteino?
You can actually pass CRC which is a single byte, even with a corrupted message. I've seen that happen without encrpytion, though rarely, but I always use encryption as well. Typically if a packet ever passes through CRC and get decrypted it's complete garbage. You mentioned you are using no encryption. You should try it with encryption and see the difference.
Also try inverting the motes, or using another Moteino and see if that has the same behavior.
There are many ways of isolating the issue.
Here's a packet that passes CRC and encryption but is garbage.
I was expecting a message from node 55. But this came through:
[175] �Yu:��Z�XJ���#/ ���i/`���#/ ���i/`���#/ ���i/ [RSSI:-45]
The RSSI is vastly different. Also there is nothing meaningless in there. If you use structs and just read bytes you will get bad data, you should add some signature chars in there if it's critical.
Again, this is very very rare. I can't remember when I saw something like this last time, but it did happen this morning.
I am using two LowPowerLab Moteinos, yes.
The corruption problem seems to have gone away for the moment. I lowered the deviation back down to 50kHz and set my RXBW to 62.5kHz. I also changed the payload length to RF_PAYLOADLENGTH_VALUE (64) from 66, since I only use the FIFO size on transmit.
Still dropping packets, though, even with great signal strength (RSSI > -30).
I still have a half-wave monopole on the transmitter; might try switching to a dipole there, as well, although I'm not sure it's a signal integrity issue so much as the receiver isn't coming back online quickly enough to catch the next packet sometimes. Does that sound plausible?
I might also be ordering some 433MHz modules, soon, as the area I need to cover has some dense vegetation that is wreaking havoc with the link when the transmitter goes behind it.
Someone suggested using 1 or 3 quarter monopoles, not half. But yeah I do agree with you. The settings can vastly influence the integrity.
So, I changed DIO4 to show me RxReady and DIO3 to output RSSI and probed them with an oscilloscope. Receiver is set for 115200kbps/67.5kHz RXBW, transmitter set to 50kHz deviation, broadcasting a 61-byte packet blindly at 15ms intervals.
I noticed two things about RSSI and RxReady on the receiver:
1) Sometimes, they both stay high for ~30ms instead of ~14ms.
2) Sometimes, there is a seemingly spurious burst about 0.5ms after a falling edge, then ~1ms before the next rising edge
If RSSI and RxReady are staying high for ~30ms, does that indicate that it missed a preamble (RX timeouts are disabled as per default)?
PayloadReady definitely had gaps when I scoped DIO0.
On the TX side, I noticed that:
1) PacketSent sometimes had a period of ~25ms instead of 15ms.
2) FifoNotEmpty sometimes had a period of ~25ms, usually following a period of ~7ms, and would have a pulsewidth of ~13ms instead of 5ms
3) ModeReady is usually 5ms, but I saw spikes around 17ms.
Any idea why the TX FIFO wouldn't be emptied at a consistent rate, given that I always call send() with the same payload length, or why ModeReady would stay active for so long? The radio is the only thing on the SPI bus. Seems like this could be causing my RX weirdness...
I'd love the RF experts in the forum to share their thoughts on this. I've seen this behavior as well when I developed the library and also in other instances when I scoped or looked at the SPI traffic with a logic analyzer. Same kinds of inconsistencies at high speed transfers. I have no idea if it's the settings that cause these glitches (though the default settings are the best all-around general purpose I could find) or it's something with the radios themselves.
I've long wondered if the chips they use are genuine or not. I am still trying to find out. If someone has a way to decap one of these and analyze the die I would send a few for free.
Also, the way the radios are implemented in hardware can be an issue. Everything is crammed together on a tiny 0.032" PCB.
The third possibility is interference, which is very plausible. You can only tell that's an issue if you pull a spectrum analyzer, or someone else has shown how it's possible to do it via SDR.