[RTTY] Added AFSK support
This commit is contained in:
parent
0a705f5bb9
commit
f7f81cd41e
3 changed files with 182 additions and 11 deletions
133
examples/RTTY/RTTY_Transmit_AFSK/RTTY_Transmit_AFSK.ino
Normal file
133
examples/RTTY/RTTY_Transmit_AFSK/RTTY_Transmit_AFSK.ino
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
RadioLib RTTY Transmit AFSK Example
|
||||
|
||||
This example sends RTTY message using SX1278's
|
||||
FSK modem. The data is modulated as AFSK.
|
||||
|
||||
Other modules that can be used for RTTY:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- Si443x/RFM2x
|
||||
|
||||
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 fsk = new Module(10, 2, 9, 3);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//SX1278 fsk = RadioShield.ModuleA;
|
||||
|
||||
// create AFSK client instance using the FSK module
|
||||
// pin 5 is connected to SX1278 DIO2
|
||||
AFSKClient audio(&fsk, 5);
|
||||
|
||||
// create RTTY client instance using the AFSK instance
|
||||
RTTYClient rtty(&audio);
|
||||
|
||||
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 RTTY
|
||||
// (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);
|
||||
}
|
||||
|
||||
// initialize RTTY client
|
||||
// NOTE: Unlike FSK RTTY, AFSK requires no rounding of
|
||||
// the frequency shift.
|
||||
Serial.print(F("[RTTY] Initializing ... "));
|
||||
// space frequency: 400 Hz
|
||||
// frequency shift: 170 Hz
|
||||
// baud rate: 45 baud
|
||||
// encoding: ASCII (7-bit)
|
||||
// stop bits: 1
|
||||
state = rtty.begin(400, 170, 45);
|
||||
if(state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while(true);
|
||||
}
|
||||
|
||||
/*
|
||||
// RadioLib also provides ITA2 ("Baudot") support
|
||||
rtty.begin(400, 170, 45, ITA2);
|
||||
|
||||
// All transmissions in loop() (strings and numbers)
|
||||
// will now be encoded using ITA2 code
|
||||
|
||||
// ASCII characters that do not have ITA2 equivalent
|
||||
// will be sent as NUL (including lower case letters!)
|
||||
*/
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[RTTY] Sending RTTY data ... "));
|
||||
|
||||
// send out idle condition for 500 ms
|
||||
rtty.idle();
|
||||
delay(500);
|
||||
|
||||
// RTTYClient supports all methods of the Serial class
|
||||
|
||||
// Arduino String class
|
||||
String aStr = "Arduino String";
|
||||
rtty.println(aStr);
|
||||
|
||||
// character array (C-String)
|
||||
rtty.println("C-String");
|
||||
|
||||
// string saved in flash
|
||||
rtty.println(F("Flash String"));
|
||||
|
||||
// character
|
||||
rtty.println('c');
|
||||
|
||||
// byte
|
||||
// formatting DEC/HEX/OCT/BIN is supported for
|
||||
// any integer type (byte/int/long)
|
||||
rtty.println(255, HEX);
|
||||
|
||||
// integer number
|
||||
int i = 1000;
|
||||
rtty.println(i);
|
||||
|
||||
// floating point number
|
||||
float f = -3.1415;
|
||||
rtty.println(f, 3);
|
||||
|
||||
Serial.println(F("done!"));
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
|
@ -106,12 +106,20 @@ uint16_t ITA2String::getBits(char c) {
|
|||
|
||||
RTTYClient::RTTYClient(PhysicalLayer* phy) {
|
||||
_phy = phy;
|
||||
_audio = nullptr;
|
||||
}
|
||||
|
||||
RTTYClient::RTTYClient(AFSKClient* audio) {
|
||||
_phy = audio->_phy;
|
||||
_audio = audio;
|
||||
}
|
||||
|
||||
int16_t RTTYClient::begin(float base, uint32_t shift, uint16_t rate, uint8_t encoding, uint8_t stopBits) {
|
||||
// save configuration
|
||||
_encoding = encoding;
|
||||
_stopBits = stopBits;
|
||||
_baseHz = base;
|
||||
_shiftHz = shift;
|
||||
|
||||
switch(encoding) {
|
||||
case ASCII:
|
||||
|
@ -148,15 +156,17 @@ int16_t RTTYClient::begin(float base, uint32_t shift, uint16_t rate, uint8_t enc
|
|||
// calculate 24-bit frequency
|
||||
_base = (base * 1000000.0) / _phy->getFreqStep();
|
||||
|
||||
// set module frequency deviation to 0
|
||||
int16_t state = _phy->setFrequencyDeviation(0);
|
||||
// set module frequency deviation to 0 if using FSK
|
||||
int16_t state = ERR_NONE;
|
||||
if(_audio == nullptr) {
|
||||
state = _phy->setFrequencyDeviation(0);
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
void RTTYClient::idle() {
|
||||
_phy->transmitDirect();
|
||||
|
||||
transmitDirect();
|
||||
mark();
|
||||
}
|
||||
|
||||
|
@ -190,7 +200,7 @@ size_t RTTYClient::write(uint8_t b) {
|
|||
mark();
|
||||
}
|
||||
|
||||
_phy->standby();
|
||||
standby();
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
@ -391,7 +401,7 @@ size_t RTTYClient::println(double d, int digits) {
|
|||
|
||||
void RTTYClient::mark() {
|
||||
uint32_t start = micros();
|
||||
_phy->transmitDirect(_base + _shift);
|
||||
transmitDirect(_base + _shift, _baseHz + _shiftHz);
|
||||
while(micros() - start < _bitDuration) {
|
||||
yield();
|
||||
}
|
||||
|
@ -399,7 +409,7 @@ void RTTYClient::mark() {
|
|||
|
||||
void RTTYClient::space() {
|
||||
uint32_t start = micros();
|
||||
_phy->transmitDirect(_base);
|
||||
transmitDirect(_base, _baseHz);
|
||||
while(micros() - start < _bitDuration) {
|
||||
yield();
|
||||
}
|
||||
|
@ -505,3 +515,19 @@ size_t RTTYClient::printFloat(double number, uint8_t digits) {
|
|||
|
||||
return n;
|
||||
}
|
||||
|
||||
int16_t RTTYClient::transmitDirect(uint32_t freq, uint32_t freqHz) {
|
||||
if(_audio != nullptr) {
|
||||
return(_audio->tone(freqHz));
|
||||
} else {
|
||||
return(_phy->transmitDirect(freq));
|
||||
}
|
||||
}
|
||||
|
||||
int16_t RTTYClient::standby() {
|
||||
if(_audio != nullptr) {
|
||||
return(_audio->noTone());
|
||||
} else {
|
||||
return(_phy->standby());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "../../TypeDef.h"
|
||||
#include "../PhysicalLayer/PhysicalLayer.h"
|
||||
#include "../AFSK/AFSK.h"
|
||||
|
||||
#define ITA2_FIGS 0x1B
|
||||
#define ITA2_LTRS 0x1F
|
||||
|
@ -84,18 +85,25 @@ class ITA2String {
|
|||
class RTTYClient {
|
||||
public:
|
||||
/*!
|
||||
\brief Default constructor.
|
||||
\brief Constructor for 2-FSK mode.
|
||||
|
||||
\param phy Pointer to the wireless module providing PhysicalLayer communication.
|
||||
*/
|
||||
RTTYClient(PhysicalLayer* phy);
|
||||
|
||||
/*!
|
||||
\brief Constructor for AFSK mode.
|
||||
|
||||
\param audio Pointer to the AFSK instance providing audio.
|
||||
*/
|
||||
RTTYClient(AFSKClient* audio);
|
||||
|
||||
// basic methods
|
||||
|
||||
/*!
|
||||
\brief Initialization method.
|
||||
|
||||
\param base Base (space) RF frequency to be used in MHz.
|
||||
\param base Base (space) frequency to be used in MHz (in 2-FSK mode), or the space tone frequency in Hz (in AFSK mode)
|
||||
|
||||
\param shift Frequency shift between mark and space in Hz.
|
||||
|
||||
|
@ -147,10 +155,11 @@ class RTTYClient {
|
|||
private:
|
||||
#endif
|
||||
PhysicalLayer* _phy;
|
||||
AFSKClient* _audio;
|
||||
|
||||
uint8_t _encoding;
|
||||
uint32_t _base;
|
||||
uint32_t _shift;
|
||||
uint32_t _base, _baseHz;
|
||||
uint32_t _shift, _shiftHz;
|
||||
uint32_t _bitDuration;
|
||||
uint8_t _dataBits;
|
||||
uint8_t _stopBits;
|
||||
|
@ -160,6 +169,9 @@ class RTTYClient {
|
|||
|
||||
size_t printNumber(unsigned long, uint8_t);
|
||||
size_t printFloat(double, uint8_t);
|
||||
|
||||
int16_t transmitDirect(uint32_t freq = 0, uint32_t freqHz = 0);
|
||||
int16_t standby();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue