RadioHead
Public Member Functions | Protected Member Functions | List of all members
RH_LoRaFileOps Class Reference

Driver to send and receive unaddressed, unreliable datagrams via a LoRa capable radio transceiver on a Linux platform (possibly Raspberry Pi), using the lora-file-ops driver by Jian-Hong Pan (starnight): https://github.com/starnight/LoRa/tree/file-ops. More...

#include <RH_LoRaFileOps.h>

Inheritance diagram for RH_LoRaFileOps:
RHGenericDriver

Public Member Functions

 RH_LoRaFileOps (const char *port)
 
virtual bool init ()
 
virtual bool available ()
 
virtual bool recv (uint8_t *buf, uint8_t *len)
 
virtual bool send (const uint8_t *data, uint8_t len)
 
virtual uint8_t maxMessageLength ()
 
bool setFrequency (uint32_t centre)
 
uint32_t getFrequency ()
 
int lastSNR ()
 
void setTxPower (int32_t power)
 
int32_t getTxPower ()
 
void setSpreadingFactor (int32_t sf)
 
int32_t getSpreadingFactor ()
 
int32_t getRSSI ()
 
int32_t getSNR ()
 
void setLNA (int32_t lna)
 
int32_t getLNA ()
 
void setLNAAGC (int32_t lnaagc)
 
void setBW (int32_t bw)
 
int32_t getBW ()
 
void setCRC (uint32_t crc)
 
- Public Member Functions inherited from RHGenericDriver
 RHGenericDriver ()
 Constructor.
 
virtual ~RHGenericDriver ()
 Generic destructor to prevent warnings when objects are dynamically allocated.
 
virtual bool init ()
 
virtual bool available ()=0
 
virtual bool recv (uint8_t *buf, uint8_t *len)=0
 
virtual bool send (const uint8_t *data, uint8_t len)=0
 
virtual uint8_t maxMessageLength ()=0
 
virtual void waitAvailable (uint16_t polldelay=0)
 
virtual bool waitPacketSent ()
 
virtual bool waitPacketSent (uint16_t timeout)
 
virtual bool waitAvailableTimeout (uint16_t timeout, uint16_t polldelay=0)
 
virtual bool waitCAD ()
 
void setCADTimeout (unsigned long cad_timeout)
 
virtual bool isChannelActive ()
 
virtual void setThisAddress (uint8_t thisAddress)
 
virtual void setHeaderTo (uint8_t to)
 
virtual void setHeaderFrom (uint8_t from)
 
virtual void setHeaderId (uint8_t id)
 
virtual void setHeaderFlags (uint8_t set, uint8_t clear=RH_FLAGS_APPLICATION_SPECIFIC)
 
virtual void setPromiscuous (bool promiscuous)
 
virtual uint8_t headerTo ()
 
virtual uint8_t headerFrom ()
 
virtual uint8_t headerId ()
 
virtual uint8_t headerFlags ()
 
virtual int16_t lastRssi ()
 
virtual RHMode mode ()
 
virtual void setMode (RHMode mode)
 Sets the operating mode of the transport. More...
 
virtual bool sleep ()
 
virtual uint16_t rxBad ()
 
virtual uint16_t rxGood ()
 
virtual uint16_t txGood ()
 

Protected Member Functions

void setState (uint32_t state)
 Set the current radio state, one of LORA_STATE_*.
 
uint32_t getState ()
 Get the current radio state.
 

Additional Inherited Members

- Public Types inherited from RHGenericDriver
enum  RHMode {
  RHModeInitialising = 0 , RHModeSleep , RHModeIdle , RHModeTx ,
  RHModeRx , RHModeCad
}
 Defines different operating modes for the transport hardware. More...
 
- Static Public Member Functions inherited from RHGenericDriver
static void printBuffer (const char *prompt, const uint8_t *buf, uint8_t len)
 
- Protected Attributes inherited from RHGenericDriver
volatile RHMode _mode
 The current transport operating mode.
 
uint8_t _thisAddress
 This node id.
 
bool _promiscuous
 Whether the transport is in promiscuous mode.
 
volatile uint8_t _rxHeaderTo
 TO header in the last received mesasge.
 
volatile uint8_t _rxHeaderFrom
 FROM header in the last received mesasge.
 
volatile uint8_t _rxHeaderId
 ID header in the last received mesasge.
 
volatile uint8_t _rxHeaderFlags
 FLAGS header in the last received mesasge.
 
uint8_t _txHeaderTo
 TO header to send in all messages.
 
uint8_t _txHeaderFrom
 FROM header to send in all messages.
 
uint8_t _txHeaderId
 ID header to send in all messages.
 
uint8_t _txHeaderFlags
 FLAGS header to send in all messages.
 
volatile int16_t _lastRssi
 The value of the last received RSSI value, in some transport specific units.
 
volatile uint16_t _rxBad
 Count of the number of bad messages (eg bad checksum etc) received.
 
volatile uint16_t _rxGood
 Count of the number of successfully transmitted messaged.
 
volatile uint16_t _txGood
 Count of the number of bad messages (correct checksum etc) received.
 
volatile bool _cad
 Channel activity detected.
 
unsigned int _cad_timeout
 Channel activity timeout in ms.
 

Detailed Description

Driver to send and receive unaddressed, unreliable datagrams via a LoRa capable radio transceiver on a Linux platform (possibly Raspberry Pi), using the lora-file-ops driver by Jian-Hong Pan (starnight): https://github.com/starnight/LoRa/tree/file-ops.

This RadioHead driver is only available to Commercial licensees. Apply to info@.nosp@m.airs.nosp@m.payce.nosp@m..com.

For an excellent discussion of LoRa range and modulations, see https://medium.com/home-wireless/testing-lora-radios-with-the-limesdr-mini-part-2-37fa481217ff Works with Dragino LoRa/GPS HAT, https://wiki.dragino.com/index.php?title=Lora/GPS_HAT modified so RFM95 pin 5 NSS was no longer connected to RPi pin P1-22 (GPIO6), but is instead connected to RPi Pin P1-24 (CE0) which is the one used by /dev/loraSPI0.0. Interoperates with RH_RF95 with modem config RH_RF95::Bw125Cr45Sf2048

Overview

This class provides basic functions for sending and receiving unaddressed, unreliable datagrams of arbitrary length up to 251 octets per packet.

Manager classes may use this class to implement reliable, addressed datagrams and streams, mesh routers, repeaters, translators etc.

Naturally, for any 2 radios to communicate that must be configured to use the same frequency and modulation scheme.

This RadioHead Driver provides an object-oriented interface for sending and receiving data messages with Semtech SX1276/77/78/79 and compatible radio modules in LoRa mode, using the lora-file-ops Linux driver. It only runs on Linux such as Raspberry Pi Debian etc.is a low-cost ISM transceiver chip. It supports FSK, GFSK, OOK over a wide range of frequencies and programmable data rates, and it also supports the proprietary LoRA (Long Range) mode, which is the only mode supported in this RadioHead driver (because that is the only mode supported by the underlying lora-file-ops Linux driver.

This Driver provides functions for sending and receiving messages of up to 251 octets on any frequency supported by the radio, in a range of predefined Bandwidths, Spreading Factors and Coding Rates. Frequency can be set with 61Hz precision to any frequency from 240.0MHz to 960.0MHz. Caution: most modules only support a more limited range of frequencies due to antenna tuning.

Up to 2 modules are supported by lora-file-ops permitting the construction of translators and frequency changers, etc.

Support for other features such as transmitter power control etc is also provided.

Tested with: RPi 2 + Debian 2021-03-04 (kernel 5.10.17-v7+ #1403) Dragino LoRa/GPS HAT, https://wiki.dragino.com/index.php?title=Lora/GPS_HAT modified so RFM95 pin 5 NSS was no longer connected to RPi pin P1-22 (GPIO6), but is instead connected to RPi Pin P1-24 (CE0) which is the one used by /dev/loraSPI0.0

Packet Format

All messages sent and received by this RH_RF95 Driver conform to this packet format:

This format is compatible with the one used by RH_RF95 by default.

Modulation

The default modulation scheme implemented by this driver is: 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on which is compatible withthe RH_RF95 modem config RH_RF95::Bw125Cr45Sf2048 and so this RadioHead driver will interoperate with RH_RF95.

Installing lora-file-ops
For this driver to work on a Linux platform such as Raspberry Pi, it is absolutely necessary to install the LoRa-file-ops Linux driver written by starnight, and which is available from github. The version currently available (2021-04-19) does not support enabling CRCs in the radio, which is strongly recommended, and necessary to work with any other RadioHead lora driver/ At this date, code to add CRC suport to the driver is avalable as a pull request on github as a Git pull request #16 from flyskywhy. We strongly recommend using it as described below.

To get LoRa-file-ops from starnight, plus the necessary patches and fixes from pull request #16 from flyskywhy and to build it and install it and load it into the kernel for testing:

# ON a recent Debian kernel:
sudo apt-get install linux-headers-rpi raspberrypi-kernel-headers
# Enable the SPI interface in the kernel
sudo raspi-config:
-> 3 Interface Options
-> P4 SPI
-> Would you like the SPI interface to be enabled? select Yes, press Return, Return, Select Finish
# in a working directory, not as root:
git clone https://github.com/starnight/LoRa.git
cd LoRa/
git checkout file-ops
git fetch origin pull/16/head:file-ops-patched # only until pull #16 is not merged into master
git checkout file-ops-patched # only until pull #16 is not merged into master
cd LoRa/
make
make install
cd ../dts-overlay
make
cd ../
# and after every reboot:
sudo dtoverlay rpi-lora-spi
sudo modprobe sx1278

If you want to permanently add the LoRa-file-ops Linux driver so it loads automatically on every boot, add this to /boot/config.txt

dtparam=rpi-lora-spi=on

Note: it may be the case in the future that pull request 16 is merged into the master of LoRa-File-Ops in which case 2 steps are not needed above

Examples
lorafileops_client.cpp, and lorafileops_server.cpp.

Constructor & Destructor Documentation

◆ RH_LoRaFileOps()

RH_LoRaFileOps::RH_LoRaFileOps ( const char *  port)

Constructor. You can have multiple instances each connected to a different LoRa port

Parameters
[in]portName of the lora-file-ops port, typically something like /dev/loraSPI0.0

Member Function Documentation

◆ available()

virtual bool RH_LoRaFileOps::available ( )
virtual

Tests whether a new message is available from the lora-file-ops Linux driver. This can be called multiple times in a timeout loop

Returns
true if a new, complete, error-free uncollected message is available to be retreived by recv()

Implements RHGenericDriver.

◆ getBW()

int32_t RH_LoRaFileOps::getBW ( )

Get the transmitter and receiver modulation bandwidth

Returns
Modulation bandwidth in Hz

◆ getFrequency()

uint32_t RH_LoRaFileOps::getFrequency ( )

Returns the current transmitter and receiver centre frequency.

Returns
Centre frequency in Hz.

◆ getLNA()

int32_t RH_LoRaFileOps::getLNA ( )

Get the current LNA gain

Returns
The current LNA gain in dBm

◆ getRSSI()

int32_t RH_LoRaFileOps::getRSSI ( )

Gets the RSSI of the last received packet

Returns
RSSI of the last received packet

◆ getSNR()

int32_t RH_LoRaFileOps::getSNR ( )

Gets the Signal To Noise (SNR) of the last received packet

Returns
SNR of the last received packet

◆ getSpreadingFactor()

int32_t RH_LoRaFileOps::getSpreadingFactor ( )

Get the LoRa Spreading Factor

Returns
The current Spreading Factor

◆ getTxPower()

int32_t RH_LoRaFileOps::getTxPower ( )

Gets the currently set transmitter power output level

Returns
Current poer level in dbM

◆ init()

virtual bool RH_LoRaFileOps::init ( )
virtual

Initialise the Driver transport hardware and software. Opens the LorFileOps driver port and initalises the radio to default settings Leaves the radio in receive mode, with default configuration of: 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 2048chips/symbol, CRC on which is compatible with RH_RF95::Bw125Cr45Sf2048

Returns
true if initialisation succeeded.

Reimplemented from RHGenericDriver.

◆ lastSNR()

int RH_LoRaFileOps::lastSNR ( )

Returns the Signal-to-noise ratio (SNR) of the last received message, as measured by the receiver.

Returns
SNR of the last received message in dB

◆ maxMessageLength()

virtual uint8_t RH_LoRaFileOps::maxMessageLength ( )
virtual

Returns the maximum message length available in this Driver.

Returns
The maximum legal message length

Implements RHGenericDriver.

◆ recv()

virtual bool RH_LoRaFileOps::recv ( uint8_t *  buf,
uint8_t *  len 
)
virtual

If there is a valid message available and it is for this node, copy it to buf and return true else return false. If a message is copied, *len is set to the length (Caution, 0 length messages are permitted). You should be sure to call this function frequently enough to not miss any messages or call it aafter available(), waitAvailable() or waitAvailableTimeout() indicate that a message is avalable It is recommended that you call it in your main loop.

Parameters
[in]bufLocation to copy the received message
[in,out]lenPointer to available space in buf. Set to the actual number of octets copied.
Returns
true if a valid message addressed to this node was copied to buf

Implements RHGenericDriver.

◆ send()

virtual bool RH_LoRaFileOps::send ( const uint8_t *  data,
uint8_t  len 
)
virtual

Loads a message into the transmitter and starts the transmitter. Note that a message length of 0 is permitted. CAD is not supported yet. The lora-file-ops driver waits for the entire message to be transmitted before resuming operations.

Parameters
[in]dataArray of data to be sent
[in]lenNumber of bytes of data to send
Returns
true if the message length was valid and it was correctly transmitted.

Implements RHGenericDriver.

◆ setBW()

void RH_LoRaFileOps::setBW ( int32_t  bw)

Set the transmitter and receiver modulation bandwidth

Parameters
[in]bwModulation bandwidth in Hz. Valid values are 7800, 10400, 15600, 20800, 312500, 41700, 62500, 125000, 250000, 500000.

◆ setCRC()

void RH_LoRaFileOps::setCRC ( uint32_t  crc)

Enable Cyclic Redundancy Check (CRC) in the transmitter and receiver. If enabled, the transmitter will always appenda CRC to every packet, and the receiver will always check the CRC on received packets, ignoring packets with incorrect CRC

Parameters
[in]crc1 to enable CRC generation and detection, 0 to disable it

◆ setFrequency()

bool RH_LoRaFileOps::setFrequency ( uint32_t  centre)

Sets the transmitter and receiver centre (carrier) frequency.

Parameters
[in]centreFrequency in Hz. 137000000 to 1020000000. Caution: SX1276/77/78/79 comes in several different frequency ranges, and setting a frequency outside that range of your radio will probably not work correctly becasue the antenna coupling or antenna wont work outside their designed frequency range
Returns
true if the selected frequency centre is within range

◆ setLNA()

void RH_LoRaFileOps::setLNA ( int32_t  lna)

Set the receiver Low Noise Amplifier (LNA) gain

Parameters
[in]lnaLNA gain in dBm

◆ setLNAAGC()

void RH_LoRaFileOps::setLNAAGC ( int32_t  lnaagc)

Set the LNA Automatic Gain Control (AGC) enabled

Parameters
[in]lnaagc1 to enable LNA AGC, 0 to disable it

◆ setSpreadingFactor()

void RH_LoRaFileOps::setSpreadingFactor ( int32_t  sf)

Set the LoRa Spreading Factor

Parameters
[in]sfThe spreading factor. Valid values are 64, 128, 256, 512, 1024, 2048, 4096.

◆ setTxPower()

void RH_LoRaFileOps::setTxPower ( int32_t  power)

Sets the transmitter power output level Be a good neighbour and set the lowest power level you need. Caution: legal power limits may apply in certain countries. After init(), the power will be set to 13dBm

Parameters
[in]powerTransmitter power level in dBm. Max 20dBm.

The documentation for this class was generated from the following file: