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.23 2019/11/02 02:34:22 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 /// \class RH_RF95 RH_RF95.h <RH_RF95.h>
247 /// \brief Driver to send and receive unaddressed, unreliable datagrams via a LoRa
248 /// capable radio transceiver.
249 ///
250 /// For Semtech SX1276/77/78/79 and HopeRF RF95/96/97/98 and other similar LoRa capable radios.
251 /// Based on http://www.hoperf.com/upload/rf/RFM95_96_97_98W.pdf
252 /// and http://www.hoperf.cn/upload/rfchip/RF96_97_98.pdf
253 /// and http://www.semtech.com/images/datasheet/LoraDesignGuide_STD.pdf
254 /// and http://www.semtech.com/images/datasheet/sx1276.pdf
255 /// and http://www.semtech.com/images/datasheet/sx1276_77_78_79.pdf
256 /// FSK/GFSK/OOK modes are not (yet) supported.
257 ///
258 /// Works with
259 /// - the excellent MiniWirelessLoRa from Anarduino http://www.anarduino.com/miniwireless
260 /// - The excellent Modtronix inAir4 http://modtronix.com/inair4.html
261 /// and inAir9 modules http://modtronix.com/inair9.html.
262 /// - the excellent Rocket Scream Mini Ultra Pro with the RFM95W
263 /// http://www.rocketscream.com/blog/product/mini-ultra-pro-with-radio/
264 /// - Lora1276 module from NiceRF http://www.nicerf.com/product_view.aspx?id=99
265 /// - Adafruit Feather M0 with RFM95
266 /// - The very fine Talk2 Whisper Node LoRa boards https://wisen.com.au/store/products/whisper-node-lora
267 /// an Arduino compatible board, which include an on-board RFM95/96 LoRa Radio (Semtech SX1276), external antenna,
268 /// run on 2xAAA batteries and support low power operations. RF95 examples work without modification.
269 /// Use Arduino Board Manager to install the Talk2 code support. Upload the code with an FTDI adapter set to 5V.
270 /// - 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
271 ///
272 /// \par Overview
273 ///
274 /// This class provides basic functions for sending and receiving unaddressed,
275 /// unreliable datagrams of arbitrary length to 251 octets per packet.
276 ///
277 /// Manager classes may use this class to implement reliable, addressed datagrams and streams,
278 /// mesh routers, repeaters, translators etc.
279 ///
280 /// Naturally, for any 2 radios to communicate that must be configured to use the same frequency and
281 /// modulation scheme.
282 ///
283 /// This Driver provides an object-oriented interface for sending and receiving data messages with Hope-RF
284 /// RFM95/96/97/98(W), Semtech SX1276/77/78/79 and compatible radio modules in LoRa mode.
285 ///
286 /// The Hope-RF (http://www.hoperf.com) RFM95/96/97/98(W) and Semtech SX1276/77/78/79 is a low-cost ISM transceiver
287 /// chip. It supports FSK, GFSK, OOK over a wide range of frequencies and
288 /// programmable data rates, and it also supports the proprietary LoRA (Long Range) mode, which
289 /// is the only mode supported in this RadioHead driver.
290 ///
291 /// This Driver provides functions for sending and receiving messages of up
292 /// to 251 octets on any frequency supported by the radio, in a range of
293 /// predefined Bandwidths, Spreading Factors and Coding Rates. Frequency can be set with
294 /// 61Hz precision to any frequency from 240.0MHz to 960.0MHz. Caution: most modules only support a more limited
295 /// range of frequencies due to antenna tuning.
296 ///
297 /// Up to 2 modules can be connected to an Arduino (3 on a Mega),
298 /// permitting the construction of translators and frequency changers, etc.
299 ///
300 /// Support for other features such as transmitter power control etc is
301 /// also provided.
302 ///
303 /// Tested on MinWirelessLoRa with arduino-1.0.5
304 /// on OpenSuSE 13.1.
305 /// Also tested with Teensy3.1, Modtronix inAir4 and Arduino 1.6.5 on OpenSuSE 13.1
306 ///
307 /// \par Packet Format
308 ///
309 /// All messages sent and received by this RH_RF95 Driver conform to this packet format:
310 ///
311 /// - LoRa mode:
312 /// - 8 symbol PREAMBLE
313 /// - Explicit header with header CRC (handled internally by the radio)
314 /// - 4 octets HEADER: (TO, FROM, ID, FLAGS)
315 /// - 0 to 251 octets DATA
316 /// - CRC (handled internally by the radio)
317 ///
318 /// \par Connecting RFM95/96/97/98 and Semtech SX1276/77/78/79 to Arduino
319 ///
320 /// We tested with Anarduino MiniWirelessLoRA, which is an Arduino Duemilanove compatible with a RFM96W
321 /// module on-board. Therefore it needs no connections other than the USB
322 /// programming connection and an antenna to make it work.
323 ///
324 /// If you have a bare RFM95/96/97/98 that you want to connect to an Arduino, you
325 /// might use these connections (untested): CAUTION: you must use a 3.3V type
326 /// Arduino, otherwise you will also need voltage level shifters between the
327 /// Arduino and the RFM95. CAUTION, you must also ensure you connect an
328 /// antenna.
329 ///
330 /// \code
331 /// Arduino RFM95/96/97/98
332 /// GND----------GND (ground in)
333 /// 3V3----------3.3V (3.3V in)
334 /// interrupt 0 pin D2-----------DIO0 (interrupt request out)
335 /// SS pin D10----------NSS (CS chip select in)
336 /// SCK pin D13----------SCK (SPI clock in)
337 /// MOSI pin D11----------MOSI (SPI Data in)
338 /// MISO pin D12----------MISO (SPI Data out)
339 /// \endcode
340 /// With these connections, you can then use the default constructor RH_RF95().
341 /// You can override the default settings for the SS pin and the interrupt in
342 /// the RH_RF95 constructor if you wish to connect the slave select SS to other
343 /// than the normal one for your Arduino (D10 for Diecimila, Uno etc and D53
344 /// for Mega) or the interrupt request to other than pin D2 (Caution,
345 /// different processors have different constraints as to the pins available
346 /// for interrupts).
347 ///
348 /// You can connect a Modtronix inAir4 or inAir9 directly to a 3.3V part such as a Teensy 3.1 like
349 /// this (tested).
350 /// \code
351 /// Teensy inAir4 inAir9
352 /// GND----------0V (ground in)
353 /// 3V3----------3.3V (3.3V in)
354 /// interrupt 0 pin D2-----------D0 (interrupt request out)
355 /// SS pin D10----------CS (CS chip select in)
356 /// SCK pin D13----------CK (SPI clock in)
357 /// MOSI pin D11----------SI (SPI Data in)
358 /// MISO pin D12----------SO (SPI Data out)
359 /// \endcode
360 /// With these connections, you can then use the default constructor RH_RF95().
361 /// you must also set the transmitter power with useRFO:
362 /// driver.setTxPower(13, true);
363 ///
364 /// Note that if you are using Modtronix inAir4 or inAir9,or any other module which uses the
365 /// transmitter RFO pins and not the PA_BOOST pins
366 /// that you must configure the power transmitter power for -1 to 14 dBm and with useRFO true.
367 /// Failure to do that will result in extremely low transmit powers.
368 ///
369 /// If you have an Arduino M0 Pro from arduino.org,
370 /// you should note that you cannot use Pin 2 for the interrupt line
371 /// (Pin 2 is for the NMI only). The same comments apply to Pin 4 on Arduino Zero from arduino.cc.
372 /// Instead you can use any other pin (we use Pin 3) and initialise RH_RF69 like this:
373 /// \code
374 /// // Slave Select is pin 10, interrupt is Pin 3
375 /// RH_RF95 driver(10, 3);
376 /// \endcode
377 ///
378 /// If you have a Rocket Scream Mini Ultra Pro with the RFM95W:
379 /// - Ensure you have Arduino SAMD board support 1.6.5 or later in Arduino IDE 1.6.8 or later.
380 /// - The radio SS is hardwired to pin D5 and the DIO0 interrupt to pin D2,
381 /// so you need to initialise the radio like this:
382 /// \code
383 /// RH_RF95 driver(5, 2);
384 /// \endcode
385 /// - The name of the serial port on that board is 'SerialUSB', not 'Serial', so this may be helpful at the top of our
386 /// sample sketches:
387 /// \code
388 /// #define Serial SerialUSB
389 /// \endcode
390 /// - You also need this in setup before radio initialisation
391 /// \code
392 /// // Ensure serial flash is not interfering with radio communication on SPI bus
393 /// pinMode(4, OUTPUT);
394 /// digitalWrite(4, HIGH);
395 /// \endcode
396 /// - and if you have a 915MHz part, you need this after driver/manager intitalisation:
397 /// \code
398 /// rf95.setFrequency(915.0);
399 /// \endcode
400 /// which adds up to modifying sample sketches something like:
401 /// \code
402 /// #include <SPI.h>
403 /// #include <RH_RF95.h>
404 /// RH_RF95 rf95(5, 2); // Rocket Scream Mini Ultra Pro with the RFM95W
405 /// #define Serial SerialUSB
406 ///
407 /// void setup()
408 /// {
409 /// // Ensure serial flash is not interfering with radio communication on SPI bus
410 /// pinMode(4, OUTPUT);
411 /// digitalWrite(4, HIGH);
412 ///
413 /// Serial.begin(9600);
414 /// while (!Serial) ; // Wait for serial port to be available
415 /// if (!rf95.init())
416 /// Serial.println("init failed");
417 /// rf95.setFrequency(915.0);
418 /// }
419 /// ...
420 /// \endcode
421 ///
422 /// For Adafruit Feather M0 with RFM95, construct the driver like this:
423 /// \code
424 /// RH_RF95 rf95(8, 3);
425 /// \endcode
426 ///
427 /// If you have a talk2 Whisper Node LoRa board with on-board RF95 radio,
428 /// the example rf95_* sketches work without modification. Initialise the radio like
429 /// with the default constructor:
430 /// \code
431 /// RH_RF95 driver;
432 /// \endcode
433 ///
434 /// It is possible to have 2 or more radios connected to one Arduino, provided
435 /// each radio has its own SS and interrupt line (SCK, SDI and SDO are common
436 /// to all radios)
437 ///
438 /// Caution: on some Arduinos such as the Mega 2560, if you set the slave
439 /// select pin to be other than the usual SS pin (D53 on Mega 2560), you may
440 /// need to set the usual SS pin to be an output to force the Arduino into SPI
441 /// master mode.
442 ///
443 /// Caution: Power supply requirements of the RFM module may be relevant in some circumstances:
444 /// RFM95/96/97/98 modules are capable of pulling 120mA+ at full power, where Arduino's 3.3V line can
445 /// give 50mA. You may need to make provision for alternate power supply for
446 /// the RFM module, especially if you wish to use full transmit power, and/or you have
447 /// other shields demanding power. Inadequate power for the RFM is likely to cause symptoms such as:
448 /// - reset's/bootups terminate with "init failed" messages
449 /// - random termination of communication after 5-30 packets sent/received
450 /// - "fake ok" state, where initialization passes fluently, but communication doesn't happen
451 /// - shields hang Arduino boards, especially during the flashing
452 ///
453 /// \par Interrupts
454 ///
455 /// The RH_RF95 driver uses interrupts to react to events in the RFM module,
456 /// such as the reception of a new packet, or the completion of transmission
457 /// of a packet. The RH_RF95 driver interrupt service routine reads status from
458 /// and writes data to the the RFM module via the SPI interface. It is very
459 /// important therefore, that if you are using the RH_RF95 driver with another
460 /// SPI based deviced, that you disable interrupts while you transfer data to
461 /// and from that other device. Use cli() to disable interrupts and sei() to
462 /// reenable them.
463 ///
464 /// \par Memory
465 ///
466 /// The RH_RF95 driver requires non-trivial amounts of memory. The sample
467 /// programs all compile to about 8kbytes each, which will fit in the
468 /// flash proram memory of most Arduinos. However, the RAM requirements are
469 /// more critical. Therefore, you should be vary sparing with RAM use in
470 /// programs that use the RH_RF95 driver.
471 ///
472 /// It is often hard to accurately identify when you are hitting RAM limits on Arduino.
473 /// The symptoms can include:
474 /// - Mysterious crashes and restarts
475 /// - Changes in behaviour when seemingly unrelated changes are made (such as adding print() statements)
476 /// - Hanging
477 /// - Output from Serial.print() not appearing
478 ///
479 /// \par Range
480 ///
481 /// We have made some simple range tests under the following conditions:
482 /// - rf95_client base station connected to a VHF discone antenna at 8m height above ground
483 /// - rf95_server mobile connected to 17.3cm 1/4 wavelength antenna at 1m height, no ground plane.
484 /// - Both configured for 13dBm, 434MHz, Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. Slow+long range
485 /// - Minimum reported RSSI seen for successful comms was about -91
486 /// - Range over flat ground through heavy trees and vegetation approx 2km.
487 /// - At 20dBm (100mW) otherwise identical conditions approx 3km.
488 /// - At 20dBm, along salt water flat sandy beach, 3.2km.
489 ///
490 /// It should be noted that at this data rate, a 12 octet message takes 2 seconds to transmit.
491 ///
492 /// At 20dBm (100mW) with Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on.
493 /// (Default medium range) in the conditions described above.
494 /// - Range over flat ground through heavy trees and vegetation approx 2km.
495 ///
496 /// Caution: the performance of this radio, especially with narrow bandwidths is strongly dependent on the
497 /// accuracy and stability of the chip clock. HopeRF and Semtech do not appear to
498 /// recommend bandwidths of less than 62.5 kHz
499 /// unless you have the optional Temperature Compensated Crystal Oscillator (TCXO) installed and
500 /// enabled on your radio module. See the refernece manual for more data.
501 /// Also https://lowpowerlab.com/forum/rf-range-antennas-rfm69-library/lora-library-experiences-range/15/
502 /// and http://www.semtech.com/images/datasheet/an120014-xo-guidance-lora-modulation.pdf
503 ///
504 /// \par Transmitter Power
505 ///
506 /// You can control the transmitter power on the RF transceiver
507 /// with the RH_RF95::setTxPower() function. The argument can be any of
508 /// +5 to +23 (for modules that use PA_BOOST)
509 /// -1 to +14 (for modules that use RFO transmitter pin)
510 /// The default is 13. Eg:
511 /// \code
512 /// driver.setTxPower(10); // use PA_BOOST transmitter pin
513 /// driver.setTxPower(10, true); // use PA_RFO pin transmitter pin
514 /// \endcode
515 ///
516 /// We have made some actual power measurements against
517 /// programmed power for Anarduino MiniWirelessLoRa (which has RFM96W-433Mhz installed)
518 /// - MiniWirelessLoRa RFM96W-433Mhz, USB power
519 /// - 30cm RG316 soldered direct to RFM96W module ANT and GND
520 /// - SMA connector
521 /// - 12db attenuator
522 /// - SMA connector
523 /// - MiniKits AD8307 HF/VHF Power Head (calibrated against Rohde&Schwartz 806.2020 test set)
524 /// - Tektronix TDS220 scope to measure the Vout from power head
525 /// \code
526 /// Program power Measured Power
527 /// dBm dBm
528 /// 5 5
529 /// 7 7
530 /// 9 8
531 /// 11 11
532 /// 13 13
533 /// 15 15
534 /// 17 16
535 /// 19 18
536 /// 20 20
537 /// 21 21
538 /// 22 22
539 /// 23 23
540 /// \endcode
541 ///
542 /// We have also measured the actual power output from a Modtronix inAir4 http://modtronix.com/inair4.html
543 /// connected to a Teensy 3.1:
544 /// Teensy 3.1 this is a 3.3V part, connected directly to:
545 /// Modtronix inAir4 with SMA antenna connector, connected as above:
546 /// 10cm SMA-SMA cable
547 /// - MiniKits AD8307 HF/VHF Power Head (calibrated against Rohde&Schwartz 806.2020 test set)
548 /// - Tektronix TDS220 scope to measure the Vout from power head
549 /// \code
550 /// Program power Measured Power
551 /// dBm dBm
552 /// -1 0
553 /// 1 2
554 /// 3 4
555 /// 5 7
556 /// 7 10
557 /// 9 13
558 /// 11 14.2
559 /// 13 15
560 /// 14 16
561 /// \endcode
562 /// (Caution: we dont claim laboratory accuracy for these power measurements)
563 /// You would not expect to get anywhere near these powers to air with a simple 1/4 wavelength wire antenna.
564 class RH_RF95 : public RHSPIDriver
565 {
566 public:
567  /// \brief Defines register values for a set of modem configuration registers
568  ///
569  /// Defines register values for a set of modem configuration registers
570  /// that can be passed to setModemRegisters() if none of the choices in
571  /// ModemConfigChoice suit your need setModemRegisters() writes the
572  /// register values from this structure to the appropriate registers
573  /// to set the desired spreading factor, coding rate and bandwidth
574  typedef struct
575  {
576  uint8_t reg_1d; ///< Value for register RH_RF95_REG_1D_MODEM_CONFIG1
577  uint8_t reg_1e; ///< Value for register RH_RF95_REG_1E_MODEM_CONFIG2
578  uint8_t reg_26; ///< Value for register RH_RF95_REG_26_MODEM_CONFIG3
579  } ModemConfig;
580 
581  /// Choices for setModemConfig() for a selected subset of common
582  /// data rates. If you need another configuration,
583  /// determine the necessary settings and call setModemRegisters() with your
584  /// desired settings. It might be helpful to use the LoRa calculator mentioned in
585  /// http://www.semtech.com/images/datasheet/LoraDesignGuide_STD.pdf
586  /// These are indexes into MODEM_CONFIG_TABLE. We strongly recommend you use these symbolic
587  /// definitions and not their integer equivalents: its possible that new values will be
588  /// introduced in later versions (though we will try to avoid it).
589  /// Caution: if you are using slow packet rates and long packets with RHReliableDatagram or subclasses
590  /// you may need to change the RHReliableDatagram timeout for reliable operations.
591  /// Caution: for some slow rates nad with ReliableDatagrams youi may need to increase the reply timeout
592  /// with manager.setTimeout() to
593  /// deal with the long transmission times.
594  typedef enum
595  {
596  Bw125Cr45Sf128 = 0, ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range
597  Bw500Cr45Sf128, ///< Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short range
598  Bw31_25Cr48Sf512, ///< Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range
599  Bw125Cr48Sf4096, ///< Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. Slow+long range
601 
602  /// Constructor. You can have multiple instances, but each instance must have its own
603  /// interrupt and slave select pin. After constructing, you must call init() to initialise the interface
604  /// and the radio module. A maximum of 3 instances can co-exist on one processor, provided there are sufficient
605  /// distinct interrupt lines, one for each instance.
606  /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the RH_RF22 before
607  /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega, D10 for Maple)
608  /// \param[in] interruptPin The interrupt Pin number that is connected to the RFM DIO0 interrupt line.
609  /// Defaults to pin 2, as required by Anarduino MinWirelessLoRa module.
610  /// Caution: You must specify an interrupt capable pin.
611  /// On many Arduino boards, there are limitations as to which pins may be used as interrupts.
612  /// On Leonardo pins 0, 1, 2 or 3. On Mega2560 pins 2, 3, 18, 19, 20, 21. On Due and Teensy, any digital pin.
613  /// On Arduino Zero from arduino.cc, any digital pin other than 4.
614  /// On Arduino M0 Pro from arduino.org, any digital pin other than 2.
615  /// On other Arduinos pins 2 or 3.
616  /// See http://arduino.cc/en/Reference/attachInterrupt for more details.
617  /// On Chipkit Uno32, pins 38, 2, 7, 8, 35.
618  /// On other boards, any digital pin may be used.
619  /// \param[in] spi Pointer to the SPI interface object to use.
620  /// Defaults to the standard Arduino hardware SPI interface
621  RH_RF95(uint8_t slaveSelectPin = SS, uint8_t interruptPin = 2, RHGenericSPI& spi = hardware_spi);
622 
623  /// Initialise the Driver transport hardware and software.
624  /// Make sure the Driver is properly configured before calling init().
625  /// \return true if initialisation succeeded.
626  virtual bool init();
627 
628  /// Prints the value of all chip registers
629  /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform
630  /// For debugging purposes only.
631  /// \return true on success
632  bool printRegisters();
633 
634  /// Sets all the registered required to configure the data modem in the RF95/96/97/98, including the bandwidth,
635  /// spreading factor etc. You can use this to configure the modem with custom configurations if none of the
636  /// canned configurations in ModemConfigChoice suit you.
637  /// \param[in] config A ModemConfig structure containing values for the modem configuration registers.
638  void setModemRegisters(const ModemConfig* config);
639 
640  /// Select one of the predefined modem configurations. If you need a modem configuration not provided
641  /// here, use setModemRegisters() with your own ModemConfig.
642  /// Caution: the slowest protocols may require a radio module with TCXO temperature controlled oscillator
643  /// for reliable operation.
644  /// \param[in] index The configuration choice.
645  /// \return true if index is a valid choice.
646  bool setModemConfig(ModemConfigChoice index);
647 
648  /// Tests whether a new message is available
649  /// from the Driver.
650  /// On most drivers, this will also put the Driver into RHModeRx mode until
651  /// a message is actually received by the transport, when it wil be returned to RHModeIdle.
652  /// This can be called multiple times in a timeout loop
653  /// \return true if a new, complete, error-free uncollected message is available to be retreived by recv()
654  virtual bool available();
655 
656  /// Turns the receiver on if it not already on.
657  /// If there is a valid message available, copy it to buf and return true
658  /// else return false.
659  /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
660  /// You should be sure to call this function frequently enough to not miss any messages
661  /// It is recommended that you call it in your main loop.
662  /// \param[in] buf Location to copy the received message
663  /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.
664  /// \return true if a valid message was copied to buf
665  virtual bool recv(uint8_t* buf, uint8_t* len);
666 
667  /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().
668  /// Then optionally waits for Channel Activity Detection (CAD)
669  /// to show the channnel is clear (if the radio supports CAD) by calling waitCAD().
670  /// Then loads a message into the transmitter and starts the transmitter. Note that a message length
671  /// of 0 is permitted.
672  /// \param[in] data Array of data to be sent
673  /// \param[in] len Number of bytes of data to send
674  /// specify the maximum time in ms to wait. If 0 (the default) do not wait for CAD before transmitting.
675  /// \return true if the message length was valid and it was correctly queued for transmit. Return false
676  /// if CAD was requested and the CAD timeout timed out before clear channel was detected.
677  virtual bool send(const uint8_t* data, uint8_t len);
678 
679  /// Sets the length of the preamble
680  /// in bytes.
681  /// Caution: this should be set to the same
682  /// value on all nodes in your network. Default is 8.
683  /// Sets the message preamble length in RH_RF95_REG_??_PREAMBLE_?SB
684  /// \param[in] bytes Preamble length in bytes.
685  void setPreambleLength(uint16_t bytes);
686 
687  /// Returns the maximum message length
688  /// available in this Driver.
689  /// \return The maximum legal message length
690  virtual uint8_t maxMessageLength();
691 
692  /// Sets the transmitter and receiver
693  /// centre frequency.
694  /// \param[in] centre Frequency in MHz. 137.0 to 1020.0. Caution: RFM95/96/97/98 comes in several
695  /// different frequency ranges, and setting a frequency outside that range of your radio will probably not work
696  /// \return true if the selected frquency centre is within range
697  bool setFrequency(float centre);
698 
699  /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running,
700  /// disables them.
701  void setModeIdle();
702 
703  /// If current mode is Tx or Idle, changes it to Rx.
704  /// Starts the receiver in the RF95/96/97/98.
705  void setModeRx();
706 
707  /// If current mode is Rx or Idle, changes it to Rx. F
708  /// Starts the transmitter in the RF95/96/97/98.
709  void setModeTx();
710 
711  /// Sets the transmitter power output level, and configures the transmitter pin.
712  /// Be a good neighbour and set the lowest power level you need.
713  /// Some SX1276/77/78/79 and compatible modules (such as RFM95/96/97/98)
714  /// use the PA_BOOST transmitter pin for high power output (and optionally the PA_DAC)
715  /// while some (such as the Modtronix inAir4 and inAir9)
716  /// use the RFO transmitter pin for lower power but higher efficiency.
717  /// You must set the appropriate power level and useRFO argument for your module.
718  /// Check with your module manufacturer which transmtter pin is used on your module
719  /// to ensure you are setting useRFO correctly.
720  /// Failure to do so will result in very low
721  /// transmitter power output.
722  /// Caution: legal power limits may apply in certain countries.
723  /// After init(), the power will be set to 13dBm, with useRFO false (ie PA_BOOST enabled).
724  /// \param[in] power Transmitter power level in dBm. For RFM95/96/97/98 LORA with useRFO false,
725  /// valid values are from +5 to +23.
726  /// For Modtronix inAir4 and inAir9 with useRFO true (ie RFO pins in use),
727  /// valid values are from -1 to 14.
728  /// \param[in] useRFO If true, enables the use of the RFO transmitter pins instead of
729  /// the PA_BOOST pin (false). Choose the correct setting for your module.
730  void setTxPower(int8_t power, bool useRFO = false);
731 
732  /// Sets the radio into low-power sleep mode.
733  /// If successful, the transport will stay in sleep mode until woken by
734  /// changing mode it idle, transmit or receive (eg by calling send(), recv(), available() etc)
735  /// Caution: there is a time penalty as the radio takes a finite time to wake from sleep mode.
736  /// \return true if sleep mode was successfully entered.
737  virtual bool sleep();
738 
739  // Bent G Christensen (bentor@gmail.com), 08/15/2016
740  /// Use the radio's Channel Activity Detect (CAD) function to detect channel activity.
741  /// Sets the RF95 radio into CAD mode and waits until CAD detection is complete.
742  /// To be used in a listen-before-talk mechanism (Collision Avoidance)
743  /// with a reasonable time backoff algorithm.
744  /// This is called automatically by waitCAD().
745  /// \return true if channel is in use.
746  virtual bool isChannelActive();
747 
748  /// Enable TCXO mode
749  /// Call this immediately after init(), to force your radio to use an external
750  /// frequency source, such as a Temperature Compensated Crystal Oscillator (TCXO), if available.
751  /// See the comments in the main documentation about the sensitivity of this radio to
752  /// clock frequency especially when using narrow bandwidths.
753  /// Leaves the module in sleep mode.
754  /// Caution, this function has not been tested by us.
755  /// Caution, the TCXO model radios are not low power when in sleep (consuming
756  /// about ~600 uA, reported by Phang Moh Lim.<br>
757  void enableTCXO();
758 
759  /// Returns the last measured frequency error.
760  /// The LoRa receiver estimates the frequency offset between the receiver centre frequency
761  /// and that of the received LoRa signal. This function returns the estimates offset (in Hz)
762  /// of the last received message. Caution: this measurement is not absolute, but is measured
763  /// relative to the local receiver's oscillator.
764  /// Apparent errors may be due to the transmitter, the receiver or both.
765  /// \return The estimated centre frequency offset in Hz of the last received message.
766  /// If the modem bandwidth selector in
767  /// register RH_RF95_REG_1D_MODEM_CONFIG1 is invalid, returns 0.
768  int frequencyError();
769 
770  /// Returns the Signal-to-noise ratio (SNR) of the last received message, as measured
771  /// by the receiver.
772  /// \return SNR of the last received message in dB
773  int lastSNR();
774 
775  /// brian.n.norman@gmail.com 9th Nov 2018
776  /// Sets the radio spreading factor.
777  /// valid values are 6 through 12.
778  /// Out of range values below 6 are clamped to 6
779  /// Out of range values above 12 are clamped to 12
780  /// See Semtech DS SX1276/77/78/79 page 27 regarding SF6 configuration.
781  ///
782  /// \param[in] uint8_t sf (spreading factor 6..12)
783  /// \return nothing
784  void setSpreadingFactor(uint8_t sf);
785 
786  /// brian.n.norman@gmail.com 9th Nov 2018
787  /// Sets the radio signal bandwidth
788  /// sbw ranges and resultant settings are as follows:-
789  /// sbw range actual bw (kHz)
790  /// 0-7800 7.8
791  /// 7801-10400 10.4
792  /// 10401-15600 15.6
793  /// 15601-20800 20.8
794  /// 20801-31250 31.25
795  /// 31251-41700 41.7
796  /// 41701-62500 62.5
797  /// 62501-12500 125.0
798  /// 12501-250000 250.0
799  /// >250000 500.0
800  /// NOTE caution Earlier - Semtech do not recommend BW below 62.5 although, in testing
801  /// I managed 31.25 with two devices in close proximity.
802  /// \param[in] sbw long, signal bandwidth e.g. 125000
803  void setSignalBandwidth(long sbw);
804 
805  /// brian.n.norman@gmail.com 9th Nov 2018
806  /// Sets the coding rate to 4/5, 4/6, 4/7 or 4/8.
807  /// Valid denominator values are 5, 6, 7 or 8. A value of 5 sets the coding rate to 4/5 etc.
808  /// Values below 5 are clamped at 5
809  /// values above 8 are clamped at 8
810  /// \param[in] denominator uint8_t range 5..8
811  void setCodingRate4(uint8_t denominator);
812 
813  /// brian.n.norman@gmail.com 9th Nov 2018
814  /// sets the low data rate flag if symbol time exceeds 16ms
815  /// ref: https://www.thethingsnetwork.org/forum/t/a-point-to-note-lora-low-data-rate-optimisation-flag/12007
816  /// called by setBandwidth() and setSpreadingfactor() since these affect the symbol time.
817  void setLowDatarate();
818 
819  /// brian.n.norman@gmail.com 9th Nov 2018
820  /// allows the payload CRC bit to be turned on/off. Normally this should be left on
821  /// so that packets with a bad CRC are rejected
822  /// \patam[in] on bool, true turns the payload CRC on, false turns it off
823  void setPayloadCRC(bool on);
824 
825 protected:
826  /// This is a low level function to handle the interrupts for one instance of RH_RF95.
827  /// Called automatically by isr*()
828  /// Should not need to be called by user code.
829  void handleInterrupt();
830 
831  /// Examine the revceive buffer to determine whether the message is for this node
832  void validateRxBuf();
833 
834  /// Clear our local receive buffer
835  void clearRxBuf();
836 
837 private:
838  /// Low level interrupt service routine for device connected to interrupt 0
839  static void isr0();
840 
841  /// Low level interrupt service routine for device connected to interrupt 1
842  static void isr1();
843 
844  /// Low level interrupt service routine for device connected to interrupt 1
845  static void isr2();
846 
847  /// Array of instances connected to interrupts 0 and 1
848  static RH_RF95* _deviceForInterrupt[];
849 
850  /// Index of next interrupt number to use in _deviceForInterrupt
851  static uint8_t _interruptCount;
852 
853  /// The configured interrupt pin connected to this instance
854  uint8_t _interruptPin;
855 
856  /// The index into _deviceForInterrupt[] for this device (if an interrupt is already allocated)
857  /// else 0xff
858  uint8_t _myInterruptIndex;
859 
860  /// Number of octets in the buffer
861  volatile uint8_t _bufLen;
862 
863  /// The receiver/transmitter buffer
864  uint8_t _buf[RH_RF95_MAX_PAYLOAD_LEN];
865 
866  /// True when there is a valid message in the buffer
867  volatile bool _rxBufValid;
868 
869  // True if we are using the HF port (779.0 MHz and above)
870  bool _usingHFport;
871 
872  // Last measured SNR, dB
873  int8_t _lastSNR;
874 };
875 
876 /// @example rf95_client.pde
877 /// @example rf95_server.pde
878 /// @example rf95_encrypted_client.pde
879 /// @example rf95_encrypted_server.pde
880 /// @example rf95_reliable_datagram_client.pde
881 /// @example rf95_reliable_datagram_server.pde
882 
883 #endif
884 
RH_RF95::setFrequency
bool setFrequency(float centre)
Definition: RH_RF95.cpp:308
RHGenericDriver::_rxGood
volatile uint16_t _rxGood
Count of the number of successfully transmitted messaged.
Definition: RHGenericDriver.h:292
RH_RF95::ModemConfig::reg_1d
uint8_t reg_1d
Value for register RH_RF95_REG_1D_MODEM_CONFIG1.
Definition: RH_RF95.h:576
RH_RF95::RH_RF95
RH_RF95(uint8_t slaveSelectPin=SS, uint8_t interruptPin=2, RHGenericSPI &spi=hardware_spi)
Definition: RH_RF95.cpp:26
RH_RF95::setModeRx
void setModeRx()
Definition: RH_RF95.cpp:339
RH_RF95::ModemConfigChoice
ModemConfigChoice
Definition: RH_RF95.h:594
RH_RF95::setSignalBandwidth
void setSignalBandwidth(long sbw)
Definition: RH_RF95.cpp:521
RHGenericSPI
Base class for SPI interfaces.
Definition: RHGenericSPI.h:30
RHGenericDriver::RHModeCad
@ RHModeCad
Transport is in the process of detecting channel activity (if supported)
Definition: RHGenericDriver.h:55
RHGenericDriver::_rxHeaderFrom
volatile uint8_t _rxHeaderFrom
FROM header in the last received mesasge.
Definition: RHGenericDriver.h:265
RH_RF95::lastSNR
int lastSNR()
Definition: RH_RF95.cpp:483
RH_RF95::setModeIdle
void setModeIdle()
Definition: RH_RF95.cpp:320
RHSPIDriver::spiWrite
uint8_t spiWrite(uint8_t reg, uint8_t val)
Definition: RHSPIDriver.cpp:42
RHSPIDriver
Base class for RadioHead drivers that use the SPI bus to communicate with its transport hardware.
Definition: RHSPIDriver.h:38
RH_RF95::validateRxBuf
void validateRxBuf()
Examine the revceive buffer to determine whether the message is for this node.
Definition: RH_RF95.cpp:209
RHGenericDriver::_lastRssi
volatile int16_t _lastRssi
The value of the last received RSSI value, in some transport specific units.
Definition: RHGenericDriver.h:286
RHGenericDriver::_rxBad
volatile uint16_t _rxBad
Count of the number of bad messages (eg bad checksum etc) received.
Definition: RHGenericDriver.h:289
RH_RF95::setCodingRate4
void setCodingRate4(uint8_t denominator)
Definition: RH_RF95.cpp:552
RHGenericDriver::_rxHeaderTo
volatile uint8_t _rxHeaderTo
TO header in the last received mesasge.
Definition: RHGenericDriver.h:262
RH_RF95::printRegisters
bool printRegisters()
Definition: RH_RF95.cpp:287
RHGenericDriver::_txHeaderFrom
uint8_t _txHeaderFrom
FROM header to send in all messages.
Definition: RHGenericDriver.h:277
RH_RF95::setLowDatarate
void setLowDatarate()
Definition: RH_RF95.cpp:569
RH_RF95::frequencyError
int frequencyError()
Definition: RH_RF95.cpp:456
RH_RF95::available
virtual bool available()
Definition: RH_RF95.cpp:227
RHSPIDriver::spiUsingInterrupt
void spiUsingInterrupt(uint8_t interruptNumber)
Definition: RHSPIDriver.cpp:91
RHGenericDriver::_thisAddress
uint8_t _thisAddress
This node id.
Definition: RHGenericDriver.h:256
RHGenericDriver::_txGood
volatile uint16_t _txGood
Count of the number of bad messages (correct checksum etc) received.
Definition: RHGenericDriver.h:295
RH_RF95::init
virtual bool init()
Definition: RH_RF95.cpp:35
RHGenericDriver::_promiscuous
bool _promiscuous
Whether the transport is in promiscuous mode.
Definition: RHGenericDriver.h:259
RHGenericDriver::_rxHeaderFlags
volatile uint8_t _rxHeaderFlags
FLAGS header in the last received mesasge.
Definition: RHGenericDriver.h:271
RH_RF95::setModeTx
void setModeTx()
Definition: RH_RF95.cpp:349
RH_RF95::ModemConfig
Defines register values for a set of modem configuration registers.
Definition: RH_RF95.h:574
RH_RF95::isChannelActive
virtual bool isChannelActive()
Definition: RH_RF95.cpp:429
RHSPIDriver::spiBurstRead
uint8_t spiBurstRead(uint8_t reg, uint8_t *dest, uint8_t len)
Definition: RHSPIDriver.cpp:56
RHGenericDriver::RHModeSleep
@ RHModeSleep
Transport hardware is in low power sleep mode (if supported)
Definition: RHGenericDriver.h:51
RHSPIDriver::spiBurstWrite
uint8_t spiBurstWrite(uint8_t reg, const uint8_t *src, uint8_t len)
Definition: RHSPIDriver.cpp:71
RH_RF95::Bw125Cr45Sf128
@ Bw125Cr45Sf128
Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range.
Definition: RH_RF95.h:596
RHSPIDriver::init
bool init()
Definition: RHSPIDriver.cpp:15
RH_RF95::setPreambleLength
void setPreambleLength(uint16_t bytes)
Definition: RH_RF95.cpp:423
RH_RF95::setSpreadingFactor
void setSpreadingFactor(uint8_t sf)
Definition: RH_RF95.cpp:498
RH_RF95::enableTCXO
void enableTCXO()
Definition: RH_RF95.cpp:445
RH_RF95::send
virtual bool send(const uint8_t *data, uint8_t len)
Definition: RH_RF95.cpp:260
RH_RF95::Bw31_25Cr48Sf512
@ Bw31_25Cr48Sf512
Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range.
Definition: RH_RF95.h:598
RHGenericDriver::_cad
volatile bool _cad
Channel activity detected.
Definition: RHGenericDriver.h:298
RH_RF95::Bw125Cr48Sf4096
@ Bw125Cr48Sf4096
Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. Slow+long range.
Definition: RH_RF95.h:599
RHGenericDriver::_txHeaderId
uint8_t _txHeaderId
ID header to send in all messages.
Definition: RHGenericDriver.h:280
RHGenericDriver::_txHeaderTo
uint8_t _txHeaderTo
TO header to send in all messages.
Definition: RHGenericDriver.h:274
RH_RF95::ModemConfig::reg_1e
uint8_t reg_1e
Value for register RH_RF95_REG_1E_MODEM_CONFIG2.
Definition: RH_RF95.h:577
RH_RF95::maxMessageLength
virtual uint8_t maxMessageLength()
Definition: RH_RF95.cpp:303
RHGenericDriver::_txHeaderFlags
uint8_t _txHeaderFlags
FLAGS header to send in all messages.
Definition: RHGenericDriver.h:283
RH_RF95::ModemConfig::reg_26
uint8_t reg_26
Value for register RH_RF95_REG_26_MODEM_CONFIG3.
Definition: RH_RF95.h:578
RHGenericDriver::_rxHeaderId
volatile uint8_t _rxHeaderId
ID header in the last received mesasge.
Definition: RHGenericDriver.h:268
RH_RF95::clearRxBuf
void clearRxBuf()
Clear our local receive buffer.
Definition: RH_RF95.cpp:235
RH_RF95::sleep
virtual bool sleep()
Definition: RH_RF95.cpp:329
RH_RF95::setModemRegisters
void setModemRegisters(const ModemConfig *config)
Definition: RH_RF95.cpp:402
RHGenericDriver::RHModeIdle
@ RHModeIdle
Transport is idle.
Definition: RHGenericDriver.h:52
RH_RF95::setModemConfig
bool setModemConfig(ModemConfigChoice index)
Definition: RH_RF95.cpp:411
RH_RF95::handleInterrupt
void handleInterrupt()
Definition: RH_RF95.cpp:124
RHSPIDriver::spiRead
uint8_t spiRead(uint8_t reg)
Definition: RHSPIDriver.cpp:30
RHGenericDriver::waitPacketSent
virtual bool waitPacketSent()
Definition: RHGenericDriver.cpp:52
RHGenericDriver::_mode
volatile RHMode _mode
The current transport operating mode.
Definition: RHGenericDriver.h:253
RH_RF95::recv
virtual bool recv(uint8_t *buf, uint8_t *len)
Definition: RH_RF95.cpp:243
RHGenericDriver::RHModeTx
@ RHModeTx
Transport is in the process of transmitting a message.
Definition: RHGenericDriver.h:53
RH_RF95::Bw500Cr45Sf128
@ Bw500Cr45Sf128
Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short range.
Definition: RH_RF95.h:597
RHGenericDriver::RHModeRx
@ RHModeRx
Transport is in the process of receiving a message.
Definition: RHGenericDriver.h:54
RHGenericDriver::waitCAD
virtual bool waitCAD()
Definition: RHGenericDriver.cpp:72
RH_RF95
Driver to send and receive unaddressed, unreliable datagrams via a LoRa capable radio transceiver.
Definition: RH_RF95.h:564
RH_RF95::setTxPower
void setTxPower(int8_t power, bool useRFO=false)
Definition: RH_RF95.cpp:359
RH_RF95::setPayloadCRC
void setPayloadCRC(bool on)
Definition: RH_RF95.cpp:603