RadioHead
|
Send and receive unaddressed, unreliable datagrams by nRF905 and compatible transceivers. More...
#include <RH_NRF905.h>
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) |
void | spiUsingInterrupt (uint8_t interruptNumber) |
Public Member Functions inherited from RHGenericDriver | |
RHGenericDriver () | |
Constructor. | |
virtual | ~RHGenericDriver () |
Generic destructor to prevent warnings when objects are dynamically allocated. | |
virtual void | waitAvailable (uint16_t polldelay=0) |
virtual bool | waitPacketSent (uint16_t timeout) |
virtual bool | waitAvailableTimeout (uint16_t timeout, uint16_t polldelay=0) |
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 () |
virtual int16_t | lastRssi () |
virtual RHMode | mode () |
virtual 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. | |
Protected Member Functions inherited from RHNRFSPIDriver | |
virtual void | beginTransaction () |
virtual void | endTransaction () |
Signal the end of an SPI transaction. | |
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. | |
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.
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.
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
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
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)
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:
Several example programs are provided. They work out of the box with Teensy 3.1 and Arduino Due connected as show above.
Frequency accuracy may be debatable.
Memory usage of this class is minimal. The compiled client and server sketches are about 16000 bytes on Teensy.
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
[in] | chipEnablePin | the Arduino pin to use to enable the chip for transmit/receive |
[in] | txEnablePin | the Arduino pin cponnected to the txEn pin on the radio that enable transmit mode |
[in] | slaveSelectPin | the 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] | spi | Pointer to the SPI interface object to use. Defaults to the standard Arduino hardware SPI interface |
|
virtual |
Checks whether a received message is available. This can be called multiple times in a timeout loop
Implements RHGenericDriver.
References RHGenericDriver::_mode, RHGenericDriver::RHModeTx, setModeIdle(), setModeRx(), RHNRFSPIDriver::spiBurstRead(), statusRead(), and validateRxBuf().
Referenced by recv().
|
virtual |
Initialises this instance and the radio module connected to it. The following steps are taken:g
Reimplemented from RHGenericDriver.
References RHNRFSPIDriver::_spi, RHGenericSPI::Frequency1MHz, RHGenericSPI::Frequency8MHz, RHNRFSPIDriver::init(), setChannel(), RHGenericSPI::setFrequency(), setModeIdle(), setRF(), spiWriteRegister(), and TransmitPowerm10dBm.
bool RH_NRF905::isSending | ( | ) |
Indicates if the chip is in transmit mode and there is a packet currently being transmitted
References RHGenericDriver::_mode, RHGenericDriver::RHModeTx, and statusRead().
|
virtual |
The maximum message length supported by this driver
Implements RHGenericDriver.
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.
References spiReadRegister().
Referenced by 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.
References printRegister().
|
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.
[in] | buf | Location to copy the received message |
[in,out] | len | Pointer to the number of octets available in buf. The number be reset to the actual number of octets copied. |
Implements RHGenericDriver.
References available(), and clearRxBuf().
|
virtual |
Sends data to the address set by setTransmitAddress() Sets the radio to TX mode
[in] | data | Data bytes to send. |
[in] | len | Number 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. |
Implements RHGenericDriver.
References RHGenericDriver::_txGood, RHGenericDriver::_txHeaderFlags, RHGenericDriver::_txHeaderFrom, RHGenericDriver::_txHeaderId, RHGenericDriver::_txHeaderTo, setModeTx(), RHNRFSPIDriver::spiBurstWrite(), and RHGenericDriver::waitCAD().
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
[in] | channel | The channel number. |
[in] | hiFrequency | false for low frequency band (422.4MHz and up), true for high frequency band (845MHz and up) |
References spiReadRegister(), and spiWriteRegister().
Referenced by init().
void RH_NRF905::setModeIdle | ( | ) |
Sets the radio in power down mode. Sets chip enable to LOW.
References RHGenericDriver::_mode, and RHGenericDriver::RHModeIdle.
Referenced by available(), init(), and waitPacketSent().
void RH_NRF905::setModeRx | ( | ) |
Sets the radio in RX mode. Sets chip enable to HIGH to enable the chip in RX mode.
References RHGenericDriver::_mode, and RHGenericDriver::RHModeRx.
Referenced by available().
void RH_NRF905::setModeTx | ( | ) |
Sets the radio in TX mode. Pulses the chip enable LOW then HIGH to enable the chip in TX mode.
References RHGenericDriver::_mode, and RHGenericDriver::RHModeTx.
Referenced by send().
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
[in] | address | The new network address. Must match the network address of any receiving node(s). |
[in] | len | Number of bytes of address to set (1 to 4). |
References RHNRFSPIDriver::spiBurstWrite(), spiBurstWriteRegister(), and spiWriteRegister().
bool RH_NRF905::setRF | ( | TransmitPower | power | ) |
Sets the transmitter power to use
[in] | power | Transmitter power. One of NRF905::TransmitPower. |
References spiReadRegister(), and spiWriteRegister().
Referenced by init().
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
[in] | reg | Register number of the first register, one of NRF905_REG_* |
[in] | dest | Array to write the register values to. Must be at least len bytes |
[in] | len | Number of bytes to read |
References RHNRFSPIDriver::spiBurstRead().
uint8_t RH_NRF905::spiBurstWriteRegister | ( | uint8_t | reg, |
uint8_t * | src, | ||
uint8_t | len | ||
) |
Write a number of consecutive registers using burst write mode
[in] | reg | Register number of the first register, one of NRF905_REG_* |
[in] | src | Array of new register values to write. Must be at least len bytes |
[in] | len | Number of bytes to write |
References RHNRFSPIDriver::spiBurstWrite().
Referenced by setNetworkAddress().
uint8_t RH_NRF905::spiReadRegister | ( | uint8_t | reg | ) |
Reads a single register from the NRF905
[in] | reg | Register number, one of NR905_REG_* |
References RHNRFSPIDriver::spiRead().
Referenced by printRegister(), setChannel(), and setRF().
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
[in] | reg | Register number, one of NRF905_REG_* |
[in] | val | The value to write |
References RHNRFSPIDriver::spiWrite().
Referenced by init(), setChannel(), setNetworkAddress(), and setRF().
uint8_t RH_NRF905::statusRead | ( | ) |
Reads and returns the device status register NRF905_REG_02_DEVICE_STATUS
References RHNRFSPIDriver::spiCommand().
Referenced by available(), isSending(), and waitPacketSent().
|
virtual |
Blocks until the current message (if any) has been transmitted
Reimplemented from RHGenericDriver.
References RHGenericDriver::_mode, RHGenericDriver::RHModeTx, setModeIdle(), and statusRead().