RadioHead
RH_NRF905.h
1// RH_NRF905.h
2// Author: Mike McCauley (mikem@airspayce.com)
3// Copyright (C) 2014 Mike McCauley
4// $Id: RH_NRF905.h,v 1.11 2017/07/25 05:26:50 mikem Exp $
5//
6
7#ifndef RH_NRF905_h
8#define RH_NRF905_h
9
10#include <RHGenericSPI.h>
11#include <RHNRFSPIDriver.h>
12
13// This is the maximum (and only) number of bytes that can be carried by the nRF905.
14// We use some for headers, leaving fewer for RadioHead messages
15#define RH_NRF905_MAX_PAYLOAD_LEN 32
16
17// The length of the headers we add.
18// The headers are inside the nRF905 payload
19// As well as the usual TO, FROM, ID, FLAGS, we also need LEN, since
20// nRF905 only has fixed width messages.
21// REVISIT: could we have put the LEN into the FLAGS field?
22#define RH_NRF905_HEADER_LEN 5
23
24// This is the maximum RadioHead user message length that can be supported by this library. Limited by
25// the supported message lengths in the nRF905
26#define RH_NRF905_MAX_MESSAGE_LEN (RH_NRF905_MAX_PAYLOAD_LEN-RH_NRF905_HEADER_LEN)
27
28// Register names
29#define RH_NRF905_REG_MASK 0x0f
30#define RH_NRF905_REG_W_CONFIG 0x00
31#define RH_NRF905_REG_R_CONFIG 0x10
32#define RH_NRF905_REG_W_TX_PAYLOAD 0x20
33#define RH_NRF905_REG_R_TX_PAYLOAD 0x21
34#define RH_NRF905_REG_W_TX_ADDRESS 0x22
35#define RH_NRF905_REG_R_TX_ADDRESS 0x23
36#define RH_NRF905_REG_R_RX_PAYLOAD 0x24
37#define RH_NRF905_REG_CHANNEL_CONFIG 0x80
38
39// Configuration register
40#define RH_NRF905_CONFIG_0 0x00
41#define RH_NRF905_CONFIG_0_CH_NO 0xff
42
43#define RH_NRF905_CONFIG_1 0x01
44#define RH_NRF905_CONFIG_1_AUTO_RETRAN 0x20
45#define RH_NRF905_CONFIG_1_RX_RED_PWR 0x10
46#define RH_NRF905_CONFIG_1_PA_PWR 0x0c
47#define RH_NRF905_CONFIG_1_PA_PWR_N10DBM 0x00
48#define RH_NRF905_CONFIG_1_PA_PWR_N2DBM 0x04
49#define RH_NRF905_CONFIG_1_PA_PWR_6DBM 0x08
50#define RH_NRF905_CONFIG_1_PA_PWR_10DBM 0x0c
51#define RH_NRF905_CONFIG_1_HFREQ_PLL 0x02
52#define RH_NRF905_CONFIG_1_CH_NO 0x01
53
54#define RH_NRF905_CONFIG_2 0x02
55#define RH_NRF905_CONFIG_2_TX_AFW 0x70
56#define RH_NRF905_CONFIG_2_RX_AFW 0x07
57
58#define RH_NRF905_CONFIG_3 0x03
59#define RH_NRF905_CONFIG_3_RX_PW 0x3f
60
61#define RH_NRF905_CONFIG_4 0x04
62#define RH_NRF905_CONFIG_4_TX_PW 0x3f
63
64#define RH_NRF905_CONFIG_5 0x05
65#define RH_NRF905_CONFIG_5_RX_ADDRESS 0xff
66
67#define RH_NRF905_CONFIG_6 0x06
68#define RH_NRF905_CONFIG_6_RX_ADDRESS 0xff
69
70#define RH_NRF905_CONFIG_7 0x07
71#define RH_NRF905_CONFIG_7_RX_ADDRESS 0xff
72
73#define RH_NRF905_CONFIG_8 0x08
74#define RH_NRF905_CONFIG_8_RX_ADDRESS 0xff
75
76#define RH_NRF905_CONFIG_9 0x09
77#define RH_NRF905_CONFIG_9_CRC_MODE_16BIT 0x80
78#define RH_NRF905_CONFIG_9_CRC_EN 0x40
79#define RH_NRF905_CONFIG_9_XOF 0x38
80#define RH_NRF905_CONFIG_9_XOF_4MHZ 0x00
81#define RH_NRF905_CONFIG_9_XOF_8MHZ 0x08
82#define RH_NRF905_CONFIG_9_XOF_12MHZ 0x10
83#define RH_NRF905_CONFIG_9_XOF_16MHZ 0x18
84#define RH_NRF905_CONFIG_9_XOF_20MHZ 0x20
85#define RH_NRF905_CONFIG_9_UP_CLK_EN 0x04
86#define RH_NRF905_CONFIG_9_UP_CLK_FREQ 0x03
87#define RH_NRF905_CONFIG_9_UP_CLK_FREQ_4MHZ 0x00
88#define RH_NRF905_CONFIG_9_UP_CLK_FREQ_2MHZ 0x01
89#define RH_NRF905_CONFIG_9_UP_CLK_FREQ_1MHZ 0x02
90#define RH_NRF905_CONFIG_9_UP_CLK_FREQ_500KHZ 0x03
91
92// Status register is always read as first byte
93#define RH_NRF905_STATUS_AM 0x80
94#define RH_NRF905_STATUS_DR 0x20
95
96/////////////////////////////////////////////////////////////////////
97/// \class RH_NRF905 RH_NRF905.h <RH_NRF905.h>
98/// \brief Send and receive unaddressed, unreliable datagrams by nRF905 and compatible transceivers.
99///
100/// This base class provides basic functions for sending and receiving unaddressed, unreliable datagrams
101/// of arbitrary length to 28 octets per packet. Use one of the Manager classes to get addressing and
102/// acknowledgement reliability, routing, meshes etc.
103///
104/// The nRF905 transceiver is configured to use Enhanced Shockburst with 16 Bit CRC, and 32 octet packets.
105///
106/// Naturally, for any 2 radios to communicate that must be configured to use the same frequency
107/// and with identical network addresses.
108///
109/// The nRF905 from Nordic Semiconductor http://www.nordicsemi.com/eng/Products/Sub-1-GHz-RF/nRF905
110/// (http://www.nordicsemi.com/jpn/nordic/content_download/2452/29528/file/Product_Specification_nRF905_v1.5.pdf)
111/// is a low-cost 433/868/915 MHz ISM transceiver module. It supports a number of channel frequencies at
112/// 100kHz deviation and 50kHz bandwidth with Manchester encoding.
113///
114/// We tested with inexpensive nRF905 modules from eBay, similar to:
115/// http://www.aliexpress.com/store/product/Free-ship-NRF905-433MHz-Wireless-Transmission-Module-Transceiver-Module-with-Antenna-for-the-433MHz-ISM-band/513046_607163305.html
116///
117/// This library provides functions for sending and receiving messages of up to 27 octets on any
118/// frequency supported by the nRF905.
119///
120/// Several nRF905 modules can be connected to an Arduino, permitting the construction of translators
121/// and frequency changers, etc.
122///
123/// Example Arduino programs are included to show the main modes of use.
124///
125/// \par Packet Format
126///
127/// All messages sent and received by this class conform to this fixed length packet format
128///
129/// - 4 octets NETWORK ADDRESS
130/// - 32 octets PAYLOAD, consisting of:
131/// - 1 octet TO header
132/// - 1 octet FROM header
133/// - 1 octet ID header
134/// - 1 octet FLAGS header
135/// - 1 octet user message length header
136/// - 0 to 27 octets of user message, trailing octets after the user message length are ignored
137/// - 2 octets CRC
138///
139/// All messages sent and received by this driver are 32 octets. The user message length is embedded in the message.
140///
141/// \par Connecting nRF905
142///
143/// The nRF905 is a 3.3V part is is *NOT* 5V tolerant. So you MUST use a 3.3V CPU such as Teensy, Arduino Due etc
144/// or else provide for level shifters between the CPU and the nRF905. Failure to consider this will probably
145/// break your nRF905.
146///
147/// The electrical connection between the nRF905 and the CPU require 3.3V, the 3 x SPI pins (SCK, SDI, SDO),
148/// a Chip Enable pin, a Transmit Enable pin and a Slave Select pin.
149///
150/// The examples below assume the commonly found cheap Chinese nRF905 modules. The RH_RF905 driver assumes the
151/// the nRF905 has a 16MHz crystal.
152///
153/// Connect the nRF905 to Teensy (or Arduino with suitable level shifters) like this
154/// \code
155/// CPU nRF905 module
156/// 3V3----------VCC (3.3V)
157/// pin D8-----------CE (chip enable in)
158/// pin D9-----------TX_EN (transmit enable in)
159/// SS pin D10----------CSN (chip select in)
160/// SCK pin D13----------SCK (SPI clock in)
161/// MOSI pin D11----------MOSI (SPI Data in)
162/// MISO pin D12----------MISO (SPI data out)
163/// GND----------GND (ground in)
164/// \endcode
165///
166/// Caution: Arduino Due is a 3.3V part and is not 5V tolerant (so too is the nRF905 module
167/// so they can be connected directly together. Unlike other Arduinos the Due has it default SPI
168/// connections on a dedicated 6 pin SPI header in the center of the board, which is
169/// physically compatible with Uno, Leonardo and Mega2560. A little dot marks pin 1 on the header.
170/// You must connect to these
171/// and *not* to the usual Arduino SPI pins Digital 11, 12 and 13.
172/// See http://21stdigitalhome.blogspot.com.au/2013/02/arduino-due-hardware-spi.html
173///
174/// Connect the nRF905 to Arduino Due like this
175/// \code
176/// CPU nRF905 module
177/// 3V3----------VCC (3.3V)
178/// pin D8-----------CE (chip enable in)
179/// pin D9-----------TX_EN (transmit enable in)
180/// SS pin D10----------CSN (chip select in)
181/// SCK on SPI header pin 3----------SCK (SPI clock in)
182/// MOSI on SPI header pin 4----------MOSI (SPI Data in)
183/// MISO on SPI header pin 1----------MISO (SPI data out)
184/// GND----------GND (ground in)
185/// \endcode
186///
187/// and you can then use the default constructor RH_NRF905().
188/// You can override the default settings for the CE, TX_EN and CSN pins
189/// in the NRF905() constructor if you wish to connect the slave select CSN to other than the normal one for your
190/// CPU.
191///
192/// It is possible to have 2 radios conected to one CPU, provided each radio has its own
193/// CSN, TX_EN and CE line (SCK, MOSI and MISO are common to both radios)
194///
195/// \par Transmitter Power
196///
197/// You can control the transmitter power to be one of 4 power levels: -10, -2, 6 or 10dBm,
198/// using the setRF() function, eg:
199/// \code
200/// nrf905.setRF(RH_NRF905::TransmitPower10dBm);
201/// \endcode
202///
203/// We have made some actual power measurements against
204/// programmed power for an nRF905 module from www.rfinchina.com under the following conditions:
205/// - Teensy 3.1
206/// - nRF905 module (with SMA antenna connector) wired to Teensy as described above, channel 108.
207/// - 20cm SMA-SMA cable
208/// - MiniKits AD8307 HF/VHF Power Head (calibrated against Rohde&Schwartz 806.2020 test set)
209/// - Tektronix TDS220 scope to measure the Vout from power head
210/// \code
211/// Program power Measured Power
212/// dBm dBm
213/// -10 -16
214/// -2 -8
215/// 6 0
216/// 10 8
217/// \endcode
218/// (Caution: we dont claim laboratory accuracy for these measurements)
219/// You would not expect to get anywhere near these powers to air with a simple 1/4 wavelength wire antenna.
220///
221/// \par Example programs
222///
223/// Several example programs are provided. They work out of the box with Teensy 3.1 and Arduino Due
224/// connected as show above.
225///
226/// \par Radio Performance
227///
228/// Frequency accuracy may be debatable.
229///
230/// \par Memory
231///
232/// Memory usage of this class is minimal. The compiled client and server sketches are about 16000 bytes on Teensy.
233///
235{
236public:
237 /// \brief Convenient values for setting transmitter power in setRF()
238 /// These are designed to agree with the values for RH_NRF905_CONFIG_1_PA_PWR after
239 /// left shifting by 2
240 /// To be passed to setRF();
241 typedef enum
242 {
243 TransmitPowerm10dBm = 0, ///< -10 dBm
246 TransmitPower10dBm ///< 10 dBm
248
249 /// Constructor. You can have multiple instances, but each instance must have its own
250 /// chip enable and slave select pin.
251 /// After constructing, you must call init() to initialise the interface
252 /// and the radio module
253 /// \param[in] chipEnablePin the Arduino pin to use to enable the chip for transmit/receive
254 /// \param[in] txEnablePin the Arduino pin cponnected to the txEn pin on the radio that enable transmit mode
255 /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the NRF905 before
256 /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega,
257 /// D10 for Maple, Teensy)
258 /// \param[in] spi Pointer to the SPI interface object to use.
259 /// Defaults to the standard Arduino hardware SPI interface
260 RH_NRF905(uint8_t chipEnablePin = 8, uint8_t txEnablePin = 9, uint8_t slaveSelectPin = SS, RHGenericSPI& spi = hardware_spi);
261
262 /// Initialises this instance and the radio module connected to it.
263 /// The following steps are taken:g
264 /// - Set the chip enable and chip select pins to output LOW, HIGH respectively.
265 /// - Initialise the SPI output pins
266 /// - Initialise the SPI interface library to 8MHz (Hint, if you want to lower
267 /// the SPI frequency (perhaps where you have other SPI shields, low voltages etc),
268 /// call SPI.setClockDivider() after init()).
269 /// -Flush the receiver and transmitter buffers
270 /// - Set the radio to receive with powerUpRx();
271 /// \return true if everything was successful
272 bool init();
273
274 /// Reads a single register from the NRF905
275 /// \param[in] reg Register number, one of NR905_REG_*
276 /// \return The value of the register
277 uint8_t spiReadRegister(uint8_t reg);
278
279 /// Writes a single byte to the NRF905, and at the ame time reads the current STATUS register
280 /// \param[in] reg Register number, one of NRF905_REG_*
281 /// \param[in] val The value to write
282 /// \return the current STATUS (read while the command is sent)
283 uint8_t spiWriteRegister(uint8_t reg, uint8_t val);
284
285 /// Reads a number of consecutive registers from the NRF905 using burst read mode
286 /// \param[in] reg Register number of the first register, one of NRF905_REG_*
287 /// \param[in] dest Array to write the register values to. Must be at least len bytes
288 /// \param[in] len Number of bytes to read
289 /// \return the current STATUS (read while the command is sent)
290 uint8_t spiBurstReadRegister(uint8_t reg, uint8_t* dest, uint8_t len);
291
292 /// Write a number of consecutive registers using burst write mode
293 /// \param[in] reg Register number of the first register, one of NRF905_REG_*
294 /// \param[in] src Array of new register values to write. Must be at least len bytes
295 /// \param[in] len Number of bytes to write
296 /// \return the current STATUS (read while the command is sent)
297 uint8_t spiBurstWriteRegister(uint8_t reg, uint8_t* src, uint8_t len);
298
299 /// Reads and returns the device status register NRF905_REG_02_DEVICE_STATUS
300 /// \return The value of the device status register
301 uint8_t statusRead();
302
303 /// Sets the transmit and receive channel number.
304 /// The RF frequency used is (422.4 + channel/10) * (1+hiFrequency) MHz
305 /// \param[in] channel The channel number.
306 /// \param[in] hiFrequency false for low frequency band (422.4MHz and up), true for high frequency band (845MHz and up)
307 /// \return true on success
308 bool setChannel(uint16_t channel, bool hiFrequency = false);
309
310 /// Sets the Network address.
311 /// Only nodes with the same network address can communicate with each other. You
312 /// can set different network addresses in different sets of nodes to isolate them from each other.
313 /// The default network address is 0xE7E7E7E7
314 /// \param[in] address The new network address. Must match the network address of any receiving node(s).
315 /// \param[in] len Number of bytes of address to set (1 to 4).
316 /// \return true on success, false if len is not in the range 1-4 inclusive.
317 bool setNetworkAddress(uint8_t* address, uint8_t len);
318
319 /// Sets the transmitter power to use
320 /// \param [in] power Transmitter power. One of NRF905::TransmitPower.
321 /// \return true on success
322 bool setRF(TransmitPower power);
323
324 /// Sets the radio in power down mode.
325 /// Sets chip enable to LOW.
326 /// \return true on success
327 void setModeIdle();
328
329 /// Sets the radio in RX mode.
330 /// Sets chip enable to HIGH to enable the chip in RX mode.
331 /// \return true on success
332 void setModeRx();
333
334 /// Sets the radio in TX mode.
335 /// Pulses the chip enable LOW then HIGH to enable the chip in TX mode.
336 /// \return true on success
337 void setModeTx();
338
339 /// Sends data to the address set by setTransmitAddress()
340 /// Sets the radio to TX mode
341 /// \param [in] data Data bytes to send.
342 /// \param [in] len Number of data bytes to set in the TX buffer. The actual size of the
343 /// transmitted data payload is set by setPayloadSize. Maximum message length actually
344 /// transmitted is RH_NRF905_MAX_MESSAGE_LEN = 27.
345 /// \return true on success (which does not necessarily mean the receiver got the message, only that the message was
346 /// successfully transmitted). Returns false if the requested message length exceeds RH_NRF905_MAX_MESSAGE_LEN.
347 bool send(const uint8_t* data, uint8_t len);
348
349 /// Blocks until the current message (if any)
350 /// has been transmitted
351 /// \return true on success, false if the chip is not in transmit mode
352 virtual bool waitPacketSent();
353
354 /// Indicates if the chip is in transmit mode and
355 /// there is a packet currently being transmitted
356 /// \return true if the chip is in transmit mode and there is a transmission in progress
357 bool isSending();
358
359 /// Prints the value of a single chip register
360 /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform
361 /// For debugging purposes only.
362 /// \return true on success
363 bool printRegister(uint8_t reg);
364
365 /// Prints the value of all chip registers
366 /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform
367 /// For debugging purposes only.
368 /// \return true on success
369 bool printRegisters();
370
371 /// Checks whether a received message is available.
372 /// This can be called multiple times in a timeout loop
373 /// \return true if a complete, valid message has been received and is able to be retrieved by
374 /// recv()
375 bool available();
376
377 /// Turns the receiver on if it not already on.
378 /// If there is a valid message available, copy it to buf and return true
379 /// else return false.
380 /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
381 /// You should be sure to call this function frequently enough to not miss any messages
382 /// It is recommended that you call it in your main loop.
383 /// \param[in] buf Location to copy the received message
384 /// \param[in,out] len Pointer to the number of octets available in buf. The number be reset to the actual number of octets copied.
385 /// \return true if a valid message was copied to buf
386 bool recv(uint8_t* buf, uint8_t* len);
387
388 /// The maximum message length supported by this driver
389 /// \return The maximum message length supported by this driver
390 uint8_t maxMessageLength();
391
392protected:
393 /// Examine the revceive buffer to determine whether the message is for this node
394 void validateRxBuf();
395
396 /// Clear our local receive buffer
397 void clearRxBuf();
398
399private:
400 /// This idle mode chip configuration
401 uint8_t _configuration;
402
403 /// the number of the chip enable pin
404 uint8_t _chipEnablePin;
405
406 /// The number of the transmit enable pin
407 uint8_t _txEnablePin;
408
409 /// Number of octets in the buffer
410 uint8_t _bufLen;
411
412 /// The receiver/transmitter buffer
413 uint8_t _buf[RH_NRF905_MAX_PAYLOAD_LEN];
414
415 /// True when there is a valid message in the buffer
416 bool _rxBufValid;
417};
418
419/// @example nrf905_client.ino
420/// @example nrf905_server.ino
421/// @example nrf905_reliable_datagram_client.ino
422/// @example nrf905_reliable_datagram_server.ino
423
424#endif
Base class for SPI interfaces.
Definition RHGenericSPI.h:31
Base class for RadioHead drivers that use the SPI bus to communicate with its NRF family transport ha...
Definition RHNRFSPIDriver.h:34
Send and receive unaddressed, unreliable datagrams by nRF905 and compatible transceivers.
Definition RH_NRF905.h:235
void setModeIdle()
Definition RH_NRF905.cpp:110
bool available()
Definition RH_NRF905.cpp:226
bool printRegisters()
Definition RH_NRF905.cpp:193
void clearRxBuf()
Clear our local receive buffer.
Definition RH_NRF905.cpp:246
uint8_t spiReadRegister(uint8_t reg)
Definition RH_NRF905.cpp:48
virtual bool waitPacketSent()
Definition RH_NRF905.cpp:163
bool init()
Definition RH_NRF905.cpp:16
bool setRF(TransmitPower power)
Definition RH_NRF905.cpp:100
uint8_t spiBurstWriteRegister(uint8_t reg, uint8_t *src, uint8_t len)
Definition RH_NRF905.cpp:63
bool printRegister(uint8_t reg)
Definition RH_NRF905.cpp:182
bool recv(uint8_t *buf, uint8_t *len)
Definition RH_NRF905.cpp:252
TransmitPower
Convenient values for setting transmitter power in setRF() These are designed to agree with the value...
Definition RH_NRF905.h:242
@ TransmitPower10dBm
10 dBm
Definition RH_NRF905.h:246
@ TransmitPower6dBm
6 dBm
Definition RH_NRF905.h:245
@ TransmitPowerm2dBm
-2 dBm
Definition RH_NRF905.h:244
@ TransmitPowerm10dBm
-10 dBm
Definition RH_NRF905.h:243
bool send(const uint8_t *data, uint8_t len)
Definition RH_NRF905.cpp:141
uint8_t statusRead()
Definition RH_NRF905.cpp:68
bool setChannel(uint16_t channel, bool hiFrequency=false)
Definition RH_NRF905.cpp:74
void setModeTx()
Definition RH_NRF905.cpp:130
uint8_t spiWriteRegister(uint8_t reg, uint8_t val)
Definition RH_NRF905.cpp:53
bool isSending()
Definition RH_NRF905.cpp:174
uint8_t maxMessageLength()
Definition RH_NRF905.cpp:267
uint8_t spiBurstReadRegister(uint8_t reg, uint8_t *dest, uint8_t len)
Definition RH_NRF905.cpp:58
void setModeRx()
Definition RH_NRF905.cpp:120
void validateRxBuf()
Examine the revceive buffer to determine whether the message is for this node.
Definition RH_NRF905.cpp:204
bool setNetworkAddress(uint8_t *address, uint8_t len)
Definition RH_NRF905.cpp:89