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