RNet: optional ACK, Dynamic Payload and Extended nRF24L01+ Driver

Time to write an update about the RNet Wireless Stack. The stack has been successfully used for the Sumo Robots as wireless controller. In the last week, there has been a lot smaller and larger extensions for it. And because the nRF24L01+ modules are so inexpensive, I bunkered more than 50, with 20 still left to be deployed:

nRF24L01+ Transceiver Modules

nRF24L01+ Transceiver Modules

With that many network nodes, it is good to have a small and scalable wireless stack. And as I have developed my own open source one, the stack grows with my needs :-).

Dynamic Payload (DPL)

One big difference between the Nordic Semiconductor nRF24L01 (without the +) and the nRF24L01+ is that the ‘+’ version supports DPL (Dynamic Payload). The Radio.c transeiver features a  macro

<br />#define NRF24_DYNAMIC_PAYLOAD  1 /* if set to one, use dynamic payload size */<br />

to enable/disable DPL:

<br />#if NRF24_DYNAMIC_PAYLOAD<br /><%%KEEPWHITESPACE%%>  /* enable dynamic payload */<br /><%%KEEPWHITESPACE%%>  RF1_WriteFeature(RF1_FEATURE_EN_DPL|RF1_FEATURE_EN_ACK_PAY|RF1_FEATURE_EN_DYN_PAY); /* set EN_DPL for dynamic payload */<br /><%%KEEPWHITESPACE%%>  RF1_EnableDynanicPayloadLength(RF1_DYNPD_DPL_P0); /* set DYNPD register for dynamic payload for pipe0 */<br />#else<br /><%%KEEPWHITESPACE%%>  RF1_SetStaticPipePayload(0, RPHY_PAYLOAD_SIZE); /* static number of payload bytes we want to send and receive */<br />#endif<br />

With DPL enabled, shorter data packets can be transmitted faster, plus the stack allows one more byte available as application payload.

RNet Stack Configuration

To configure the stack, there is now a configuration header file at the application level and ot overwrite default values inside the stack. Things like (short) address size, application message types, maximum payload size or acknowledge handling.

<br />/**<br />* \file<br />* \brief This is a configuration file for the RNet stack<br />* \author (c) 2013 Erich Styger, https://mcuoneclipse.com/<br />* \note MIT License (http://opensource.org/licenses/mit-license.html)<br />*<br />* Here the stack can be configured using macros.<br />*/<br /><br />#ifndef __RNET_APP_CONFIG__<br />#define __RNET_APP_CONFIG__<br /><br />#include "Platform.h"<br />#if PL_HAS_RADIO<br /><br />/*! Type ID's for application messages */<br />typedef enum {<br /><%%KEEPWHITESPACE%%>  RAPP_MSG_TYPE_STDIN = 0x00,<br /><%%KEEPWHITESPACE%%>  RAPP_MSG_TYPE_STDOUT = 0x01,<br /><%%KEEPWHITESPACE%%>  RAPP_MSG_TYPE_STDERR = 0x02,<br /><%%KEEPWHITESPACE%%>  RAPP_MSG_TYPE_DATA = 0x03<br />} RAPP_MSG_Type;<br /><br />#define RNET_CONFIG_TRANSCEIVER_PAYLOAD_SIZE  32<br /><%%KEEPWHITESPACE%%>  /*!< Size of the physical transceiver payload (bytes), max 32 bytes for nRF24L01+, max 128 bytes for MC1320x */<br /><br />#define RNET_CONFIG_SHORT_ADDR_SIZE   1<br /><%%KEEPWHITESPACE%%>  /*!< size of short address type. Either 1 or 2 */<br /><br />#define RNET_CONFIG_USE_ACK           1<br /><%%KEEPWHITESPACE%%>  /*!< If set to 1, the NWK layer will send an acknowledge message for every data packet received */<br /><br />#endif /* PL_HAS_RADIO */<br /><br />#endif /* __RNET_APP_CONFIG__ */<br />

RNet Acknowledge

The Rnet stack uses internally flags for things like acknowledge handling on the wireless stack level. As such, it is possible now to send messages either with or without acknowledge. If the application wants an ACK, then it passes RPHY_PACKET_FLAGS_REQ_ACK:

<br />if (RAPP_SendPayloadDataBlock(&val8, sizeof(val8), RAPP_MSG_TYPE_DATA, APP_dstAddr, RPHY_PACKET_FLAGS_REQ_ACK) != ERR_OK) {<br />CLS1_SendStr((unsigned char*)"ERR: failed sending data\r\n", io->stdErr);<br />return ERR_FAILED;<br />}<br />

nRF24L01+ Processor Expert Component

The component has been extended with several functions:

nRF24L01+ Component

nRF24L01+ Component

  • Functions to enable and deal with DPL (Dynamic PayLoad)
  • Functions to read/write the FEATURE register (dynamic payload and acknowledge control)
  • Function to read the OBSERVE_TX register: that way I can get the number of retry and number of re-transmitted packets.
  • Function to read the RPD (Received Power Detector) bit.

❗ I have found that the RPD information often reports a zero bit. This because it easily gets reset by a ‘foreign’ packet, e.g. having WiFi traffic. With this, the usage of that bit is somewhat minimal.

Shell Support

The Command Line Shell support has been extended: It is now possible to change the radio channel from the command line. The radio channel along with state machine state and the information from the OBSERVE_TX register is displayed in the shell too:

Radio Status in Shell

Radio Status in Shell

The optional built-in Sniffing support reports extended information about every incoming or outgoing packet:

Sniffing Output

Sniffing Output

That packet sniffing has helped me many times as debugging aid and to quickly see what is going on.

Sources on GitHub

The sources and example project for FRDM-KL25Z are as always available on GitHub. The stack sources itself are available here.

Summary

I’m using the stack now in multiple projects taking advantage of wireless communication, both with the Nordic Semiconductor nRF24L01+ and the Freescale MC1320x/MC1321x transceiver. I have experimental short address assignment based on the Kinetis UID working, but this is still work in progress.

Happy RNeting 🙂

8 thoughts on “RNet: optional ACK, Dynamic Payload and Extended nRF24L01+ Driver

  1. Pingback: RNet Stack for 8bit MC9S08QE128 Microcontroller and MC13201 Transceiver | MCU on Eclipse

  2. Hello,
    thanks for your work here 🙂
    Would it be hard to add support for nRF905 or CC1101 to RNET? One could choose if he wants 2.4G or sub-1G frequency. nRF905 (less programming, I think, it should be very similar to NRF24L01) modules on E-bay usualy have 14pins, thats a little disadvatage – you can’t have same PCB for both.
    But there are 8pin modules with CC1101, that seems to be pin-compatible with NRF24L01. Then you could have same PCB and just change wireless driver.

    BTW1: Does Rnet already work without FreeRTOS? I am working on ColdFire V1 without FreeRTOS (and not using Proc.Expert), I am using another driver for NRF24L01, so I am thinking if I should stick with that or try your (I think better) driver …
    BTW2: Sorry that I din’t check your source code completely, but is there any data encryption implemented, or should I make my own?

    Thanks.

    Like

    • Hi Martin,
      Adding the nRF905 would not be hard at all, it is very similar to the nRF24L01+. A benefit of the nRF905 would be a higher range, but on the other side it seems that the modules are much more expensive than the nRF24L01+. CC1101 would be some more work, but not too hard. The CC1101 would be attractive as it seems to support true broadcast capabilites.
      RNet can work without any RTOS, but right now it is using the queue mechanism for the message buffers. This could be easily rewritten to use either a static array or a ring buffer instead. I just have not done it as anyway in my applications it is very handy to use FreeRTOS.
      I have not added encryption yet, but this again can be easily added, like AES or something similar. I simply have not had a need for it, so be free to add encryption to the stack.

      Like

      • Hello,
        so I ordered some 8pin CC1101 modules from Ebay, I will wait and when it comes (3-4 weeks), I try to make it work on CFv1. If you wil not have it already done, I will send you the code for “make it more professional” 🙂 now I should go and chech that FreeRTOS

        Like

  3. Pingback: Debugging the same Project Multiple Times in Parallel with Eclipse | MCU on Eclipse

  4. Hi,
    Thank for the work. I have been using Zigbee network. Are the nrf24l01 and the software supporting multi-hop ? I am designing mesh network.

    Like

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.