Open mikaelnousiainen opened 7 years ago
Hi @mikaelnousiainen, thanks for providing a detailed report along with captures. I'll try to find some time this weekend to look into your issue. In the meantime, can you confirm that you're using implicit header mode?
The resampler and rotator are there to channelize the signal. I typically capture with the signal offset from the center frequency to avoid the SDR's DC spike. The rotator "shifts" the band so that the signal is centered and the DC spike is offset, and then the resampler reduces the sample rate to match the bandwidth of the LoRa signal -- effectively discarding whatever is outside of said bandwidth. This leaves you with a neatly channelized signal, which is what the LoRa demodulator expects.
Try using Baudline or an FFT/Waterfall sink to visualize each stage of this transformation and you'll see it in action.
I was using explicit header in the IQ sample. I just noticed that it isn't supported yet by gr-lora. I'll do another IQ recording with implicit header mode next week (once I'm back at where I have the hardware) and see how it works. One question though: how does the demodulator/decoder know the packet length with implicit header mode? Isn't the packet length what is left out when not using the header?
Is there something in particular blocking the decoding of explicit headers?
Thanks explaining how the GR components are used. I assumed something like that, but wasn't sure.
Packet framing: The demodulator uses a squelch to find the end of the frame. Check it out here: https://github.com/BastilleResearch/gr-lora/blob/master/lib/demod_impl.cc#L392
Why it doesn't do explicit headers: Explicit header decoding is blocked by not having been able to fully derive the whitening sequence that applies to said header. This gets into some of the weedy details of LoRa. Here's an abridged explanation:
One of the operations within the LoRa modulation is whitening, where your outgoing frame is XORed against the a predetermined pseudorandom string. LoRa's demodulation performs the same operation, XORing the incoming frame against said predetermined pseudorandom string, which returns the outgoing frame because XOR is its own inverse.
I was able to derive the implicit whitening sequences because I have control of every bit within the frame, including bits that would otherwise be used by the explicit header. Thus, I can zero them out and exploit XOR to get an off the shelf LoRa module to tell me what it's whitening sequence is.
My initial assumption was that implicit and explicit header mode would share the same whitening sequence (because why wouldn't they?) but empirically I found this wasn't the case. Additionally, under explicit mode I do not have control of the header bits, meaning I cannot force their value to 0. Thus I cannot derive the whitening bits that apply to the header.
The good news is that I've made good progress on mapping out a few whitened values within the header format. Thus I'll be able to implement some of the explicit header fields and functionality. Perhaps if I can guess their unwhitened values I'll be able to take a whack at the PHY header's CRC as well (the header has its own CRC).
Explicit header mode is being tracked in issues https://github.com/BastilleResearch/gr-lora/issues/3 and https://github.com/BastilleResearch/gr-lora/issues/4.
tl;dr some explicit mode support is coming soon™
Ok, yes, that makes sense (for the explicit headers). Thanks for the detailed explanation!
I made another two test captures with the same data and settings as described above, but with implicit header enabled. This time I gr-lora (nor rpp0's gr-lora) couldn't really decode any of the data. Anyway, here are the recordings in case they are useful to you.
The first one was recorded with the SDR dongle antenna (for 434MHz) a bit further away, so I decided to bring it very close (30cm) to see if it makes a difference.
https://expirebox.com/download/d36c3e50fe65efaff49885d1fbf4a612.html
https://expirebox.com/download/c0ce4cf6561bccaa6236b51fa02d8ad6.html
Again, the links expire in 48h.
I'm trying to receive LoRa packets sent by my Raspberry Pi LoRa shield with RFM98W chip, but I've only succeeded to receive corrupt data (very randomly).
I'm using 2M sample rate on 434.250 MHz frequency with NESDR SMArt (RTL-SDR) USB dongle and I've verified using Gqrx that when tuning to 434.250, it's receiving at the center of the signal bandwidth.
I've tested another gr-lora implementation (by rpp0) and had similar problems: https://github.com/rpp0/gr-lora/issues/15 although I was able to receive parts of the data correctly.
I'm submitting the same example IQ file and the GNU Radio graphs for this project to help development. (Unfortunately, my skills in signal processing are almost nonexistent, so I'm not able to contribute to the code...)
I've made a cfile (converted to complex from rtl_sdr bin capture) of using settings: SF7, CR4:8, bandwidth 125kHz, 2M sample rate and preamble of 0x08, and tested that reception "works" from the file in GNU Radio. I verified that packets are missed and data in all packets is corrupt. All data in packets should be plain text (as listed below).
I've attached the GNU radio graph here: rtlsdr-lora-receive-mattknight.grc.zip
(BTW Why are the additional resampler and rotator elements needed? This could be added to the documentation.)
The captured signal cfile can be downloaded here (for the next 48 hours): https://expirebox.com/download/cb1750ca2f660e6290186ff0cedf79a7.html
For capturing the signal I used the following command:
And for conversion I used this GNU Radio graph: http://ham.stackexchange.com/a/2117
The transmission contains the following messages (without the quotes):
What I receive in Wireshark is just garbage in the data portion of the UDP packets.