-
Notifications
You must be signed in to change notification settings - Fork 398
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Receiving APRS #569
Comments
At the moment, RadioLib does not support receiving APRS and most other HAM modes like RTTY. This is because even transmitting it is achieved by a massive hack (basically by using the transceiver to only send a carrier and directly modulating that). I recently added Morse code reception, and the same mechanism used for that might be usable to receive AFSK signal (and so APRS). Basically by putting the module to a special mode in which it outputs demodulated data on one of its pins, and so AFSK tones become a square wave signal. However, it's a big question whether the processing of the AFSK signal can be made reliable enough. And even bigger question is - is it worth it? I can easily imagine a use case for APRS transmissions using RadioLib - in microcontroller-based trackers. However, less so for receiving - why build microcontroller-based repeaters or IGates? |
@sebastian-king I did some experiments, and it looks like could be possible using the direct mode reception. In this mode, the radio outputs the demodulated data as digital signals on two of its pins (one is data, the other is clock). With that, the AFSK audio signal becomes digital waveform. The high and low tones are clearly visible as 1200/2200 Hz. This signal can then be sampled by using the clock signal as a source for interrupt to read the data line. The result is an array of bits representing the AFSK signal, like this:
However, there's going to be significant signal processing required - for example, due to slight timing errors, it's not as simple as e.g. taking every 4 bits to resolve the tones. TL;DR - It's possible, but not straightforward and will likely require manual tuning. |
Is there any plan to support this or add its implementation? |
@DeflateAwning yes, there is - as per my previous comment, it is turning out to be a bit more tricky, so if anyone can provide an algorithm for demodulating AFSK in the form of binary strings, let me know ;) |
Would love to try to help! Need this for another project! Is there docs on what the format/encoding of those binary strings are? How did you find out that "01010 is a 2200 Hz tone, while 00110011 is a 1200 Hz tone"? In applying that pattern to the bit array you had there, it appears that there are lots of bits that don't fit that encoding scheme; any idea how they are supposed to fit in or where they come from? |
There's no format, it's just the result of sampling a digital pin that's coming from the radio. It's being sampled at 4400 Hz (twice the highest tone as needed by Nyqist theorem), so an alternating sequence of 01010... corrseponds to frequency of 2200 Hz. When there is enough time for the same level to be sapled twice (001100...), it means that the tone is about 1100 Hz.
That's exactly the problem, because 2200 divided by 1200 is not exactly two, there will be timing discrepancies if you try to just "count the bits". I tried implementing a simple correlating demodulator with local oscillators at 1200 and 2200 Hz just over the binary sequence, but it seems that's impossible (since the binary sequence would have a "DC offset" of 0.5, which doesn't make sense for a digital value). After the signal is demodulated, you would then have to extract the clock and only then start decoding. |
I think my initial plan might be to sample at an even higher frequency than the Nyqist frequency to better read out the 2200 Hz symbols. In the example in the original issue, do you know what the second arg to Which pin were you sampling on the SX1276? |
For most of my experiments, I was working at 26.4 kHz, since 26400 can be divided by both 1200 and 2200. Didn't work because of the aforementioned DC offset. I think the core issue is that to perform correlation with local oscillators, two-state samples are not enough, it would have to be at least -1/0/1.
Ignore the original, that was just the OPs attempt to guess the parameters. The third arguments is frequency deviation, which is only used for Tx. The bit rate determines the sampling frequency, os you should do something like
DIO2. You have to enable OOK and direct mode: // the "sync word" are some AX.25 preamble bits at the set sampling rate
radio.setDirectSyncWord(0x3F03F03F, 32);
radio.setDirectAction(readBit);
radio.receiveDirect();
(...)
void readBit(void) {
// read the DIO2 pin
radio.readBit(4);
}
void loop() {
// wait to get some data
if(radio.available() > 22) {
radio.standby();
while(radio.available()) {
uint8_t b = radio.read();
// demodulate here
}
radio.receiveDirect();
}
} |
Can you explain why you chose OOK mode? I'm having trouble seeing the connection between AFSK and OOK |
@DeflateAwning hmm, it's been a while so I'm not entirely sure, I think that without it there was some issue with generating the digital output, but I don't recall what exactly it was. |
Do you have the exact code snippet you used to generate the bitstream on Sep 18, 2022? |
@DeflateAwning I don't have the exact code, so I attached the last working version I found, which contains couple attempts at demodulation. Though I'm not sure if it will help you, the point is to take the received data and demodulate it. It doesn't matter much if the data is actually being received - the reception does work. The point is to take that binary string and turn it into 0x7E 0x01 0x01 0x01. |
There are microcontroller-based repeaters and IGates already, such as:
There is also a "microcontroller-based" APRS transceiver, such as All the projects above are using LibAPRS-ESP32 library that
|
@lyusupov interesting projects, thanks! However, to me it doesn't answer the fundamental question, if this is really needed in RadioLib. And if so, then how to do it. As far as I can tell, the LibAPRS-ESP32 library comes with significant caveats, mainly the dependency on the ESP32 platform and its I2S peripheral. In addition, all of the projects above use significantly different hardware than what RadioLib targets, so unfrontunately I don't think it's very useful even as an inspiration for implementing AX.25/APRS reception here. |
Not necessarily.
The LibAPRS-ESP32 for ESP32-S3 can
More details are available on this thread: erstec/APRS-ESP#29 |
That's interesting, but still not what would need to be done for APRS reception in RadioLib. The fundamental issue is that the signal has already been demodulated by the transceiver. So what RadioLib reads is a serial digital input of 1s and 0s at the mark and space frequencies (as shown a few posts above), which has turned out to be quite tricky to further process, at least for me. Though I will admit DSP is not my strong suit, so I'm inviting anyone willing to take a shot at this :) |
I am interested in receiving APRS data using RadioLib, however, I am struggling to figure out how to do so. The APRSClient only provides methods for sending packets, not receiving them.
I am using the following code to try to receive an APRS packet, however, even though my handheld radio is receiving APRS just fine, my SX1276 module does not show any received packets. I am able to transmit ax.25 packets without issue.
If it helps, I am using a TTGO T-Beam (V1.1).
The text was updated successfully, but these errors were encountered: