Compare commits
2 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d62c9a6283 | ||
![]() |
b0d660cf42 |
4 changed files with 132 additions and 0 deletions
87
examples/AFSK/AFSK_No_Tone/AFSK_No_Tone.ino
Normal file
87
examples/AFSK/AFSK_No_Tone/AFSK_No_Tone.ino
Normal 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.
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue