jgromes / RadioLib

Universal wireless communication library for embedded devices
https://jgromes.github.io/RadioLib/
MIT License
1.49k stars 376 forks source link

[AFSK] Support for AFSK without tone #431

Closed jgromes closed 2 years ago

jgromes commented 2 years ago

As per the comment https://github.com/jgromes/RadioLib/issues/429#issuecomment-1001028486

What DL7AD did with pecanpico10 ( https://github.com/DL7AD/pecanpico10 ) is to also set the TX to FSK but the modulation source being the FIFO using a carefully calculated bitrate (a multiple of the audio freq (2..4x audio fmax I guess) disabling data whitening, preambles and such. He then wrote the actual PWM ("tone") waveform to the FIFO as e.g. (in bin) 00001111 11110000 etc., getting in essence the same 'AFSK' out the RF end as when you would modulate it using the GPIO and tone. So no need for SSB/FSK demod, but the RF-signal having a higher spectral 'content' b/c the AFSK is a square-wave. It just lets the TRX Chip take care of the 'dirty AFSK hack' and freeing CPU ressources.

This could be implemented as an option, to run AFSK on tone-less platforms (e.g. by providing RADIOLIB_NC as the pin number for AFSKClient constructor).

iangoegebuer commented 2 years ago

This is also somewhat needed for AX5043(#194) as it supports AFSK natively

jgromes commented 2 years ago

@iangoegebuer this is slightly different - AFSK for AX5043 might have to be modified if it doesn't support the unmodulated carrier + PWM hack that is used to achieve AFSK/RTTY/other stuff on modules like SX1278, however, this issue is about the case when the Arduino platform doesn't support tone().

tkrahn commented 2 years ago

Just a thought: The SX1262 datasheet mentions: 13.1.10 SetTxInfinitePreamble SetTxInfinitePreamble() is a test command to generate an infinite sequence of alternating zeros and ones in FSK modulation. In LoRa®, the radio is only able to constantly modulate LoRa® preamble symbols. Th e device will remain in TX infinite preamble until the host sends a mode configuration command. While this command has no real use case in real life, it can provide valuable help to the developer to check and monitor the performances of the radio while modulating in Tx mode.

This might be an easy way to generate the tones (without pin, by just switching two baud rates).

jgromes commented 2 years ago

@tkrahn this would be an option for SX126x modules (and possibly for SX128x, if you wanted AFSK at 2.4 GHz for some reason), unfortunately it's not generic enough to be used on other transceivers.

tkrahn commented 2 years ago

Thanks for looking into this. Other chips may fortunately have a GPIO pin to toggle the tones as you use it already. I just try to make a HTCC-AB02 board speak (AFSK) APRS as a second option next to LORA APRS. This would make cross-mode digipeaters possible. I can send "tones" with regular baud rate parameters, but I'm not a good enough programmer to get AFSK actually working.

jgromes commented 2 years ago

I did some digging into this, and it turns out that the approach outlined in the original post is not very good for RadioLib. The primary issue is the generic nature of the library - it's a core design goal for major features to be supported as widely as possible.

I was able to get AFSK tone emulation working by transmitting packets of just 1s and 0s (or 11s and 00s etc.), with all the packet features such as preambles etc. disabled. However, there are two major problems:

  1. Most modules are not able to perform FSK slower than 1200 bps (including SX127x). This means that to get tones lower than 1200 Hz, it would be needed to use e.g. 0xCC bytes instead of 0xAA, and double the FSK bit rate. However, this cuts the maximum possible tone length in half.
  2. Maximum achievable tone length ends up being a function of the tone tone frequency, and is different for different modules (based on the maximum FSK packet length), which is very inconvenient.

Currently, there are only a couple of platforms supported by RadioLib that do not implement tone(): ESP32, anything using the mbed core (e.g. Nano 33 BLE, Portenta, Raspberry Pi Pico) and CubeCell. However, for ESP32 and mbed, tone is emulated via PWM so the only platform for which solution does not exist at the moment is CubeCell.

To me, it seems much more simple to just have some sort of tone() emulation for CubeCell. @tkrahn for example, this is how ESP32 tone is emulated. Doing something like that for CubeCell is something I'm open to, however, I don't know the platform and don't have any to test with, so if you would be willing take a look at it, I would gladly accept a PR.

https://github.com/jgromes/RadioLib/blob/ba67ce2720d7809ff52bc3d58d61613a46481592/src/Module.cpp#L279-L283

I left all the changes in this branch if anyone is interested (it only build for SX1278, as some method implementations are missing for other modules): https://github.com/jgromes/RadioLib/tree/no-tone