Optimized RF24Network Layer v2.0.2
2024 - Optimized RF24 Network Layer for NRF24L01 & NRF52x radios
Loading...
Searching...
No Matches
ESBNetwork< radio_t > Class Template Reference

#include <RF24Network.h>

Public Member Functions

Primary Interface

These are the main methods you need to operate the network

 ESBNetwork (radio_t &_radio)
 
void begin (uint16_t _node_address)
 
uint8_t update (void)
 
bool available (void)
 
uint16_t peek (RF24NetworkHeader &header)
 
void peek (RF24NetworkHeader &header, void *message, uint16_t maxlen=MAX_PAYLOAD_SIZE)
 
uint16_t read (RF24NetworkHeader &header, void *message, uint16_t maxlen=MAX_PAYLOAD_SIZE)
 
bool write (RF24NetworkHeader &header, const void *message, uint16_t len)
 
Advanced Operation

For advanced operation of the network

void failures (uint32_t *_fails, uint32_t *_ok)
 
bool multicast (RF24NetworkHeader &header, const void *message, uint16_t len, uint8_t level=7)
 
bool write (RF24NetworkHeader &header, const void *message, uint16_t len, uint16_t writeDirect)
 
bool sleepNode (unsigned int cycles, int interruptPin, uint8_t INTERRUPT_MODE=0)
 
uint16_t parent () const
 
uint16_t addressOfPipe (uint16_t node, uint8_t pipeNo)
 
bool is_valid_address (uint16_t node)
 
Deprecated

Maintained for backwards compatibility

void begin (uint8_t _channel, uint16_t _node_address)
 

Advanced Configuration

For advanced configuration of the network

bool multicastRelay
 
uint32_t txTimeout
 Network timeout value.
 
uint16_t routeTimeout
 Timeout for routed payloads.
 
void multicastLevel (uint8_t level)
 
void setup_watchdog (uint8_t prescalar)
 

External Applications/Systems

Interface for External Applications and Systems ( RF24Mesh, RF24Ethernet )

uint8_t frame_buffer [MAX_FRAME_SIZE]
 The raw system frame buffer.
 
std::queue< RF24NetworkFrameexternal_queue
 
RF24NetworkFramefrag_ptr
 
bool returnSysMsgs
 
uint8_t networkFlags
 
uint8_t _multicast_level
 
uint16_t node_address
 

Detailed Description

template<class radio_t = RF24>
class ESBNetwork< radio_t >

2014-2021 - Optimized Network Layer for RF24 Radios

This class implements an OSI Network Layer using nRF24L01(+) radios driven by RF24 library.

Template Parameters
radio_tThe radio object's type. Defaults to RF24 for legacy behavior. This new abstraction is really meant for using the nRF52840 SoC as a drop-in replacement for the nRF24L01 radio. For more detail, see the nrf_to_nrf Arduino library.
Examples
Network_Ping.ino, Network_Ping_Sleep.ino, Network_Priority_RX.ino, Network_Priority_TX.ino, helloworld_rx.ino, helloworld_rx_advanced.ino, helloworld_tx.ino, and helloworld_tx_advanced.ino.

Constructor & Destructor Documentation

◆ ESBNetwork()

template<class radio_t >
ESBNetwork< radio_t >::ESBNetwork ( radio_t & _radio)

Construct the network

v2.0 supports a backward compatible constructor:

RF24 radio(7, 8);
RF24Network network(radio); // for nRF24L01
nrf_to_nrf radio1;
RF52Network network(radio1); // for nRF52xxx family
Definition RF24Network.h:384
See also
v2.0 supports nrf_to_nrf Arduino library for nrf52 chips' internal radio.
Parameters
_radioThe underlying radio driver instance

Member Function Documentation

◆ begin() [1/2]

template<class radio_t = RF24>
void ESBNetwork< radio_t >::begin ( uint16_t _node_address)
inline

Bring up the network using the current radio frequency/channel. Calling begin brings up the network, and configures the address, which designates the location of the node within RF24Network topology.

Note
Node addresses are specified in Octal format, see RF24Network Addressing for more information. The address 04444 is reserved for RF24Mesh usage (when a mesh node is connecting to the network).
Warning
Be sure to first call RF24::begin() to initialize the radio properly.

Example 1: Begin on current radio channel with address 0 (master node)

network.begin(00);

Example 2: Begin with address 01 (child of master)

network.begin(01);

Example 3: Begin with address 011 (child of 01, grandchild of master)

network.begin(011);
See also
begin(uint8_t _channel, uint16_t _node_address)
Parameters
_node_addressThe logical address of this node.

◆ update()

template<class radio_t >
uint8_t ESBNetwork< radio_t >::update ( void )

Main layer loop

This function must be called regularly to keep the layer going. This is where payloads are re-routed, received, and all the action happens.

Returns
Returns the RF24NetworkHeader::type of the last received payload.

◆ available()

template<class radio_t >
bool ESBNetwork< radio_t >::available ( void )

Test whether there is a message available for this node

Returns
Whether there is a message available for this node

◆ peek() [1/2]

template<class radio_t >
uint16_t ESBNetwork< radio_t >::peek ( RF24NetworkHeader & header)

Read the next available header

Reads the next available header without advancing to the next incoming message. Useful for doing a switch on the message type.

Parameters
[out]headerThe RF24NetworkHeader (envelope) of the next message. If there is no message available, the referenced header object is not touched
Returns
The length of the next available message in the queue.

◆ peek() [2/2]

template<class radio_t >
void ESBNetwork< radio_t >::peek ( RF24NetworkHeader & header,
void * message,
uint16_t maxlen = MAX_PAYLOAD_SIZE )

Read the next available payload

Reads the next available payload without advancing to the next incoming message. Useful for doing a transparent packet manipulation layer on top of RF24Network.

Parameters
[out]headerThe RF24NetworkHeader (envelope) of this message
[out]messagePointer to memory where the message should be placed
maxlenAmount of bytes to copy to message . If this parameter is left unspecified, the entire length of the message is fetched. Hint: Use peek(RF24NetworkHeader) to get the length of next available message in the queue.

◆ read()

template<class radio_t >
uint16_t ESBNetwork< radio_t >::read ( RF24NetworkHeader & header,
void * message,
uint16_t maxlen = MAX_PAYLOAD_SIZE )

Read a message

Note
This function assumes there is a frame in the queue.
while (network.available()) {
uint32_t time;
uint16_t msg_size = network.peek(header);
if (header.type == 'T') {
network.read(header, &time, sizeof(time));
Serial.print("Got time: ");
Serial.println(time);
}
}
Definition RF24Network.h:229
unsigned char type
Definition RF24Network.h:246
Parameters
[out]headerThe RF24NetworkHeader (envelope) of this message
[out]messagePointer to memory where the message should be placed
maxlenThe largest message size which can be held in message . If this parameter is left unspecified, the entire length of the message is fetched. Hint: Use peek(RF24NetworkHeader &) to get the length of next available message in the queue.
Returns
The total number of bytes copied into message

◆ write() [1/2]

template<class radio_t >
bool ESBNetwork< radio_t >::write ( RF24NetworkHeader & header,
const void * message,
uint16_t len )

Send a message

Note
RF24Network now supports fragmentation for very long messages, send as normal. Fragmentation may need to be enabled or configured by editing the RF24Network_config.h file. Default max payload size is 120 bytes.
uint32_t time = millis();
uint16_t to = 00; // Send to master
RF24NetworkHeader header(to, 'T'); // Send header type 'T'
network.write(header, &time, sizeof(time));
Parameters
[in,out]headerThe header (envelope) of this message. The critical thing to fill in is the to_node field so we know where to send the message. It is then updated with the details of the actual header sent.
messagePointer to memory where the message is located
lenThe size of the message
Returns
Whether the message was successfully received

◆ multicastLevel()

template<class radio_t >
void ESBNetwork< radio_t >::multicastLevel ( uint8_t level)

By default, multicast addresses are divided into 5 network levels:

  • The master node is the only node on level 0 (the lowest level)
  • Nodes 01-05 (level 1) share a multicast address
  • Nodes 0n1-0n5 (level 2) share a multicast address
  • Nodes 0n11-0n55 (level 3) share a multicast address
  • Nodes 0n111-0n555 (level 4) share a multicast address

Notice "n" (used in the list above) stands for an octal digit in range [0, 5]

This optional function is used to override the default level set when a node's logical address changes, and it can be used to create custom multicast groups that all share a single address.

See also
Parameters
levelLevels 0 to 4 are available. All nodes at the same level will receive the same messages if in range. Messages will be routed in order of level, low to high, by default.

◆ setup_watchdog()

template<class radio_t = RF24>
void ESBNetwork< radio_t >::setup_watchdog ( uint8_t prescalar)

Set up the watchdog timer for sleep mode using the number 0 through 10 to represent the following time periods:
wdt_16ms = 0, wdt_32ms, wdt_64ms, wdt_128ms, wdt_250ms, wdt_500ms, wdt_1s, wdt_2s, wdt_4s, wdt_8s

setup_watchdog(7); // Sets the WDT to trigger every second
void setup_watchdog(uint8_t prescalar)
Parameters
prescalarThe WDT prescaler to define how often the node will wake up. When defining sleep mode cycles, this time period is 1 cycle.

◆ failures()

template<class radio_t = RF24>
void ESBNetwork< radio_t >::failures ( uint32_t * _fails,
uint32_t * _ok )

Return the number of failures and successes for all transmitted payloads, routed or sent directly

Note
This needs to be enabled via #define ENABLE_NETWORK_STATS in RF24Network_config.h
bool fails, success;
network.failures(&fails, &success);

◆ multicast()

template<class radio_t >
bool ESBNetwork< radio_t >::multicast ( RF24NetworkHeader & header,
const void * message,
uint16_t len,
uint8_t level = 7 )

Send a multicast message to multiple nodes at once Allows messages to be rapidly broadcast through the network

Multicasting is arranged in levels, with all nodes on the same level listening to the same address Levels are assigned by network level ie: nodes 01-05: Level 1, nodes 011-055: Level 2

See also
Parameters
headerreference to the RF24NetworkHeader object used for this message
messagePointer to memory where the message is located
lenThe size of the message
levelMulticast level to broadcast to. If this parameter is unspecified, then the node's current multicastLevel() is used.
Returns
Whether the message was successfully sent

◆ write() [2/2]

template<class radio_t >
bool ESBNetwork< radio_t >::write ( RF24NetworkHeader & header,
const void * message,
uint16_t len,
uint16_t writeDirect )

Writes a direct (unicast) payload. This allows routing or sending messages outside of the usual routing paths. The same as write, but a physical address is specified as the last option. The payload will be written to the physical address, and routed as necessary by the recipient.

◆ sleepNode()

template<class radio_t = RF24>
bool ESBNetwork< radio_t >::sleepNode ( unsigned int cycles,
int interruptPin,
uint8_t INTERRUPT_MODE = 0 )

Sleep this node - For AVR devices only

Note
NEW - Nodes can now be slept while the radio is not actively transmitting. This must be manually enabled by uncommenting the #define ENABLE_SLEEP_MODE in RF24Network_config.h
The watchdog timer should be configured in the sketch's setup() if using sleep mode. This function will sleep the node, with the radio still active in receive mode. See setup_watchdog().

The node can be awoken in two ways, both of which can be enabled simultaneously:

  1. An interrupt - usually triggered by the radio receiving a payload. Must use pin 2 (interrupt 0) or 3 (interrupt 1) on Uno, Nano, etc.
  2. The watchdog timer waking the MCU after a designated period of time, can also be used instead of delays to control transmission intervals.
if(!network.available())
network.sleepNode(1, 0); // Sleep the node for 1 second or a payload is received
// Other options:
network.sleepNode(0, 0); // Sleep this node for the designated time period, or a payload is received.
network.sleepNode(1, 255); // Sleep this node for 1 cycle. Do not wake up until then, even if a payload is received ( no interrupt )
Parameters
cyclesThe node will sleep in cycles of 1s. Using 2 will sleep 2 WDT cycles, 3 sleeps 3WDT cycles...
interruptPinThe interrupt number to use (0, 1) for pins 2 and 3 on Uno & Nano. More available on Mega etc. Setting this parameter to 255 will disable interrupt wake-ups.
INTERRUPT_MODEan identifying number to indicate what type of state for which the interrupt_pin will be used to wake up the radio.
INTERRUPT_MODE type of state
0 LOW
1 RISING
2 FALLING
3 CHANGE
Returns
True if sleepNode completed normally, after the specified number of cycles. False if sleep was interrupted

◆ parent()

template<class radio_t >
uint16_t ESBNetwork< radio_t >::parent ( ) const

This node's parent address

Returns
This node's parent address, or 65535 (-1 when casted to a signed int16_t) if this is the master node.

◆ addressOfPipe()

template<class radio_t >
uint16_t ESBNetwork< radio_t >::addressOfPipe ( uint16_t node,
uint8_t pipeNo )

Provided a node address and a pipe number, will return the RF24Network address of that child pipe for that node.

◆ is_valid_address()

template<class radio_t >
bool ESBNetwork< radio_t >::is_valid_address ( uint16_t node)

Validate a network address as a proper logical address

Note
Addresses are specified in octal form, ie 011, 034. Review RF24Network addressing for more information.
Parameters
nodeThe specified logical address of a network node.
Returns
True if the specified node address is a valid network address, otherwise false.
Remarks
This function will validate an improper address of 0100 as it is the reserved NETWORK_MULTICAST_ADDRESS used for multicasted messages.

◆ begin() [2/2]

template<class radio_t >
void ESBNetwork< radio_t >::begin ( uint8_t _channel,
uint16_t _node_address )

Bring up the network on a specific radio frequency/channel.

Deprecated
Use RF24::setChannel() to configure the radio channel. Use ESBNetwork::begin(uint16_t _node_address) to set the node address.

Example 1: Begin on channel 90 with address 0 (master node)

network.begin(90, 0);

Example 2: Begin on channel 90 with address 01 (child of master)

network.begin(90, 01);

Example 3: Begin on channel 90 with address 011 (child of 01, grandchild of master)

network.begin(90, 011);
Parameters
_channelThe RF channel to operate on.
_node_addressThe logical address of this node.

Member Data Documentation

◆ multicastRelay

template<class radio_t = RF24>
bool ESBNetwork< radio_t >::multicastRelay

Enabling this will allow this node to automatically forward received multicast frames to the next highest multicast level. Forwarded frames will also be enqueued on the forwarding node as a received frame.

This is disabled by default.

See also
multicastLevel()

◆ txTimeout

template<class radio_t = RF24>
uint32_t ESBNetwork< radio_t >::txTimeout

Network timeout value.

Note
This value is automatically assigned based on the node address to reduce errors and increase throughput of the network.

Sets the timeout period for individual payloads in milliseconds at staggered intervals. Payloads will be retried automatically until success or timeout. Set to 0 to use the normal auto retry period defined by radio.setRetries().

◆ routeTimeout

template<class radio_t = RF24>
uint16_t ESBNetwork< radio_t >::routeTimeout

Timeout for routed payloads.

This only affects payloads that are routed through one or more nodes. This specifies how long to wait for an ack from across the network. Radios sending directly to their parent or children nodes do not utilize this value.

◆ frame_buffer

template<class radio_t = RF24>
uint8_t ESBNetwork< radio_t >::frame_buffer[MAX_FRAME_SIZE]

The raw system frame buffer.

This member can be accessed to retrieve the latest received data just after it is enqueued. This buffer is also used for outgoing data.

Warning
Conditionally, this buffer may only contain fragments of a message (either outgoing or incoming).
Note
The first 8 bytes of this buffer is latest handled frame's RF24NetworkHeader data.

◆ external_queue

template<class radio_t = RF24>
std::queue<RF24NetworkFrame> ESBNetwork< radio_t >::external_queue

Linux platforms only

Data with a header type of EXTERNAL_DATA_TYPE will be loaded into a separate queue. The data can be accessed as follows:

while(network.external_queue.size() > 0) {
f = network.external_queue.front();
uint16_t dataSize = f.message_size;
// read the frame message buffer
memcpy(&myBuffer, &f.message_buffer, dataSize);
network.external_queue.pop();
}
Definition RF24Network.h:312
uint8_t * message_buffer
Definition RF24Network.h:326
uint16_t message_size
Definition RF24Network.h:317

◆ frag_ptr

template<class radio_t = RF24>
RF24NetworkFrame* ESBNetwork< radio_t >::frag_ptr

ARDUINO platforms only

The frag_ptr is only used with Arduino (not RPi/Linux) and is mainly used for external data systems like RF24Ethernet. When a payload of type EXTERNAL_DATA_TYPE is received, and returned from update(), the frag_ptr will always point to the starting memory location of the received frame. This is used by external data systems (RF24Ethernet) to immediately copy the received data to a buffer, without using the user-cache.

See also
RF24NetworkFrame
uint8_t return_type = network.update();
if(return_type == EXTERNAL_DATA_TYPE) {
memcpy(&myDataBuffer, network.frag_ptr->message_buffer, network.frag_ptr->message_size);
}
#define EXTERNAL_DATA_TYPE
Definition RF24Network.h:103

Linux devices (defined as RF24_LINUX) currently cache all payload types, and do not utilize frag_ptr.

◆ returnSysMsgs

template<class radio_t = RF24>
bool ESBNetwork< radio_t >::returnSysMsgs

Variable to determine whether update() will return after the radio buffers have been emptied (DEFAULT), or whether to return immediately when (most) system types are received.

As an example, this is used with RF24Mesh to catch and handle system messages without loading them into the user cache.

The following reserved/system message types are handled automatically, and not returned.

System Message Types (Not Returned)
NETWORK_ADDR_RESPONSE
NETWORK_ACK
NETWORK_PING
NETWORK_POLL (With multicast enabled)
NETWORK_REQ_ADDRESS

◆ networkFlags

template<class radio_t = RF24>
uint8_t ESBNetwork< radio_t >::networkFlags

Network Flags allow control of data flow

Incoming Blocking: If the network user-cache is full, lets radio cache fill up. Radio ACKs are not sent when radio internal cache is full. This behaviour may seem to result in more failed sends, but the payloads would have otherwise been dropped due to the cache being full.

FLAGS Value Description
FLAG_FAST_FRAG 4 (bit 2 asserted) INTERNAL: Replaces the fastFragTransfer variable, and allows for faster transfers between directly connected nodes.
FLAG_NO_POLL 8 (bit 3 asserted) EXTERNAL/USER: Disables NETWORK_POLL responses on a node-by-node basis.
Note
Bit positions 0 & 1 in the networkFlags byte are no longer used as they once were during experimental development.

◆ _multicast_level

template<class radio_t = RF24>
uint8_t ESBNetwork< radio_t >::_multicast_level
protected

The current node's network level (used for multicast TX/RX-ing).

See also
Use multicastLevel() to adjust this when needed.

◆ node_address

template<class radio_t = RF24>
uint16_t ESBNetwork< radio_t >::node_address
protected

Logical node address of this unit, typically in range [0, 2925] (that's [0, 05555] in octal).

Note
The values 0 represents the network master node. Additionally, the value 1 is occupied when using RF24Ethernet layer.