diff --git a/examples/AFSK/AFSK_Tone/AFSK_Tone.ino b/examples/AFSK/AFSK_Tone/AFSK_Tone.ino new file mode 100644 index 00000000..09e66c28 --- /dev/null +++ b/examples/AFSK/AFSK_Tone/AFSK_Tone.ino @@ -0,0 +1,80 @@ +/* + RadioLib AFSK Example + + This example shows hot to send audio FSK tones + using SX1278's FSK modem. + + Other modules that can be used for AFSK: + - SX127x/RFM9x + - RF69 + - SX1231 + - CC1101 + - Si443x/RFM2x + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ +*/ + +// include the library +#include + +// SX1278 has the following connections: +// NSS pin: 10 +// DIO0 pin: 2 +// RESET pin: 9 +// DIO1 pin: 3 +SX1278 fsk = new Module(10, 2, 9, 3); + +// create AFSK client instance using the FSK module +// this requires connection to the module direct +// input pin, here connected to Arduino pin 5 +// SX127x/RFM9x: DIO2 +// RF69: DIO2 +// SX1231: DIO2 +// CC1101: GDO2 +// Si443x/RFM2x: GPIO +AFSKClient audio(&fsk, 5); + +void setup() { + Serial.begin(9600); + + // initialize SX1278 + Serial.print(F("[SX1278] Initializing ... ")); + // carrier frequency: 434.0 MHz + // bit rate: 48.0 kbps + // frequency deviation: 50.0 kHz + // Rx bandwidth: 125.0 kHz + // output power: 13 dBm + // current limit: 100 mA + int state = fsk.beginFSK(); + + // when using one of the non-LoRa modules for AFSK + // (RF69, CC1101,, Si4432 etc.), use the basic begin() method + // int state = fsk.begin(); + + if(state == 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 + audio.tone(400); + delay(1000); + + // silence + audio.noTone(); + 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. +} diff --git a/keywords.txt b/keywords.txt index 21e58818..53b945b0 100644 --- a/keywords.txt +++ b/keywords.txt @@ -53,6 +53,7 @@ AX25Client KEYWORD1 AX25Frame KEYWORD1 SSTVClient KEYWORD1 HellClient KEYWORD1 +AFSKClient KEYWORD1 # SSTV modes Scottie1 KEYWORD1 @@ -225,6 +226,10 @@ getRangingResult KEYWORD2 # Hellschreiber printGlyph KEYWORD2 +# AFSK +tone KEYWORD2 +noTone KEYWORD2 + ####################################### # Constants (LITERAL1) ####################################### diff --git a/src/RadioLib.h b/src/RadioLib.h index b9446834..c6afae7a 100644 --- a/src/RadioLib.h +++ b/src/RadioLib.h @@ -91,6 +91,7 @@ // physical layer protocols #include "protocols/PhysicalLayer/PhysicalLayer.h" +#include "protocols/AFSK/AFSK.h" #include "protocols/AX25/AX25.h" #include "protocols/Hellschreiber/Hellschreiber.h" #include "protocols/Morse/Morse.h" diff --git a/src/protocols/AFSK/AFSK.cpp b/src/protocols/AFSK/AFSK.cpp new file mode 100644 index 00000000..a8453925 --- /dev/null +++ b/src/protocols/AFSK/AFSK.cpp @@ -0,0 +1,21 @@ +#include "AFSK.h" + +AFSKClient::AFSKClient(PhysicalLayer* phy, RADIOLIB_PIN_TYPE pin) { + _phy = phy; + _pin = pin; +} + +int16_t AFSKClient::tone(uint16_t freq, bool autoStart) { + if(autoStart) { + int16_t state = _phy->transmitDirect(); + RADIOLIB_ASSERT(state); + } + + Module::tone(_pin, freq); + return(ERR_NONE); +} + +int16_t AFSKClient::noTone() { + Module::noTone(_pin); + return(_phy->standby()); +} diff --git a/src/protocols/AFSK/AFSK.h b/src/protocols/AFSK/AFSK.h new file mode 100644 index 00000000..c5c71221 --- /dev/null +++ b/src/protocols/AFSK/AFSK.h @@ -0,0 +1,57 @@ +#ifndef _RADIOLIB_AFSK_H +#define _RADIOLIB_AFSK_H + +#include "../../TypeDef.h" +#include "../../Module.h" + +#include "../PhysicalLayer/PhysicalLayer.h" + +/*! + \class AFSKClient + + \brief Client for audio-based transmissions. Requires Arduino tone() function, and a module capable of direct mode transmission using DIO pins. +*/ +class AFSKClient { + public: + /*! + \brief Default contructor. + + \param phy Pointer to the wireless module providing PhysicalLayer communication. + + \param pin The pin that will be used for audio output. + */ + AFSKClient(PhysicalLayer* phy, RADIOLIB_PIN_TYPE pin); + + /*! + \brief Start transmitting audio tone. + + \param freq Frequency of the tone in Hz. + + \param autoStart Whether to automatically enter transmission mode. Defaults to true. + + \returns \ref status_codes + */ + int16_t tone(uint16_t freq, bool autoStart = true); + + /*! + \brief Stops transmitting audio tone. + + \returns \ref status_codes + */ + int16_t noTone(); + +#ifndef RADIOLIB_GODMODE + private: +#endif + PhysicalLayer* _phy; + RADIOLIB_PIN_TYPE _pin; + + // allow specific classes access the private PhysicalLayer pointer + friend class RTTYClient; + friend class MorseClient; + friend class HellClient; + friend class SSTVClient; + friend class AX25Client; +}; + +#endif