MySensors Library & Examples  2.3.2-62-ge298769
RFM95.h
Go to the documentation of this file.
1 /*
2  * The MySensors Arduino library handles the wireless radio link and protocol
3  * between your home built sensors/actuators and HA controller of choice.
4  * The sensors forms a self healing radio network with optional repeaters. Each
5  * repeater and gateway builds a routing tables in EEPROM which keeps track of the
6  * network topology allowing messages to be routed to nodes.
7  *
8  * Created by Henrik Ekblad <[email protected]>
9  * Copyright (C) 2013-2022 Sensnology AB
10  * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
11  *
12  * Documentation: http://www.mysensors.org
13  * Support Forum: http://forum.mysensors.org
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * version 2 as published by the Free Software Foundation.
18  *
19  * Based on Mike McCauley's RFM95 library, Copyright (C) 2014 Mike McCauley <[email protected]>
20  * Radiohead http://www.airspayce.com/mikem/arduino/RadioHead/index.html
21  *
22  * RFM95 driver refactored and optimized for MySensors, Copyright (C) 2017-2018 Olivier Mauti <[email protected]>
23  *
24  * Changelog:
25  * - ACK with sequenceNumber
26  * - ATC control
27  *
28  * Definitions for HopeRF LoRa radios:
29  * http://www.hoperf.com/upload/rf/RFM95_96_97_98W.pdf
30  *
31  */
32 
79 #ifndef _RFM95_h
80 #define _RFM95_h
81 
82 #include "RFM95registers.h"
83 
84 #if !defined(RFM95_SPI)
85 #define RFM95_SPI hwSPI
86 #endif
87 
88 // default PIN assignments, can be overridden
89 #if defined(ARDUINO_ARCH_AVR)
90 #if defined(__AVR_ATmega32U4__)
91 #define DEFAULT_RFM95_IRQ_PIN (3)
92 #else
93 #define DEFAULT_RFM95_IRQ_PIN (2)
94 #endif
95 #elif defined(ARDUINO_ARCH_ESP8266)
96 #define DEFAULT_RFM95_IRQ_PIN (5)
97 #elif defined(ARDUINO_ARCH_ESP32)
98 #define DEFAULT_RFM95_IRQ_PIN (16)
99 #define DEFAULT_RFM95_IRQ_NUM digitalPinToInterrupt(DEFAULT_RFM95_IRQ_PIN)
100 #elif defined(ARDUINO_ARCH_SAMD)
101 #define DEFAULT_RFM95_IRQ_PIN (2)
102 #elif defined(LINUX_ARCH_RASPBERRYPI)
103 #define DEFAULT_RFM95_IRQ_PIN (22)
104 #elif defined(ARDUINO_ARCH_STM32F1)
105 #define DEFAULT_RFM95_IRQ_PIN (PA3)
106 #elif defined(TEENSYDUINO)
107 #define DEFAULT_RFM95_IRQ_PIN (8)
108 #else
109 #define DEFAULT_RFM95_IRQ_PIN (2)
110 #endif
111 
112 #define DEFAULT_RFM95_CS_PIN (SS)
113 
114 // SPI settings
115 #define RFM95_SPI_DATA_ORDER MSBFIRST
116 #define RFM95_SPI_DATA_MODE SPI_MODE0
117 
118 // RFM95 radio configurations: reg_1d, reg_1e, reg_26 (see datasheet)
119 #define RFM95_BW125CR45SF128 RFM95_BW_125KHZ | RFM95_CODING_RATE_4_5, RFM95_SPREADING_FACTOR_128CPS | RFM95_RX_PAYLOAD_CRC_ON, RFM95_AGC_AUTO_ON
120 #define RFM95_BW500CR45SF128 RFM95_BW_500KHZ | RFM95_CODING_RATE_4_5, RFM95_SPREADING_FACTOR_128CPS | RFM95_RX_PAYLOAD_CRC_ON, RFM95_AGC_AUTO_ON
121 #define RFM95_BW31_25CR48SF512 RFM95_BW_31_25KHZ | RFM95_CODING_RATE_4_8, RFM95_SPREADING_FACTOR_512CPS | RFM95_RX_PAYLOAD_CRC_ON, RFM95_AGC_AUTO_ON
122 #define RFM95_BW125CR48SF4096 RFM95_BW_125KHZ | RFM95_CODING_RATE_4_8, RFM95_SPREADING_FACTOR_4096CPS | RFM95_RX_PAYLOAD_CRC_ON, RFM95_AGC_AUTO_ON | RFM95_LOW_DATA_RATE_OPTIMIZE
123 
124 #if !defined(RFM95_RETRY_TIMEOUT_MS)
125 // air-time approximation for timeout, 1 hop ~15 bytes payload - adjust if needed
126 // BW125/SF128: 50ms
127 // BW500/SF128: 15ms
128 // BW31.25/SF512: 900ms
129 // BW125/SF4096: 1500ms
130 #define RFM95_RETRY_TIMEOUT_MS (500ul)
131 #endif
132 
133 #if !defined(MY_RFM95_TX_TIMEOUT_MS)
134 #define MY_RFM95_TX_TIMEOUT_MS (5*1000ul)
135 #endif
136 
137 // Frequency definitions
138 #define RFM95_169MHZ (169000000ul)
139 #define RFM95_315MHZ (315000000ul)
140 #define RFM95_434MHZ (433920000ul)
141 #define RFM95_868MHZ (868100000ul)
142 #define RFM95_915MHZ (915000000ul)
143 
144 #define RFM95_RETRIES (5u)
145 #define RFM95_FIFO_SIZE (0xFFu)
146 #define RFM95_RX_FIFO_ADDR (0x00u)
147 #define RFM95_TX_FIFO_ADDR (0x80u)
148 #define RFM95_MAX_PACKET_LEN (0x40u)
149 #define RFM95_PREAMBLE_LENGTH (8u)
150 #define RFM95_CAD_TIMEOUT_MS (2*1000ul)
151 #define RFM95_POWERUP_DELAY_MS (100u)
152 
153 #define RFM95_PACKET_HEADER_VERSION (1u)
154 #define RFM95_MIN_PACKET_HEADER_VERSION (1u)
155 #define RFM95_BIT_ACK_REQUESTED (7u)
156 #define RFM95_BIT_ACK_RECEIVED (6u)
157 #define RFM95_BIT_ACK_RSSI_REPORT (5u)
158 
159 #define RFM95_BROADCAST_ADDRESS (255u)
160 #define RFM95_ATC_TARGET_RANGE_DBM (2u)
161 #define RFM95_RSSI_OFFSET (137u)
162 #define RFM95_TARGET_RSSI (-70)
163 #define RFM95_PROMISCUOUS (false)
164 
165 #define RFM95_FXOSC (32*1000000ul)
166 #define RFM95_FSTEP (RFM95_FXOSC / 524288.0f)
167 
168 // helper macros
169 #define RFM95_getACKRequested(__value) ((bool)bitRead(__value, RFM95_BIT_ACK_REQUESTED))
170 #define RFM95_setACKRequested(__value, __flag) bitWrite(__value, RFM95_BIT_ACK_REQUESTED,__flag)
171 #define RFM95_getACKReceived(__value) ((bool)bitRead(__value, RFM95_BIT_ACK_RECEIVED))
172 #define RFM95_setACKReceived(__value, __flag) bitWrite(__value, RFM95_BIT_ACK_RECEIVED,__flag)
173 #define RFM95_setACKRSSIReport(__value, __flag) bitWrite(__value, RFM95_BIT_ACK_RSSI_REPORT,__flag)
174 #define RFM95_getACKRSSIReport(__value) ((bool)bitRead(__value, RFM95_BIT_ACK_RSSI_REPORT))
175 #define RFM95_internalToSNR(__value) ((int8_t)(__value / 4))
176 
177 #define RFM95_MIN_POWER_LEVEL_DBM ((rfm95_powerLevel_t)5u)
178 #if defined(MY_RFM95_MAX_POWER_LEVEL_DBM)
179 #define RFM95_MAX_POWER_LEVEL_DBM MY_RFM95_MAX_POWER_LEVEL_DBM
180 #else
181 #define RFM95_MAX_POWER_LEVEL_DBM ((rfm95_powerLevel_t)23u)
182 #endif
183 
186 typedef enum {
193 
197 typedef struct {
198  uint8_t reg_1d;
199  uint8_t reg_1e;
200  uint8_t reg_26;
202 
206 typedef uint16_t rfm95_sequenceNumber_t; // will eventually change to uint8_t in 3.0
210 typedef uint8_t rfm95_RSSI_t;
214 typedef int8_t rfm95_SNR_t;
218 typedef uint8_t rfm95_controlFlags_t;
222 typedef int8_t rfm95_powerLevel_t;
226 typedef struct {
227  uint8_t version;
228  uint8_t recipient;
229  uint8_t sender;
232 } __attribute__((packed)) rfm95_header_t;
233 
237 typedef struct {
238  rfm95_sequenceNumber_t sequenceNumber;
241 } __attribute__((packed)) rfm95_ack_t;
242 
243 
244 #define RFM95_HEADER_LEN sizeof(rfm95_header_t)
245 #define RFM95_MAX_PAYLOAD_LEN (RFM95_MAX_PACKET_LEN - RFM95_HEADER_LEN)
246 
247 
250 typedef struct {
251  union {
252  struct {
253  rfm95_header_t header;
254  union {
255  uint8_t payload[RFM95_MAX_PAYLOAD_LEN];
256  rfm95_ack_t ACK;
257  };
258  };
259  uint8_t data[RFM95_MAX_PACKET_LEN];
260  };
261  uint8_t payloadLen;
262  rfm95_RSSI_t RSSI;
263  rfm95_SNR_t SNR;
264 } __attribute__((packed)) rfm95_packet_t;
265 
266 
270 typedef struct {
271  uint8_t address;
272  rfm95_packet_t currentPacket;
276  // 8 bit
278  bool channelActive : 1;
279  bool ATCenabled : 1;
280  bool ackReceived : 1;
281  bool dataReceived : 1;
282  bool reserved : 1;
284 
285 #define LOCAL static
286 
287 
292 LOCAL bool RFM95_initialise(const uint32_t frequencyHz);
297 LOCAL void RFM95_setAddress(const uint8_t addr);
302 LOCAL uint8_t RFM95_getAddress(void);
313 LOCAL bool RFM95_available(void);
320 LOCAL uint8_t RFM95_receive(uint8_t *buf, const uint8_t maxBufSize);
330 LOCAL bool RFM95_send(const uint8_t recipient, uint8_t *data, const uint8_t len,
331  const rfm95_controlFlags_t flags, const bool increaseSequenceCounter = true);
338 LOCAL bool RFM95_sendFrame(rfm95_packet_t *packet, const bool increaseSequenceCounter = true);
343 LOCAL void RFM95_setPreambleLength(const uint16_t preambleLength);
348 LOCAL void RFM95_setFrequency(const uint32_t frequencyHz);
355 
361 LOCAL bool RFM95_setTxPowerPercent(const uint8_t newPowerPercent);
362 
371 LOCAL void RFM95_enableTCXO(void);
372 
377 LOCAL bool RFM95_sleep(void);
382 LOCAL bool RFM95_standBy(void);
386 LOCAL void RFM95_powerDown(void);
390 LOCAL void RFM95_powerUp(void);
398 LOCAL void RFM95_sendACK(const uint8_t recipient, const rfm95_sequenceNumber_t sequenceNumber,
399  const rfm95_RSSI_t RSSI, const rfm95_SNR_t SNR);
408 LOCAL bool RFM95_sendWithRetry(const uint8_t recipient, const void *buffer,
409  const uint8_t bufferSize, const bool noACK);
414 LOCAL bool RFM95_waitCAD(void);
415 
421 LOCAL bool RFM95_setRadioMode(const rfm95_radioMode_t newRadioMode);
425 LOCAL void RFM95_interruptHandler(void);
426 
430 LOCAL void RFM95_interruptHandling(void);
431 
435 LOCAL void RFM95_handler(void);
440 LOCAL int16_t RFM95_getReceivingRSSI(void);
445 LOCAL int16_t RFM95_getSendingRSSI(void);
450 LOCAL int16_t RFM95_getReceivingSNR(void);
455 LOCAL int16_t RFM95_getSendingSNR(void);
460 LOCAL uint8_t RFM95_getTxPowerPercent(void);
465 LOCAL uint8_t RFM95_getTxPowerLevel(void);
472 LOCAL bool RFM95_executeATC(const rfm95_RSSI_t currentRSSI, const rfm95_RSSI_t targetRSSI);
478 LOCAL void RFM95_ATCmode(const bool OnOff, const int16_t targetRSSI = RFM95_TARGET_RSSI);
483 LOCAL bool RFM95_sanityCheck(void);
484 
485 #endif
486 
rfm95_modemConfig_t
RFM95 modem config registers.
Definition: RFM95.h:197
rfm95_internal_t
RFM95 internal variables.
Definition: RFM95.h:270
data
char data[MAX_PAYLOAD_SIZE+1]
Buffer for raw payload data.
Definition: MyMessage.h:654
rfm95_SNR_t
int8_t rfm95_SNR_t
SNR data type.
Definition: RFM95.h:214
RFM95_RADIO_MODE_TX
@ RFM95_RADIO_MODE_TX
TX mode.
Definition: RFM95.h:188
rfm95_internal_t::ackReceived
bool ackReceived
ACK received.
Definition: RFM95.h:280
RFM95_send
LOCAL bool RFM95_send(const uint8_t recipient, uint8_t *data, const uint8_t len, const rfm95_controlFlags_t flags, const bool increaseSequenceCounter=true)
RFM95_send.
rfm95_controlFlags_t
uint8_t rfm95_controlFlags_t
Control flag data type.
Definition: RFM95.h:218
RFM95_sanityCheck
LOCAL bool RFM95_sanityCheck(void)
RFM95_sanityCheck.
RFM95_setTxPowerPercent
LOCAL bool RFM95_setTxPowerPercent(const uint8_t newPowerPercent)
Sets the transmitter power output percent.
RFM95_getSendingSNR
LOCAL int16_t RFM95_getSendingSNR(void)
RFM95_getSendingSNR.
config
Config file.
Definition: config.h:30
rfm95_internal_t::ATCenabled
bool ATCenabled
ATC enabled.
Definition: RFM95.h:279
rfm95_internal_t::radioMode
rfm95_radioMode_t radioMode
current transceiver state
Definition: RFM95.h:277
RFM95_powerDown
LOCAL void RFM95_powerDown(void)
Powerdown radio, if RFM95_POWER_PIN defined.
RFM95_executeATC
LOCAL bool RFM95_executeATC(const rfm95_RSSI_t currentRSSI, const rfm95_RSSI_t targetRSSI)
RFM_executeATC.
RFM95_setAddress
LOCAL void RFM95_setAddress(const uint8_t addr)
Set the driver/node address.
rfm95_internal_t::currentPacket
rfm95_packet_t currentPacket
Buffer for current packet.
Definition: RFM95.h:272
RFM95_waitCAD
LOCAL bool RFM95_waitCAD(void)
Wait until no channel activity detected.
rfm95_RSSI_t
uint8_t rfm95_RSSI_t
RSSI data type.
Definition: RFM95.h:210
rfm95_sequenceNumber_t
uint16_t rfm95_sequenceNumber_t
Sequence number data type.
Definition: RFM95.h:206
RFM95_standBy
LOCAL bool RFM95_standBy(void)
Sets the radio into standby mode.
RFM95_setTxPowerLevel
LOCAL bool RFM95_setTxPowerLevel(rfm95_powerLevel_t newPowerLevel)
Sets the transmitter power output level, and configures the transmitter pin.
RFM95_sleep
LOCAL bool RFM95_sleep(void)
Sets the radio into low-power sleep mode.
RFM95_interruptHandler
LOCAL void RFM95_interruptHandler(void)
Low level interrupt handler.
RFM95_setModemRegisters
LOCAL void RFM95_setModemRegisters(const rfm95_modemConfig_t *config)
Sets all the registers required to configure the data modem in the RF95/96/97/98, including the bandw...
RFM95_TARGET_RSSI
#define RFM95_TARGET_RSSI
RSSI target.
Definition: RFM95.h:162
rfm95_internal_t::reserved
bool reserved
unused
Definition: RFM95.h:282
__attribute__::ACK
rfm95_ack_t ACK
Union: ACK.
Definition: RFM95.h:256
RFM95_enableTCXO
LOCAL void RFM95_enableTCXO(void)
Enable TCXO mode Call this immediately after init(), to force your radio to use an external frequency...
__attribute__::sequenceNumber
rfm95_sequenceNumber_t sequenceNumber
Packet sequence number, used for ACK.
Definition: RFM95.h:231
RFM95_setPreambleLength
LOCAL void RFM95_setPreambleLength(const uint16_t preambleLength)
RFM95_setPreambleLength.
rfm95_internal_t::ATCtargetRSSI
rfm95_RSSI_t ATCtargetRSSI
ATC: target RSSI.
Definition: RFM95.h:275
rfm95_modemConfig_t::reg_26
uint8_t reg_26
Value for register REG_26_MODEM_CONFIG3.
Definition: RFM95.h:200
RFM95_getAddress
LOCAL uint8_t RFM95_getAddress(void)
Get driver/node address.
__attribute__
struct @4::@5 __attribute__
Doxygen will complain without this comment.
Definition: DigitalPin.h:65
RFM95_RADIO_MODE_CAD
@ RFM95_RADIO_MODE_CAD
CAD mode.
Definition: RFM95.h:189
LOCAL
#define LOCAL
static
Definition: RFM95.h:285
RFM95_MAX_PAYLOAD_LEN
#define RFM95_MAX_PAYLOAD_LEN
Max payload length.
Definition: RFM95.h:245
RFM95_ATCmode
LOCAL void RFM95_ATCmode(const bool OnOff, const int16_t targetRSSI=RFM95_TARGET_RSSI)
RFM95_ATCmode.
RFM95_RADIO_MODE_RX
@ RFM95_RADIO_MODE_RX
RX mode.
Definition: RFM95.h:187
RFM95_setFrequency
LOCAL void RFM95_setFrequency(const uint32_t frequencyHz)
Sets the transmitter and receiver centre frequency.
RFM95_getReceivingSNR
LOCAL int16_t RFM95_getReceivingSNR(void)
RFM95_getReceivingSNR.
__attribute__::header
rfm95_header_t header
LoRa header.
Definition: RFM95.h:253
rfm95_powerLevel_t
int8_t rfm95_powerLevel_t
Power level in dBm.
Definition: RFM95.h:222
RFM95_interruptHandling
LOCAL void RFM95_interruptHandling(void)
Packet engine.
RFM95_getReceivingRSSI
LOCAL int16_t RFM95_getReceivingRSSI(void)
RFM95_getSendingRSSI.
sender
uint8_t sender
8 bit - Id of sender node (origin)
Definition: MyMessage.h:335
__attribute__::RSSI
rfm95_RSSI_t RSSI
RSSI.
Definition: RFM95.h:239
RFM95_sendACK
LOCAL void RFM95_sendACK(const uint8_t recipient, const rfm95_sequenceNumber_t sequenceNumber, const rfm95_RSSI_t RSSI, const rfm95_SNR_t SNR)
RFM95_sendACK.
rfm95_internal_t::txSequenceNumber
rfm95_sequenceNumber_t txSequenceNumber
RFM95_txSequenceNumber.
Definition: RFM95.h:273
rfm95_internal_t::dataReceived
bool dataReceived
Data received.
Definition: RFM95.h:281
RFM95_initialise
LOCAL bool RFM95_initialise(const uint32_t frequencyHz)
Initialise the driver transport hardware and software.
RFM95_getTxPowerLevel
LOCAL uint8_t RFM95_getTxPowerLevel(void)
Get transmitter power level.
rfm95_modemConfig_t::reg_1e
uint8_t reg_1e
Value for register REG_1E_MODEM_CONFIG2.
Definition: RFM95.h:199
RFM95_RADIO_MODE_STDBY
@ RFM95_RADIO_MODE_STDBY
STDBY mode.
Definition: RFM95.h:191
RFM95_handler
LOCAL void RFM95_handler(void)
RFM95_handler.
rfm95_internal_t::powerLevel
rfm95_powerLevel_t powerLevel
TX power level dBm.
Definition: RFM95.h:274
RFM95_available
LOCAL bool RFM95_available(void)
Tests whether a new message is available.
rfm95_modemConfig_t::reg_1d
uint8_t reg_1d
Value for register REG_1D_MODEM_CONFIG1.
Definition: RFM95.h:198
RFM95_sendWithRetry
LOCAL bool RFM95_sendWithRetry(const uint8_t recipient, const void *buffer, const uint8_t bufferSize, const bool noACK)
RFM95_sendWithRetry.
RFM95_getSendingRSSI
LOCAL int16_t RFM95_getSendingRSSI(void)
RFM95_getSendingRSSI.
RFM95_MAX_PACKET_LEN
#define RFM95_MAX_PACKET_LEN
This is the maximum number of bytes that can be carried by the LORA.
Definition: RFM95.h:148
__attribute__::SNR
rfm95_SNR_t SNR
SNR.
Definition: RFM95.h:240
RFM95_getTxPowerPercent
LOCAL uint8_t RFM95_getTxPowerPercent(void)
Get transmitter power level.
__attribute__::controlFlags
rfm95_controlFlags_t controlFlags
Control flags, used for ACK.
Definition: RFM95.h:230
RFM95_powerUp
LOCAL void RFM95_powerUp(void)
Powerup radio, if RFM95_POWER_PIN defined.
RFM95_receive
LOCAL uint8_t RFM95_receive(uint8_t *buf, const uint8_t maxBufSize)
If a valid message is received, copy it to buf and return length. 0 byte messages are permitted.
RFM95_sendFrame
LOCAL bool RFM95_sendFrame(rfm95_packet_t *packet, const bool increaseSequenceCounter=true)
RFM95_sendFrame.
rfm95_internal_t::address
uint8_t address
Node address.
Definition: RFM95.h:271
rfm95_internal_t::channelActive
bool channelActive
RFM95_cad.
Definition: RFM95.h:278
rfm95_radioMode_t
rfm95_radioMode_t
Radio modes.
Definition: RFM95.h:186
RFM95_setRadioMode
LOCAL bool RFM95_setRadioMode(const rfm95_radioMode_t newRadioMode)
RFM95_setRadioMode.
RFM95_RADIO_MODE_SLEEP
@ RFM95_RADIO_MODE_SLEEP
SLEEP mode.
Definition: RFM95.h:190