RadioHead
Public Types | Public Member Functions | Protected Member Functions | List of all members
RH_NRF905 Class Reference

Send and receive unaddressed, unreliable datagrams by nRF905 and compatible transceivers. More...

#include <RH_NRF905.h>

Inheritance diagram for RH_NRF905:
RHNRFSPIDriver RHGenericDriver

Public Types

enum  TransmitPower { TransmitPowerm10dBm = 0, TransmitPowerm2dBm, TransmitPower6dBm, TransmitPower10dBm }
 Convenient values for setting transmitter power in setRF() These are designed to agree with the values for RH_NRF905_CONFIG_1_PA_PWR after left shifting by 2 To be passed to setRF();. More...
 
- Public Types inherited from RHGenericDriver
enum  RHMode {
  RHModeInitialising = 0, RHModeSleep, RHModeIdle, RHModeTx,
  RHModeRx, RHModeCad
}
 Defines different operating modes for the transport hardware. More...
 

Public Member Functions

 RH_NRF905 (uint8_t chipEnablePin=8, uint8_t txEnablePin=9, uint8_t slaveSelectPin=SS, RHGenericSPI &spi=hardware_spi)
 
bool init ()
 
uint8_t spiReadRegister (uint8_t reg)
 
uint8_t spiWriteRegister (uint8_t reg, uint8_t val)
 
uint8_t spiBurstReadRegister (uint8_t reg, uint8_t *dest, uint8_t len)
 
uint8_t spiBurstWriteRegister (uint8_t reg, uint8_t *src, uint8_t len)
 
uint8_t statusRead ()
 
bool setChannel (uint16_t channel, bool hiFrequency=false)
 
bool setNetworkAddress (uint8_t *address, uint8_t len)
 
bool setRF (TransmitPower power)
 
void setModeIdle ()
 
void setModeRx ()
 
void setModeTx ()
 
bool send (const uint8_t *data, uint8_t len)
 
virtual bool waitPacketSent ()
 
bool isSending ()
 
bool printRegister (uint8_t reg)
 
bool printRegisters ()
 
bool available ()
 
bool recv (uint8_t *buf, uint8_t *len)
 
uint8_t maxMessageLength ()
 
- Public Member Functions inherited from RHNRFSPIDriver
 RHNRFSPIDriver (uint8_t slaveSelectPin=SS, RHGenericSPI &spi=hardware_spi)
 
bool init ()
 
uint8_t spiCommand (uint8_t command)
 
uint8_t spiRead (uint8_t reg)
 
uint8_t spiWrite (uint8_t reg, uint8_t val)
 
uint8_t spiBurstRead (uint8_t reg, uint8_t *dest, uint8_t len)
 
uint8_t spiBurstWrite (uint8_t reg, const uint8_t *src, uint8_t len)
 
void setSlaveSelectPin (uint8_t slaveSelectPin)
 
- Public Member Functions inherited from RHGenericDriver
 RHGenericDriver ()
 Constructor.
 
virtual void waitAvailable ()
 
virtual bool waitPacketSent (uint16_t timeout)
 
virtual bool waitAvailableTimeout (uint16_t timeout)
 
virtual bool waitCAD ()
 
void setCADTimeout (unsigned long cad_timeout)
 
virtual bool isChannelActive ()
 
virtual void setThisAddress (uint8_t thisAddress)
 
virtual void setHeaderTo (uint8_t to)
 
virtual void setHeaderFrom (uint8_t from)
 
virtual void setHeaderId (uint8_t id)
 
virtual void setHeaderFlags (uint8_t set, uint8_t clear=RH_FLAGS_APPLICATION_SPECIFIC)
 
virtual void setPromiscuous (bool promiscuous)
 
virtual uint8_t headerTo ()
 
virtual uint8_t headerFrom ()
 
virtual uint8_t headerId ()
 
virtual uint8_t headerFlags ()
 
int16_t lastRssi ()
 
RHMode mode ()
 
void setMode (RHMode mode)
 Sets the operating mode of the transport.
 
virtual bool sleep ()
 
virtual uint16_t rxBad ()
 
virtual uint16_t rxGood ()
 
virtual uint16_t txGood ()
 

Protected Member Functions

void validateRxBuf ()
 Examine the revceive buffer to determine whether the message is for this node.
 
void clearRxBuf ()
 Clear our local receive buffer.
 

Additional Inherited Members

- Static Public Member Functions inherited from RHGenericDriver
static void printBuffer (const char *prompt, const uint8_t *buf, uint8_t len)
 
- Protected Attributes inherited from RHNRFSPIDriver
RHGenericSPI_spi
 Reference to the RHGenericSPI instance to use to trasnfer data with teh SPI device.
 
uint8_t _slaveSelectPin
 The pin number of the Slave Select pin that is used to select the desired device.
 
- Protected Attributes inherited from RHGenericDriver
volatile RHMode _mode
 The current transport operating mode.
 
uint8_t _thisAddress
 This node id.
 
bool _promiscuous
 Whether the transport is in promiscuous mode.
 
volatile uint8_t _rxHeaderTo
 TO header in the last received mesasge.
 
volatile uint8_t _rxHeaderFrom
 FROM header in the last received mesasge.
 
volatile uint8_t _rxHeaderId
 ID header in the last received mesasge.
 
volatile uint8_t _rxHeaderFlags
 FLAGS header in the last received mesasge.
 
uint8_t _txHeaderTo
 TO header to send in all messages.
 
uint8_t _txHeaderFrom
 FROM header to send in all messages.
 
uint8_t _txHeaderId
 ID header to send in all messages.
 
uint8_t _txHeaderFlags
 FLAGS header to send in all messages.
 
volatile int16_t _lastRssi
 The value of the last received RSSI value, in some transport specific units.
 
volatile uint16_t _rxBad
 Count of the number of bad messages (eg bad checksum etc) received.
 
volatile uint16_t _rxGood
 Count of the number of successfully transmitted messaged.
 
volatile uint16_t _txGood
 Count of the number of bad messages (correct checksum etc) received.
 
volatile bool _cad
 Channel activity detected.
 
unsigned int _cad_timeout
 Channel activity timeout in ms.
 

Detailed Description

Send and receive unaddressed, unreliable datagrams by nRF905 and compatible transceivers.

This base class provides basic functions for sending and receiving unaddressed, unreliable datagrams of arbitrary length to 28 octets per packet. Use one of the Manager classes to get addressing and acknowledgement reliability, routing, meshes etc.

The nRF905 transceiver is configured to use Enhanced Shockburst with 16 Bit CRC, and 32 octet packets.

Naturally, for any 2 radios to communicate that must be configured to use the same frequency and with identical network addresses.

The nRF905 from Nordic Semiconductor http://www.nordicsemi.com/eng/Products/Sub-1-GHz-RF/nRF905 (http://www.nordicsemi.com/jpn/nordic/content_download/2452/29528/file/Product_Specification_nRF905_v1.5.pdf) is a low-cost 433/868/915 MHz ISM transceiver module. It supports a number of channel frequencies at 100kHz deviation and 50kHz bandwidth with Manchester encoding.

We tested with inexpensive nRF905 modules from eBay, similar to: 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

This library provides functions for sending and receiving messages of up to 27 octets on any frequency supported by the nRF905.

Several nRF905 modules can be connected to an Arduino, permitting the construction of translators and frequency changers, etc.

Example Arduino programs are included to show the main modes of use.

Packet Format

All messages sent and received by this class conform to this fixed length packet format

All messages sent and received by this driver are 32 octets. The user message length is embedded in the message.

Connecting nRF905

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 or else provide for level shifters between the CPU and the nRF905. Failure to consider this will probably break your nRF905.

The electrical connection between the nRF905 and the CPU require 3.3V, the 3 x SPI pins (SCK, SDI, SDO), a Chip Enable pin, a Transmit Enable pin and a Slave Select pin.

The examples below assume the commonly found cheap Chinese nRF905 modules. The RH_RF905 driver assumes the the nRF905 has a 16MHz crystal.

Connect the nRF905 to Teensy (or Arduino with suitable level shifters) like this

CPU nRF905 module
3V3----------VCC (3.3V)
pin D8-----------CE (chip enable in)
pin D9-----------TX_EN (transmit enable in)
SS pin D10----------CSN (chip select in)
SCK pin D13----------SCK (SPI clock in)
MOSI pin D11----------MOSI (SPI Data in)
MISO pin D12----------MISO (SPI data out)
GND----------GND (ground in)

Caution: Arduino Due is a 3.3V part and is not 5V tolerant (so too is the nRF905 module so they can be connected directly together. Unlike other Arduinos the Due has it default SPI connections on a dedicated 6 pin SPI header in the center of the board, which is physically compatible with Uno, Leonardo and Mega2560. A little dot marks pin 1 on the header. You must connect to these and not to the usual Arduino SPI pins Digital 11, 12 and 13. See http://21stdigitalhome.blogspot.com.au/2013/02/arduino-due-hardware-spi.html

Connect the nRF905 to Arduino Due like this

CPU nRF905 module
3V3----------VCC (3.3V)
pin D8-----------CE (chip enable in)
pin D9-----------TX_EN (transmit enable in)
SS pin D10----------CSN (chip select in)
SCK on SPI header pin 3----------SCK (SPI clock in)
MOSI on SPI header pin 4----------MOSI (SPI Data in)
MISO on SPI header pin 1----------MISO (SPI data out)
GND----------GND (ground in)

and you can then use the default constructor RH_NRF905(). You can override the default settings for the CE, TX_EN and CSN pins in the NRF905() constructor if you wish to connect the slave select CSN to other than the normal one for your CPU.

It is possible to have 2 radios conected to one CPU, provided each radio has its own CSN, TX_EN and CE line (SCK, MOSI and MISO are common to both radios)

Transmitter Power

You can control the transmitter power to be one of 4 power levels: -10, -2, 6 or 10dBm, using the setRF() function, eg:

We have made some actual power measurements against programmed power for an nRF905 module from www.rfinchina.com under the following conditions:

Example programs

Several example programs are provided. They work out of the box with Teensy 3.1 and Arduino Due connected as show above.

Radio Performance

Frequency accuracy may be debatable.

Memory

Memory usage of this class is minimal. The compiled client and server sketches are about 16000 bytes on Teensy.

Member Enumeration Documentation

◆ TransmitPower

Convenient values for setting transmitter power in setRF() These are designed to agree with the values for RH_NRF905_CONFIG_1_PA_PWR after left shifting by 2 To be passed to setRF();.

Enumerator
TransmitPowerm10dBm 

-10 dBm

TransmitPowerm2dBm 

-2 dBm

TransmitPower6dBm 

6 dBm

TransmitPower10dBm 

10 dBm

Constructor & Destructor Documentation

◆ RH_NRF905()

RH_NRF905::RH_NRF905 ( uint8_t  chipEnablePin = 8,
uint8_t  txEnablePin = 9,
uint8_t  slaveSelectPin = SS,
RHGenericSPI spi = hardware_spi 
)

Constructor. You can have multiple instances, but each instance must have its own chip enable and slave select pin. After constructing, you must call init() to initialise the interface and the radio module

Parameters
[in]chipEnablePinthe Arduino pin to use to enable the chip for transmit/receive
[in]txEnablePinthe Arduino pin cponnected to the txEn pin on the radio that enable transmit mode
[in]slaveSelectPinthe Arduino pin number of the output to use to select the NRF905 before accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega, D10 for Maple, Teensy)
[in]spiPointer to the SPI interface object to use. Defaults to the standard Arduino hardware SPI interface

Member Function Documentation

◆ available()

bool RH_NRF905::available ( )
virtual

Checks whether a received message is available. This can be called multiple times in a timeout loop

Returns
true if a complete, valid message has been received and is able to be retrieved by recv()

Implements RHGenericDriver.

References RHGenericDriver::_mode, RHGenericDriver::RHModeTx, setModeIdle(), setModeRx(), RHNRFSPIDriver::spiBurstRead(), statusRead(), and validateRxBuf().

Referenced by recv().

◆ init()

bool RH_NRF905::init ( )
virtual

Initialises this instance and the radio module connected to it. The following steps are taken:g

  • Set the chip enable and chip select pins to output LOW, HIGH respectively.
  • Initialise the SPI output pins
  • Initialise the SPI interface library to 8MHz (Hint, if you want to lower the SPI frequency (perhaps where you have other SPI shields, low voltages etc), call SPI.setClockDivider() after init()). -Flush the receiver and transmitter buffers
  • Set the radio to receive with powerUpRx();
    Returns
    true if everything was successful

Reimplemented from RHGenericDriver.

References RHNRFSPIDriver::_spi, RHGenericSPI::Frequency1MHz, RHGenericSPI::Frequency8MHz, RHNRFSPIDriver::init(), setChannel(), RHGenericSPI::setFrequency(), setModeIdle(), setRF(), spiWriteRegister(), and TransmitPowerm10dBm.

◆ isSending()

bool RH_NRF905::isSending ( )

Indicates if the chip is in transmit mode and there is a packet currently being transmitted

Returns
true if the chip is in transmit mode and there is a transmission in progress

References RHGenericDriver::_mode, RHGenericDriver::RHModeTx, and statusRead().

◆ maxMessageLength()

uint8_t RH_NRF905::maxMessageLength ( )
virtual

The maximum message length supported by this driver

Returns
The maximum message length supported by this driver

Implements RHGenericDriver.

◆ printRegister()

bool RH_NRF905::printRegister ( uint8_t  reg)

Prints the value of a single chip register to the Serial device if RH_HAVE_SERIAL is defined for the current platform For debugging purposes only.

Returns
true on success

References spiReadRegister().

Referenced by printRegisters().

◆ printRegisters()

bool RH_NRF905::printRegisters ( )

Prints the value of all chip registers to the Serial device if RH_HAVE_SERIAL is defined for the current platform For debugging purposes only.

Returns
true on success

References printRegister().

◆ recv()

bool RH_NRF905::recv ( uint8_t *  buf,
uint8_t *  len 
)
virtual

Turns the receiver on if it not already on. If there is a valid message available, copy it to buf and return true else return false. If a message is copied, *len is set to the length (Caution, 0 length messages are permitted). You should be sure to call this function frequently enough to not miss any messages It is recommended that you call it in your main loop.

Parameters
[in]bufLocation to copy the received message
[in,out]lenPointer to available space in buf. Set to the actual number of octets copied.
Returns
true if a valid message was copied to buf

Implements RHGenericDriver.

References available(), and clearRxBuf().

◆ send()

bool RH_NRF905::send ( const uint8_t *  data,
uint8_t  len 
)
virtual

Sends data to the address set by setTransmitAddress() Sets the radio to TX mode

Parameters
[in]dataData bytes to send.
[in]lenNumber of data bytes to set in the TX buffer. The actual size of the transmitted data payload is set by setPayloadSize. Maximum message length actually transmitted is RH_NRF905_MAX_MESSAGE_LEN = 27.
Returns
true on success (which does not necessarily mean the receiver got the message, only that the message was successfully transmitted). Returns false if the requested message length exceeds RH_NRF905_MAX_MESSAGE_LEN.

Implements RHGenericDriver.

References RHGenericDriver::_txGood, RHGenericDriver::_txHeaderFlags, RHGenericDriver::_txHeaderFrom, RHGenericDriver::_txHeaderId, RHGenericDriver::_txHeaderTo, setModeTx(), RHNRFSPIDriver::spiBurstWrite(), and RHGenericDriver::waitCAD().

◆ setChannel()

bool RH_NRF905::setChannel ( uint16_t  channel,
bool  hiFrequency = false 
)

Sets the transmit and receive channel number. The RF frequency used is (422.4 + channel/10) * (1+hiFrequency) MHz

Parameters
[in]channelThe channel number.
[in]hiFrequencyfalse for low frequency band (422.4MHz and up), true for high frequency band (845MHz and up)
Returns
true on success

References spiReadRegister(), and spiWriteRegister().

Referenced by init().

◆ setModeIdle()

void RH_NRF905::setModeIdle ( )

Sets the radio in power down mode. Sets chip enable to LOW.

Returns
true on success

References RHGenericDriver::_mode, and RHGenericDriver::RHModeIdle.

Referenced by available(), init(), and waitPacketSent().

◆ setModeRx()

void RH_NRF905::setModeRx ( )

Sets the radio in RX mode. Sets chip enable to HIGH to enable the chip in RX mode.

Returns
true on success

References RHGenericDriver::_mode, and RHGenericDriver::RHModeRx.

Referenced by available().

◆ setModeTx()

void RH_NRF905::setModeTx ( )

Sets the radio in TX mode. Pulses the chip enable LOW then HIGH to enable the chip in TX mode.

Returns
true on success

References RHGenericDriver::_mode, and RHGenericDriver::RHModeTx.

Referenced by send().

◆ setNetworkAddress()

bool RH_NRF905::setNetworkAddress ( uint8_t *  address,
uint8_t  len 
)

Sets the Network address. Only nodes with the same network address can communicate with each other. You can set different network addresses in different sets of nodes to isolate them from each other. The default network address is 0xE7E7E7E7

Parameters
[in]addressThe new network address. Must match the network address of any receiving node(s).
[in]lenNumber of bytes of address to set (1 to 4).
Returns
true on success, false if len is not in the range 1-4 inclusive.

References RHNRFSPIDriver::spiBurstWrite(), spiBurstWriteRegister(), and spiWriteRegister().

◆ setRF()

bool RH_NRF905::setRF ( TransmitPower  power)

Sets the transmitter power to use

Parameters
[in]powerTransmitter power. One of NRF905::TransmitPower.
Returns
true on success

References spiReadRegister(), and spiWriteRegister().

Referenced by init().

◆ spiBurstReadRegister()

uint8_t RH_NRF905::spiBurstReadRegister ( uint8_t  reg,
uint8_t *  dest,
uint8_t  len 
)

Reads a number of consecutive registers from the NRF905 using burst read mode

Parameters
[in]regRegister number of the first register, one of NRF905_REG_*
[in]destArray to write the register values to. Must be at least len bytes
[in]lenNumber of bytes to read
Returns
the current STATUS (read while the command is sent)

References RHNRFSPIDriver::spiBurstRead().

◆ spiBurstWriteRegister()

uint8_t RH_NRF905::spiBurstWriteRegister ( uint8_t  reg,
uint8_t *  src,
uint8_t  len 
)

Write a number of consecutive registers using burst write mode

Parameters
[in]regRegister number of the first register, one of NRF905_REG_*
[in]srcArray of new register values to write. Must be at least len bytes
[in]lenNumber of bytes to write
Returns
the current STATUS (read while the command is sent)

References RHNRFSPIDriver::spiBurstWrite().

Referenced by setNetworkAddress().

◆ spiReadRegister()

uint8_t RH_NRF905::spiReadRegister ( uint8_t  reg)

Reads a single register from the NRF905

Parameters
[in]regRegister number, one of NR905_REG_*
Returns
The value of the register

References RHNRFSPIDriver::spiRead().

Referenced by printRegister(), setChannel(), and setRF().

◆ spiWriteRegister()

uint8_t RH_NRF905::spiWriteRegister ( uint8_t  reg,
uint8_t  val 
)

Writes a single byte to the NRF905, and at the ame time reads the current STATUS register

Parameters
[in]regRegister number, one of NRF905_REG_*
[in]valThe value to write
Returns
the current STATUS (read while the command is sent)

References RHNRFSPIDriver::spiWrite().

Referenced by init(), setChannel(), setNetworkAddress(), and setRF().

◆ statusRead()

uint8_t RH_NRF905::statusRead ( )

Reads and returns the device status register NRF905_REG_02_DEVICE_STATUS

Returns
The value of the device status register

References RHNRFSPIDriver::spiCommand().

Referenced by available(), isSending(), and waitPacketSent().

◆ waitPacketSent()

bool RH_NRF905::waitPacketSent ( )
virtual

Blocks until the current message (if any) has been transmitted

Returns
true on success, false if the chip is not in transmit mode

Reimplemented from RHGenericDriver.

References RHGenericDriver::_mode, RHGenericDriver::RHModeTx, setModeIdle(), and statusRead().


The documentation for this class was generated from the following files: