New: RF24Ethernet TCP/IP library for nrf24l01+ radio modules

For those of you who may be interested, I've released a new library (in beta form) - RF24Ethernet - that brings TCP/IP functionality directly to RF24. The API is very similar to the standard Arduino Ethernet library, and it is loosely based on the uIPEthernet library for ENC28j60.

RF24Ethernet utilizes my optimized RF24 and RF24Network_DEV libraries, which add a surprising level of performance and reliability to nrf24l01 modules, generally not found in other libraries. It was initially developed as a testing tool for RF24 & RF24Network_DEV, but after witnessing its capabilities, I decided to develop it into a user library.

In short, the library allows users to easily construct an IoT network using nrf24l01+ devices, and connect directly to the devices using a web-browser, nodejs etc, or have them connect out to the internet for information. The RF24Ethernet network requires either a Raspberry Pi as a gateway, or an Arduino connected to a SLIP capable device, for internet or LAN access.

Development is still ongoing, but the library is relatively stable now, with some very positive feed-back so far. The associated RF24toTUN program allows testing to be conducted using standard TCP/IP networking tools via RPi, helping to make this a fairly interesting experiment in networking and protocols.

General Test Results: RPi to RPi link over NRF24l01: 0-RF24Network Hops: 15-20KB/s over TCP/IP 1-RF24Network Hop: 5-7KB/s over TCP/IP

Response Times (RPi to Arduino): ICMP - 64bytes, 0-RF24Network Hops - 12-13ms ICMP - 64bytes, 1-RF4Network Hop - 35-40ms

Arduino devices are somewhat rate-limited to a few KB/s, to allow multiple devices to communicate over the network at the same time. Integration with RF24Mesh is working, but not fully tested, with both libraries still under development.

For the brave, curious, or foolish: Documentation & Download Links: http://tmrh20.github.io/RF24Ethernet/ Blog: http://tmrh20.blogspot.com/2014/11/rf24ethernet-for-diy-internet-of-things.html Source Code: https://github.com/TMRh20/RF24Ethernet

Please keep any technical questions to the forums etc, but software issues can be reported on GitHub.

Note: Email notifications from this forum sometimes come months later, so I apologize in advance if I am slow to reply.

peace, TMRh20

I am not familiar with SLIP capable devices? I have a MEGA with a 5100 wiznet shield, would this not be sufficient as a gateway? Thinking about getting a Pi2 and this may just be a good excuse to get one :)

In the context of RF24Ethernet, a 'SLIP capable device' generally refers to a PC, MAC or Linux machine with a complete IP stack that is capable of utilizing the SLIP protocol. SLIP is just a simple protocol that allows Arduino to receive raw TCP/IP data and send it to the computer over a Serial connection. See http://en.wikipedia.org/wiki/Serial_Line_Internet_Protocol

SLIP: SLIP uses a full computer + Arduino with nrf24l01 for the Gateway (Arduino receives the raw TCP data, and sends it to the computer for processing)

TUN/TAP (Preferred): Uses RPi ( or other RF24 supported Linux devices ) with nrf24l01 for the Gateway. (RPi receives the raw TCP data, and sends it to the IP stack for processing)

Now, it might be possible to modify things to use an Arduino + Wiznet + nrf24l01 module somewhat as the gateway, but this is unsupported. Why?

With a Linux device like RPi, users can also configure advanced routing, firewalling and NAT rules, to manage TCP/IP traffic and prevent unauthorized access, etc. (See IPtables/NAT tutorial - http://www.karlrupp.net/en/computer/nat_tutorial ) Linux also provides abundant options for scripting and customization, making it easy to interact with your devices/sensors directly from RPI, from a web browser with no custom apps etc., or have them interact with services running on the RPi, LAN, Internet, etc.

One user has done some investigation into configuring an Arduino as a standard USB Network device, which can be seen here: https://github.com/TMRh20/RF24Ethernet/issues/2 but as far as I am aware, it isn't being actively developed yet.

Thanks TMRh20! That does make alot of sense.

Is there an active forum for the RF24Mesh library? This is my fallback to creating a internet enabled mesh network where the nodes just talk via the Mega+Ethernet to my pc. Love the work you have done so far, will hopefully understand enough to contribute somewhat.

There is no specific forum for RF24Mesh, but I've started a general thread regarding the main RF24 fork ( Link ), so anything related can be posted there, and I should be notified. I prefer using existing forums, liek these Arduino forums, since it allows other users to provide insight, related knowledge etc. and there is a pretty knowledgeable userbase that can help answer questions I may not be able to. Technically RF24Mesh it is still in testing, but is fairly usable. It seems every time I'm about to get a chance to work on it more, something else comes up.

Also, thanks for the compliments! Feedback and user contributions are some of the best parts of this whole thing, and keeps everything moving forward.

Hi TMR,

i tried to compile the RF24 and RF24Network on a BBB (BeagleBone) but i receive error on GPIO and CPU, because BBB is very different from an RPi ;)

Is there a version of your library for the BBB ? It is simple port it to the BBB ?

this is the errors:

error: 'RPI_BPLUS_GPIO_J8_15' was not declared in this scope
error: 'RPI_BPLUS_GPIO_J8_24' was not declared in this scope
error: 'BCM2835_SPI_SPEED_8MHZ' was not declared in this scope

Testato: Is there a version of your library for the BBB ?

Yup. http://tmrh20.github.io/RF24/BBB.html

Testato: It is simple port it to the BBB ?

Nope.

Great, I'm going through some tests here with RPi & Arduino Nano, late on I'll try with BBB. For TCP It is working like a charm

How to initialize the UDP?? I've tried: EthernetUDP Udp; but won't compile.

Arduino/libraries/RF24Ethernet/ethernet_comp.h:7:21: error: 'RF24UDP' does not name a type

define EthernetUDP RF24UDP

Thanks.

UDP functions are disabled by default to save space, so you need to open the library folder (in windows, usually Documents/Arduino/libraries/RF24Ethernet ) and edit uip-conf.h with a text editor.

Many of the options are shown in the documentation

The main options to uncomment & configure are:

#define UIP_CONF_UDP             0
#define UIP_CONF_BROADCAST       0
#define UIP_CONF_UDP_CONNS       1

Note: The maximum TCP payload length is 104 bytes (144 bytes - IP/TCP/UDP headers) & configured in RF24Network_config.h via adjusting the MAIN_BUFFER_SIZE

I haven't done a whole lot of testing with UDP, so any input is useful.

It is running 24/7 for the last 10 days. with a current transducer in the arduino it is streaming the house power consumption every second, the total are 60 bytes/package. Working great.

I'm using the RF24GatewayNode as daemon during the startup. is this the correct way to go? I see it takes 17% of the CPU all time (RPi).

What is the best way to change the setDataRate to RF24_250KBPS in the RPi?

Rberg: I'm using the RF24GatewayNode as daemon during the startup. is this the correct way to go?

Awesome, its great to get some feedback.

As far as the 'correct' way to go, I'm no expert. I tend to use the ncurses interface with screen, because I always want the extra information for debugging etc. The general GWNode works pretty much the same, but without the ncurses overhead etc.

Rberg: I see it takes 17% of the CPU all time (RPi).

Yeah, this is due to the constant polling of the radio. I assume that 'proper' hardware drivers for linux would be more likely to utilize IRQ based polling etc, but that tends to make things more difficult. The last time I looked at RPi support for IRQ with the BCM driver or SPIDEV, I was not able to figure it out or make it happen. This in no way means it is not possible.

Currently, RF24Gateway just uses delays in attempts to minimize CPU load, while ensuring data throughput. If you are sending in data at a fairly consistent rate, you could just add some delays to the Node sketch, because the radio will buffer incoming data in its FIFO, without any interaction from the RPi.

There are probably better ways to manage CPU usage on Linux, but I have not had a chance to properly educate myself.

TMRh20: There are probably better ways to manage CPU usage on Linux, but I have not had a chance to properly educate myself.

So a workaround for a while.

apt-get install cpulimit
sudo cpulimit -l 10 ./RF24GatewayNode

The name explain it self. Just to ensure nothing goes wrong to fry the RPi

I added a second node right now. it is working fine however I just found out that if the destination UDP port (server) is down the red led in the RPi will blink. According to the RPi docs, in case it blinks could be related to power issue. "scratching the head now..."

Node (Send UDP pack) --> RF24Gateway (forward with nat) --> UDP Server (listen)

As soon the server is up (UDP listening) the led stops blink coming back to normal.

Hmm, I'm really not sure about the LED on RPi, the only time I've seen it blink on mine is when I had a faulty SD card. How are you connecting via UDP? Care to share your code or an example?

Hi TMRh20,

In my university I’m working on a project of a sensor networking for power comsumption. I’m using the rf24l01+ radios with your libraries for arduino. I managed to create a network and everything is working well so far. In this network, several nodes that are connected to current sensors send their data (power consumed) to a base node (address 00). Now I need to use this data to make graphs and stuff like that. I thought of using the thingspeak examples and a ethernet shield to upload this information to a server. However, I learnt that there is a conflict with the SPI when using the rf24l01+ and ethernet shields. To solve this problem, someone created a modified version of rf24 library that allows the arduino to communicate with the shield and the radio. The website where I found this is here: http://shanes.net/how-to-use-an-nrf24l01-rf24-with-an-arduino-ethernet-shield/
The problem is that this user modified an older version of the library, which is not compatible with the current rf24network I’m using. It would be very complicated for me to adapt the modifications to the newer libraries so I looked for another solution and I found this your rf24ethernet library. I think this would be the best solution for me. Could you tell me how I could use my base node and your library to upload information received to thingspeak server or anyother server? Here is my base node code. In this code I’m showing the current (in Amperes) in a LCD screen. The power consumption is being calculated and printed in the serial Monitor. I would like to upload theses datas in a server, like thingspeak.

base_00.ino (4.67 KB)

Just take a look at the RF24 documentation at http://tmrh20.github.io/RF24/Arduino.html

The new library supports soft-SPI as well as using the UART as a (hardware driven) secondary SPI BUS.

If you have problems getting it working, please post an issue at https://github.com/TMRh20/RF24/issues.

As for thingspeak, without looking into it in great detail, you probably just have to connect and send data in the proper format I would guess.

Thanks a lot!! I changed the library and now the radio and ethernet shield are working fine. You did an excellent job with theses libraries. :D

Does anyone know of good tutorial to set up RPi2 and Arduino with RF24 as a sensor/action node and gateway?

I have managed to get the dynamic ping example to work and both units are sending and receiving packets.

But i am struggelig to set the RPi as a gateway to receive and send out MQTT messages.

I have uploaded the simple MQTT example to my arduino, but how do i configure the RPi to receive/answer/redirect the MQTT messages?

If i try to run the RF24GatewayNode example the arduino wont connect.

 Failed
Attempting MQTT connection...failed, rc=-2 try again in 5 seconds

WHat shall the IP adress (in the arduino sketch) be?

IPAddress ip(Arduino IP?); IPAddress gateway(RPi2 IP?); IPAddress server(Mosquitto IP?);

This is a kind of complicated set of questions, but to start, you need a good general understanding of networking and TCP/IP.

Before getting into too many details, you might want to look at https://www.mysensors.org/ if looking for a more user friendly option.

The RPi needs to run a MQTT broker like mosquitto: http://mosquitto.org/documentation/

Once you have assigned an IP and started up the gateway on the RPi, it will automatically handle IP traffic as it would with any network interface. Linux forwarding and IPTables rules etc apply. You should be able to ping the Arduino IP from the RPi. See http://tmrh20.github.io/RF24Ethernet/ConfigAndSetup.html also.

The IP configuration is up to you, with the RPi being the gateway, so standard IP & subnetting rules apply. The Arduino needs an IP, and it also needs to know the IP of the gateway (RPi). If you want to connect to an external MQTT broker, then it also needs to know the IP of that server, and the RPi needs to be configured to route IP traffic accordingly. I would say this is geared towards advanced users or users that really want to spend some time.

Thanks for the reply!

After some troubleshooting i think the problem is located at the arduino side.

RPi (ethernet ip=192.168.0.100 nrf24 ip=192.168.1.115)
Arduino (nrf24 ip=192.168.1.114)

I have added a staticroute on my router that redirects traffic heading for the network 192.168.1.0 through the RPi ethernet IP address.

I can ping the RPi nrf24 IP adress from my windows machine.

When i ping the arduino from my RPi i can see that the RPi is sending packets (from both IP adresses using ping -I )
But nothing is received, but i can see that the arduino is showing in the Ncurses interface.

RF24Gateway Ncurses Interface by TMRh20 - 2015
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
tun_nrf24 IP: 192.168.1.115

 qqq IF Stats: qqqqqq     qqq Mesh Info: qqqqqqq   qqq RF24Network Info: q
 RX Bytes 0                Address: 04 ID: 114     Address: 00
 RX Packets 0                                      nodeID: 0
 RX Errs 0                                         En Mesh: True
 TX Bytes 17748                                    Data-Rate: 1MBPS
 TX Packets 216                                    PA Level: MAX
 TX Errs 0                                         IF Type: TUN
                                                   IF Drops: 0
 RX 0.000 KB/s
 TX 0.000 KB/s

When running the RF24GatewayNode i get some errors if i open up the ncurses interrface at the same time.

Cosmc@osmc:~/rf24libs/RF24Gateway/examples$ sudo ./RF24GatewayNode
================ SPI Configuration ================
CSN Pin          = CE0 (PI Hardware Driven)
CE Pin           = Custom GPIO22
Clock Speed      = 8 Mhz
================ NRF Configuration ================
STATUS           = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0xccccccccc3 0xcccccccc3c
RX_ADDR_P2-5     = 0x33 0xce 0x3e 0xe3
TX_ADDR          = 0xcccccc3ce3
RX_PW_P0-6       = 0x20 0x20 0x20 0x20 0x20 0x20
EN_AA            = 0x00
EN_RXADDR        = 0x3f
RF_CH            = 0x61
RF_SETUP         = 0x06
CONFIG           = 0x7f
DYNPD/FEATURE    = 0x3f 0x04
Data Rate        = 1MBPS
Model            = nRF24L01
CRC Length       = 16 bits
PA Power         = PA_MAX
RF24 HARDWARE FAIL: Radio not responding, verify pin connections, wiring, etc.
RF24 HARDWARE FAIL: Radio not responding, verify pin connections, wiring, etc.
RF24 HARDWARE FAIL: Radio not responding, verify pin connections, wiring, etc.
RF24 HARDWARE FAIL: Radio not responding, verify pin connections, wiring, etc.
Received Network Message, type: 14 id 0 from -1
Received Network Message, type: 0 id 0 from 0
Received Network Message, type: 0 id 0 from 0
RF24 HARDWARE FAIL: Radio not responding, verify pin connections, wiring, etc.
RF24 HARDWARE FAIL: Radio not responding, verify pin connections, wiring, etc.
RF24 HARDWARE FAIL: Radio not responding, verify pin connections, wiring, etc.
Received Network Message, type: 0 id 0 from -1

Do this suggest software or hardware related problems?

Here is the ifconfig if needed

tun_nrf24 Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:10.10.2.2  P-t-P:10.10.2.2  Mask:255.255.255.0
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:217 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:0 (0.0 B)  TX bytes:17828 (17.4 KiB)

Active IP connections ncurses interface:
The last entry is my windows computer trying to ping the arduino IP.

 1  13 src=192.168.0.107 dst=192.168.1.115 type=8 code=0 id=1 src=192.168.1.115 dst=192.168.0.107 type=0 code=0 id=1
 2  6 7 SYN_SENT src=192.168.0.107 dst=192.168.1.1 sport=57442 dport=80 [UNREPLIED] src=192.168.1.1 dst=192.168.1.115 sport=80 dport=57442
 3  28 src=84.213.205.180 dst=192.168.1.2 sport=60725 dport=60309 [UNREPLIED] src=192.168.1.2 dst=192.168.1.115 sport=60309 dport=60725
 4  1 6 src=192.168.0.107 dst=192.168.1.114 type=8 code=0 id=1 [UNREPLIED] src=192.168.1.114 dst=192.168.1.115 type=0 code=0 id=1

Still troubleshooting and tried to change IP adress from 192.168.1.114 and 192.168.1.115 to the same as the ethernet IP (and the rest of the network) 192.168.0.114 and 192.168.0.115.

I can now see the arduino sending packets to the RPi (trying to connect to mqtt with the simple mqtt sketch).

 18  31 SYN_RECV src=192.168.0.114 dst=192.168.0.100 sport=1033 dport=1883 src=192.168.0.100 dst=192.168.0.114 sport=1883 dport=1033

But i still get connection failed to the mqtt in the serial monitor (arduino)