[Hell] Added AFSK support
This commit is contained in:
parent
ed69931041
commit
21c0703383
4 changed files with 171 additions and 8 deletions
|
@ -13,6 +13,9 @@
|
|||
- nRF24
|
||||
- Si443x/RFM2x
|
||||
- SX128x
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
RadioLib Hellschreiber Transmit AFSK Example
|
||||
|
||||
This example sends Hellschreiber message using
|
||||
SX1278's FSK modem. The data is modulated
|
||||
as AFSK.
|
||||
|
||||
Other modules that can be used for Hellschreiber
|
||||
with AFSK modulation:
|
||||
- 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 Hellschreiber client instance using the AFSK instance
|
||||
HellClient hell(&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 Morse code
|
||||
// (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 Hellschreiber client
|
||||
Serial.print(F("[Hell] Initializing ... "));
|
||||
// AFSK tone frequency: 400 Hz
|
||||
// speed: 122.5 Baud ("Feld Hell")
|
||||
state = hell.begin(400);
|
||||
if(state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while(true);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[Hell] Sending Hellschreiber data ... "));
|
||||
|
||||
// HellClient supports all methods of the Serial class
|
||||
// NOTE: Lower case letter will be capitalized.
|
||||
|
||||
// Arduino String class
|
||||
String aStr = "Arduino String";
|
||||
hell.print(aStr);
|
||||
|
||||
// character array (C-String)
|
||||
hell.print("C-String");
|
||||
|
||||
// string saved in flash
|
||||
hell.print(F("Flash String"));
|
||||
|
||||
// character
|
||||
hell.print('c');
|
||||
|
||||
// byte
|
||||
// formatting DEC/HEX/OCT/BIN is supported for
|
||||
// any integer type (byte/int/long)
|
||||
hell.print(255, HEX);
|
||||
|
||||
// integer number
|
||||
int i = 1000;
|
||||
hell.print(i);
|
||||
|
||||
// floating point number
|
||||
// NOTE: println() has no effect on the transmission,
|
||||
// and is only kept for compatibility reasons.
|
||||
float f = -3.1415;
|
||||
hell.println(f, 3);
|
||||
|
||||
// custom glyph - must be a 7 byte array of rows 7 pixels long
|
||||
uint8_t customGlyph[] = { 0b0000000, 0b0010100, 0b0010100, 0b0000000, 0b0100010, 0b0011100, 0b0000000 };
|
||||
hell.printGlyph(customGlyph);
|
||||
|
||||
Serial.println(F("done!"));
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
|
@ -2,17 +2,27 @@
|
|||
|
||||
HellClient::HellClient(PhysicalLayer* phy) {
|
||||
_phy = phy;
|
||||
_audio = nullptr;
|
||||
}
|
||||
|
||||
HellClient::HellClient(AFSKClient* audio) {
|
||||
_phy = audio->_phy;
|
||||
_audio = audio;
|
||||
}
|
||||
|
||||
int16_t HellClient::begin(float base, float rate) {
|
||||
// calculate 24-bit frequency
|
||||
_baseHz = base;
|
||||
_base = (base * 1000000.0) / _phy->getFreqStep();
|
||||
|
||||
// calculate "pixel" duration
|
||||
_pixelDuration = 1000000.0/rate;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
@ -23,16 +33,16 @@ size_t HellClient::printGlyph(uint8_t* buff) {
|
|||
for(int8_t i = HELL_FONT_HEIGHT - 1; i >= 0; i--) {
|
||||
uint32_t start = micros();
|
||||
if(buff[i] & mask) {
|
||||
_phy->transmitDirect(_base);
|
||||
transmitDirect(_base, _baseHz);
|
||||
} else {
|
||||
_phy->standby();
|
||||
standby();
|
||||
}
|
||||
while(micros() - start < _pixelDuration);
|
||||
}
|
||||
}
|
||||
|
||||
// make sure transmitter is off
|
||||
_phy->standby();
|
||||
standby();
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
@ -269,3 +279,19 @@ size_t HellClient::printFloat(double number, uint8_t digits) {
|
|||
|
||||
return n;
|
||||
}
|
||||
|
||||
int16_t HellClient::transmitDirect(uint32_t freq, uint32_t freqHz) {
|
||||
if(_audio != nullptr) {
|
||||
return(_audio->tone(freqHz));
|
||||
} else {
|
||||
return(_phy->transmitDirect(freq));
|
||||
}
|
||||
}
|
||||
|
||||
int16_t HellClient::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 HELL_FONT_WIDTH 7
|
||||
#define HELL_FONT_HEIGHT 7
|
||||
|
@ -85,18 +86,25 @@ static const uint8_t HellFont[64][HELL_FONT_WIDTH - 2] PROGMEM = {
|
|||
class HellClient {
|
||||
public:
|
||||
/*!
|
||||
\brief Default constructor.
|
||||
\brief Constructor for 2-FSK mode.
|
||||
|
||||
\param phy Pointer to the wireless module providing PhysicalLayer communication.
|
||||
*/
|
||||
HellClient(PhysicalLayer* phy);
|
||||
|
||||
/*!
|
||||
\brief Constructor for AFSK mode.
|
||||
|
||||
\param audio Pointer to the AFSK instance providing audio.
|
||||
*/
|
||||
HellClient(AFSKClient* audio);
|
||||
|
||||
// basic methods
|
||||
|
||||
/*!
|
||||
\brief Initialization method.
|
||||
|
||||
\param base Base RF frequency to be used in MHz.
|
||||
\param base Base RF frequency to be used in MHz (in 2-FSK mode), or the tone frequency in Hz (in AFSK mode).
|
||||
|
||||
\param rate Baud rate to be used during transmission. Defaults to 122.5 ("Feld Hell")
|
||||
*/
|
||||
|
@ -140,12 +148,16 @@ class HellClient {
|
|||
private:
|
||||
#endif
|
||||
PhysicalLayer* _phy;
|
||||
AFSKClient* _audio;
|
||||
|
||||
uint32_t _base;
|
||||
uint32_t _base, _baseHz;
|
||||
uint32_t _pixelDuration;
|
||||
|
||||
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