RadioHead
RH_RF95.h
1// RH_RF95.h
2//
3// Definitions for HopeRF LoRa radios per:
4// http://www.hoperf.com/upload/rf/RFM95_96_97_98W.pdf
5// http://www.hoperf.cn/upload/rfchip/RF96_97_98.pdf
6//
7// Author: Mike McCauley (mikem@airspayce.com)
8// Copyright (C) 2014 Mike McCauley
9// $Id: RH_RF95.h,v 1.26 2020/06/15 23:39:39 mikem Exp $
10//
11
12#ifndef RH_RF95_h
13#define RH_RF95_h
14
15#include <RHSPIDriver.h>
16
17// This is the maximum number of interrupts the driver can support
18// Most Arduinos can handle 2, Megas can handle more
19#define RH_RF95_NUM_INTERRUPTS 3
20
21// Max number of octets the LORA Rx/Tx FIFO can hold
22#define RH_RF95_FIFO_SIZE 255
23
24// This is the maximum number of bytes that can be carried by the LORA.
25// We use some for headers, keeping fewer for RadioHead messages
26#define RH_RF95_MAX_PAYLOAD_LEN RH_RF95_FIFO_SIZE
27
28// The length of the headers we add.
29// The headers are inside the LORA's payload
30#define RH_RF95_HEADER_LEN 4
31
32// This is the maximum message length that can be supported by this driver.
33// Can be pre-defined to a smaller size (to save SRAM) prior to including this header
34// Here we allow for 1 byte message length, 4 bytes headers, user data and 2 bytes of FCS
35#ifndef RH_RF95_MAX_MESSAGE_LEN
36 #define RH_RF95_MAX_MESSAGE_LEN (RH_RF95_MAX_PAYLOAD_LEN - RH_RF95_HEADER_LEN)
37#endif
38
39// The crystal oscillator frequency of the module
40#define RH_RF95_FXOSC 32000000.0
41
42// The Frequency Synthesizer step = RH_RF95_FXOSC / 2^^19
43#define RH_RF95_FSTEP (RH_RF95_FXOSC / 524288)
44
45
46// Register names (LoRa Mode, from table 85)
47#define RH_RF95_REG_00_FIFO 0x00
48#define RH_RF95_REG_01_OP_MODE 0x01
49#define RH_RF95_REG_02_RESERVED 0x02
50#define RH_RF95_REG_03_RESERVED 0x03
51#define RH_RF95_REG_04_RESERVED 0x04
52#define RH_RF95_REG_05_RESERVED 0x05
53#define RH_RF95_REG_06_FRF_MSB 0x06
54#define RH_RF95_REG_07_FRF_MID 0x07
55#define RH_RF95_REG_08_FRF_LSB 0x08
56#define RH_RF95_REG_09_PA_CONFIG 0x09
57#define RH_RF95_REG_0A_PA_RAMP 0x0a
58#define RH_RF95_REG_0B_OCP 0x0b
59#define RH_RF95_REG_0C_LNA 0x0c
60#define RH_RF95_REG_0D_FIFO_ADDR_PTR 0x0d
61#define RH_RF95_REG_0E_FIFO_TX_BASE_ADDR 0x0e
62#define RH_RF95_REG_0F_FIFO_RX_BASE_ADDR 0x0f
63#define RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR 0x10
64#define RH_RF95_REG_11_IRQ_FLAGS_MASK 0x11
65#define RH_RF95_REG_12_IRQ_FLAGS 0x12
66#define RH_RF95_REG_13_RX_NB_BYTES 0x13
67#define RH_RF95_REG_14_RX_HEADER_CNT_VALUE_MSB 0x14
68#define RH_RF95_REG_15_RX_HEADER_CNT_VALUE_LSB 0x15
69#define RH_RF95_REG_16_RX_PACKET_CNT_VALUE_MSB 0x16
70#define RH_RF95_REG_17_RX_PACKET_CNT_VALUE_LSB 0x17
71#define RH_RF95_REG_18_MODEM_STAT 0x18
72#define RH_RF95_REG_19_PKT_SNR_VALUE 0x19
73#define RH_RF95_REG_1A_PKT_RSSI_VALUE 0x1a
74#define RH_RF95_REG_1B_RSSI_VALUE 0x1b
75#define RH_RF95_REG_1C_HOP_CHANNEL 0x1c
76#define RH_RF95_REG_1D_MODEM_CONFIG1 0x1d
77#define RH_RF95_REG_1E_MODEM_CONFIG2 0x1e
78#define RH_RF95_REG_1F_SYMB_TIMEOUT_LSB 0x1f
79#define RH_RF95_REG_20_PREAMBLE_MSB 0x20
80#define RH_RF95_REG_21_PREAMBLE_LSB 0x21
81#define RH_RF95_REG_22_PAYLOAD_LENGTH 0x22
82#define RH_RF95_REG_23_MAX_PAYLOAD_LENGTH 0x23
83#define RH_RF95_REG_24_HOP_PERIOD 0x24
84#define RH_RF95_REG_25_FIFO_RX_BYTE_ADDR 0x25
85#define RH_RF95_REG_26_MODEM_CONFIG3 0x26
86
87#define RH_RF95_REG_27_PPM_CORRECTION 0x27
88#define RH_RF95_REG_28_FEI_MSB 0x28
89#define RH_RF95_REG_29_FEI_MID 0x29
90#define RH_RF95_REG_2A_FEI_LSB 0x2a
91#define RH_RF95_REG_2C_RSSI_WIDEBAND 0x2c
92#define RH_RF95_REG_31_DETECT_OPTIMIZE 0x31
93#define RH_RF95_REG_33_INVERT_IQ 0x33
94#define RH_RF95_REG_37_DETECTION_THRESHOLD 0x37
95#define RH_RF95_REG_39_SYNC_WORD 0x39
96
97#define RH_RF95_REG_40_DIO_MAPPING1 0x40
98#define RH_RF95_REG_41_DIO_MAPPING2 0x41
99#define RH_RF95_REG_42_VERSION 0x42
100
101#define RH_RF95_REG_4B_TCXO 0x4b
102#define RH_RF95_REG_4D_PA_DAC 0x4d
103#define RH_RF95_REG_5B_FORMER_TEMP 0x5b
104#define RH_RF95_REG_61_AGC_REF 0x61
105#define RH_RF95_REG_62_AGC_THRESH1 0x62
106#define RH_RF95_REG_63_AGC_THRESH2 0x63
107#define RH_RF95_REG_64_AGC_THRESH3 0x64
108
109// RH_RF95_REG_01_OP_MODE 0x01
110#define RH_RF95_LONG_RANGE_MODE 0x80
111#define RH_RF95_ACCESS_SHARED_REG 0x40
112#define RH_RF95_LOW_FREQUENCY_MODE 0x08
113#define RH_RF95_MODE 0x07
114#define RH_RF95_MODE_SLEEP 0x00
115#define RH_RF95_MODE_STDBY 0x01
116#define RH_RF95_MODE_FSTX 0x02
117#define RH_RF95_MODE_TX 0x03
118#define RH_RF95_MODE_FSRX 0x04
119#define RH_RF95_MODE_RXCONTINUOUS 0x05
120#define RH_RF95_MODE_RXSINGLE 0x06
121#define RH_RF95_MODE_CAD 0x07
122
123// RH_RF95_REG_09_PA_CONFIG 0x09
124#define RH_RF95_PA_SELECT 0x80
125#define RH_RF95_MAX_POWER 0x70
126#define RH_RF95_OUTPUT_POWER 0x0f
127
128// RH_RF95_REG_0A_PA_RAMP 0x0a
129#define RH_RF95_LOW_PN_TX_PLL_OFF 0x10
130#define RH_RF95_PA_RAMP 0x0f
131#define RH_RF95_PA_RAMP_3_4MS 0x00
132#define RH_RF95_PA_RAMP_2MS 0x01
133#define RH_RF95_PA_RAMP_1MS 0x02
134#define RH_RF95_PA_RAMP_500US 0x03
135#define RH_RF95_PA_RAMP_250US 0x04
136#define RH_RF95_PA_RAMP_125US 0x05
137#define RH_RF95_PA_RAMP_100US 0x06
138#define RH_RF95_PA_RAMP_62US 0x07
139#define RH_RF95_PA_RAMP_50US 0x08
140#define RH_RF95_PA_RAMP_40US 0x09
141#define RH_RF95_PA_RAMP_31US 0x0a
142#define RH_RF95_PA_RAMP_25US 0x0b
143#define RH_RF95_PA_RAMP_20US 0x0c
144#define RH_RF95_PA_RAMP_15US 0x0d
145#define RH_RF95_PA_RAMP_12US 0x0e
146#define RH_RF95_PA_RAMP_10US 0x0f
147
148// RH_RF95_REG_0B_OCP 0x0b
149#define RH_RF95_OCP_ON 0x20
150#define RH_RF95_OCP_TRIM 0x1f
151
152// RH_RF95_REG_0C_LNA 0x0c
153#define RH_RF95_LNA_GAIN 0xe0
154#define RH_RF95_LNA_GAIN_G1 0x20
155#define RH_RF95_LNA_GAIN_G2 0x40
156#define RH_RF95_LNA_GAIN_G3 0x60
157#define RH_RF95_LNA_GAIN_G4 0x80
158#define RH_RF95_LNA_GAIN_G5 0xa0
159#define RH_RF95_LNA_GAIN_G6 0xc0
160#define RH_RF95_LNA_BOOST_LF 0x18
161#define RH_RF95_LNA_BOOST_LF_DEFAULT 0x00
162#define RH_RF95_LNA_BOOST_HF 0x03
163#define RH_RF95_LNA_BOOST_HF_DEFAULT 0x00
164#define RH_RF95_LNA_BOOST_HF_150PC 0x03
165
166// RH_RF95_REG_11_IRQ_FLAGS_MASK 0x11
167#define RH_RF95_RX_TIMEOUT_MASK 0x80
168#define RH_RF95_RX_DONE_MASK 0x40
169#define RH_RF95_PAYLOAD_CRC_ERROR_MASK 0x20
170#define RH_RF95_VALID_HEADER_MASK 0x10
171#define RH_RF95_TX_DONE_MASK 0x08
172#define RH_RF95_CAD_DONE_MASK 0x04
173#define RH_RF95_FHSS_CHANGE_CHANNEL_MASK 0x02
174#define RH_RF95_CAD_DETECTED_MASK 0x01
175
176// RH_RF95_REG_12_IRQ_FLAGS 0x12
177#define RH_RF95_RX_TIMEOUT 0x80
178#define RH_RF95_RX_DONE 0x40
179#define RH_RF95_PAYLOAD_CRC_ERROR 0x20
180#define RH_RF95_VALID_HEADER 0x10
181#define RH_RF95_TX_DONE 0x08
182#define RH_RF95_CAD_DONE 0x04
183#define RH_RF95_FHSS_CHANGE_CHANNEL 0x02
184#define RH_RF95_CAD_DETECTED 0x01
185
186// RH_RF95_REG_18_MODEM_STAT 0x18
187#define RH_RF95_RX_CODING_RATE 0xe0
188#define RH_RF95_MODEM_STATUS_CLEAR 0x10
189#define RH_RF95_MODEM_STATUS_HEADER_INFO_VALID 0x08
190#define RH_RF95_MODEM_STATUS_RX_ONGOING 0x04
191#define RH_RF95_MODEM_STATUS_SIGNAL_SYNCHRONIZED 0x02
192#define RH_RF95_MODEM_STATUS_SIGNAL_DETECTED 0x01
193
194// RH_RF95_REG_1C_HOP_CHANNEL 0x1c
195#define RH_RF95_PLL_TIMEOUT 0x80
196#define RH_RF95_RX_PAYLOAD_CRC_IS_ON 0x40
197#define RH_RF95_FHSS_PRESENT_CHANNEL 0x3f
198
199// RH_RF95_REG_1D_MODEM_CONFIG1 0x1d
200#define RH_RF95_BW 0xf0
201
202#define RH_RF95_BW_7_8KHZ 0x00
203#define RH_RF95_BW_10_4KHZ 0x10
204#define RH_RF95_BW_15_6KHZ 0x20
205#define RH_RF95_BW_20_8KHZ 0x30
206#define RH_RF95_BW_31_25KHZ 0x40
207#define RH_RF95_BW_41_7KHZ 0x50
208#define RH_RF95_BW_62_5KHZ 0x60
209#define RH_RF95_BW_125KHZ 0x70
210#define RH_RF95_BW_250KHZ 0x80
211#define RH_RF95_BW_500KHZ 0x90
212#define RH_RF95_CODING_RATE 0x0e
213#define RH_RF95_CODING_RATE_4_5 0x02
214#define RH_RF95_CODING_RATE_4_6 0x04
215#define RH_RF95_CODING_RATE_4_7 0x06
216#define RH_RF95_CODING_RATE_4_8 0x08
217#define RH_RF95_IMPLICIT_HEADER_MODE_ON 0x01
218
219// RH_RF95_REG_1E_MODEM_CONFIG2 0x1e
220#define RH_RF95_SPREADING_FACTOR 0xf0
221#define RH_RF95_SPREADING_FACTOR_64CPS 0x60
222#define RH_RF95_SPREADING_FACTOR_128CPS 0x70
223#define RH_RF95_SPREADING_FACTOR_256CPS 0x80
224#define RH_RF95_SPREADING_FACTOR_512CPS 0x90
225#define RH_RF95_SPREADING_FACTOR_1024CPS 0xa0
226#define RH_RF95_SPREADING_FACTOR_2048CPS 0xb0
227#define RH_RF95_SPREADING_FACTOR_4096CPS 0xc0
228#define RH_RF95_TX_CONTINUOUS_MODE 0x08
229
230#define RH_RF95_PAYLOAD_CRC_ON 0x04
231#define RH_RF95_SYM_TIMEOUT_MSB 0x03
232
233// RH_RF95_REG_26_MODEM_CONFIG3
234#define RH_RF95_MOBILE_NODE 0x08 // HopeRF term
235#define RH_RF95_LOW_DATA_RATE_OPTIMIZE 0x08 // Semtechs term
236#define RH_RF95_AGC_AUTO_ON 0x04
237
238// RH_RF95_REG_4B_TCXO 0x4b
239#define RH_RF95_TCXO_TCXO_INPUT_ON 0x10
240
241// RH_RF95_REG_4D_PA_DAC 0x4d
242#define RH_RF95_PA_DAC_DISABLE 0x04
243#define RH_RF95_PA_DAC_ENABLE 0x07
244
245
246/////////////////////////////////////////////////////////////////////
247/// \class RH_RF95 RH_RF95.h <RH_RF95.h>
248/// \brief Driver to send and receive unaddressed, unreliable datagrams via a LoRa
249/// capable radio transceiver.
250///
251/// For an excellent discussion of LoRa range and modulations, see
252/// https://medium.com/home-wireless/testing-lora-radios-with-the-limesdr-mini-part-2-37fa481217ff
253///
254/// For Semtech SX1276/77/78/79 and HopeRF RF95/96/97/98 and other similar LoRa capable radios.
255/// Based on http://www.hoperf.com/upload/rf/RFM95_96_97_98W.pdf
256/// and http://www.hoperf.cn/upload/rfchip/RF96_97_98.pdf
257/// and http://www.semtech.com/images/datasheet/LoraDesignGuide_STD.pdf
258/// and http://www.semtech.com/images/datasheet/sx1276.pdf
259/// and http://www.semtech.com/images/datasheet/sx1276_77_78_79.pdf
260/// FSK/GFSK/OOK modes are not (yet) supported.
261///
262/// Works with
263/// - the excellent MiniWirelessLoRa from Anarduino http://www.anarduino.com/miniwireless
264/// - The excellent Modtronix inAir4 http://modtronix.com/inair4.html
265/// and inAir9 modules http://modtronix.com/inair9.html.
266/// - the excellent Rocket Scream Mini Ultra Pro with the RFM95W
267/// http://www.rocketscream.com/blog/product/mini-ultra-pro-with-radio/
268/// - Lora1276 module from NiceRF http://www.nicerf.com/product_view.aspx?id=99
269/// - Adafruit Feather M0 with RFM95
270/// - The very fine Talk2 Whisper Node LoRa boards https://wisen.com.au/store/products/whisper-node-lora
271/// an Arduino compatible board, which include an on-board RFM95/96 LoRa Radio (Semtech SX1276), external antenna,
272/// run on 2xAAA batteries and support low power operations. RF95 examples work without modification.
273/// Use Arduino Board Manager to install the Talk2 code support. Upload the code with an FTDI adapter set to 5V.
274/// - heltec / TTGO ESP32 LoRa OLED https://www.aliexpress.com/item/Internet-Development-Board-SX1278-ESP32-WIFI-chip-0-96-inch-OLED-Bluetooth-WIFI-Lora-Kit-32/32824535649.html
275///
276/// \par Overview
277///
278/// This class provides basic functions for sending and receiving unaddressed,
279/// unreliable datagrams of arbitrary length to 251 octets per packet.
280///
281/// Manager classes may use this class to implement reliable, addressed datagrams and streams,
282/// mesh routers, repeaters, translators etc.
283///
284/// Naturally, for any 2 radios to communicate that must be configured to use the same frequency and
285/// modulation scheme.
286///
287/// This Driver provides an object-oriented interface for sending and receiving data messages with Hope-RF
288/// RFM95/96/97/98(W), Semtech SX1276/77/78/79 and compatible radio modules in LoRa mode.
289///
290/// The Hope-RF (http://www.hoperf.com) RFM95/96/97/98(W) and Semtech SX1276/77/78/79 is a low-cost ISM transceiver
291/// chip. It supports FSK, GFSK, OOK over a wide range of frequencies and
292/// programmable data rates, and it also supports the proprietary LoRA (Long Range) mode, which
293/// is the only mode supported in this RadioHead driver.
294///
295/// This Driver provides functions for sending and receiving messages of up
296/// to 251 octets on any frequency supported by the radio, in a range of
297/// predefined Bandwidths, Spreading Factors and Coding Rates. Frequency can be set with
298/// 61Hz precision to any frequency from 240.0MHz to 960.0MHz. Caution: most modules only support a more limited
299/// range of frequencies due to antenna tuning.
300///
301/// Up to 2 modules can be connected to an Arduino (3 on a Mega),
302/// permitting the construction of translators and frequency changers, etc.
303///
304/// Support for other features such as transmitter power control etc is
305/// also provided.
306///
307/// Tested on MinWirelessLoRa with arduino-1.0.5
308/// on OpenSuSE 13.1.
309/// Also tested with Teensy3.1, Modtronix inAir4 and Arduino 1.6.5 on OpenSuSE 13.1
310///
311/// \par Packet Format
312///
313/// All messages sent and received by this RH_RF95 Driver conform to this packet format, which is compatible with RH_SX126x:
314///
315/// - LoRa mode:
316/// - 8 symbol PREAMBLE
317/// - Explicit header with header CRC (default CCITT, handled internally by the radio)
318/// - 4 octets HEADER: (TO, FROM, ID, FLAGS)
319/// - 0 to 251 octets DATA
320/// - CRC (default CCITT, handled internally by the radio)
321///
322/// \par Connecting RFM95/96/97/98 and Semtech SX1276/77/78/79 to Arduino
323///
324/// We tested with Anarduino MiniWirelessLoRA, which is an Arduino Duemilanove compatible with a RFM96W
325/// module on-board. Therefore it needs no connections other than the USB
326/// programming connection and an antenna to make it work.
327///
328/// If you have a bare RFM95/96/97/98 that you want to connect to an Arduino, you
329/// might use these connections (untested): CAUTION: you must use a 3.3V type
330/// Arduino, otherwise you will also need voltage level shifters between the
331/// Arduino and the RFM95. CAUTION, you must also ensure you connect an
332/// antenna.
333///
334/// \code
335/// Arduino RFM95/96/97/98
336/// GND----------GND (ground in)
337/// 3V3----------3.3V (3.3V in)
338/// interrupt 0 pin D2-----------DIO0 (interrupt request out)
339/// SS pin D10----------NSS (CS chip select in)
340/// SCK pin D13----------SCK (SPI clock in)
341/// MOSI pin D11----------MOSI (SPI Data in)
342/// MISO pin D12----------MISO (SPI Data out)
343/// \endcode
344/// With these connections, you can then use the default constructor RH_RF95().
345/// You can override the default settings for the SS pin and the interrupt in
346/// the RH_RF95 constructor if you wish to connect the slave select SS to other
347/// than the normal one for your Arduino (D10 for Diecimila, Uno etc and D53
348/// for Mega) or the interrupt request to other than pin D2 (Caution,
349/// different processors have different constraints as to the pins available
350/// for interrupts).
351///
352/// You can connect a Modtronix inAir4 or inAir9 directly to a 3.3V part such as a Teensy 3.1 like
353/// this (tested).
354/// \code
355/// Teensy inAir4 inAir9
356/// GND----------0V (ground in)
357/// 3V3----------3.3V (3.3V in)
358/// interrupt 0 pin D2-----------D0 (interrupt request out)
359/// SS pin D10----------CS (CS chip select in)
360/// SCK pin D13----------CK (SPI clock in)
361/// MOSI pin D11----------SI (SPI Data in)
362/// MISO pin D12----------SO (SPI Data out)
363/// \endcode
364/// With these connections, you can then use the default constructor RH_RF95().
365/// you must also set the transmitter power with useRFO:
366/// driver.setTxPower(13, true);
367///
368/// Note that if you are using Modtronix inAir4 or inAir9,or any other module which uses the
369/// transmitter RFO pins and not the PA_BOOST pins
370/// that you must configure the power transmitter power for -1 to 14 dBm and with useRFO true.
371/// Failure to do that will result in extremely low transmit powers.
372///
373/// If you have an Arduino M0 Pro from arduino.org,
374/// you should note that you cannot use Pin 2 for the interrupt line
375/// (Pin 2 is for the NMI only). The same comments apply to Pin 4 on Arduino Zero from arduino.cc.
376/// Instead you can use any other pin (we use Pin 3) and initialise RH_RF69 like this:
377/// \code
378/// // Slave Select is pin 10, interrupt is Pin 3
379/// RH_RF95 driver(10, 3);
380/// \endcode
381/// You can use the same constructor for Arduino Due, and this pinout diagram may be useful:
382/// http://www.robgray.com/temp/Due-pinout-WEB.png
383///
384/// If you have a Rocket Scream Mini Ultra Pro with the RFM95W:
385/// - Ensure you have Arduino SAMD board support 1.6.5 or later in Arduino IDE 1.6.8 or later.
386/// - The radio SS is hardwired to pin D5 and the DIO0 interrupt to pin D2,
387/// so you need to initialise the radio like this:
388/// \code
389/// RH_RF95 driver(5, 2);
390/// \endcode
391/// - The name of the serial port on that board is 'SerialUSB', not 'Serial', so this may be helpful at the top of our
392/// sample sketches:
393/// \code
394/// #define Serial SerialUSB
395/// \endcode
396/// - You also need this in setup before radio initialisation
397/// \code
398/// // Ensure serial flash is not interfering with radio communication on SPI bus
399/// pinMode(4, OUTPUT);
400/// digitalWrite(4, HIGH);
401/// \endcode
402/// - and if you have a 915MHz part, you need this after driver/manager intitalisation:
403/// \code
404/// rf95.setFrequency(915.0);
405/// \endcode
406/// which adds up to modifying sample sketches something like:
407/// \code
408/// #include <SPI.h>
409/// #include <RH_RF95.h>
410/// RH_RF95 rf95(5, 2); // Rocket Scream Mini Ultra Pro with the RFM95W
411/// #define Serial SerialUSB
412///
413/// void setup()
414/// {
415/// // Ensure serial flash is not interfering with radio communication on SPI bus
416/// pinMode(4, OUTPUT);
417/// digitalWrite(4, HIGH);
418///
419/// Serial.begin(9600);
420/// while (!Serial) ; // Wait for serial port to be available
421/// if (!rf95.init())
422/// Serial.println("init failed");
423/// rf95.setFrequency(915.0);
424/// }
425/// ...
426/// \endcode
427///
428/// For Adafruit Feather M0 with RFM95, construct the driver like this:
429/// \code
430/// RH_RF95 rf95(8, 3);
431/// \endcode
432///
433/// If you have a talk2 Whisper Node LoRa board with on-board RF95 radio,
434/// the example rf95_* sketches work without modification. Initialise the radio like
435/// with the default constructor:
436/// \code
437/// RH_RF95 driver;
438/// \endcode
439///
440/// It is possible to have 2 or more radios connected to one Arduino, provided
441/// each radio has its own SS and interrupt line (SCK, SDI and SDO are common
442/// to all radios)
443///
444/// Caution: on some Arduinos such as the Mega 2560, if you set the slave
445/// select pin to be other than the usual SS pin (D53 on Mega 2560), you may
446/// need to set the usual SS pin to be an output to force the Arduino into SPI
447/// master mode.
448///
449/// Caution: Power supply requirements of the RFM module may be relevant in some circumstances:
450/// RFM95/96/97/98 modules are capable of pulling 120mA+ at full power, where Arduino's 3.3V line can
451/// give 50mA. You may need to make provision for alternate power supply for
452/// the RFM module, especially if you wish to use full transmit power, and/or you have
453/// other shields demanding power. Inadequate power for the RFM is likely to cause symptoms such as:
454/// - reset's/bootups terminate with "init failed" messages
455/// - random termination of communication after 5-30 packets sent/received
456/// - "fake ok" state, where initialization passes fluently, but communication doesn't happen
457/// - shields hang Arduino boards, especially during the flashing
458///
459/// \par Interrupts
460///
461/// The RH_RF95 driver uses interrupts to react to events in the RFM module,
462/// such as the reception of a new packet, or the completion of transmission
463/// of a packet. The driver configures the radio so the required interrupt is generated by the radio's DIO0 pin.
464/// The RH_RF95 driver interrupt service routine reads status from
465/// and writes data to the the RFM module via the SPI interface. It is very
466/// important therefore, that if you are using the RH_RF95 driver with another
467/// SPI based deviced, that you disable interrupts while you transfer data to
468/// and from that other device. Use cli() to disable interrupts and sei() to
469/// reenable them.
470///
471/// \par Memory
472///
473/// The RH_RF95 driver requires non-trivial amounts of memory. The sample
474/// programs all compile to about 8kbytes each, which will fit in the
475/// flash proram memory of most Arduinos. However, the RAM requirements are
476/// more critical. Therefore, you should be vary sparing with RAM use in
477/// programs that use the RH_RF95 driver.
478///
479/// It is often hard to accurately identify when you are hitting RAM limits on Arduino.
480/// The symptoms can include:
481/// - Mysterious crashes and restarts
482/// - Changes in behaviour when seemingly unrelated changes are made (such as adding print() statements)
483/// - Hanging
484/// - Output from Serial.print() not appearing
485///
486/// \par Range
487///
488/// We have made some simple range tests under the following conditions:
489/// - rf95_client base station connected to a VHF discone antenna at 8m height above ground
490/// - rf95_server mobile connected to 17.3cm 1/4 wavelength antenna at 1m height, no ground plane.
491/// - Both configured for 13dBm, 434MHz, Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. Slow+long range
492/// - Minimum reported RSSI seen for successful comms was about -91
493/// - Range over flat ground through heavy trees and vegetation approx 2km.
494/// - At 20dBm (100mW) otherwise identical conditions approx 3km.
495/// - At 20dBm, along salt water flat sandy beach, 3.2km.
496///
497/// It should be noted that at this data rate, a 12 octet message takes 2 seconds to transmit.
498///
499/// At 20dBm (100mW) with Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on.
500/// (Default medium range) in the conditions described above.
501/// - Range over flat ground through heavy trees and vegetation approx 2km.
502///
503/// Caution: the performance of this radio, especially with narrow bandwidths is strongly dependent on the
504/// accuracy and stability of the chip clock. HopeRF and Semtech do not appear to
505/// recommend bandwidths of less than 62.5 kHz
506/// unless you have the optional Temperature Compensated Crystal Oscillator (TCXO) installed and
507/// enabled on your radio module. See the refernece manual for more data.
508/// Also https://lowpowerlab.com/forum/rf-range-antennas-rfm69-library/lora-library-experiences-range/15/
509/// and http://www.semtech.com/images/datasheet/an120014-xo-guidance-lora-modulation.pdf
510///
511/// \par Transmitter Power
512///
513/// You can control the transmitter power on the RF transceiver
514/// with the RH_RF95::setTxPower() function. The argument can be any of
515/// +2 to +20 (for modules that use PA_BOOST)
516/// 0 to +15 (for modules that use RFO transmitter pin)
517/// The default is 13. Eg:
518/// \code
519/// driver.setTxPower(10); // use PA_BOOST transmitter pin
520/// driver.setTxPower(10, true); // use PA_RFO pin transmitter pin instead of PA_BOOST
521/// \endcode
522///
523/// We have made some actual power measurements against
524/// programmed power for Anarduino MiniWirelessLoRa (which has RFM96W-433Mhz installed, and which includes an RF power
525/// amp for addition 3dBm of power
526/// - MiniWirelessLoRa RFM96W-433Mhz, USB power
527/// - 30cm RG316 soldered direct to RFM96W module ANT and GND
528/// - SMA connector
529/// - 12db attenuator
530/// - SMA connector
531/// - MiniKits AD8307 HF/VHF Power Head (calibrated against Rohde&Schwartz 806.2020 test set)
532/// - Tektronix TDS220 scope to measure the Vout from power head
533/// \code
534/// Program power Measured Power
535/// dBm dBm
536/// 2 5
537/// 4 7
538/// 6 8
539/// 8 11
540/// 10 13
541/// 12 15
542/// 14 16
543/// 16 18
544/// 17 20
545/// 18 21
546/// 19 22
547/// 20 23
548/// \endcode
549///
550/// We have also measured the actual power output from a Modtronix inAir4 http://modtronix.com/inair4.html
551/// connected to a Teensy 3.1:
552/// Teensy 3.1 this is a 3.3V part, connected directly to:
553/// Modtronix inAir4 with SMA antenna connector, connected as above:
554/// 10cm SMA-SMA cable
555/// - MiniKits AD8307 HF/VHF Power Head (calibrated against Rohde&Schwartz 806.2020 test set)
556/// - Tektronix TDS220 scope to measure the Vout from power head
557/// \code
558/// Program power Measured Power
559/// dBm dBm
560/// 0 0
561/// 2 2
562/// 3 4
563/// 6 7
564/// 8 10
565/// 10 13
566/// 12 14.2
567/// 14 15
568/// 15 16
569/// \endcode
570/// (Caution: we dont claim laboratory accuracy for these power measurements)
571/// You would not expect to get anywhere near these powers to air with a simple 1/4 wavelength wire antenna.
572class RH_RF95 : public RHSPIDriver
573{
574public:
575 /// \brief Defines register values for a set of modem configuration registers
576 ///
577 /// Defines register values for a set of modem configuration registers
578 /// that can be passed to setModemRegisters() if none of the choices in
579 /// ModemConfigChoice suit your need setModemRegisters() writes the
580 /// register values from this structure to the appropriate registers
581 /// to set the desired spreading factor, coding rate and bandwidth
582 typedef struct
583 {
584 uint8_t reg_1d; ///< Value for register RH_RF95_REG_1D_MODEM_CONFIG1
585 uint8_t reg_1e; ///< Value for register RH_RF95_REG_1E_MODEM_CONFIG2
586 uint8_t reg_26; ///< Value for register RH_RF95_REG_26_MODEM_CONFIG3
587 } ModemConfig;
588
589 /// Choices for setModemConfig() for a selected subset of common
590 /// data rates. If you need another configuration,
591 /// determine the necessary settings and call setModemRegisters() with your
592 /// desired settings. It might be helpful to use the LoRa calculator mentioned in
593 /// http://www.semtech.com/images/datasheet/LoraDesignGuide_STD.pdf
594 /// These are indexes into MODEM_CONFIG_TABLE. We strongly recommend you use these symbolic
595 /// definitions and not their integer equivalents: its possible that new values will be
596 /// introduced in later versions (though we will try to avoid it).
597 /// Caution: if you are using slow packet rates and long packets with RHReliableDatagram or subclasses
598 /// you may need to change the RHReliableDatagram timeout for reliable operations.
599 /// Caution: for some slow rates nad with ReliableDatagrams you may need to increase the reply timeout
600 /// with manager.setTimeout() to
601 /// deal with the long transmission times.
602 /// Caution: SX1276 family errata suggests alternate settings for some LoRa registers when 500kHz bandwidth
603 /// is in use. See the Semtech SX1276/77/78 Errata Note. These are not implemented by RH_RF95.
604 typedef enum
605 {
606 Bw125Cr45Sf128 = 0, ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range
607 Bw500Cr45Sf128, ///< Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short range
608 Bw31_25Cr48Sf512, ///< Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range
609 Bw125Cr48Sf4096, ///< Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, low data rate, CRC on. Slow+long range
610 Bw125Cr45Sf2048, ///< Bw = 125 kHz, Cr = 4/5, Sf = 2048chips/symbol, CRC on. Slow+long range
612
613 /// Constructor. You can have multiple instances, but each instance must have its own
614 /// interrupt and slave select pin. After constructing, you must call init() to initialise the interface
615 /// and the radio module. A maximum of 3 instances can co-exist on one processor, provided there are sufficient
616 /// distinct interrupt lines, one for each instance.
617 /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the RH_RF22 before
618 /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega, D10 for Maple)
619 /// \param[in] interruptPin The interrupt Pin number that is connected to the RFM DIO0 interrupt line.
620 /// Defaults to pin 2, as required by Anarduino MinWirelessLoRa module.
621 /// Caution: You must specify an interrupt capable pin.
622 /// On many Arduino boards, there are limitations as to which pins may be used as interrupts.
623 /// On Leonardo pins 0, 1, 2 or 3. On Mega2560 pins 2, 3, 18, 19, 20, 21. On Due and Teensy, any digital pin.
624 /// On Arduino Zero from arduino.cc, any digital pin other than 4.
625 /// On Arduino M0 Pro from arduino.org, any digital pin other than 2.
626 /// On other Arduinos pins 2 or 3.
627 /// See http://arduino.cc/en/Reference/attachInterrupt for more details.
628 /// On Chipkit Uno32, pins 38, 2, 7, 8, 35.
629 /// On other boards, any digital pin may be used.
630 /// \param[in] spi Pointer to the SPI interface object to use.
631 /// Defaults to the standard Arduino hardware SPI interface
632 RH_RF95(uint8_t slaveSelectPin = SS, uint8_t interruptPin = 2, RHGenericSPI& spi = hardware_spi);
633
634 /// Initialise the Driver transport hardware and software.
635 /// Leaves the radio in idle mode,
636 /// with default configuration of: 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
637 /// \return true if initialisation succeeded.
638 virtual bool init();
639
640 /// Prints the value of all chip registers
641 /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform
642 /// For debugging purposes only.
643 /// \return true on success
644 bool printRegisters();
645
646 /// Sets all the registers required to configure the data modem in the radio, including the bandwidth,
647 /// spreading factor etc. You can use this to configure the modem with custom configurations if none of the
648 /// canned configurations in ModemConfigChoice suit you.
649 /// \param[in] config A ModemConfig structure containing values for the modem configuration registers.
650 void setModemRegisters(const ModemConfig* config);
651
652 /// Select one of the predefined modem configurations. If you need a modem configuration not provided
653 /// here, use setModemRegisters() with your own ModemConfig.
654 /// Caution: the slowest protocols may require a radio module with TCXO temperature controlled oscillator
655 /// for reliable operation.
656 /// \param[in] index The configuration choice.
657 /// \return true if index is a valid choice.
659
660 /// Tests whether a new message is available from the Driver.
661 /// On most drivers, this will also put the Driver into RHModeRx mode until
662 /// a message is actually received by the transport, when it will be returned to RHModeIdle.
663 /// This can be called multiple times in a timeout loop
664 /// \return true if a new, complete, error-free uncollected message is available to be retreived by recv()
665 virtual bool available();
666
667 /// Turns the receiver on if it not already on.
668 /// If there is a valid message available, copy it to buf and return true
669 /// else return false.
670 /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
671 /// You should be sure to call this function frequently enough to not miss any messages
672 /// It is recommended that you call it in your main loop.
673 /// \param[in] buf Location to copy the received message
674 /// \param[in,out] len Pointer to the number of octets available in buf. The number be reset to the actual number of octets copied.
675 /// \return true if a valid message was copied to buf
676 virtual bool recv(uint8_t* buf, uint8_t* len);
677
678 /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().
679 /// Then optionally waits for Channel Activity Detection (CAD)
680 /// to show the channnel is clear (if the radio supports CAD) by calling waitCAD().
681 /// Then loads a message into the transmitter and starts the transmitter. Note that a message length
682 /// of 0 is permitted.
683 /// \param[in] data Array of data to be sent
684 /// \param[in] len Number of bytes of data to send
685 /// specify the maximum time in ms to wait. If 0 (the default) do not wait for CAD before transmitting.
686 /// \return true if the message length was valid and it was correctly queued for transmit. Return false
687 /// if CAD was requested and the CAD timeout timed out before clear channel was detected.
688 virtual bool send(const uint8_t* data, uint8_t len);
689
690 /// Sets the length of the preamble
691 /// in bytes.
692 /// Caution: this should be set to the same
693 /// value on all nodes in your network. Default is 8.
694 /// Sets the message preamble length in RH_RF95_REG_??_PREAMBLE_?SB
695 /// \param[in] bytes Preamble length in bytes.
696 void setPreambleLength(uint16_t bytes);
697
698 /// Returns the maximum message length
699 /// available in this Driver.
700 /// \return The maximum legal message length
701 virtual uint8_t maxMessageLength();
702
703 /// Sets the transmitter and receiver
704 /// centre frequency.
705 /// \param[in] centre Frequency in MHz. 137.0 to 1020.0. Caution: RFM95/96/97/98 comes in several
706 /// different frequency ranges, and setting a frequency outside that range of your radio will probably not work
707 /// \return true if the selected frquency centre is within range
708 bool setFrequency(float centre);
709
710 /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running,
711 /// disables them.
712 void setModeIdle();
713
714 /// If current mode is Tx or Idle, changes it to Rx.
715 /// Starts the receiver in the RF95/96/97/98.
716 void setModeRx();
717
718 /// If current mode is Rx or Idle, changes it to Rx. F
719 /// Starts the transmitter in the RF95/96/97/98.
720 void setModeTx();
721
722 /// Sets the transmitter power output level, and configures the transmitter pin.
723 /// Be a good neighbour and set the lowest power level you need.
724 /// Some SX1276/77/78/79 and compatible modules (such as RFM95/96/97/98)
725 /// use the PA_BOOST transmitter pin for high power output (and optionally the PA_DAC)
726 /// while some (such as the Modtronix inAir4 and inAir9)
727 /// use the RFO transmitter pin for lower power but higher efficiency.
728 /// You must set the appropriate power level and useRFO argument for your module.
729 /// Check with your module manufacturer which transmtter pin is used on your module
730 /// to ensure you are setting useRFO correctly.
731 /// Failure to do so will result in very low
732 /// transmitter power output.
733 /// Caution: legal power limits may apply in certain countries.
734 /// After init(), the power will be set to 13dBm, with useRFO false (ie PA_BOOST enabled).
735 /// \param[in] power Transmitter power level in dBm. For RFM95/96/97/98 LORA with useRFO false,
736 /// valid values are from +2 to +20. For 18, 19 and 20, PA_DAC is enabled,
737 /// For Modtronix inAir4 and inAir9 with useRFO true (ie RFO pins in use),
738 /// valid values are from 0 to 15.
739 /// \param[in] useRFO If true, enables the use of the RFO transmitter pins instead of
740 /// the PA_BOOST pin (false). Choose the correct setting for your module.
741 void setTxPower(int8_t power, bool useRFO = false);
742
743 /// Sets the radio into low-power sleep mode.
744 /// If successful, the transport will stay in sleep mode until woken by
745 /// changing mode it idle, transmit or receive (eg by calling send(), recv(), available() etc)
746 /// Caution: there is a time penalty as the radio takes a finite time to wake from sleep mode.
747 /// \return true if sleep mode was successfully entered.
748 virtual bool sleep();
749
750 // Bent G Christensen (bentor@gmail.com), 08/15/2016
751 /// Use the radio's Channel Activity Detect (CAD) function to detect channel activity.
752 /// Sets the RF95 radio into CAD mode and waits until CAD detection is complete.
753 /// To be used in a listen-before-talk mechanism (Collision Avoidance)
754 /// with a reasonable time backoff algorithm.
755 /// This is called automatically by waitCAD().
756 /// \return true if channel is in use.
757 virtual bool isChannelActive();
758
759 /// Enable TCXO mode
760 /// Call this immediately after init(), to force your radio to use an external
761 /// frequency source, such as a Temperature Compensated Crystal Oscillator (TCXO), if available.
762 /// See the comments in the main documentation about the sensitivity of this radio to
763 /// clock frequency especially when using narrow bandwidths.
764 /// Leaves the module in sleep mode.
765 /// Caution: the TCXO model radios are not low power when in sleep (consuming
766 /// about ~600 uA, reported by Phang Moh Lim.<br>
767 /// Caution: if you enable TCXO and there is no exernal TCXO signal connected to the radio
768 /// or if the exerrnal TCXO is not
769 /// powered up, the radio <b>will not work<\b>
770 /// \param[in] on If true (the default) enables the radio to use the external TCXO.
771 void enableTCXO(bool on = true);
772
773 /// Returns the last measured frequency error.
774 /// The LoRa receiver estimates the frequency offset between the receiver centre frequency
775 /// and that of the received LoRa signal. This function returns the estimates offset (in Hz)
776 /// of the last received message. Caution: this measurement is not absolute, but is measured
777 /// relative to the local receiver's oscillator.
778 /// Apparent errors may be due to the transmitter, the receiver or both.
779 /// \return The estimated centre frequency offset in Hz of the last received message.
780 /// If the modem bandwidth selector in
781 /// register RH_RF95_REG_1D_MODEM_CONFIG1 is invalid, returns 0.
782 int frequencyError();
783
784 /// Returns the Signal-to-noise ratio (SNR) of the last received message, as measured
785 /// by the receiver.
786 /// \return SNR of the last received message in dB
787 int lastSNR();
788
789 /// brian.n.norman@gmail.com 9th Nov 2018
790 /// Sets the radio spreading factor.
791 /// valid values are 6 through 12.
792 /// Out of range values below 6 are clamped to 6
793 /// Out of range values above 12 are clamped to 12
794 /// See Semtech DS SX1276/77/78/79 page 27 regarding SF6 configuration.
795 ///
796 /// \param[in] uint8_t sf (spreading factor 6..12)
797 /// \return nothing
798 void setSpreadingFactor(uint8_t sf);
799
800 /// brian.n.norman@gmail.com 9th Nov 2018
801 /// Sets the radio signal bandwidth
802 /// sbw ranges and resultant settings are as follows:-
803 /// sbw range actual bw (kHz)
804 /// 0-7800 7.8
805 /// 7801-10400 10.4
806 /// 10401-15600 15.6
807 /// 15601-20800 20.8
808 /// 20801-31250 31.25
809 /// 31251-41700 41.7
810 /// 41701-62500 62.5
811 /// 62501-12500 125.0
812 /// 12501-250000 250.0
813 /// >250000 500.0
814 /// NOTE caution Earlier - Semtech do not recommend BW below 62.5 although, in testing
815 /// I managed 31.25 with two devices in close proximity.
816 /// \param[in] sbw long, signal bandwidth e.g. 125000
817 void setSignalBandwidth(long sbw);
818
819 /// brian.n.norman@gmail.com 9th Nov 2018
820 /// Sets the coding rate to 4/5, 4/6, 4/7 or 4/8.
821 /// Valid denominator values are 5, 6, 7 or 8. A value of 5 sets the coding rate to 4/5 etc.
822 /// Values below 5 are clamped at 5
823 /// values above 8 are clamped at 8.
824 /// Default for all standard modem config options is 4/5.
825 /// \param[in] denominator uint8_t range 5..8
826 void setCodingRate4(uint8_t denominator);
827
828 /// brian.n.norman@gmail.com 9th Nov 2018
829 /// sets the low data rate flag if symbol time exceeds 16ms
830 /// ref: https://www.thethingsnetwork.org/forum/t/a-point-to-note-lora-low-data-rate-optimisation-flag/12007
831 /// called by setBandwidth() and setSpreadingfactor() since these affect the symbol time.
832 void setLowDatarate();
833
834 /// brian.n.norman@gmail.com 9th Nov 2018
835 /// Allows the CRC to be turned on/off. Default is true (enabled)
836 /// When true, RH_RF95 sends a CRC in outgoing packets and requires a valid CRC to be
837 /// present and correct on incoming packets.
838 /// When false, does not send CRC in outgoing packets and does not require a CRC to be
839 /// present on incoming packets. However if a CRC is present, it must be correct.
840 /// Normally this should be left on (the default)
841 /// so that packets with a bad CRC are rejected. If turned off you will be much more likely to receive
842 /// false noise packets.
843 /// \param[in] on bool, true enables CRCs in incoming and outgoing packets, false disables them
844 void setPayloadCRC(bool on);
845
846 /// tilman_1@gloetzner.net
847 /// Returns device version from register 42
848 /// \param none
849 /// \return uint8_t deviceID
850 uint8_t getDeviceVersion();
851
852protected:
853
854 /// Do whatever is necesary to establish the interrupt handler. Subclasses may have different needs
856
857 /// This is a low level function to handle the interrupts for one instance of RH_RF95.
858 /// Called automatically by isr*()
859 /// Should not need to be called by user code.
860 void handleInterrupt();
861
862 /// Examine the revceive buffer to determine whether the message is for this node
863 void validateRxBuf();
864
865 /// Clear our local receive buffer
866 void clearRxBuf();
867
868 /// Called by RH_RF95 when the radio mode is about to change to a new setting.
869 /// Can be used by subclasses to implement antenna switching etc.
870 /// \param[in] mode RHMode the new mode about to take effect
871 /// \return true if the subclasses changes successful
872 virtual bool modeWillChange(RHMode) {return true;}
873
874 /// False if the PA_BOOST transmitter output pin is to be used.
875 /// True if the RFO transmitter output pin is to be used.
877
878private:
879 /// Low level interrupt service routine for device connected to interrupt 0
880 static void isr0();
881
882 /// Low level interrupt service routine for device connected to interrupt 1
883 static void isr1();
884
885 /// Low level interrupt service routine for device connected to interrupt 1
886 static void isr2();
887
888 /// Array of instances connected to interrupts 0 and 1
889 static RH_RF95* _deviceForInterrupt[];
890
891 /// Index of next interrupt number to use in _deviceForInterrupt
892 static uint8_t _interruptCount;
893
894 /// The configured interrupt pin connected to this instance
895 uint8_t _interruptPin;
896
897 /// The index into _deviceForInterrupt[] for this device (if an interrupt is already allocated)
898 /// else 0xff
899 uint8_t _myInterruptIndex;
900
901 /// Number of octets in the buffer
902 volatile uint8_t _bufLen;
903
904 /// The receiver/transmitter buffer
905 uint8_t _buf[RH_RF95_MAX_PAYLOAD_LEN];
906
907 /// True when there is a valid message in the buffer
908 volatile bool _rxBufValid;
909
910 /// True if we are using the HF port (779.0 MHz and above)
911 bool _usingHFport;
912
913 /// Last measured SNR, dB
914 int8_t _lastSNR;
915
916 /// If true, sends CRCs in every packet and requires a valid CRC in every received packet
917 bool _enableCRC;
918
919 /// device ID
920 uint8_t _deviceVersion = 0x00;
921
922};
923
924/// @example rf95_client.ino
925/// @example rf95_client.ino
926/// @example rf95_server.ino
927/// @example rf95_encrypted_client.ino
928/// @example rf95_encrypted_server.ino
929/// @example rf95_reliable_datagram_client.ino
930/// @example rf95_reliable_datagram_server.ino
931
932#endif
933
RHMode
Defines different operating modes for the transport hardware.
Definition RHGenericDriver.h:49
Base class for SPI interfaces.
Definition RHGenericSPI.h:31
Base class for RadioHead drivers that use the SPI bus to communicate with its transport hardware.
Definition RHSPIDriver.h:39
Driver to send and receive unaddressed, unreliable datagrams via a LoRa capable radio transceiver.
Definition RH_RF95.h:573
void setSignalBandwidth(long sbw)
Definition RH_RF95.cpp:620
void validateRxBuf()
Examine the revceive buffer to determine whether the message is for this node.
Definition RH_RF95.cpp:280
int lastSNR()
Definition RH_RF95.cpp:582
virtual bool modeWillChange(RHMode)
Definition RH_RF95.h:872
void handleInterrupt()
Definition RH_RF95.cpp:158
void clearRxBuf()
Clear our local receive buffer.
Definition RH_RF95.cpp:311
void setModeIdle()
Definition RH_RF95.cpp:401
void setModeTx()
Definition RH_RF95.cpp:433
bool setupInterruptHandler()
Do whatever is necesary to establish the interrupt handler. Subclasses may have different needs.
Definition RH_RF95.cpp:99
virtual bool isChannelActive()
Definition RH_RF95.cpp:516
bool setFrequency(float centre)
Definition RH_RF95.cpp:389
virtual bool recv(uint8_t *buf, uint8_t *len)
Definition RH_RF95.cpp:319
void enableTCXO(bool on=true)
Definition RH_RF95.cpp:533
void setLowDatarate()
Definition RH_RF95.cpp:668
virtual bool available()
Definition RH_RF95.cpp:298
int frequencyError()
Definition RH_RF95.cpp:555
void setPayloadCRC(bool on)
Definition RH_RF95.cpp:701
void setModemRegisters(const ModemConfig *config)
Definition RH_RF95.cpp:489
virtual bool init()
Definition RH_RF95.cpp:42
virtual bool sleep()
Definition RH_RF95.cpp:411
uint8_t getDeviceVersion()
Definition RH_RF95.cpp:713
void setTxPower(int8_t power, bool useRFO=false)
Definition RH_RF95.cpp:444
ModemConfigChoice
Definition RH_RF95.h:605
@ Bw500Cr45Sf128
Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short range.
Definition RH_RF95.h:607
@ Bw125Cr48Sf4096
Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, low data rate, CRC on. Slow+long range.
Definition RH_RF95.h:609
@ Bw125Cr45Sf128
Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range.
Definition RH_RF95.h:606
@ Bw125Cr45Sf2048
Bw = 125 kHz, Cr = 4/5, Sf = 2048chips/symbol, CRC on. Slow+long range.
Definition RH_RF95.h:610
@ Bw31_25Cr48Sf512
Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range.
Definition RH_RF95.h:608
void setSpreadingFactor(uint8_t sf)
Definition RH_RF95.cpp:597
bool _useRFO
Definition RH_RF95.h:876
void setCodingRate4(uint8_t denominator)
Definition RH_RF95.cpp:651
void setModeRx()
Definition RH_RF95.cpp:422
virtual bool send(const uint8_t *data, uint8_t len)
Definition RH_RF95.cpp:338
void setPreambleLength(uint16_t bytes)
Definition RH_RF95.cpp:510
bool setModemConfig(ModemConfigChoice index)
Definition RH_RF95.cpp:498
bool printRegisters()
Definition RH_RF95.cpp:368
virtual uint8_t maxMessageLength()
Definition RH_RF95.cpp:384
Defines register values for a set of modem configuration registers.
Definition RH_RF95.h:583
uint8_t reg_1d
Value for register RH_RF95_REG_1D_MODEM_CONFIG1.
Definition RH_RF95.h:584
uint8_t reg_1e
Value for register RH_RF95_REG_1E_MODEM_CONFIG2.
Definition RH_RF95.h:585
uint8_t reg_26
Value for register RH_RF95_REG_26_MODEM_CONFIG3.
Definition RH_RF95.h:586