Compare commits

...
Sign in to create a new pull request.

2 commits

Author SHA1 Message Date
jgromes
d62c9a6283 [AFSK] Fixed incorrect mathod name 2022-06-19 16:06:24 +02:00
jgromes
b0d660cf42 [AFSK] Added experimental support for platforms without tone 2022-06-19 15:56:34 +02:00
4 changed files with 132 additions and 0 deletions

View file

@ -0,0 +1,87 @@
/*
RadioLib AFSK Example
This example shows hot to send audio FSK tones
using SX1278's FSK modem, on platforms that do
not support the tone() function.
Other modules that can be used for AFSK:
- SX127x/RFM9x
- RF69
- SX1231
- CC1101
- Si443x/RFM2x
For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/
*/
// include the library
#include <RadioLib.h>
// SX1278 has the following connections:
// NSS pin: 10
// DIO0 pin: 2
// RESET pin: 9
// DIO1 pin: 3
SX1278 radio = new Module(5, 2, 9, 3);
// create AFSK client instance using the FSK module
// enable tone emulation by setting the pin to
// "not connected"
AFSKClient audio(&radio, RADIOLIB_NC);
void setup() {
Serial.begin(9600);
// initialize SX1278 with default settings
Serial.print(F("[SX1278] Initializing ... "));
int state = radio.beginFSK();
// when using one of the non-LoRa modules for AFSK
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
// int state = radio.begin();
if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
while(true);
}
// initialize AFSK client
Serial.print(F("[AFSK] Initializing ... "));
state = audio.begin();
if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
while(true);
}
}
void loop() {
// AFSKClient can be used to transmit tones,
// same as Arduino tone() function
// 400 Hz tone
Serial.print(F("[AFSK] 400 Hz tone ... "));
const size_t len = 64;
uint8_t bits[len] = { 0 };
for(size_t i = 0; i < len; i++) {
bits[i] = 0xF0;
}
audio.emulateTone(400, bits, len);
Serial.println(F("done!"));
delay(1000);
// AFSKClient can also be used to transmit HAM-friendly
// RTTY, Morse code, Hellschreiber, SSTV and AX.25.
// Details on how to use AFSK are in the example
// folders for each of the above modes.
}

View file

@ -6,6 +6,19 @@ AFSKClient::AFSKClient(PhysicalLayer* phy, RADIOLIB_PIN_TYPE pin): _pin(pin) {
}
int16_t AFSKClient::begin() {
if(_pin == RADIOLIB_NC) {
// set encoding to NRZ
int16_t state = _phy->setEncoding(RADIOLIB_ENCODING_NRZ);
RADIOLIB_ASSERT(state);
// disable preamble
state = _phy->setPreambleLength(0);
RADIOLIB_ASSERT(state);
// disable CRC
state = _phy->setCrcFiltering(false);
return(state);
}
return(_phy->startDirect());
}
@ -34,4 +47,29 @@ int16_t AFSKClient::noTone(bool keepOn) {
return(_phy->standby());
}
int16_t AFSKClient::emulateTone(float baseFreq, uint8_t* bits, size_t len) {
// set fixed packet length mode
int16_t state = _phy->fixedPacketLengthMode(len);
RADIOLIB_ASSERT(state);
float br = baseFreq;
if((br < 1200)) {
if(br < 1200/8) {
// this is too low to achieve by a single octet
// FIXME - if tones lower than 150 Hz are needed, multiple octets must be used
return(RADIOLIB_ERR_INVALID_FREQUENCY);
}
// this tone frequency is lower than what most modules can do
// but we can easily emulate tones in this range
br *= 8.0;
}
// set the base frequency
state = _phy->setBitRate(br / 1000.0);
RADIOLIB_ASSERT(state);
// transmit
return(_phy->transmit(bits, len));
}
#endif

View file

@ -52,6 +52,8 @@ class AFSKClient {
*/
int16_t noTone(bool keepOn = false);
int16_t emulateTone(float baseFreq, uint8_t* bits, size_t len);
#if !defined(RADIOLIB_GODMODE)
private:
#endif

View file

@ -302,6 +302,11 @@ class PhysicalLayer {
virtual Module* getMod() = 0;
virtual int16_t setPreambleLength(uint16_t preambleLength) = 0;
virtual int16_t setCrcFiltering(bool crcOn) = 0;
virtual int16_t fixedPacketLengthMode(uint8_t preambleLength) = 0;
virtual int16_t setBitRate(float br) = 0;
protected:
void updateDirectBuffer(uint8_t bit);