commit
bd0158c734
5 changed files with 294 additions and 4 deletions
110
examples/SX127x/SX127x_Receive_FHSS/SX127x_Receive_FHSS.ino
Normal file
110
examples/SX127x/SX127x_Receive_FHSS/SX127x_Receive_FHSS.ino
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
RadioLib SX127x Transmit with Frequency Hopping Example
|
||||
|
||||
This example transmits packets using SX1278 LoRa radio module.
|
||||
Each packet contains up to 256 bytes of data, in the form of:
|
||||
- Arduino String
|
||||
- null-terminated char array (C-string)
|
||||
- arbitrary binary data (byte array)
|
||||
|
||||
Other modules from SX127x/RFM9x family can also be used.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
|
||||
The SX1276 / 7 / 8 / 9 supports FHSS or Frequency Hopping Spread Spectrum.
|
||||
Once a hopping period is set and a transmission is started the radio
|
||||
will begin triggering interrupts every hop period where the radio frequency
|
||||
is changed to the next channel.
|
||||
*/
|
||||
|
||||
#include <RadioLib.h> //Click here to get the library: http://librarymanager/All#RadioLib
|
||||
|
||||
// SX1276 has the following connections:
|
||||
const int pin_cs = 10;
|
||||
const int pin_dio0 = 2;
|
||||
const int pin_dio1 = 9;
|
||||
const int pin_rst = 3;
|
||||
SX1276 radio = new Module(pin_cs, pin_dio0, pin_rst, pin_dio1);
|
||||
|
||||
volatile bool rxComplete = false;
|
||||
volatile bool fhssChange = false;
|
||||
|
||||
// the channel frequencies can be generated randomly or hard coded
|
||||
float channels[] = {908.0, 906.0, 907.0, 905.0, 903.0, 910.0, 909.0};
|
||||
int numberOfChannels = sizeof(channels) / sizeof(float);
|
||||
|
||||
int hopsCompleted = 0;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// begin radio on home channel
|
||||
Serial.print(F("[SX127x] Initializing ... "));
|
||||
int state = radio.begin(channels[0]);
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("Failed with code: "));
|
||||
Serial.println(state);
|
||||
}
|
||||
else
|
||||
Serial.println(F("Success!"));
|
||||
|
||||
// set hop period to enable FHSS
|
||||
state = radio.setFHSSHoppingPeriod(9);
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("Error setting hopping period: "));
|
||||
Serial.println(state);
|
||||
}
|
||||
radio.setDio0Action(dio0ISR); // called when transmission is finished
|
||||
radio.setDio1Action(dio1ISR); // called after a transmission has started, so we can move to next freq
|
||||
|
||||
// start listening for LoRa packets
|
||||
Serial.print(F("[SX1278] Starting to listen ... "));
|
||||
state = radio.startReceive();
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (rxComplete == true) {
|
||||
uint8_t incomingBuffer[255];
|
||||
radio.readData(incomingBuffer, 255);
|
||||
uint8_t receivedBytes = radio.getPacketLength();
|
||||
Serial.write(incomingBuffer, receivedBytes);
|
||||
Serial.println();
|
||||
|
||||
Serial.print(F("Hops completed: "));
|
||||
Serial.println(hopsCompleted);
|
||||
hopsCompleted = 0;
|
||||
|
||||
radio.startReceive();
|
||||
|
||||
rxComplete = false;
|
||||
}
|
||||
|
||||
if (fhssChange == true) {
|
||||
radio.setFrequency(channels[radio.getFHSSChannel() % numberOfChannels]);
|
||||
|
||||
hopsCompleted++;
|
||||
radio.clearFHSSInt();
|
||||
fhssChange = false;
|
||||
}
|
||||
}
|
||||
|
||||
// ISR when DIO0 goes low
|
||||
// called when transmission is complete or when RX is received
|
||||
void dio0ISR(void) {
|
||||
rxComplete = true;
|
||||
}
|
||||
|
||||
// ISR when DIO1 goes low
|
||||
// called when FhssChangeChannel interrupt occurs (at the beginning of each transmission)
|
||||
void dio1ISR(void) {
|
||||
fhssChange = true;
|
||||
}
|
113
examples/SX127x/SX127x_Transmit_FHSS/SX127x_Transmit_FHSS.ino
Normal file
113
examples/SX127x/SX127x_Transmit_FHSS/SX127x_Transmit_FHSS.ino
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
RadioLib SX127x Transmit with Frequency Hopping Example
|
||||
|
||||
This example transmits packets using SX1278 LoRa radio module.
|
||||
Each packet contains up to 256 bytes of data, in the form of:
|
||||
- Arduino String
|
||||
- null-terminated char array (C-string)
|
||||
- arbitrary binary data (byte array)
|
||||
|
||||
Other modules from SX127x/RFM9x family can also be used.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
|
||||
The SX1276 / 7 / 8 / 9 supports FHSS or Frequency Hopping Spread Spectrum.
|
||||
Once a hopping period is set and a transmission is started the radio
|
||||
will begin triggering interrupts every hop period where the radio frequency
|
||||
is changed to the next channel.
|
||||
*/
|
||||
|
||||
#include <RadioLib.h> //Click here to get the library: http://librarymanager/All#RadioLib
|
||||
|
||||
// SX1276 has the following connections:
|
||||
const int pin_cs = 10;
|
||||
const int pin_dio0 = 2;
|
||||
const int pin_dio1 = 9;
|
||||
const int pin_rst = 3;
|
||||
SX1276 radio = new Module(pin_cs, pin_dio0, pin_rst, pin_dio1);
|
||||
|
||||
volatile bool xmitComplete = false;
|
||||
volatile bool fhssChange = false;
|
||||
|
||||
// the channel frequencies can be generated randomly or hard coded
|
||||
float channels[] = {908.0, 906.0, 907.0, 905.0, 903.0, 910.0, 909.0};
|
||||
int numberOfChannels = sizeof(channels) / sizeof(float);
|
||||
|
||||
int hopsCompleted = 0;
|
||||
int counter = 0;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// begin radio on home channel
|
||||
Serial.print(F("[SX127x] Initializing ... "));
|
||||
int state = radio.begin(channels[0]);
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("Failed with code: "));
|
||||
Serial.println(state);
|
||||
}
|
||||
else
|
||||
Serial.println(F("Success!"));
|
||||
|
||||
// set hop period to enable FHSS
|
||||
state = radio.setFHSSHoppingPeriod(9);
|
||||
if(state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("Error setting hopping period: "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
radio.setDio0Action(dio0ISR); // called when transmission is finished
|
||||
radio.setDio1Action(dio1ISR); // called after a transmission has started, so we can move to next freq
|
||||
|
||||
Serial.print(F("Transmitting packet..."));
|
||||
|
||||
String longOutput = "Let's create a really long packet to trigger lots of hop interrupts. A packet can be up to 256 bytes long. This packet is 222 bytes so using sf = 9, bw = 125, timeOnAir is 1488ms. 1488ms / (9*4.10ms) = 40 hops. Counter: ";
|
||||
|
||||
state = radio.startTransmit(longOutput + counter);
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("Error transmitting with code: "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (xmitComplete == true) {
|
||||
xmitComplete = false;
|
||||
Serial.println(F("Transmit complete"));
|
||||
Serial.print(F("Radio after xmit is on channel: "));
|
||||
Serial.println(radio.getFHSSChannel());
|
||||
// the FHSS channel is automatically reset to 0 upon end of transmission
|
||||
|
||||
radio.setFrequency(channels[radio.getFHSSChannel() % numberOfChannels]); // Return to home channel before next transaction
|
||||
|
||||
Serial.print(F("Hops completed: "));
|
||||
Serial.println(hopsCompleted);
|
||||
hopsCompleted = 0;
|
||||
|
||||
radio.startReceive();
|
||||
}
|
||||
|
||||
if (fhssChange == true) {
|
||||
radio.setFrequency(channels[radio.getFHSSChannel() % numberOfChannels]);
|
||||
|
||||
hopsCompleted++;
|
||||
fhssChange = false;
|
||||
radio.clearFHSSInt();
|
||||
}
|
||||
}
|
||||
|
||||
// ISR when DIO0 goes low
|
||||
// called when transmission is complete or when RX is received
|
||||
void dio0ISR(void) {
|
||||
xmitComplete = true;
|
||||
}
|
||||
|
||||
// ISR when DIO1 goes low
|
||||
// called when FhssChangeChannel interrupt occurs (at regular HoppingPeriods)
|
||||
void dio1ISR(void) {
|
||||
fhssChange = true;
|
||||
}
|
|
@ -142,6 +142,10 @@ setDirectAction KEYWORD2
|
|||
readBit KEYWORD2
|
||||
enableBitSync KEYWORD2
|
||||
disableBitSync KEYWORD2
|
||||
setFHSSHoppingPeriod KEYWORD2
|
||||
getFHSSHoppingPeriod KEYWORD2
|
||||
getFHSSChannel KEYWORD2
|
||||
clearFHSSInt KEYWORD2
|
||||
|
||||
# RF69-specific
|
||||
setAESKey KEYWORD2
|
||||
|
|
|
@ -375,7 +375,12 @@ int16_t SX127x::startReceive(uint8_t len, uint8_t mode) {
|
|||
int16_t modem = getActiveModem();
|
||||
if(modem == RADIOLIB_SX127X_LORA) {
|
||||
// set DIO pin mapping
|
||||
state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_RX_DONE | RADIOLIB_SX127X_DIO1_RX_TIMEOUT, 7, 4);
|
||||
if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) {
|
||||
state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_RX_DONE | RADIOLIB_SX127X_DIO1_FHSS_CHANGE_CHANNEL, 7, 4);
|
||||
}
|
||||
else {
|
||||
state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_RX_DONE | RADIOLIB_SX127X_DIO1_RX_TIMEOUT, 7, 4);
|
||||
}
|
||||
|
||||
// set expected packet length for SF6
|
||||
if(_sf == 6) {
|
||||
|
@ -448,7 +453,12 @@ int16_t SX127x::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
|
|||
}
|
||||
|
||||
// set DIO mapping
|
||||
_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_TX_DONE, 7, 6);
|
||||
if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) {
|
||||
_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_TX_DONE | RADIOLIB_SX127X_DIO1_FHSS_CHANGE_CHANNEL, 7, 4);
|
||||
}
|
||||
else {
|
||||
_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_TX_DONE, 7, 6);
|
||||
}
|
||||
|
||||
// apply fixes to errata
|
||||
RADIOLIB_ERRATA_SX127X(false);
|
||||
|
@ -987,8 +997,12 @@ int16_t SX127x::setOOK(bool enableOOK) {
|
|||
}
|
||||
|
||||
int16_t SX127x::setFrequencyRaw(float newFreq) {
|
||||
// set mode to standby
|
||||
int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
|
||||
int16_t state = RADIOLIB_ERR_NONE;
|
||||
|
||||
// set mode to standby if not FHSS
|
||||
if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) == RADIOLIB_SX127X_HOP_PERIOD_OFF) {
|
||||
state = setMode(RADIOLIB_SX127X_STANDBY);
|
||||
}
|
||||
|
||||
// calculate register values
|
||||
uint32_t FRF = (newFreq * (uint32_t(1) << RADIOLIB_SX127X_DIV_EXPONENT)) / RADIOLIB_SX127X_CRYSTAL_FREQ;
|
||||
|
@ -1353,4 +1367,25 @@ void SX127x::readBit(RADIOLIB_PIN_TYPE pin) {
|
|||
updateDirectBuffer((uint8_t)digitalRead(pin));
|
||||
}
|
||||
|
||||
int16_t SX127x::setFHSSHoppingPeriod(uint8_t freqHoppingPeriod) {
|
||||
return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD, freqHoppingPeriod));
|
||||
}
|
||||
|
||||
uint8_t SX127x::getFHSSHoppingPeriod(void) {
|
||||
return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD));
|
||||
}
|
||||
|
||||
uint8_t SX127x::getFHSSChannel(void) {
|
||||
return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_CHANNEL, 5, 0));
|
||||
}
|
||||
|
||||
void SX127x::clearFHSSInt(void) {
|
||||
int16_t modem = getActiveModem();
|
||||
if(modem == RADIOLIB_SX127X_LORA) {
|
||||
_mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS, getIRQFlags() | RADIOLIB_SX127X_CLEAR_IRQ_FLAG_FHSS_CHANGE_CHANNEL);
|
||||
} else if(modem == RADIOLIB_SX127X_FSK_OOK) {
|
||||
return; //These are not the interrupts you are looking for
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1073,6 +1073,34 @@ class SX127x: public PhysicalLayer {
|
|||
*/
|
||||
void readBit(RADIOLIB_PIN_TYPE pin);
|
||||
|
||||
/*!
|
||||
\brief Sets the hopping period and enables FHSS
|
||||
|
||||
\param freqHoppingPeriod Integer multiple of symbol periods between hops
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setFHSSHoppingPeriod(uint8_t freqHoppingPeriod);
|
||||
|
||||
/*!
|
||||
\brief Gets FHSS hopping period
|
||||
|
||||
\returns 8 bit period
|
||||
*/
|
||||
uint8_t getFHSSHoppingPeriod(void);
|
||||
|
||||
/*!
|
||||
\brief Gets the FHSS channel in use
|
||||
|
||||
\returns 6 bit channel number
|
||||
*/
|
||||
uint8_t getFHSSChannel(void);
|
||||
|
||||
/*!
|
||||
\brief Clear the FHSS interrupt
|
||||
*/
|
||||
void clearFHSSInt(void);
|
||||
|
||||
#if !defined(RADIOLIB_GODMODE) && !defined(RADIOLIB_LOW_LEVEL)
|
||||
protected:
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue