Arduino and NRF24L01

I've always tried to bring connectivity into my Arduinos with an Ethernet Shield and even Ethernet SPI modules but I was never much pleased with the result. They somehow were very unstable, didn't run smoothly and, therefore, not much reliable (specially if your intention is to feed pets or something alike). Maybe it's just too much processing for the Arduino, to handle the HTTP requests and responses and still do what they're intended to (specially if you're working with interruptions, timers, PWM functions or combinations of them)

Raspberry Pi B+ and NRF24L01

Recently I've found an outstanding solution bringing more computational power into the design and, at the same time, making the orchestration go wireless, which allows me to spread my nodes all over the house. I've done it using a Raspberry Pi B+ and a couple of NRF24L01 modules. The result has very satisfying and they could communicate over a 35 meters distance. 

The Raspberry can handle HTTPS connections (to securely connect my sensor network into the web), host a database management system (so I don't even need to publish "sensing" data anywhere) and run many sorts of software (Python, Perl, PHP, C, Java, etc), being perfect as an intermediator between my private sensor network and the wild. The Arduinos can now just worry about handling very controlled and pre-formatted data and most of its concern is to implement what they actually must do. And better, wireless!, covering a much higher distance from my Access Point that they would using Ethernet cables.

Having the NRF240L1 modules in hand, connect them following the circuit schematics below.

Boards Pinout
Raspberry Pi B+ Arduino
Raspberry Pi B+ pinout Arduino pinout  

For both boards, Arduino and Raspberry, I used the same library package available at http://tmrh20.github.io/ (Optimized RF24 NRF24L01 Radio Library for Arduino - despite the name, this package also includes the libraries that we're going to use within the Raspberry). So, download the library, import it into the Arduino (Sketch->Import library). Prepare the environment at the Raspberry:

$ git clone https://github.com/TMRh20/RF24.git
$ cd RF24
$ sudo make install

As we're going to use JSON-C lib, install using the apt-get:

sudo apt-get install libjson0-dev

Talking about the sample application developed on the top of this infrastructure, I designed a solution where, somehow (through an SSH Internet connection or through a web service) I would request to the Raspberry some information located at the Arduino (in this case, the LED state located at pin 6). The Raspberry, in its turn, would then use the NRF240L1 module to talk to the Arduino, request the required information, receive it and give it back to the application (it should also manage timeout exceptions or any problems related to the communication towards the Arduino). This message could also mean an order, delegating the Arduino to do something (in this case, to change the LED's state). The image below illustrates the proposed

undefined

To do so, the Raspberry will always transmit data structured in a 16 bytes sized message object...

struct payload_request_t
{
  uint8_t number;
  uint8_t destination;
  char message[14];
};

... and the Arduino will always reply with a, also 16 bytes sized, message object:

struct payload_general_t
{
  uint8_t number;
  char message[15];
};

The request payload includes: a randomly created number as the message identifier; the destination node number identifier; and the message itself. The answer payload includes the request's number identifier and its reply message.

The application hosted at the Raspberry receives a JSON-structured string as the input parameter containing, apart from the destination node number and the message, an optional field "TTL" that represents a timeout delay tolerance for the transmission. This program always exits a JSON-structured string that describes if the message/request has been successfully transmitted and answered or not.

Input sample string:

{
	"to":"1",        // node 1
	"message":"get", // request/command
	"TTL":"2500"     // (optional) "time to live" (better said, "wait for")
}

Output sample string:

{
	"status":"true",  // it has been successfully transmitted 
	"code":"0",       // error code, if any
	"message":"ok"    // replied message
}

 Snapshot taken while running the presented solution.

undefined

Material list:

 Source codes: