Introduction
I wanted to experiment with the NRF24L01+ radio from Nordic Semiconductor as it seemed to offer very low cost
and very low energy radio communications for embedded systems. You can buy a pair of modules for about 4 Euro
if you shop around. They claim to have a range of up to 80m and can support data rates of up to 2Mbps. More
technical details can be found at the Nordic semiconductor website.
The modules I used were bought in dx.com.
Of course these modules need to be used in conjunction with some sort of host processor. This little
project uses the LPC1114FN28 chip from NXP on one end and an Intel Galileo 2 board on the other.
Software development
I spent quite a while going through and trying various online libraries for the NRF24L01 to varying degrees of
success. There are plenty of Arduino and AVR tutorials and also some for MSP430's and ARMs. There are fewer
examples for the Intel Galileo 2 however which led me to the decision that I should write my own interface
library. The library is actually written in two languages. The LPC1114 version is written in C while the
Galileo version is written in Javascript as it will be run using node.js and its MRAA library.
Development of both libraries was carried out in tandem so function names and semantics are common to both.
LPC1114 Interface
The LPC1114 hardware Interface is shown below. The MCU is connected to the NRF using 5 wires. Pin 5 of the MCU
must be pulled up as it is an open collector output. Push buttons for Reset and ISP-mode are also shown along with
a USB/Serial converter for ISP programming. Details of how to program in ISP mode are available here.

The LPC1114 is capable of generating Slave-Select signals for SPI peripherals but I found it difficult
to make it perform exactly as required. In the end, the Slave-Select (also known as CSN) and Chip Enable (CE)
controls were managed by sofware. The figure below shows the behaviour of the SPI signals during a read of
the configuration register in the NRF24L01+. When the CSN line goes low, the NRF outputs its status during the
first byte transfer (the value 0x0e). The next byte is the contents of the requested register (0x08).
These traces were captured using a Bitscope Micro USB logic analyser.

One of the difficulties with the NRF24L01+ modules is that the use a double row header to connect to the outside
world. This makes them difficult to use with a breadboard. In the case of this project, a little adapter was
made using a piece of stripboard as shown below

Below is a photo of the assembled and working board.

Galileo Gen2 Interface
The Intel Galileo 2 is fitted with Arduino compatible headers. The NRF24L01 radio module was interfaced by plugging
wires directly into these headers and then into the NRF module. The wiring diagram is as follows

VERY IMPORTANT: Switch the I/O voltage to 3.3 volts by moving the IOREF jumper as shown
A photo of the assembled board is shown below

LPC1114 software operation
int main()
{
uint8_t payload[10];
int index;
initUART();
NRFinit();
enable_interrupts();
printRegisters();
NRFWriteData(sizeof(payload),payload);
delay(1000000);
NRFWriteCE(1);
printRegisters();
payload[0]=0;
while(1)
{
NRFFlushTX();
NRFFlushRX();
payload[0]++;
NRFWriteData(sizeof(payload),payload);
delay(100000);
NRFEnableRXMode();
// check status register to see if there is data
if ((NRFReadRegister(7) & 0x40))
{
printString("Got Data ");
NRFReadData(sizeof(payload),payload);
printInteger(payload[1]);
printString("\r\n");
}
}
}
The main function for the LPC1114 code is shown above. The program consists of a number of files:
main.cstrong> : Contains the main program code
serial.c: UART routines for communicating with the host PC
nrf24l01.c : Library routines for the NRF24L01
spi.c: Low level functions for the SPI interface
init.c: startup code for the program and interrupt vectors
The program begins by initializing the UART and the NRF24L01 (and consequently the SPI0 interface).
The printRegisters function outputs the contents of the NRF24L01 registers to the host PC
which is very useful for debugging.
The main program loop sends a 10 byte payload to the target NRF module. The first byte of this payload
is an increasing 8 bit value. The main loop then checks to see if a packet has been received, and if so,
it prints the second byte from the payload (the other device involved in the conversation puts something
in here).
Galileo software operation
The javascipt (node.js) code that runs on the Galileo is shown below. It is much the same as the C example. The
poll runs every 50ms and checks for new data. If there is new data then a reply is sent back
to the other communicating party with the second byte set equal to the bitwise inverse of the first.
/* The main body of the program follows.
* The NRF is initialized with correct addresses etc and is periodically
* polled to see if there is any data available in the RX FIFO
* If there is data it is read and a reply is sent back
*/
function poll()
{
// check to see if there is any received data
if ((NRFReadRegister(0x7) & 0x40) > 0)
{
// Got data!
console.log("Got data");
var RXData = new Buffer(10);
NRFReadData(10,RXData);
console.log(RXData);
NRFWriteRegister(0x07,0x70); // clear status flags
RXData[1]=~RXData[0]; // send back some 'dummy' data
NRFWriteData(10,RXData);
}
setTimeout(poll,50);
}
NRFinit();
NRFSetRXAddress0(5,DESTINATION_ADDRESS); // set auto ack address = destination
NRFSetTXAddress(5,DESTINATION_ADDRESS); // set destination address
NRFSetRXAddress1(5,SOURCE_ADDRESS); // set source address
console.log("Switching to RX mode");
NRFFlushTX();
NRFFlushRX();
NRFEnableRXMode();
NRFWriteCE(1);
printRegisters();
poll();
Software Operation
The figure below shows the output from node.js (the left hand panel) and the LPC1114 uart (right hand side)

The Galileo code outputs the full contents of the buffer while the LPC1114 code outputs just the second byte
that was generated by the Galileo.
Downloads and links
The Galileo code is in a file call nrf24l01.js and is included along with the LPC1114 C code here
The Galileo was configured to run on the IOTDK (Internet of Things Development Kit) which was obtained from http://iotdk.intel.com/
If you have any questions mail me at frank.duignan@dit.ie