RadioHead
RadioHead.h
1 // RadioHead.h
2 // Author: Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY
3 // Copyright (C) 2014 Mike McCauley
4 // $Id: RadioHead.h,v 1.81 2020/01/07 23:35:02 mikem Exp mikem $
5 
6 /*! \mainpage RadioHead Packet Radio library for embedded microprocessors
7 
8 This is the RadioHead Packet Radio library for embedded microprocessors.
9 It provides a complete object-oriented library for sending and receiving packetized messages
10 via a variety of common data radios and other transports on a range of embedded microprocessors.
11 
12 The version of the package that this documentation refers to can be downloaded
13 from http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.100.zip
14 You can find the latest version of the documentation at http://www.airspayce.com/mikem/arduino/RadioHead
15 
16 You can also find online help and discussion at
17 http://groups.google.com/group/radiohead-arduino
18 Please use that group for all questions and discussions on this topic.
19 Do not contact the author directly, unless it is to discuss commercial licensing.
20 Before asking a question or reporting a bug, please read
21 - http://en.wikipedia.org/wiki/Wikipedia:Reference_desk/How_to_ask_a_software_question
22 - http://www.catb.org/esr/faqs/smart-questions.html
23 - http://www.chiark.greenend.org.uk/~shgtatham/bugs.html
24 
25 Caution: Developing this type of software and using data radios
26 successfully is challenging and requires a substantial knowledge
27 base in software and radio and data transmission technologies and
28 theory. It may not be an appropriate project for beginners. If
29 you are a beginner, you will need to spend some time gaining
30 knowledge in these areas first.
31 
32 \par Overview
33 
34 RadioHead consists of 2 main sets of classes: Drivers and Managers.
35 
36 - Drivers provide low level access to a range of different packet radios and other packetized message transports.
37 - Managers provide high level message sending and receiving facilities for a range of different requirements.
38 
39 Every RadioHead program will have an instance of a Driver to
40 provide access to the data radio or transport, and usually a
41 Manager that uses that driver to send and receive messages for the
42 application. The programmer is required to instantiate a Driver
43 and a Manager, and to initialise the Manager. Thereafter the
44 facilities of the Manager can be used to send and receive
45 messages.
46 
47 It is also possible to use a Driver on its own, without a Manager, although this only allows unaddressed,
48 unreliable transport via the Driver's facilities.
49 
50 In some specialised use cases, it is possible to instantiate more than one Driver and more than one Manager.
51 
52 A range of different common embedded microprocessor platforms are supported, allowing your project to run
53 on your choice of processor.
54 
55 Example programs are included to show the main modes of use.
56 
57 \par Drivers
58 
59 The following Drivers are provided:
60 
61 - RH_RF22
62 Works with Hope-RF
63 RF22B and RF23B based transceivers, and compatible chips and modules,
64 including the RFM22B transceiver module such as
65 hthis bare module: http://www.sparkfun.com/products/10153
66 and this shield: http://www.sparkfun.com/products/11018
67 and this board: http://www.anarduino.com/miniwireless
68 and RF23BP modules such as: http://www.anarduino.com/details.jsp?pid=130
69 Supports GFSK, FSK and OOK. Access to other chip
70 features such as on-chip temperature measurement, analog-digital
71 converter, transmitter power control etc is also provided.
72 
73 - RH_RF24
74 Works with Silicon Labs Si4460/4461/4463/4464 family of transceivers chip, and the equivalent
75 HopeRF RF24/26/27 family of chips and the HopeRF RFM24W/26W/27W modules.
76 Supports GFSK, FSK and OOK. Access to other chip
77 features such as on-chip temperature measurement, analog-digital
78 converter, transmitter power control etc is also provided.
79 
80 - RH_RF69
81 Works with Hope-RF
82 RF69B based radio modules, such as the RFM69 module, (as used on the excellent Moteino and Moteino-USB
83 boards from LowPowerLab http://lowpowerlab.com/moteino/ )
84 and compatible chips and modules such as RFM69W, RFM69HW, RFM69CW, RFM69HCW (Semtech SX1231, SX1231H).
85 Also works with Anarduino MiniWireless -CW and -HW boards http://www.anarduino.com/miniwireless/ including
86 the marvellous high powered MinWireless-HW (with 20dBm output for excellent range).
87 Supports GFSK, FSK.
88 
89 - RH_NRF24
90 Works with Nordic nRF24 based 2.4GHz radio modules, such as nRF24L01 and others.
91 Also works with Hope-RF RFM73
92 and compatible devices (such as BK2423). nRF24L01 and RFM73 can interoperate
93 with each other.
94 
95 - RH_NRF905
96 Works with Nordic nRF905 based 433/868/915 MHz radio modules.
97 
98 - RH_NRF51
99 Works with Nordic nRF51 compatible 2.4 GHz SoC/devices such as the nRF51822.
100 Also works with Sparkfun nRF52832 breakout board, with Arduino 1.8.9 and
101 Sparkfun nRF52 boards manager 0.2.3. Caution: although RadioHead compiles with nRF52832 as at 2020-03-12
102 there appears to be a problem with the support of interupt handlers in the Sparkfun support libraries,
103 and drivers (ie most of the other SPI based radio drivers) that require interrupts do not work correctly.
104 
105 - RH_RF95
106 Works with Semtech SX1276/77/78/79, Modtronix inAir4 and inAir9,
107 and HopeRF RFM95/96/97/98 and other similar LoRa capable radios.
108 Supports Long Range (LoRa) with spread spectrum frequency hopping, large payloads etc.
109 FSK/GFSK/OOK modes are not (yet) supported.
110 
111 - RH_MRF89
112 Works with Microchip MRF89XA and compatible transceivers.
113 and modules such as MRF89XAM9A.
114 
115 - RH_CC110
116 Works with Texas Instruments CC110L transceivers and compatible modules such as
117 Anaren AIR BoosterPack 430BOOST-CC110L
118 
119 - RH_E32
120 Works with EBYTE E32-TTL-1W serial radio transceivers (and possibly other transceivers in the same family)
121 
122 - RH_ASK
123 Works with a range of inexpensive ASK (amplitude shift keying) RF transceivers such as RX-B1
124 (also known as ST-RX04-ASK) receiver; TX-C1 transmitter and DR3100 transceiver; FS1000A/XY-MK-5V transceiver;
125 HopeRF RFM83C / RFM85. Supports ASK (OOK).
126 
127 - RH_Serial
128 Works with RS232, RS422, RS485, RS488 and other point-to-point and multidropped serial connections,
129 or with TTL serial UARTs such as those on Arduino and many other processors,
130 or with data radios with a
131 serial port interface. RH_Serial provides packetization and error detection over any hardware or
132 virtual serial connection. Also builds and runs on Linux and OSX.
133 
134 - RH_TCP
135 For use with simulated sketches compiled and running on Linux.
136 Works with tools/etherSimulator.pl to pass messages between simulated sketches, allowing
137 testing of Manager classes on Linux and without need for real radios or other transport hardware.
138 
139 - RHEncryptedDriver
140 Adds encryption and decryption to any RadioHead transport driver, using any encrpytion cipher
141 supported by ArduinoLibs Cryptographic Library http://rweather.github.io/arduinolibs/crypto.html
142 
143 Drivers can be used on their own to provide unaddressed, unreliable datagrams.
144 All drivers have the same identical API.
145 Or you can use any Driver with any of the Managers described below.
146 
147 We welcome contributions of well tested and well documented code to support other transports.
148 
149 If your radio or transciever is not on the list above, there is a good chance it
150 wont work without modifying RadioHead to suit it. If you wish for
151 support for another radio or transciever, and you send 2 of them to
152 AirSpayce Pty Ltd, we will consider adding support for it.
153 
154 \par Managers
155 
156 The drivers above all provide for unaddressed, unreliable, variable
157 length messages, but if you need more than that, the following
158 Managers are provided:
159 
160 - RHDatagram
161 Addressed, unreliable variable length messages, with optional broadcast facilities.
162 
163 - RHReliableDatagram
164 Addressed, reliable, retransmitted, acknowledged variable length messages.
165 
166 - RHRouter
167 Multi-hop delivery of RHReliableDatagrams from source node to destination node via 0 or more
168 intermediate nodes, with manual, pre-programmed routing.
169 
170 - RHMesh
171 Multi-hop delivery of RHReliableDatagrams with automatic route discovery and rediscovery.
172 
173 Any Manager may be used with any Driver.
174 
175 \par Platforms
176 
177 A range of processors and platforms are supported:
178 
179 - Arduino and the Arduino IDE (version 1.0 to 1.8.1 and later)
180 Including Diecimila, Uno, Mega, Leonardo, Yun, Due, Zero etc. http://arduino.cc/, Also similar boards such as
181  - Moteino http://lowpowerlab.com/moteino/
182  - Anarduino Mini http://www.anarduino.com/mini/
183  - RedBearLab Blend V1.0 http://redbearlab.com/blend/ (with Arduino 1.0.5 and RedBearLab Blend Add-On version 20140701)
184  - MoteinoMEGA https://lowpowerlab.com/shop/moteinomega
185  (with Arduino 1.0.5 and the MoteinoMEGA Arduino Core
186  https://github.com/LowPowerLab/Moteino/tree/master/MEGA/Core)
187  - ESP8266 on Arduino IDE and Boards Manager per https://github.com/esp8266/Arduino
188  Tested using Arduino 1.6.8 with esp8266 by ESP8266 Community version 2.1.0
189  Also Arduino 1.8.1 with esp8266 by SparkFun Electronics 2.5.2
190  Examples serial_reliable_datagram_* and ask_* are shown to work.
191  CAUTION: The GHz radio included in the ESP8266 is
192  not yet supported.
193  CAUTION: tests here show that when powered by an FTDI USB-Serial converter,
194  the ESP8266 can draw so much power when transmitting on its GHz WiFi that VCC will sag
195  causing random crashes. We strongly recommend a large cap, say 1000uF 10V on VCC if you are also using the WiFi.
196  - Various Talk2 Whisper boards eg https://wisen.com.au/store/products/whisper-node-lora.
197  Use Arduino Board Manager to install the Talk2 code support.
198  - etc.
199 
200 - STM32 F4 Discover board, using Arduino 1.8.2 or later and
201  Roger Clarkes Arduino_STM from https://github.com/rogerclarkmelbourne/Arduino_STM32
202  Caution: with this library and board, sending text to Serial causes the board to hang in mysterious ways.
203  Serial2 emits to PA2. The default SPI pins are SCK: PB3, MOSI PB5, MISO PB4.
204  We tested with PB0 as slave select and PB1 as interrupt pin for various radios. RH_ASK and RH_Serial also work.
205 
206 - ChipKIT Core with Arduino IDE on any ChipKIT Core supported Digilent processor (tested on Uno32)
207  http://chipkit.net/wiki/index.php?title=ChipKIT_core
208 
209 - Maple and Flymaple boards with libmaple and the Maple-IDE development environment
210  http://leaflabs.com/devices/maple/ and http://www.open-drone.org/flymaple
211 
212 - Teensy including Teensy 3.1 and earlier built using Arduino IDE 1.0.5 to 1.6.4 and later with
213  teensyduino addon 1.18 to 1.23 and later.
214  http://www.pjrc.com/teensy
215 
216 - Particle Photon https://store.particle.io/collections/photon and ARM3 based CPU with built-in
217  Wi-Fi transceiver and extensive IoT software suport. RadioHead does not support the built-in transceiver
218  but can be used to control other SPI based radios, Serial ports etc.
219  See below for details on how to build RadioHead for Photon
220 
221 - ATTiny built using Arduino IDE 1.8 and the ATTiny core from
222  https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json
223  using the instructions at
224  https://medium.com/jungletronics/attiny85-easy-flashing-through-arduino-b5f896c48189
225  (Caution: these are very small processors and not all RadioHead features may be available, depending on memory requirements)
226  (Caution: we have not had good success building RH_ASK sketches for ATTiny 85 with SpenceKonde ATTinyCore)
227 
228 - ATtiny Mega (tinyAVR 1-series) chips supported by Spencer Konde's megaTinyCore
229  (https://github.com/SpenceKonde/megaTinyCore)
230  (on Arduino 1.8.9 or later) such as AtTiny 3216, ATtiny 1616 etc. These chips can be easily programmed through their
231  UPDI pin, using an ordinary Arduino board programmed as a jtag2updi programmer as described in
232  https://github.com/SpenceKonde/megaTinyCore/blob/master/MakeUPDIProgrammer.md.
233  Make sure you set the programmer type to jtag2updi in the Arduino Tools->Programmer menu.
234  See https://github.com/SpenceKonde/megaTinyCore/blob/master/megaavr/extras/ImportantInfo.md for links to pinouts
235  and pin numbering information for all the suported chips.
236 
237 - nRF51 compatible Arm chips such as nRF51822 with Arduino 1.6.4 and later using the procedures
238  in http://redbearlab.com/getting-started-nrf51822/
239 
240 - nRF52 compatible Arm chips such as as Adafruit BLE Feather board
241  https://www.adafruit.com/product/3406
242 
243 - Adafruit Feather. These are excellent boards that are available with a variety of radios. We tested with the
244  Feather 32u4 with RFM69HCW radio, with Arduino IDE 1.6.8 and the Adafruit AVR Boards board manager version 1.6.10.
245  https://www.adafruit.com/products/3076
246 
247 - Adafruit Feather M0 boards with Arduino 1.8.1 and later, using the Arduino and Adafruit SAMD board support.
248  https://learn.adafruit.com/adafruit-feather-m0-basic-proto/using-with-arduino-ide
249 
250 - ESP32 built using Arduino IDE 1.8.9 or later using the ESP32 toolchain installed per
251  https://github.com/espressif/arduino-esp32
252  The internal 2.4GHz radio is not yet supported. Tested with RFM22 using SPI interface
253 
254 - Raspberry Pi
255  Uses BCM2835 library for GPIO http://www.airspayce.com/mikem/bcm2835/
256  Currently works only with RH_NRF24 driver or other drivers that do not require interrupt support.
257  Contributed by Mike Poublon.
258 
259 - Linux and OSX
260  Using the RHutil/HardwareSerial class, the RH_Serial driver and any manager will
261  build and run on Linux and OSX. These can be used to build programs that talk securely and reliably to
262  Arduino and other processors or to other Linux or OSX hosts on a reliable, error detected (and possibly encrypted) datagram
263  protocol over various types of serial line.
264 
265 - Mongoose OS, courtesy Paul Austen. Mongoose OSis an Internet of Things Firmware Development Framework
266  available under Apache License Version 2.0. It supports low power, connected microcontrollers such as:
267  ESP32, ESP8266, TI CC3200, TI CC3220, STM32.
268  https://mongoose-os.com/
269 
270 Other platforms are partially supported, such as Generic AVR 8 bit processors, MSP430.
271 We welcome contributions that will expand the range of supported platforms.
272 
273 If your processor is not on the list above, there is a good chance it
274 wont work without modifying RadioHead to suit it. If you wish for
275 support for another processor, and you send 2 of them to
276 AirSpayce Pty Ltd, we will consider adding support for it.
277 
278 RadioHead is available (through the efforts of others)
279 for PlatformIO. PlatformIO is a cross-platform code builder and the missing library manager.
280 http://platformio.org/#!/lib/show/124/RadioHead
281 
282 \par History
283 
284 RadioHead was created in April 2014, substantially based on code from some of our other earlier Radio libraries:
285 
286 - RHMesh, RHRouter, RHReliableDatagram and RHDatagram are derived from the RF22 library version 1.39.
287 - RH_RF22 is derived from the RF22 library version 1.39.
288 - RH_RF69 is derived from the RF69 library version 1.2.
289 - RH_ASK is based on the VirtualWire library version 1.26, after significant conversion to C++.
290 - RH_Serial was new.
291 - RH_NRF24 is based on the NRF24 library version 1.12, with some significant changes.
292 
293 During this combination and redevelopment, we have tried to retain all the processor dependencies and support from
294 the libraries that were contributed by other people. However not all platforms can be tested by us, so if you
295 find that support from some platform has not been successfully migrated, please feel free to fix it and send us a
296 patch.
297 
298 Users of RHMesh, RHRouter, RHReliableDatagram and RHDatagram in the previous RF22 library will find that their
299 existing code will run mostly without modification. See the RH_RF22 documentation for more details.
300 
301 \par Installation
302 
303 Install in the usual way: unzip the distribution zip file to the libraries
304 sub-folder of your sketchbook.
305 The example sketches will be visible in in your Arduino, mpide, maple-ide or whatever.
306 http://arduino.cc/en/Guide/Libraries
307 
308 \par Building for Particle Photon
309 
310 The Photon is not supported by the Arduino IDE, so it takes a little effort to set up a build environment.
311 Heres what we did to enable building of RadioHead example sketches on Linux,
312 but there are other ways to skin this cat.
313 Basic reference for getting started is: http://particle-firmware.readthedocs.org/en/develop/build/
314 - Download the ARM gcc cross compiler binaries and unpack it in a suitable place:
315 \code
316 cd /tmp
317 wget https://launchpad.net/gcc-arm-embedded/5.0/5-2015-q4-major/+download/gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2
318 tar xvf gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2
319 \endcode
320 - If dfu-util and friends not installed on your platform, download dfu-util and friends to somewhere in your path
321 \code
322 cd ~/bin
323 wget http://dfu-util.sourceforge.net/releases/dfu-util-0.8-binaries/linux-i386/dfu-util
324 wget http://dfu-util.sourceforge.net/releases/dfu-util-0.8-binaries/linux-i386/dfu-suffix
325 wget http://dfu-util.sourceforge.net/releases/dfu-util-0.8-binaries/linux-i386/dfu-prefix
326 \endcode
327 - Download the Particle firmware (contains headers and libraries require to compile Photon sketches)
328  to a suitable place:
329 \code
330 cd /tmp
331 wget https://github.com/spark/firmware/archive/develop.zip
332 unzip develop.zip
333 \endcode
334 - Make a working area containing the RadioHead library source code and your RadioHead sketch. You must
335  rename the sketch from .pde or .ino to application.cpp
336 \code
337 cd /tmp
338 mkdir RadioHead
339 cd RadioHead
340 cp /usr/local/projects/arduino/libraries/RadioHead/ *.h .
341 cp /usr/local/projects/arduino/libraries/RadioHead/ *.cpp .
342 cp /usr/local/projects/arduino/libraries/RadioHead/examples/cc110/cc110_client/cc110_client.pde application.cpp
343 \endcode
344 - Edit application.cpp and comment out any \#include <SPI.h> so it looks like:
345 \code
346  // #include <SPI.h>
347 \endcode
348 - Connect your Photon by USB. Put it in DFU mode as descibed in Photon documentation. Light should be flashing yellow
349 - Compile the RadioHead sketch and install it as the user program (this does not update the rest of the
350  Photon firmware, just the user part:
351 \code
352 cd /tmp/firmware-develop/main
353 PATH=$PATH:/tmp/gcc-arm-none-eabi-5_2-2015q4/bin make APPDIR=/tmp/RadioHead all PLATFORM=photon program-dfu
354 \endcode
355 - You should see RadioHead compile without errors and download the finished sketch into the Photon.
356 
357 \par Compatible Hardware Suppliers
358 
359 We have had good experiences with the following suppliers of RadioHead compatible hardware:
360 
361 - LittleBird http://littlebirdelectronics.com.au in Australia for all manner of Arduinos and radios.
362 - LowPowerLab http://lowpowerlab.com/moteino in USA for the excellent Moteino and Moteino-USB
363  boards which include Hope-RF RF69B radios on-board.
364 - Anarduino and HopeRF USA (http://www.hoperfusa.com and http://www.anarduino.com) who have a wide range
365  of HopeRF radios and Arduino integrated modules.
366 - SparkFun https://www.sparkfun.com/ in USA who design and sell a wide range of Arduinos and radio modules.
367 - Wisen http://wisen.com.au who design and sell a wide range of integrated radio/processor modules including the
368  excellent Talk2 range.
369 
370 \par Coding Style
371 
372 RadioHead is designed so it can run on small processors with very
373 limited resources and strict timing contraints. As a result, we
374 tend only to use the simplest and least demanding (in terms of memory and CPU) C++
375 facilities. In particular we avoid as much as possible dynamic
376 memory allocation, and the use of complex objects like C++
377 strings, IO and buffers. We are happy with this, but we are aware
378 that some people may think we are legaving useful tools on the
379 table. You should not use this code as an example of how to do
380 generalised C++ programming on well resourced processors.
381 
382 \par Donations
383 
384 This library is offered under a free GPL license for those who want to use it that way.
385 We try hard to keep it up to date, fix bugs
386 and to provide free support. If this library has helped you save time or money, please consider donating at
387 http://www.airspayce.com or here:
388 
389 \htmlonly <form action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_donations" /> <input type="hidden" name="business" value="mikem@airspayce.com" /> <input type="hidden" name="lc" value="AU" /> <input type="hidden" name="item_name" value="Airspayce" /> <input type="hidden" name="item_number" value="RadioHead" /> <input type="hidden" name="currency_code" value="USD" /> <input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHosted" /> <input type="image" alt="PayPal — The safer, easier way to pay online." name="submit" src="https://www.paypalobjects.com/en_AU/i/btn/btn_donateCC_LG.gif" /> <img alt="" src="https://www.paypalobjects.com/en_AU/i/scr/pixel.gif" width="1" height="1" border="0" /></form> \endhtmlonly
390 
391 \subpage packingdata "Passing Sensor Data Between RadioHead nodes"
392 
393 \par Trademarks
394 
395 RadioHead is a trademark of AirSpayce Pty Ltd. The RadioHead mark was first used on April 12 2014 for
396 international trade, and is used only in relation to data communications hardware and software and related services.
397 It is not to be confused with any other similar marks covering other goods and services.
398 
399 \par Copyright
400 
401 This software is Copyright (C) 2011-2018 Mike McCauley. Use is subject to license
402 conditions. The main licensing options available are GPL V3 or Commercial:
403 
404 \par Open Source Licensing GPL V3
405 
406 This is the appropriate option if you want to share the source code of your
407 application with everyone you distribute it to, and you also want to give them
408 the right to share who uses it. If you wish to use this software under Open
409 Source Licensing, you must contribute all your source code to the open source
410 community in accordance with the GPL Version 3 when your application is
411 distributed. See https://www.gnu.org/licenses/gpl-3.0.html
412 
413 \par Commercial Licensing
414 
415 This is the appropriate option if you are creating proprietary applications
416 and you are not prepared to distribute and share the source code of your
417 application. To purchase a commercial license, contact info@airspayce.com
418 
419 \par Revision History
420 \version 1.1 2014-04-14<br>
421  Initial public release
422 \version 1.2 2014-04-23<br>
423  Fixed various typos. <br>
424  Added links to compatible Anarduino products.<br>
425  Added RHNRFSPIDriver, RH_NRF24 classes to support Nordic NRF24 based radios.
426 \version 1.3 2014-04-28<br>
427  Various documentation fixups.<br>
428  RHDatagram::setThisAddress() did not set the local copy of thisAddress. Reported by Steve Childress.<br>
429  Fixed a problem on Teensy with RF22 and RF69, where the interrupt pin needs to be set for input, <br>
430  else pin interrupt doesn't work properly. Reported by Steve Childress and patched by
431  Adrien van den Bossche. Thanks.<br>
432  Fixed a problem that prevented RF22 honouring setPromiscuous(true). Reported by Steve Childress.<br>
433  Updated documentation to clarify some issues to do with maximum message lengths
434  reported by Steve Childress.<br>
435  Added support for yield() on systems that support it (currently Arduino 1.5.5 and later)
436  so that spin-loops can suport multitasking. Suggested by Steve Childress.<br>
437  Added RH_RF22::setGpioReversed() so the reversal it can be configured at run-time after
438  radio initialisation. It must now be called _after_ init(). Suggested by Steve Childress.<br>
439 \version 1.4 2014-04-29<br>
440  Fixed further problems with Teensy compatibility for RH_RF22. Tested on Teensy 3.1.
441  The example/rf22_* examples now run out of the box with the wiring connections as documented for Teensy
442  in RH_RF22.<br>
443  Added YIELDs to spin-loops in RHRouter, RHMesh and RHReliableDatagram, RH_NRF24.<br>
444  Tested RH_Serial examples with Teensy 3.1: they now run out of the box.<br>
445  Tested RH_ASK examples with Teensy 3.1: they now run out of the box.<br>
446  Reduced default SPI speed for NRF24 from 8MHz to 1MHz on Teensy, to improve reliability when
447  poor wiring is in use.<br>
448  on some devices such as Teensy.<br>
449  Tested RH_NRF24 examples with Teensy 3.1: they now run out of the box.<br>
450 \version 1.5 2014-04-29<br>
451  Added support for Nordic Semiconductor nRF905 transceiver with RH_NRF905 driver. Also
452  added examples for nRF905 and tested on Teensy 3.1
453 \version 1.6 2014-04-30<br>
454  NRF905 examples were missing
455 \version 1.7 2014-05-03<br>
456  Added support for Arduino Due. Tested with RH_NRF905, RH_Serial, RH_ASK.
457  IMPORTANT CHANGE to interrupt pins on Arduino with RH_RF22 and RH_RF69 constructors:
458  previously, you had to specify the interrupt _number_ not the interrupt _pin_. Arduinos and Uno32
459  are now consistent with all other platforms: you must specify the interrupt pin number. Default
460  changed to pin 2 (a common choice with RF22 shields).
461  Removed examples/maple/maple_rf22_reliable_datagram_client and
462  examples/maple/maple_rf22_reliable_datagram_client since the rf22 examples now work out
463  of the box with Flymaple.
464  Removed examples/uno32/uno32_rf22_reliable_datagram_client and
465  examples/uno32/uno32_rf22_reliable_datagram_client since the rf22 examples now work out
466  of the box with ChipKit Uno32.
467 \version 1.8 2014-05-08 <br>
468  Added support for YIELD in Teensy 2 and 3, suggested by Steve Childress.<br>
469  Documentation updates. Clarify use of headers and Flags<br>
470  Fixed misalignment in RH_RF69 between ModemConfigChoice definitions and the implemented choices
471  which meant you didnt get the choice you thought and GFSK_Rb55555Fd50 hung the transmitter.<br>
472  Preliminary work on Linux simulator.
473 \version 1.9 2014-05-14 <br>
474  Added support for using Timer 2 instead of Timer 1 on Arduino in RH_ASK when
475  RH_ASK_ARDUINO_USE_TIMER2 is defined. With the kind assistance of
476  Luc Small. Thanks!<br>
477  Updated comments in RHReliableDatagram concerning servers, retries, timeouts and delays.
478  Fixed an error in RHReliableDatagram where recvfrom return value was not checked.
479  Reported by Steve Childress.<br>
480  Added Linux simulator support so simple RadioHead sketches can be compiled and run on Linux.<br>
481  Added RH_TCP driver to permit message passing between simulated sketches on Linux.<br>
482  Added example simulator sketches.<br>
483  Added tools/etherSimulator.pl, a simulator of the 'Luminiferous Ether' that passes
484  messages between simulated sketches and can simulate random message loss etc.<br>
485  Fixed a number of typos and improved some documentation.<br>
486 \version 1.10 2014-05-15 <br>
487  Added support for RFM73 modules to RH_NRF24. These 2 radios are very similar, and can interoperate
488  with each other. Added new RH_NRF24::TransmitPower enums for the RFM73, which has a different
489  range of available powers<br>
490  reduced the default SPI bus speed for RH_NRF24 to 1MHz, since so many modules and CPU have problems
491  with 8MHz.<br>
492 \version 1.11 2014-05-18<br>
493  Testing RH_RF22 with RFM23BP and 3.3V Teensy 3.1 and 5V Arduinos.
494  Updated documentation with respect to GPIO and antenna
495  control pins for RFM23. Updated documentation with respect to transmitter power control for RFM23<br>
496  Fixed a problem with RH_RF22 driver, where GPIO TX and RX pins were not configured during
497  initialisation, causing poor transmit power and sensitivity on those RF22/RF23 devices where GPIO controls
498  the antenna selection pins.
499 \version 1.12 2014-05-20<br>
500  Testing with RF69HW and the RH_RF69 driver. Works well with the Anarduino MiniWireless -CW and -HW
501  boards http://www.anarduino.com/miniwireless/ including
502  the marvellous high powered MinWireless-HW (with 20dBm output for excellent range).<br>
503  Clarified documentation of RH_RF69::setTxPower values for different models of RF69.<br>
504  Added RHReliableDatagram::resetRetransmissions().<br>
505  Retransmission count precision increased to uin32_t.<br>
506  Added data about actual power measurements from RFM22 module.<br>
507 \version 1.13 2014-05-23<br>
508  setHeaderFlags(flags) changed to setHeaderFlags(set, clear), enabling any flags to be
509  individually set and cleared by either RadioHead or application code. Requested by Steve Childress.<br>
510  Fixed power output setting for boost power on RF69HW for 18, 19 and 20dBm.<br>
511  Added data about actual power measurements from RFM69W and RFM69HW modules.<br>
512 \version 1.14 2014-05-26<br>
513  RH_RF69::init() now always sets the PA boost back to the default settings, else can get invalid
514  PA power modes after uploading new sketches without a power cycle. Reported by Bryan.<br>
515  Added new macros RH_VERSION_MAJOR RH_VERSION_MINOR, with automatic maintenance in Makefile.<br>
516  Improvements to RH_TCP: constructor now honours the server argument in the form "servername:port".<br>
517  Added YIELD to RHReliableDatagram::recvfromAckTimeout. Requested by Steve Childress.<br>
518  Fixed a problem with RH_RF22 reliable datagram acknowledgements that was introduced in version 1.13.
519  Reported by Steve Childress.<br>
520 \version 1.15 2014-05-27<br>
521  Fixed a problem with the RadioHead .zip link.
522 \version 1.16 2014-05-30 <br>
523  Fixed RH_RF22 so that lastRssi() returns the signal strength in dBm. Suggested by Steve Childress.<br>
524  Added support for getLastPreambleTime() to RH_RF69. Requested by Steve Childress.<br>
525  RH_NRF24::init() now checks if there is a device connected and responding, else init() will fail.
526  Suggested by Steve Brown.<br>
527  RHSoftwareSPI now initialises default values for SPI pins MOSI = 12, MISO = 11 and SCK = 13.<br>
528  Fixed some problems that prevented RH_NRF24 working with mixed software and hardware SPI
529  on different devices: a race condition
530  due to slow SPI transfers and fast acknowledgement.<br>
531 \version 1.17 2014-06-02 <br>
532  Fixed a debug typo in RHReliableDatagram that was introduced in 1.16.<br>
533  RH_NRF24 now sets default power, data rate and channel in init(), in case another
534  app has previously set different values without powerdown.<br>
535  Caution: there are still problems with RH_NRF24 and Software SPI. Do not use.<br>
536 \version 1.18 2014-06-02<br>
537  Improvements to performance of RH_NRF24 statusRead, allowing RH_NRF24 and Software SPI
538  to operate on slow devices like Arduino Uno.<br>
539 \version 1.19 2014-06-19<br>
540  Added examples ask_transmitter.pde and ask_receiver.pde.<br>
541  Fixed an error in the RH_RF22 doc for connection of Teensy to RF22.<br>
542  Improved documentation of start symbol bit patterns in RH_ASK.cpp
543 \version 1.20 2014-06-24<br>
544  Fixed a problem with compiling on platforms such as ATtiny where SS is not defined.<br>
545  Added YIELD to RHMesh::recvfromAckTimeout().<br>
546 \version 1.21 2014-06-24<br>
547  Fixed an issue in RH_Serial where characters might be lost with back-to-back frames.
548  Suggested by Steve Childress.<br>
549  Brought previous RHutil/crc16.h code into mainline RHCRC.cpp to prevent name collisions
550  with other similarly named code in other libraries. Suggested by Steve Childress.<br>
551  Fix SPI bus speed errors on 8MHz Arduinos.
552 \version 1.22 2014-07-01<br>
553  Update RH_ASK documentation for common wiring connections.<br>
554  Testing RH_ASK with HopeRF RFM83C/RFM85 courtesy Anarduino http://www.anarduino.com/<br>
555  Testing RH_NRF24 with Itead Studio IBoard Pro http://imall.iteadstudio.com/iboard-pro.html
556  using both hardware SPI on the ITDB02 Parallel LCD Module Interface pins and software SPI
557  on the nRF24L01+ Module Interface pins. Documented wiring required.<br>
558  Added support for AVR 1284 and 1284p, contributed by Peter Scargill.
559  Added support for Semtech SX1276/77/78 and HopeRF RFM95/96/97/98 and other similar LoRa capable radios
560  in LoRa mode only. Tested with the excellent MiniWirelessLoRa from
561  Anarduino http://www.anarduino.com/miniwireless<br>
562 \version 1.23 2014-07-03<br>
563  Changed the default modulation for RH_RF69 to GFSK_Rb250Fd250, since the previous default
564  was not very reliable.<br>
565  Documented RH_RF95 range tests.<br>
566  Improvements to RH_RF22 RSSI readings so that lastRssi correctly returns the last message in dBm.<br>
567 \version 1.24 2014-07-18
568  Added support for building RadioHead for STM32F4 Discovery boards, using the native STM Firmware libraries,
569  in order to support Codec2WalkieTalkie (http://www.airspayce.com/mikem/Codec2WalkieTalkie)
570  and other projects. See STM32ArduinoCompat.<br>
571  Default modulation for RH_RF95 was incorrectly set to a very slow Bw125Cr48Sf4096
572 \version 1.25 2014-07-25
573  The available() function will longer terminate any current transmission, and force receive mode.
574  Now, if there is no unprocessed incoming message and an outgoing message is currently being transmitted,
575  available() will return false.<br>
576  RHRouter::sendtoWait(uint8_t*, uint8_t, uint8_t, uint8_t) renamed to sendtoFromSourceWait due to conflicts
577  with new sendtoWait() with optional flags.<br>
578  RHMEsh and RHRouter already supported end-to-end application layer flags, but RHMesh::sendtoWait()
579  and RHRouter::sendToWait have now been extended to expose a way to send optional application layer flags.
580 \version 1.26 2014-08-12
581  Fixed a Teensy 2.0 compile problem due yield() not available on Teensy < 3.0. <br>
582  Adjusted the algorithm of RH_RF69::temperatureRead() to more closely reflect reality.<br>
583  Added functions to RHGenericDriver to get driver packet statistics: rxBad(), rxGood(), txGood().<br>
584  Added RH_RF69::printRegisters().<br>
585  RH_RF95::printRegisters() was incorrectly printing the register index instead of the address.
586  Reported by Phang Moh Lim.<br>
587  RH_RF95, added definitions for some more registers that are usable in LoRa mode.<br>
588  RH_RF95::setTxPower now uses RH_RF95_PA_DAC_ENABLE to achieve 21, 22 and 23dBm.<br>
589  RH_RF95, updated power output measurements.<br>
590  Testing RH_RF69 on Teensy 3.1 with RF69 on PJRC breakout board. OK.<br>
591  Improvements so RadioHead will build under Arduino where SPI is not supported, such as
592  ATtiny.<br>
593  Improvements so RadioHead will build for ATTiny using Arduino IDE and tinycore arduino-tiny-0100-0018.zip.<br>
594  Testing RH_ASK on ATTiny85. Reduced RAM footprint.
595  Added helpful documentation. Caution: RAM memory is *very* tight on this platform.<br>
596  RH_RF22 and RH_RF69, added setIdleMode() function to allow the idle mode radio operating state
597  to be controlled for lower idle power consumption at the expense of slower transitions to TX and RX.<br>
598 \version 1.27 2014-08-13
599  All RH_RF69 modulation schemes now have data whitening enabled by default.<br>
600  Tested and added a number of OOK modulation schemes to RH_RF69 Modem config table.<br>
601  Minor improvements to a number of the faster RH_RF69 modulation schemes, but some slower ones
602  are still not working correctly.<br>
603 \version 1.28 2014-08-20
604  Added new RH_RF24 driver to support Si446x, RF24/26/26, RFM24/26/27 family of transceivers.
605  Tested with the excellent
606  Anarduino Mini and RFM24W and RFM26W with the generous assistance of the good people at
607  Anarduino http://www.anarduino.com.
608 \version 1.29 2014-08-21
609  Fixed a compile error in RH_RF24 introduced at the last minute in hte previous release.<br>
610  Improvements to RH_RF69 modulation schemes: now include the AFCBW in teh ModemConfig.<br>
611  ModemConfig RH_RF69::FSK_Rb2Fd5 and RH_RF69::GFSK_Rb2Fd5 are now working.<br>
612 \version 1.30 2014-08-25
613  Fixed some compile problems with ATtiny84 on Arduino 1.5.5 reported by Glen Cook.<br>
614 \version 1.31 2014-08-27
615  Changed RH_RF69 FSK and GFSK modulations from Rb2_4Fd2_4 to Rb2_4Fd4_8 and FSK_Rb4_8Fd4_8 to FSK_Rb4_8Fd9_6
616  since the previous ones were unreliable (they had modulation indexes of 1).<br>
617 \version 1.32 2014-08-28
618  Testing with RedBearLab Blend board http://redbearlab.com/blend/. OK.<br>
619  Changed more RH_RF69 FSK and GFSK slowish modulations to have modulation index of 2 instead of 1.
620  This required chnaging the symbolic names.<br>
621 \version 1.33 2014-09-01
622  Added support for sleep mode in RHGeneric driver, with new mode
623  RHModeSleep and new virtual function sleep().<br>
624  Added support for sleep to RH_RF69, RH_RF22, RH_NRF24, RH_RF24, RH_RF95 drivers.<br>
625 \version 1.34 2014-09-19
626  Fixed compile errors in example rf22_router_test.<br>
627  Fixed a problem with RH_NRF24::setNetworkAddress, also improvements to RH_NRF24 register printing.
628  Patched by Yveaux.<br>
629  Improvements to RH_NRF24 initialisation for version 2.0 silicon.<br>
630  Fixed problem with ambigiguous print call in RH_RFM69 when compiling for Codec2.<br>
631  Fixed a problem with RH_NRF24 on RFM73 where the LNA gain was not set properly, reducing the sensitivity
632  of the receiver.
633 \version 1.35 2014-09-19
634  Fixed a problem with interrupt setup on RH_RF95 with Teensy3.1. Reported by AD.<br>
635 \version 1.36 2014-09-22
636  Improvements to interrupt pin assignments for __AVR_ATmega1284__ and__AVR_ATmega1284P__, provided by
637  Peter Scargill.<br>
638  Work around a bug in Arduino 1.0.6 where digitalPinToInterrupt is defined but NOT_AN_INTERRUPT is not.<br>
639  \version 1.37 2014-10-19
640  Updated doc for connecting RH_NRF24 to Arduino Mega.<br>
641  Changes to RHGenericDriver::setHeaderFlags(), so that the default for the clear argument
642  is now RH_FLAGS_APPLICATION_SPECIFIC, which is less surprising to users.
643  Testing with the excellent MoteinoMEGA from LowPowerLab
644  https://lowpowerlab.com/shop/moteinomega with on-board RFM69W.
645  \version 1.38 2014-12-29
646  Fixed compile warning on some platforms where RH_RF24::send and RH_RF24::writeTxFifo
647  did not return a value.<br>
648  Fixed some more compiler warnings in RH_RF24 on some platforms.<br>
649  Refactored printRegisters for some radios. Printing to Serial
650  is now controlled by the definition of RH_HAVE_SERIAL.<br>
651  Added partial support for ARM M4 w/CMSIS with STM's Hardware Abstraction lib for
652  Steve Childress.<br>
653  \version 1.39 2014-12-30
654  Fix some compiler warnings under IAR.<br>
655  RH_HAVE_SERIAL and Serial.print calls removed for ATTiny platforms.<br>
656  \version 1.40 2015-03-09
657  Added notice about availability on PlatformIO, thanks to Ivan Kravets.<br>
658  Fixed a problem with RH_NRF24 where short packet lengths would occasionally not be trasmitted
659  due to a race condition with RH_NRF24_TX_DS. Reported by Mark Fox.<br>
660  \version 1.41 2015-03-29
661  RH_RF22, RH_RF24, RH_RF69 and RH_RF95 improved to allow driver.init() to be called multiple
662  times without reallocating a new interrupt, allowing the driver to be reinitialised
663  after sleeping or powering down.
664  \version 1.42 2015-05-17
665  Added support for RH_NRF24 driver on Raspberry Pi, using BCM2835
666  library for GPIO pin IO. Contributed by Mike Poublon.<br>
667  Tested RH_NRF24 module with NRF24L01+PA+LNA SMA Antenna Wireless Transceiver modules
668  similar to: http://www.elecfreaks.com/wiki/index.php?title=2.4G_Wireless_nRF24L01p_with_PA_and_LNA
669  works with no software changes. Measured max power output 18dBm.<br>
670  \version 1.43 2015-08-02
671  Added RH_NRF51 driver to support Nordic nRF51 family processor with 2.4GHz radio such
672  as nRF51822, to be built on Arduino 1.6.4 and later. Tested with RedBearLabs nRF51822 board
673  and BLE Nano kit<br>
674  \version 1.44 2015-08-08
675  Fixed errors with compiling on some platforms without serial, such as ATTiny.
676  Reported by Friedrich Müller.<br>
677  \version 1.45 2015-08-13
678  Added support for using RH_Serial on Linux and OSX (new class RHutil/HardwareSerial
679  encapsulates serial ports on those platforms). Example examples/serial upgraded
680  to build and run on Linux and OSX using the tools/simBuild builder.
681  RHMesh, RHRouter and RHReliableDatagram updated so they can use RH_Serial without
682  polling loops on Linux and OSX for CPU efficiency.<br>
683  \version 1.46 2015-08-14
684  Amplified some doc concerning Linux and OSX RH_Serial. Added support for 230400
685  baud rate in HardwareSerial.<br>
686  Added sample sketches nrf51_audio_tx and nrf51_audio_rx which show how to
687  build an audio TX/RX pair with RedBear nRF51822 boards and a SparkFun MCP4725 DAC board.
688  Uses the built-in ADC of the nRF51822 to sample audio at 5kHz and transmit packets
689  to the receiver which plays them via the DAC.<br>
690 \version 1.47 2015-09-18
691  Removed top level Makefile from distribution: its only used by the developer and
692  its presence confuses some people.<br>
693  Fixed a problem with RHReliableDatagram with some versions of Raspberry Pi random() that causes
694  problems: random(min, max) sometimes exceeds its max limit.
695 \version 1.48 2015-09-30
696  Added support for Arduino Zero. Tested on Arduino Zero Pro.
697 \version 1.49 2015-10-01
698  Fixed problems that prevented interrupts working correctly on Arduino Zero and Due.
699  Builds and runs with 1.6.5 (with 'Arduino SAMD Boards' for Zero version 1.6.1) from arduino.cc.
700  Arduino version 1.7.7 from arduino.org is not currently supported.
701 \version 1.50 2015-10-25
702  Verified correct building and operation with Arduino 1.7.7 from arduino.org.
703  Caution: You must burn the bootloader from 1.7.7 to the Arduino Zero before it will
704  work with Arduino 1.7.7 from arduino.org. Conversely, you must burn the bootloader from 1.6.5
705  to the Arduino Zero before it will
706  work with Arduino 1.6.5 from arduino.cc. Sigh.
707  Fixed a problem with RH_NRF905 that prevented the power and frequency ranges being set
708  properly. Reported by Alan Webber.
709 \version 1.51 2015-12-11
710  Changes to RH_RF6::setTxPower() to be compatible with SX1276/77/78/79 modules that
711  use RFO transmitter pins instead of PA_BOOST, such as the excellent
712  Modtronix inAir4 http://modtronix.com/inair4.html
713  and inAir9 modules http://modtronix.com/inair9.html. With the kind assistance of
714  David from Modtronix.
715 \version 1.52 2015-12-17
716  Added RH_MRF89 module to suport Microchip MRF89XA and compatible transceivers.
717  and modules.<br>
718 \version 1.53 2016-01-02
719  Added RH_CC110 module to support Texas Instruments CC110L and compatible transceivers and modules.<br>
720 \version 1.54 2016-01-29
721  Added support for ESP8266 processor on Arduino IDE. Examples serial_reliable_datagram_* are shown to work.
722  CAUTION: SPI not supported yet. Timers used by RH_ASK are not tested.
723  The GHz radio included in the ESP8266 is not yet supported.
724 \version 1.55 2016-02-12
725  Added macros for htons() and friends to RadioHead.h.
726  Added example sketch serial_gateway.pde. Acts as a transparent gateway between RH_RF22 and RH_Serial,
727  and with minor mods acts as a universal gateway between any 2 RadioHead driver networks.
728  Initial work on supporting STM32 F2 on Particle Photon: new platform type defined.
729  Fixed many warnings exposed by test building for Photon.
730  Particle Photon tested support for RH_Serial, RH_ASK, SPI, RH_CC110 etc.
731  Added notes on how to build RadioHead sketches for Photon.
732 \version 1.56 2016-02-18
733  Implemented timers for RH_ASK on ESP8266, added some doc on IO pin selection.
734 \version 1.57 2016-02-23
735  Fixed an issue reported by S3B, where RH_RF22 would sometimes not clear the rxbufvalid flag.
736 \version 1.58 2-16-04-04
737  Tested RH_RF69 with Arduino Due. OK. Updated doc.<br>
738  Added support for all ChipKIT Core supported boards
739  http://chipkit.net/wiki/index.php?title=ChipKIT_core
740  Tested on ChipKIT Uno32.<br>
741  Digilent Uno32 under the old MPIDE is no longer formally
742  supported but may continue to work for some time.<br>
743 \version 1.59 2016-04-12
744  Testing with the excellent Rocket Scream Mini Ultra Pro with the RFM95W and RFM69HCW modules from
745  http://www.rocketscream.com/blog/product/mini-ultra-pro-with-radio/ (915MHz versions). Updated
746  documentation with hints to suit. Caution: requires Arduino 1.6.8 and Arduino SAMD Boards 1.6.5.
747  See also http://www.rocketscream.com/blog/2016/03/10/radio-range-test-with-rfm69hcw/
748  for the vendors tests and range with the RFM69HCW version. They also have an RF95 version equipped with
749  TCXO temperature controllled oscillator for extra frequency stability and support of very slow and
750  long range protocols.
751  These boards are highly recommended. They also include battery charging support.
752 \version 1.60 2016-06-25
753  Tested with the excellent talk2 Whisper Node boards
754  (https://talk2.wisen.com.au/ and https://bitbucket.org/talk2/),
755  an Arduino Nano compatible board, which include an on-board RF69 radio, external antenna,
756  run on 2xAA batteries and support low power operations. RF69 examples work without modification.
757  Added support for ESP8266 SPI, provided by David Skinner.
758 \version 1.61 2016-07-07
759  Patch to RH_ASK.cpp for ESP8266, to prevent crashes in interrupt handlers. Patch from Alexander Mamchits.
760 \version 1.62 2016-08-17
761  Fixed a problem in RH_ASK where _rxInverted was not properly initialised. Reported by "gno.sun.sop".
762  Added support for waitCAD() and isChannelActive() and setCADTimeout() to RHGeneric.
763  Implementation of RH_RF95::isChannelActive() allows the RF95 module to support
764  Channel Activity Detection (CAD). Based on code contributed by Bent Guldbjerg Christensen.
765  Implmentations of isChannelActive() plus documentation for other radio modules wil be welcomed.
766 \version 1.63 2016-10-20
767  Testing with Adafruit Feather 32u4 with RFM69HCW. Updated documentation to reflect.<br>
768 \version 1.64 2016-12-10
769  RHReliableDatagram now initialises _seenids. Fix from Ben Lim.<br>
770  In RH_NRF51, added get_temperature().<br>
771  In RH_NRF51, added support for AES packet encryption, which required a slight change
772  to the on-air message format.<br>
773 \version 1.65 2017-01-11
774  Fixed a race condition with RH_NRF51 that prevented ACKs being reliably received.<br>
775  Removed code in RH_NRF51 that enabled the DC-DC converter. This seems not to be a necessary condition
776  for the radio to work and is now left to the application if that is required.<br>
777  Proven interoperation between nRF51822 and nRF52832.<br>
778  Modification and testing of RH_NRF51 so it works with nRF52 family processors,
779  such Sparkfun nRF52832 breakout board, with Arduino 1.6.13 and
780  Sparkfun nRF52 boards manager 0.2.3 using the procedures outlined in
781  https://learn.sparkfun.com/tutorials/nrf52832-breakout-board-hookup-guide<br>
782  Caution, the Sparkfun development system for Arduino is still immature. We had to
783  rebuild the nrfutil program since the supplied one was not suitable for
784  the Linux host we were developing on. See https://forum.sparkfun.com/viewtopic.php?f=32&t=45071
785  Also, after downloading a sketch in the nRF52832, the program does not start executing cleanly:
786  you have to reset the processor again by pressing the reset button.
787  This appears to be a problem with nrfutil, rather than a bug in RadioHead.
788 \version 1.66 2017-01-15
789  Fixed some errors in (unused) register definitions in RH_RF95.h.<br>
790  Fixed a problem that caused compilation errors in RH_NRF51 if the appropriate board
791  support was not installed.
792 \version 1.67 2017-01-24
793  Added RH_RF95::frequencyError() to return the estimated centre frequency offset in Hz
794  of the last received message
795 \version 1.68 2017-01-25
796  Fixed arithmetic error in RH_RF95::frequencyError() for some platforms.
797 \version 1.69 2017-02-02
798  Added RH_RF95::lastSNR() and improved lastRssi() calculations per the manual.
799 \version 1.70 2017-02-03
800  Added link to Binpress commercial license purchasing.
801 \version 1.71 2017-02-07
802  Improved support for STM32. Patch from Bent Guldbjerg Christensen.
803 \version 1.72 2017-03-02
804  In RH_RF24, fixed a problem where some important properties were not set by the ModemConfig.
805  Added properties 2007, 2008, 2009. Also properties 200a was not being set in the chip.
806  Reported by Shannon Bailey and Alan Adamson.
807  Fixed corresponding convert.pl and added it to the distribution.
808 \version 1.73 2017-03-04
809  Significant changes to RH_RF24 and its API. It is no longer possible to change the modulation scheme
810  programatically: it proved impossible to cater for all the possible crystal frequencies,
811  base frequency and modulation schemes. Instead you can use one of a small set of supplied radio
812  configuration header files, or generate your own with Silicon Labs WDS application. Changing
813  modulation scheme required editing RH_RF24.cpp to specify the appropriate header and recompiling.
814  convert.pl is now redundant and removed from the distribution.
815 \version 1.74 2017-03-08
816  Changed RHReliableDatagram so it would not ACK messages heard addressed to other nodes
817  in promiscuous mode.<br>
818  Added RH_RF24::deviceType() to return the integer value of the connected device.<br>
819  Added documentation about how to connect RFM69 to an ESP8266. Tested OK.<br>
820  RH_RF24 was not correctly changing state in sleep() and setModeIdle().<br>
821  Added example rf24_lowpower_client.pde showing how to put an arduino and radio into a low power
822  mode between transmissions to save battery power.<br>
823  Improvements to RH_RF69::setTxPower so it now takes an optional ishighpowermodule
824  flag to indicate if the connected module is a high power RFM69HW, and so set the power level
825  correctly. Based on code contributed by bob.
826 \version 1.75 2017-06-22
827  Fixed broken compiler issues with RH_RF95::frequencyError() reported by Steve Rogerson.<br>
828  Testing with the very excellent Rocket Scream boards equipped with RF95 TCXO modules. The
829  temperature controlled oscillator stabilises the chip enough to be able to use even the slowest
830  protocol Bw125Cr48Sf4096. Caution, the TCXO model radios are not low power when in sleep (consuming
831  about ~600 uA, reported by Phang Moh Lim).<br>
832  Added support for EBYTE E32-TTL-1W and family serial radio transceivers. These RF95 LoRa based radios
833  can deliver reliable messages at up to 7km measured.
834 \version 1.76 2017-06-23
835  Fixed a problem with RH_RF95 hanging on transmit under some mysterious circumstances.
836  Reported by several people at https://forum.pjrc.com/threads/41878-Probable-race-condition-in-Radiohead-library?p=146601#post146601 <br>
837  Increased the size of rssi variables to 16 bits to permit RSSI less than -128 as reported by RF95.
838 \version 1.77 2017-06-25
839  Fixed a compilation error with lastRssi().<br>
840 \version 1.78 2017-07-19
841  Fixed a number of unused variable warnings from g++.<br>
842  Added new module RHEncryptedDriver and examples, contributed by Philippe Rochat, which
843  adds encryption and decryption to any RadioHead transport driver, using any encryption cipher
844  supported by ArduinoLibs Cryptographic Library http://rweather.github.io/arduinolibs/crypto.html
845  Includes several examples.<br>
846 \version 1.79 2017-07-25
847  Added documentation about 'Passing Sensor Data Between RadioHead nodes'.<br>
848  Changes to RH_CC110 driver to calculate RSSI in dBm, based on a patch from Jurie Pieterse.<br>
849  Added missing passthroughmethoids to RHEncryptedDriver, allowing it to be used with RHDatagram,
850  RHReliableDatagram etc. Tested with RH_Serial. Added examples
851 \version 1.80 2017-10-04
852  Testing with the very fine Talk2 Whisper Node LoRa boards https://wisen.com.au/store/products/whisper-node-lora
853  an Arduino compatible board, which include an on-board RFM95/96 LoRa Radio (Semtech SX1276), external antenna,
854  run on 2xAAA batteries and support low power operations. RF95 examples work without modification.
855  Use Arduino Board Manager to install the Talk2 code support. Upload the code with an FTDI adapter set to 5V.<br>
856  Added support for SPI transactions in development environments that support it with SPI_HAS_TRANSACTION.
857  Tested on ESP32 with RFM-22 and Teensy 3.1 with RF69
858  Added support for ESP32, tested with RFM-22 connected by SPI.<br>
859 \version 1.81 2017-11-15
860  RH_CC110, moved setPaTable() from protected to public.<br>
861  RH_RF95 modem config Bw125Cr48Sf4096 altered to enable slow daat rate in register 26
862  as suggested by Dieter Kneffel.
863  Added support for nRF52 compatible Arm chips such as as Adafruit BLE Feather board
864  https://www.adafruit.com/product/3406, with a patch from Mike Bell.<br>
865  Fixed a problem where rev 1.80 broke Adafruit M0 LoRa support by declaring
866  bitOrder variable always as a unsigned char. Reported by Guilherme Jardim.<br>
867  In RH_RF95, all modes now have AGC enabled, as suggested by Dieter Kneffel.<br>
868 \version 1.82 2018-01-07
869  Added guard code to RH_NRF24::waitPacketSent() so that if the transmit never completes for some
870  reason, the code will eventually return with FALSE.
871  Added the low-datarate-optimization bit to config for RH_RF95::Bw125Cr48Sf4096.
872  Fix from Jurie Pieterse to ensure RH_CC110::sleep always enters sleep mode.
873  Update ESP32 support to include ASK timers. RH_ASK module is now working on ESP32.
874 \version 1.83 2018-02-12
875  Testing adafruit M0 Feather with E32. Updated RH_E32 documentation to show suggested connections
876  and contructor initialisation.<br>
877  Fixed a problem with RHEncryptedDriver that could cause a crash on some platforms when used
878  with RHReliableDatagram. Reported by Joachim Baumann.<br>
879  Improvments to doxygen doc layout in RadioHead.h
880 \version 1.84 2018-05-07
881  Compiles with Roger Clarkes Arduino_STM32 https://github.com/rogerclarkmelbourne/Arduino_STM32,
882  to support STM32F103C etc, and STM32 F4 Discovery etc.<br>
883  Tested STM32 F4 Discovery board with RH_RF22, RH_ASK and RH_Serial.
884 
885 \version 1.85 2018-07-09
886  RHGenericDriver methods changed to virtual, to allow overriding by RHEncrypredDriver:
887  lastRssi(), mode(), setMode(). Reported by Eyal Gal.<br>
888  Fixed a problem with compiling RH_E32 on some older IDEs, contributed by Philippe Rochat.<br>
889  Improvements to RH_RF95 to improve detection of bad packets, contributed by PiNi.<br>
890  Fixed an error in RHEncryptedDriver that caused incorrect message lengths for messages multiples of 16 bytes
891  when STRICT_CONTENT_LEN is defined.<br>
892  Fixed a bug in RHMesh which causes the creation of a route to the address which is the byte
893  behind the end of the route array. Reported by Pascal Gillès de Pélichy.<br>
894 \version 1.86 2018-08-28
895  Update commercial licensing, remove binpress.
896 \version 1.87 2018-10-06
897  RH_RF22 now resets all registers to default state before initialisation commences. Suggested by Wothke.<br>
898  Added RH_ENABLE_EXPLICIT_RETRY_DEDUP which improves the handling of duplicate detection especiually
899  in the case where a transmitter periodically wakes up and start tranmitting from the first sequence number.
900  Patch courtesy Justin Newitter. Thanks.
901 \version 1.88 2018-11-13
902  Updated to support ATTiny using instructions in
903  https://medium.com/jungletronics/attiny85-easy-flashing-through-arduino-b5f896c48189
904  Updated examples ask_transmitter and ask_receiver to compile cleanly on ATTiny.
905  Tested using ATTiny85 and Arduino 1.8.1. <br>
906 \version 1.89 2018-11-15
907  Testing with ATTiny core from https://github.com/SpenceKonde/ATTinyCore and RH_ASK,
908  using example ask_transmitter. This resulted in 'Low Memory, instability may occur',
909  and the resulting sketch would transmit only one packet. Suggest ATTiny users do not use this core, but use
910  the one from https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json
911  as described in https://medium.com/jungletronics/attiny85-easy-flashing-through-arduino-b5f896c48189 <br>
912  Added support for RH_RF95::setSpreadingFactor(), RH_RF95::setSignalBandwidth(), RH_RF95::setLowDatarate() and
913  RH_RF95::setPayloadCRC(). Patch from Brian Norman. Thanks.<br>
914 
915 \version 1.90 2019-05-21
916  Fixed a block size error in RhEncryptedDriver for the case when
917  using STRICT_CONTENT_LEN and sending messages of exactly _blockcipher.blockSize() bytes in length.
918  Reported and patched by Philippe Rochat.
919  Patch from Samuel Archibald to prevent compile errors with RH_AAK.cpp fo ATSAMD51.
920  Fixed a probem in RH_RF69::setSyncWords that prevented setSyncWords(NULL, 0) correctly
921  disabling sync detection and generation. Reported by Federico Maggi.
922  RHHardwareSPI::usingInterrupt() was a noop. Fixed to call SPI.usingInterrupt(interrupt);.
923 
924 \version 1.91 2019-06-01
925  Fixed a problem with new RHHardwareSPI::usingInterrupt() that prevented compilation on ESP8266
926  which does not have that call.
927 
928 \version 1.92 2019-07-14
929  Retested serial_reliable_datagram_client.pde and serial_reliable_datagram_server.pde built on Linux
930  as described in their headers, and with USB-RS485 adapters. No changes, working correctly.
931  Testing of nRF5232 with Sparkfun nRF52 board support 0.2.3 shows that there appears to be a problem with
932  interrupt handlers on this board, and none of the interrupt based radio drivers can be expected to work
933  with this chip.
934  Ensured all interrupt routines are flagged with ICACHE_RAM_ATTR when compiled for ESP8266, to prevent crashes.
935 
936 \version 1.94 2019-09-02
937  Fixed a bug in RHSoftwareSPI where RHGenericSPI::setBitOrder() has no effect for
938  on RHSoftwareSPI. Reported by Peter.<br>
939  Added support in RHRouter for a node to optionally be leaf node, and not participate as a router in the
940  network. See RHRouter::setNodeTypePatch from Alex Evans.<br>
941  Fixed a problem with ESP32 causing compile errors over missing SPI.usingInterrupt().<br>
942 
943 \version 1.95 2019-10-14
944  Fixed some typos in RH_RF05.h macro definitions reported by Clayton Smith.<br>
945  Patch from Michael Cain from RH_ASK on ESP32, untested by me.<br>
946  Added support for RPi Zero and Zero W for the RF95, contributed by Brody Mahoney.
947  Not tested by me.<br>
948 
949 \version 1.96 2019-10-14
950  Added examples for RPi Zero and Zero W to examples/raspi/rf95, contributed by Brody Mahoney
951  not tested by me. <br>
952 
953 \version 1.97 2019-11-02
954  Added support for Mongoose OS, contributed by Paul Austen.
955 
956 \version 1.98 2020-01-06
957  Rationalised use of RH_PLATFORM_ATTINY to be consistent with other platforms.<br>
958  Added support for RH_PLATFORM_ATTINY_MEGA, for use with Spencer Konde's megaTinyCore
959  https://github.com/SpenceKonde/megaTinyCore on Atmel megaAVR ATtiny 1-series chips.
960  Tested with AtTiny 3217, 3216 and 1614, using
961  RH_Serial, RH_ASK, and RH_RF22 drivers.<br>
962 
963 \version 1.99 2020-03-07
964  Release under GPL V3
965 
966 \version 1.100 2020-03-12
967  Fixed a problem that prevent compilation for Sparkfun nRF52832 Breakout board.<br>
968 
969 \author Mike McCauley. DO NOT CONTACT THE AUTHOR DIRECTLY. USE THE GOOGLE LIST GIVEN ABOVE
970 */
971 
972 /*! \page packingdata
973 \par Passing Sensor Data Between RadioHead nodes
974 
975 People often ask about how to send data (such as numbers, sensor
976 readings etc) from one RadioHead node to another. Although this issue
977 is not specific to RadioHead, and more properly lies in the area of
978 programming for networks, we will try to give some guidance here.
979 
980 One reason for the uncertainty and confusion in this area, especially
981 amongst beginners, is that there is no *best* way to do it. The best
982 solution for your project may depend on the range of processors and
983 data that you have to deal with. Also, it gets more difficult if you
984 need to send several numbers in one packet, and/or deal with floating
985 point numbers and/or different types of processors.
986 
987 The principal cause of difficulty is that different microprocessors of
988 the kind that run RadioHead may have different ways of representing
989 binary data such as integers. Some processors are little-endian and
990 some are big-endian in the way they represent multi-byte integers
991 (https://en.wikipedia.org/wiki/Endianness). And different processors
992 and maths libraries may represent floating point numbers in radically
993 different ways:
994 (https://en.wikipedia.org/wiki/Floating-point_arithmetic)
995 
996 All the RadioHead examples show how to send and receive simple ASCII
997 strings, and if thats all you want, refer to the examples folder in
998 your RadioHead distribution. But your needs may be more complicated
999 than that.
1000 
1001 The essence of all engineering is compromise so it will be up to you to
1002 decide whats best for your particular needs. The main choices are:
1003 - Raw Binary
1004 - Network Order Binary
1005 - ASCII
1006 
1007 \par Raw Binary
1008 
1009 With this technique you just pack the raw binary numbers into the packet:
1010 
1011 \code
1012 // Sending a single 16 bit unsigned integer
1013 // in the transmitter:
1014 ...
1015 uint16_t data = getsomevalue();
1016 if (!driver.send((uint8_t*)&data, sizeof(data)))
1017 {
1018  ...
1019 \endcode
1020 
1021 \code
1022 // and in the receiver:
1023 ...
1024 uint16_t data;
1025 uint8_t datalen = sizeof(data);
1026 if ( driver.recv((uint8_t*)&data, &datalen)
1027  && datalen == sizeof(data))
1028 {
1029  // Have the data, so do something with it
1030  uint16_t xyz = data;
1031  ...
1032 \endcode
1033 
1034 If you need to send more than one number at a time, its best to pack
1035 them into a structure
1036 
1037 \code
1038 // Sending several 16 bit unsigned integers in a structure
1039 // in a common header for your project:
1040 typedef struct
1041 {
1042  uint16_t dataitem1;
1043  uint16_t dataitem2;
1044 } MyDataStruct;
1045 ...
1046 \endcode
1047 
1048 \code
1049 // In the transmitter
1050 ...
1051 MyDataStruct data;
1052 data.dataitem1 = getsomevalue();
1053 data.dataitem2 = getsomeothervalue();
1054 if (!driver.send((uint8_t*)&data, sizeof(data)))
1055 {
1056  ...
1057 \endcode
1058 
1059 \code
1060 // in the receiver
1061 MyDataStruct data;
1062 uint8_t datalen = sizeof(data);
1063 if ( driver.recv((uint8_t*)&data, &datalen)
1064  && datalen == sizeof(data))
1065 {
1066  // Have the data, so do something with it
1067  uint16_t pqr = data.dataitem1;
1068  uint16_t xyz = data.dataitem2;
1069  ....
1070 \endcode
1071 
1072 
1073 The disadvantage with this simple technique becomes apparent if your
1074 transmitter and receiver have different endianness: the integers you
1075 receive will not be the same as the ones you sent (actually they are,
1076 but with the internal bytes swapped around, so they probably wont make
1077 sense to you). Endianness is not a problem if *every* data item you
1078 send is a just single byte (uint8_t or int8_t or char), or if the
1079 transmitter and receiver have the same endianness.
1080 
1081 So you should only adopt this technique if:
1082 - You only send data items of a single byte each, or
1083 - You are absolutely sure (now and forever into the future) that you
1084 will only ever use the same processor endianness in the transmitter and receiver.
1085 
1086 \par Network Order Binary
1087 
1088 One solution to the issue of endianness in your processors is to
1089 always convert your data from the processor's native byte order to
1090 'network byte order' before transmission and then convert it back to
1091 the receiver's native byte order on reception. You do this with the
1092 htons (host to network short) macro and friends. These functions may
1093 be a no-op on big-endian processors.
1094 
1095 With this technique you convert every multi-byte number to and from
1096 network byte order (note that in most Arduino processors an integer is
1097 in fact a short, and is the same as int16_t. We prefer to use types
1098 that explicitly specify their size so we can be sure of applying the
1099 right conversions):
1100 
1101 \code
1102 // Sending a single 16 bit unsigned integer
1103 // in the transmitter:
1104 ...
1105 uint16_t data = htons(getsomevalue());
1106 if (!driver.send((uint8_t*)&data, sizeof(data)))
1107 {
1108  ...
1109 \endcode
1110 \code
1111 // and in the receiver:
1112 ...
1113 uint16_t data;
1114 uint8_t datalen = sizeof(data);
1115 if ( driver.recv((uint8_t*)&data, &datalen)
1116  && datalen == sizeof(data))
1117 {
1118  // Have the data, so do something with it
1119  uint16_t xyz = ntohs(data);
1120  ...
1121 \endcode
1122 
1123 If you need to send more than one number at a time, its best to pack
1124 them into a structure
1125 
1126 \code
1127 // Sending several 16 bit unsigned integers in a structure
1128 // in a common header for your project:
1129 typedef struct
1130 {
1131  uint16_t dataitem1;
1132  uint16_t dataitem2;
1133 } MyDataStruct;
1134 ...
1135 \endcode
1136 \code
1137 // In the transmitter
1138 ...
1139 MyDataStruct data;
1140 data.dataitem1 = htons(getsomevalue());
1141 data.dataitem2 = htons(getsomeothervalue());
1142 if (!driver.send((uint8_t*)&data, sizeof(data)))
1143 {
1144  ...
1145 \endcode
1146 \code
1147 // in the receiver
1148 MyDataStruct data;
1149 uint8_t datalen = sizeof(data);
1150 if ( driver.recv((uint8_t*)&data, &datalen)
1151  && datalen == sizeof(data))
1152 {
1153  // Have the data, so do something with it
1154  uint16_t pqr = ntohs(data.dataitem1);
1155  uint16_t xyz = ntohs(data.dataitem2);
1156  ....
1157 \endcode
1158 
1159 This technique is quite general for integers but may not work if you
1160 want to send floating point number between transmitters and receivers
1161 that have different floating point number representations.
1162 
1163 
1164 \par ASCII
1165 
1166 In this technique, you transmit the printable ASCII equivalent of
1167 each floating point and then convert it back to a float in the receiver:
1168 
1169 \code
1170 // In the transmitter
1171 ...
1172 float data = getsomevalue();
1173 uint8_t buf[15]; // Bigger than the biggest possible ASCII
1174 snprintf(buf, sizeof(buf), "%f", data);
1175 if (!driver.send(buf, strlen(buf) + 1)) // Include the trailing NUL
1176 {
1177  ...
1178 \endcode
1179 \code
1180 
1181 // In the receiver
1182 ...
1183 float data;
1184 uint8_t buf[15]; // Bigger than the biggest possible ASCII
1185 uint8_t buflen = sizeof(buf);
1186 if (driver.recv(buf, &buflen))
1187 {
1188  // Have the data, so do something with it
1189  float data = atof(buf); // String to float
1190  ...
1191 \endcode
1192 
1193 \par Conclusion:
1194 
1195 - This is just a basic introduction to the issues. You may need to
1196 extend your study into related C/C++ programming techniques.
1197 
1198 - You can extend these ideas to signed 16 bit (int16_t) and 32 bit
1199 (uint32_t, int32_t) numbers.
1200 
1201 - Things can be simple or complicated depending on the needs of your
1202 project.
1203 
1204 - We are not going to write your code for you: its up to you to take
1205 these examples and explanations and extend them to suit your needs.
1206 
1207 */
1208 
1209 
1210 
1211 #ifndef RadioHead_h
1212 #define RadioHead_h
1213 
1214 // Official version numbers are maintained automatically by Makefile:
1215 #define RH_VERSION_MAJOR 1
1216 #define RH_VERSION_MINOR 100
1217 
1218 // Symbolic names for currently supported platform types
1219 #define RH_PLATFORM_ARDUINO 1
1220 #define RH_PLATFORM_MSP430 2
1221 #define RH_PLATFORM_STM32 3
1222 #define RH_PLATFORM_GENERIC_AVR8 4
1223 #define RH_PLATFORM_UNO32 5
1224 #define RH_PLATFORM_UNIX 6
1225 #define RH_PLATFORM_STM32STD 7
1226 #define RH_PLATFORM_STM32F4_HAL 8
1227 #define RH_PLATFORM_RASPI 9
1228 #define RH_PLATFORM_NRF51 10
1229 #define RH_PLATFORM_ESP8266 11
1230 #define RH_PLATFORM_STM32F2 12
1231 #define RH_PLATFORM_CHIPKIT_CORE 13
1232 #define RH_PLATFORM_ESP32 14
1233 #define RH_PLATFORM_NRF52 15
1234 #define RH_PLATFORM_MONGOOSE_OS 16
1235 #define RH_PLATFORM_ATTINY 17
1236 // Spencer Kondes megaTinyCore:
1237 #define RH_PLATFORM_ATTINY_MEGA 18
1238 
1239 ////////////////////////////////////////////////////
1240 // Select platform automatically, if possible
1241 #ifndef RH_PLATFORM
1242  #if (defined(MPIDE) && MPIDE>=150 && defined(ARDUINO))
1243  // Using ChipKIT Core on Arduino IDE
1244  #define RH_PLATFORM RH_PLATFORM_CHIPKIT_CORE
1245  #elif defined(MPIDE)
1246  // Uno32 under old MPIDE, which has been discontinued:
1247  #define RH_PLATFORM RH_PLATFORM_UNO32
1248  #elif defined(NRF51) || defined(NRF52)
1249  #define RH_PLATFORM RH_PLATFORM_NRF51
1250  #elif defined(NRF52)
1251  #define RH_PLATFORM RH_PLATFORM_NRF52
1252  #elif defined(ESP8266)
1253  #define RH_PLATFORM RH_PLATFORM_ESP8266
1254  #elif defined(ESP32)
1255  #define RH_PLATFORM RH_PLATFORM_ESP32
1256  #elif defined(MGOS)
1257  #define RH_PLATFORM RH_PLATFORM_MONGOOSE_OS
1258  #elif defined(ARDUINO_attinyxy2) || defined(ARDUINO_attinyxy4) || defined(ARDUINO_attinyxy6) || defined(ARDUINO_attinyxy7)
1259  #define RH_PLATFORM RH_PLATFORM_ATTINY_MEGA
1260  #elif defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtinyX4__) || defined(__AVR_ATtinyX5__) || defined(__AVR_ATtiny2313__) || defined(__AVR_ATtiny4313__) || defined(__AVR_ATtinyX313__) || defined(ARDUINO_attiny)
1261  #define RH_PLATFORM RH_PLATFORM_ATTINY
1262  #elif defined(ARDUINO)
1263  #define RH_PLATFORM RH_PLATFORM_ARDUINO
1264  #elif defined(__MSP430G2452__) || defined(__MSP430G2553__)
1265  #define RH_PLATFORM RH_PLATFORM_MSP430
1266  #elif defined(MCU_STM32F103RE)
1267  #define RH_PLATFORM RH_PLATFORM_STM32
1268  #elif defined(STM32F2XX)
1269  #define RH_PLATFORM RH_PLATFORM_STM32F2
1270  #elif defined(USE_STDPERIPH_DRIVER)
1271  #define RH_PLATFORM RH_PLATFORM_STM32STD
1272  #elif defined(RASPBERRY_PI)
1273  #define RH_PLATFORM RH_PLATFORM_RASPI
1274  #elif defined(__unix__) // Linux
1275  #define RH_PLATFORM RH_PLATFORM_UNIX
1276  #elif defined(__APPLE__) // OSX
1277  #define RH_PLATFORM RH_PLATFORM_UNIX
1278  #else
1279  #error Platform not defined!
1280  #endif
1281 #endif
1282 
1283 ////////////////////////////////////////////////////
1284 // Platform specific headers:
1285 #if (RH_PLATFORM == RH_PLATFORM_ARDUINO)
1286  #if (ARDUINO >= 100)
1287  #include <Arduino.h>
1288  #else
1289  #include <wiring.h>
1290  #endif
1291  #include <SPI.h>
1292  #define RH_HAVE_HARDWARE_SPI
1293  #define RH_HAVE_SERIAL
1294  #if defined(ARDUINO_ARCH_STM32F4)
1295  // output to Serial causes hangs on STM32 F4 Discovery board
1296  // There seems to be no way to output text to the USB connection
1297  #define Serial Serial2
1298  #endif
1299 #elif (RH_PLATFORM == RH_PLATFORM_ATTINY)
1300  #warning Arduino TinyCore does not support hardware SPI. Use software SPI instead.
1301 #elif (RH_PLATFORM == RH_PLATFORM_ATTINY_MEGA)
1302  #include <SPI.h>
1303  #define RH_HAVE_HARDWARE_SPI
1304  #define RH_HAVE_SERIAL
1305 #elif (RH_PLATFORM == RH_PLATFORM_ESP8266) // ESP8266 processor on Arduino IDE
1306  #include <Arduino.h>
1307  #include <SPI.h>
1308  #define RH_HAVE_HARDWARE_SPI
1309  #define RH_HAVE_SERIAL
1310  #define RH_MISSING_SPIUSINGINTERRUPT
1311 
1312 #elif (RH_PLATFORM == RH_PLATFORM_ESP32) // ESP32 processor on Arduino IDE
1313  #include <Arduino.h>
1314  #include <SPI.h>
1315  #define RH_HAVE_HARDWARE_SPI
1316  #define RH_HAVE_SERIAL
1317  #define RH_MISSING_SPIUSINGINTERRUPT
1318 
1319  #elif (RH_PLATFORM == RH_PLATFORM_MONGOOSE_OS) // Mongoose OS platform
1320  #include <mgos.h>
1321  #include <mgos_adc.h>
1322  #include <mgos_pwm.h>
1323  #include <MGOSCompat/HardwareSerial.h>
1324  #include <MGOSCompat/HardwareSPI.h>
1325  #include <MGOSCompat/MGOS.h>
1326  #include <math.h> // We use the floor() math function.
1327  #define RH_HAVE_HARDWARE_SPI
1328  //If a Radio is connected via a serial port then this defines the serial
1329  //port the radio is connected to.
1330  #if defined(RH_SERIAL_PORT)
1331  #if RH_SERIAL_PORT == 0
1332  #define Serial Serial0
1333  #elif RH_SERIAL_PORT == 1
1334  #define Serial Serial1
1335  #elif RH_SERIAL_PORT == 2
1336  #define Serial Serial2
1337  #endif
1338  #else
1339  #warning "RH_SERIAL_PORT not defined. Therefore serial port 0 selected"
1340  #define Serial Serial0
1341  #endif
1342  #define RH_HAVE_SERIAL
1343 
1344 #elif (RH_PLATFORM == RH_PLATFORM_MSP430) // LaunchPad specific
1345  #include "legacymsp430.h"
1346  #include "Energia.h"
1347  #include <SPI.h>
1348  #define RH_HAVE_HARDWARE_SPI
1349  #define RH_HAVE_SERIALg
1350 
1351 #elif (RH_PLATFORM == RH_PLATFORM_UNO32 || RH_PLATFORM == RH_PLATFORM_CHIPKIT_CORE)
1352  #include <WProgram.h>
1353  #include <string.h>
1354  #include <SPI.h>
1355  #define RH_HAVE_HARDWARE_SPI
1356  #define memcpy_P memcpy
1357  #define RH_HAVE_SERIAL
1358 
1359 #elif (RH_PLATFORM == RH_PLATFORM_STM32) // Maple, Flymaple etc
1360  #include <STM32ArduinoCompat/wirish.h>
1361  #include <stdint.h>
1362  #include <string.h>
1363  #include <STM32ArduinoCompat/HardwareSPI.h>
1364  #define RH_HAVE_HARDWARE_SPI
1365  // Defines which timer to use on Maple
1366  #define MAPLE_TIMER 1
1367  #define PROGMEM
1368  #define memcpy_P memcpy
1369  #define Serial SerialUSB
1370  #define RH_HAVE_SERIAL
1371 
1372 #elif (RH_PLATFORM == RH_PLATFORM_STM32F2) // Particle Photon with firmware-develop
1373  #include <stm32f2xx.h>
1374  #include <application.h>
1375  #include <math.h> // floor
1376  #define RH_HAVE_SERIAL
1377  #define RH_HAVE_HARDWARE_SPI
1378 
1379 #elif (RH_PLATFORM == RH_PLATFORM_STM32STD) // STM32 with STM32F4xx_StdPeriph_Driver
1380  #include <stm32f4xx.h>
1381  #include <wirish.h>
1382  #include <stdint.h>
1383  #include <string.h>
1384  #include <math.h>
1385  #include <HardwareSPI.h>
1386  #define RH_HAVE_HARDWARE_SPI
1387  #define Serial SerialUSB
1388  #define RH_HAVE_SERIAL
1389 
1390 #elif (RH_PLATFORM == RH_PLATFORM_GENERIC_AVR8)
1391  #include <avr/io.h>
1392  #include <avr/interrupt.h>
1393  #include <util/delay.h>
1394  #include <string.h>
1395  #include <stdbool.h>
1396  #define RH_HAVE_HARDWARE_SPI
1397  #include <SPI.h>
1398 
1399 // For Steve Childress port to ARM M4 w/CMSIS with STM's Hardware Abstraction lib.
1400 // See ArduinoWorkarounds.h (not supplied)
1401 #elif (RH_PLATFORM == RH_PLATFORM_STM32F4_HAL)
1402  #include <ArduinoWorkarounds.h>
1403  #include <stm32f4xx.h> // Also using ST's CubeMX to generate I/O and CPU setup source code for IAR/EWARM, not GCC ARM.
1404  #include <stdint.h>
1405  #include <string.h>
1406  #include <math.h>
1407  #define RH_HAVE_HARDWARE_SPI // using HAL (Hardware Abstraction Libraries from ST along with CMSIS, not arduino libs or pins concept.
1408 
1409 #elif (RH_PLATFORM == RH_PLATFORM_RASPI)
1410  #define RH_HAVE_HARDWARE_SPI
1411  #define RH_HAVE_SERIAL
1412  #define PROGMEM
1413  #if (__has_include (<pigpio.h>))
1414  #include <RHutil_pigpio/RasPi.h>
1415  #else
1416  #include <RHutil/RasPi.h>
1417  #endif
1418  #include <string.h>
1419  //Define SS for CS0 or pin 24
1420  #define SS 8
1421 
1422 #elif (RH_PLATFORM == RH_PLATFORM_NRF51)
1423  #define RH_HAVE_SERIAL
1424  #define PROGMEM
1425  #include <Arduino.h>
1426 
1427 #elif (RH_PLATFORM == RH_PLATFORM_NRF52)
1428  #include <SPI.h>
1429  #define RH_HAVE_HARDWARE_SPI
1430  #define RH_HAVE_SERIAL
1431  #define PROGMEM
1432  #include <Arduino.h>
1433 
1434 #elif (RH_PLATFORM == RH_PLATFORM_UNIX)
1435  // Simulate the sketch on Linux and OSX
1436  #include <RHutil/simulator.h>
1437  #define RH_HAVE_SERIAL
1438 #include <netinet/in.h> // For htons and friends
1439 
1440 #else
1441  #error Platform unknown!
1442 #endif
1443 
1444 ////////////////////////////////////////////////////
1445 // This is an attempt to make a portable atomic block
1446 #if (RH_PLATFORM == RH_PLATFORM_ARDUINO)
1447 #if defined(__arm__)
1448  #include <RHutil/atomic.h>
1449  #else
1450  #include <util/atomic.h>
1451  #endif
1452  #define ATOMIC_BLOCK_START ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
1453  #define ATOMIC_BLOCK_END }
1454 #elif (RH_PLATFORM == RH_PLATFORM_CHIPKIT_CORE)
1455  // UsingChipKIT Core on Arduino IDE
1456  #define ATOMIC_BLOCK_START unsigned int __status = disableInterrupts(); {
1457  #define ATOMIC_BLOCK_END } restoreInterrupts(__status);
1458 #elif (RH_PLATFORM == RH_PLATFORM_UNO32)
1459  // Under old MPIDE, which has been discontinued:
1460  #include <peripheral/int.h>
1461  #define ATOMIC_BLOCK_START unsigned int __status = INTDisableInterrupts(); {
1462  #define ATOMIC_BLOCK_END } INTRestoreInterrupts(__status);
1463 #elif (RH_PLATFORM == RH_PLATFORM_STM32F2) // Particle Photon with firmware-develop
1464  #define ATOMIC_BLOCK_START { int __prev = HAL_disable_irq();
1465  #define ATOMIC_BLOCK_END HAL_enable_irq(__prev); }
1466 #elif (RH_PLATFORM == RH_PLATFORM_ESP8266)
1467 // See hardware/esp8266/2.0.0/cores/esp8266/Arduino.h
1468  #define ATOMIC_BLOCK_START { uint32_t __savedPS = xt_rsil(15);
1469  #define ATOMIC_BLOCK_END xt_wsr_ps(__savedPS);}
1470 #else
1471  // TO BE DONE:
1472  #define ATOMIC_BLOCK_START
1473  #define ATOMIC_BLOCK_END
1474 #endif
1475 
1476 ////////////////////////////////////////////////////
1477 // Try to be compatible with systems that support yield() and multitasking
1478 // instead of spin-loops
1479 // Recent Arduino IDE or Teensy 3 has yield()
1480 #if (RH_PLATFORM == RH_PLATFORM_ARDUINO && ARDUINO >= 155) || (defined(TEENSYDUINO) && defined(__MK20DX128__))
1481  #define YIELD yield();
1482 #elif (RH_PLATFORM == RH_PLATFORM_ESP8266)
1483 // ESP8266 also has it
1484  #define YIELD yield();
1485 #elif (RH_PLATFORM == RH_PLATFORM_MONGOOSE_OS)
1486  //ESP32 and ESP8266 use freertos so we include calls
1487  //that we would normall exit a function and return to
1488  //the rtos in mgosYield() (E.G flush TX uart buffer
1489  extern "C" {
1490  void mgosYield(void);
1491  }
1492  #define YIELD mgosYield()
1493 #else
1494  #define YIELD
1495 #endif
1496 
1497 ////////////////////////////////////////////////////
1498 // digitalPinToInterrupt is not available prior to Arduino 1.5.6 and 1.0.6
1499 // See http://arduino.cc/en/Reference/attachInterrupt
1500 #ifndef NOT_AN_INTERRUPT
1501  #define NOT_AN_INTERRUPT -1
1502 #endif
1503 #ifndef digitalPinToInterrupt
1504  #if (RH_PLATFORM == RH_PLATFORM_ARDUINO) && !defined(__arm__)
1505 
1506  #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
1507  // Arduino Mega, Mega ADK, Mega Pro
1508  // 2->0, 3->1, 21->2, 20->3, 19->4, 18->5
1509  #define digitalPinToInterrupt(p) ((p) == 2 ? 0 : ((p) == 3 ? 1 : ((p) >= 18 && (p) <= 21 ? 23 - (p) : NOT_AN_INTERRUPT)))
1510 
1511  #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
1512  // Arduino 1284 and 1284P - See Manicbug and Optiboot
1513  // 10->0, 11->1, 2->2
1514  #define digitalPinToInterrupt(p) ((p) == 10 ? 0 : ((p) == 11 ? 1 : ((p) == 2 ? 2 : NOT_AN_INTERRUPT)))
1515 
1516  #elif defined(__AVR_ATmega32U4__)
1517  // Leonardo, Yun, Micro, Pro Micro, Flora, Esplora
1518  // 3->0, 2->1, 0->2, 1->3, 7->4
1519  #define digitalPinToInterrupt(p) ((p) == 0 ? 2 : ((p) == 1 ? 3 : ((p) == 2 ? 1 : ((p) == 3 ? 0 : ((p) == 7 ? 4 : NOT_AN_INTERRUPT)))))
1520 
1521  #else
1522  // All other arduino except Due:
1523  // Serial Arduino, Extreme, NG, BT, Uno, Diecimila, Duemilanove, Nano, Menta, Pro, Mini 04, Fio, LilyPad, Ethernet etc
1524  // 2->0, 3->1
1525  #define digitalPinToInterrupt(p) ((p) == 2 ? 0 : ((p) == 3 ? 1 : NOT_AN_INTERRUPT))
1526 
1527  #endif
1528 
1529  #elif (RH_PLATFORM == RH_PLATFORM_UNO32) || (RH_PLATFORM == RH_PLATFORM_CHIPKIT_CORE)
1530  // Hmmm, this is correct for Uno32, but what about other boards on ChipKIT Core?
1531  #define digitalPinToInterrupt(p) ((p) == 38 ? 0 : ((p) == 2 ? 1 : ((p) == 7 ? 2 : ((p) == 8 ? 3 : ((p) == 735 ? 4 : NOT_AN_INTERRUPT)))))
1532 
1533  #else
1534  // Everything else (including Due and Teensy) interrupt number the same as the interrupt pin number
1535  #define digitalPinToInterrupt(p) (p)
1536  #endif
1537 #endif
1538 
1539 // On some platforms, attachInterrupt() takes a pin number, not an interrupt number
1540 #if (RH_PLATFORM == RH_PLATFORM_ARDUINO) && defined (__arm__) && (defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_SAM_DUE))
1541  #define RH_ATTACHINTERRUPT_TAKES_PIN_NUMBER
1542 #endif
1543 
1544 // Slave select pin, some platforms such as ATTiny do not define it.
1545 #ifndef SS
1546  #define SS 10
1547 #endif
1548 
1549 // Some platforms require specail attributes for interrupt routines
1550 #if (RH_PLATFORM == RH_PLATFORM_ESP8266)
1551  // interrupt handler and related code must be in RAM on ESP8266,
1552  // according to issue #46.
1553  #define RH_INTERRUPT_ATTR ICACHE_RAM_ATTR
1554 
1555 #elif (RH_PLATFORM == RH_PLATFORM_ESP32)
1556  #define RH_INTERRUPT_ATTR IRAM_ATTR
1557 #else
1558  #define RH_INTERRUPT_ATTR
1559 #endif
1560 
1561 // These defs cause trouble on some versions of Arduino
1562 #undef abs
1563 #undef round
1564 #undef double
1565 
1566 // Sigh: there is no widespread adoption of htons and friends in the base code, only in some WiFi headers etc
1567 // that have a lot of excess baggage
1568 #if RH_PLATFORM != RH_PLATFORM_UNIX && !defined(htons)
1569 // #ifndef htons
1570 // These predefined macros available on modern GCC compilers
1571  #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1572  // Atmel processors
1573  #define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) )
1574  #define ntohs(x) htons(x)
1575  #define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \
1576  ((x)<< 8 & 0x00FF0000UL) | \
1577  ((x)>> 8 & 0x0000FF00UL) | \
1578  ((x)>>24 & 0x000000FFUL) )
1579  #define ntohl(x) htonl(x)
1580 
1581  #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1582  // Others
1583  #define htons(x) (x)
1584  #define ntohs(x) (x)
1585  #define htonl(x) (x)
1586  #define ntohl(x) (x)
1587 
1588  #else
1589  #error "Dont know how to define htons and friends for this processor"
1590  #endif
1591 #endif
1592 
1593 // This is the address that indicates a broadcast
1594 #define RH_BROADCAST_ADDRESS 0xff
1595 
1596 // Uncomment this is to enable Encryption (see RHEncryptedDriver):
1597 // But ensure you have installed the Crypto directory from arduinolibs first:
1598 // http://rweather.github.io/arduinolibs/index.html
1599 //#define RH_ENABLE_ENCRYPTION_MODULE
1600 
1601 #endif