$0.87 WiFi for Raspberry Pi and Arduino Projects

My project goal is to make internet access for micro controllers dirt cheap and dead simple to implement in your own projects.

Similar projects worth following
My project goal is to make internet access for micro controllers dirt cheap and simple to implement in your own projects.

The NRF24L01+ is a easy to use SPI device, that allows short packet transmissions. It handles all the RF, packet transmission, CRC and retransmission. It is also available for $0.87.

The first component of this project involves writing software on the Raspberry Pi that turns the NRF24L01+ into a TAP networking device. This allows for the NRF24L01+ to appear like a native ethernet interface on the linux device. With that running you can bridge the NRF24L01+ to your local ethernet and all IP traffic will seamlessly pass between the ethernet cable and the NRF24L01+ RF interface.

The second part of the project involves writing an Arduino driver that is capable of sending or receiving a single UDP packet at a time. You won't be able to stream youtube videos, but you will be able to send and receive simple packets to the internet. All for only $0.87.

*Under Construction*

As with most projects I am trying to learn the system, and rushing against the deadline to get my project entered into the contest.  Please be patient as I figure out the best way to organize my page.  Over time it should become more coherent.

Build Something

One of the requirements for the Hackaday Prize is that you build something.  I asked myself if building a communications protocol would count?  While I have built my fair share of PCB's I really wanted to push myself and make something that will benefit everyone if successful.   Being able to add internet connectivity to a device for less than $1 would be an awesome addition to so many projects.  And if that doesn't count I can always fall back on the technicality that I did 'build' a Raspberry Pi with a  nRF24L01+ plugged into it.  Right?

Development Setup

Please read the project logs (starting from the bottom) for details of this project.

  • 2 × Raspberry Pi SBC
  • 2 × nRF24L01+ RF Module - Nordic Semiconductor
  • 16 × Jumper Cables

  • Phase 1 - Success

    surfingsteve08/21/2014 at 05:27 0 comments

    I am able to send pings over the nRF24 interface using the custom protocol.  The code right now is just a proof of concept, and can be considered in the pre-alpha stage.  However I do plan on releasing it soon on Git-hub, as soon as I can clean it up a bit.   In the video the top two windows are connected to the first raspberry pi, and the bottom two windows are connected to the second raspberry pi.  The windows on the left show the debug output from the nRF24 link.

    Jump to 1:27 to see the good part.

  • Youtube Intro - 2min

    surfingsteve08/21/2014 at 03:36 0 comments

    Very high level overview of the project posted on youtube.  More details here in the log.

  • Tap/Tun Overview

    surfingsteve08/20/2014 at 06:52 0 comments

    Central to this project is using a Raspberry Pi, or similar linux device, to act as a bridge between the internet and the nRF24L01+ device.  Our task includes two steps.  First we create a network driver for the nRF24L01+.  Second we bridge this new device we created with the ethernet port on the Raspberry Pi.  Wikipedia: Network Bridging  Alternatively we could setup Routing, IP Masquerading (NAT) or any other linux network techniques to our newly created interface, but that discussion is beyond the scope of this hack.

    Building a network device driver in linux requires kernel device programming (not as hard as it sounds) and constant updates with each new kernel release.  This can be a lot of work and a pain to maintain your code. Fortunately there is a way in software to create a virtual network interface that can be initialized by a simple C program.  This is a trick often used by VPN clients in linux to create virtual network interfaces to a remote network.

    There are two types of virtual network interfaces in Linux, TAP and TUN.  Paraphrasing Wikipedia, both devices are purely created in software.  TUN, short for tunnel, simulates a layer 3 IP communications, think IP addresses.  TAP, short for network TAP, simulates layer 2 data link communications, think MAC addresses.  Now might be a good time to review the network Wikipedia: OSI layer model.  

    For our project we are going to use the TAP interface.  This allows us to operate at the layer 2 level and forward ethernet data in a more raw form.  We just have packets of bytes we want to shuttle back and forth with no concept in our software of IP addresses, IPv4/IPv6 or TCP/UDP.  These are all things we can support without having to know anything about then.  This is an advantage of the network OSI model.  This gives us great flexibility of being protocol agnostic.  Our nodes can use DHCP, send network broadcasts, or communicate in IPv6.  Our hardware doesn't know or care because it's all bytes to us at the layer 2 level.  As a side note the RF modulation would be the layer 1 level in this use case, but for now that's a detail we can safely ignore.

    Here is a quick example of a tap interface on a linux machine:

  • Packet Structure

    surfingsteve08/20/2014 at 06:06 0 comments

    The maximum size that a RF24L01+ can transmit is 32 bytes.  An ethernet frame can contain up to 1500 bytes.  We need to define a very simple protocol that will allow us to transmit the larger 1500 byte ethernet frames over the limited 32 byte messages that are sent via the RF24L01+.  

    The full Ethernet frame is broken up to small 29 byte size packets to transmit over the wireless link. The additional 3 bytes of overhead are used to help reassemble the frame on the receiving end of the link.  A random ID is generated to identify the packets belonging to the same frame.  We rely on the CRC that is already generated by the RF24L01+ to ensure the messages we receive are correct.  This is acceptable because the RF24L01+ has a mode that automatically calculates and sends a CRC with the transmission of every 32 byte packet.  When the 32 byte packet is received on the other end the CRC is checked, and if found to be incorrect it is automatically re-requested before passing the data to us.   An additional CRC in our code would be wasteful overhead.


    • 2 bytes - random "packet id", only used to identify each particular ethernet frame
    • 1 byte - control
    • 7 - start bit - indicates this is the first packet of the ethernet frame
    • 6 - stop bit - indicates this is the last packet of the ethernet frame
    • 5:0 - uint count - value 0->63 *
    • 29 - bytes data, zero pad end for last packet

    *The count variable is an integer index for each of the RF24L01+ transmitted packets.  For example, [0,1,2,3...n].  This helps the receiving end place the data from each RF24L01+ packet into the correct location of the reassembled ethernet frame.  The only exception is with the "last" 29 byte packet.  If the last flag is set to 1, then the count variable identifies how many bytes are contained in this last packet.  The rest of the packet will be 0 padded.

    Example - ethernet frame (the data used here is gibberish)

    (0x00 repeated 29 times) (0x01 repeated 29 times) (0x02 repeated 4 times)

    - or -

    0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x02 0x02 0x02 0x02

    This results in being parsed into:

    nRF24 packet 0 - 0xba 0x02 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
    nRF24 packet 1 - 0xba 0x02 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01
    nRF24 packet 2 - 0xba 0x02 0x44 0x02 0x02 0x02 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

    packet 1

    0xba 0x02 - random packet id

    0x80 - start bit 7 set, stop bit 6 cleared, count = 0 (packet index)

    0x00 repeated 29 times - data payload

    packet 2

    0xba 0x02 - random packet id

    0x01 - start bit 7 cleared, stop bit 6 cleared, count = 1 (packet index)

    0x01 repeated 29 times - data payload

    packet 3

    0xba 0x02 - random packet id

    0x01 - start bit 7 cleared, stop bit 6 set, count = 4 (valid bytes in this last packet)

    0x02 0x02 0x02 0x02 (0x00 repeated 25 times)  - data payload, only first 4 bytes valid

    Notice how the random packet id is the same id for each ethernet frame.  The packet only changes with each new ethernet frame.  This allows us to have multiple nodes broadcasting segments of different ethernet frames to the root node and still provide the root node with enough information to reassemble the frames.

  • Proof of Concept

    surfingsteve08/20/2014 at 05:22 0 comments

    In order to determine the feasibility of this idea first I wanted to implement a simple Raspberry Pi to Raspberry Pi, two node link.  In an ideal case we want a network similar to WiFi with a single access point and multiple nodes. 

View all 5 project logs

  • 1
    Step 1

    For the majority of my tests I used two Raspberry Pi's, each with a nRF24L01+ connected to the SPI bus. The nRF24L01+ radio is available either at Amazon or Aliexpress. All of you should have a Raspberry Pi by now. If you want to follow along, here is how you connect the two devices together.

  • 2
    Step 2

  • 3
    Step 3

    For clarity here is the nRF24L01+ pinout:

    And the Raspberry Pi v2 GPIO header pinout:

View all 3 instructions

Enjoy this project?



Cris Harrison wrote 09/19/2016 at 01:01 point

I like this but, I really need the 100mhz stuff is there a 'cheep' Ethernet adapter that would work on a Arduino Mega. It would make my life easier than lots of  problematic USB cables. 

  Are you sure? yes | no

James Newton wrote 09/09/2016 at 16:02 point

I'm sad that no source code has been released.

  Are you sure? yes | no

david wrote 10/22/2014 at 17:43 point
I've never seen NRF24L01+ modules or bare chips for as little as 87 cents -- I'd love it if someone could point me to a source that cheap...

  Are you sure? yes | no

Ted Mieske wrote 02/28/2016 at 18:07 point

I found them cheaper on Ebay

  Are you sure? yes | no

manosv wrote 09/16/2014 at 12:24 point
This is awesome.I really like it. nrf24l01 is very flexible after all

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates