Matt Reid
Electronics Design Specialist
NRF24L01 Transciever Range Test
The NRF24L01 is a RF transciever that works at the 2.4GHz ISM band. You can find these transmitters on ebay or various sites for no more than 5 to 10 dollars each which was one of the reasons I was attracted to it. The boards you can buy off ebay(shown below) comes with all the parts on it that you need to run it. You can also buy the IC in a small QFN package individually if you want to add only the chip to whatever project or PCB you are working on.
The reason I am posting my code is because there are loads of examples for Arduino on the internet on how to use these chips, but they show you a very top level description of how the transciever works utilizing pre-written libraries. There arnt as many examples posted online using anything other than an Arduino. Although the code is written using Picbasic pro you dont have to be a BASIC programmer to be able to understand what is happening. The first bit of code is for the side set up as a reciever. Below that is the code for the transmitter. Both use a PIC16F688.
The code tests toggles an output which I had an LED connected to if it recieves the decimal value of 52(just a random value I chose). If it does not recieves any valid data the LED stops blinking. The only purpose of this code was for me to familiarize myself with these transcievers for use in future projects. I used this to test the range. I was able to get between 200-300 Meters until the LED stopped blinking. More info on program operation to come...
Code is best viewed from a computer. Spacing is off on mobile
'****************************************************************
'* Name : RECIEVER.BAS
'* Author : Matthew Reid
'* Notice : Copyright (c) 2013 [select VIEW...EDITOR OPTIONS]
'* : All Rights Reserved
'* Date : 10/24/2013
'* Version : 1.0
'* Notes : Testing with the new nRF24L01's
'* : PIc16F688
'****************************************************************
include "modedefs.bas"
'DISABLE ANALOG INPUT FUNCTIONS AND MAKE THEM SHIT DIGITALZ
OSCCON = %01101010
CMCON0 = %00000111
ADCON0 = %00000000
ANSEL = %00000000
OSCCON = %01101010
define OSC 4
trisa = %11011111
porta = %00000000
trisc = %00000000
portc = %00000000
'set up hardware serial port
define HSER_RCSTA 90H
define HSER_TXSTA 24H
DEFINE HSER_BAUD 19200
hserout [$80]
RX_CE VAR PORTC.0 'out
RX_CSN VAR PORTC.1 'out
RX_SCK VAR PORTA.5 'out
RX_MOSI VAR PORTC.3 'out
RX_MISO VAR PORTA.2 'in
RX_IRQ VAR PORTA.0 'in
i var byte
j var byte
data1 var byte
data2 var byte
cmd var byte
data_array VAR byte[4]
x var byte
y var byte
pause 1000
pause 1000
gosub configure_rx
portc.2 = 0
mainloop:
if RX_IRQ = 0 then
gosub reset_RX
endif
goto mainloop
'This sets up one RF-24G for shockburst transmission----------------------------
configure_rx:
rx_CSN = 1
rX_CE = 0
rX_CSN = 0
'PRX, CRC enabled
data1 = $39
cmd = $20
for i = 1 to 8
rX_MOSI = cmd.7
rX_SCK = 1
RX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
RX_MOSI = data1.7
RX_SCK = 1
RX_SCK = 0
data1 = data1<<1
next i
RX_CSN = 1
RX_CSN = 0
'dissable auto-ack for all channels
data1 = $00
cmd = $21
for i = 1 to 8
rX_MOSI = cmd.7
rX_SCK = 1
RX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
RX_MOSI = data1.7
RX_SCK = 1
RX_SCK = 0
data1 = data1<<1
next i
RX_CSN = 1
RX_CSN = 0
'address width = 5 bytes
data1 = $03
cmd = $23
for i = 1 to 8
rX_MOSI = cmd.7
rX_SCK = 1
RX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
RX_MOSI = data1.7
RX_SCK = 1
RX_SCK = 0
data1 = data1<<1
next i
RX_CSN = 1
RX_CSN = 0
'data rate = 1MB
data1 = $07
cmd = $26
for i = 1 to 8
rX_MOSI = cmd.7
rX_SCK = 1
RX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
RX_MOSI = data1.7
RX_SCK = 1
RX_SCK = 0
data1 = data1<<1
next i
RX_CSN = 1
RX_CSN = 0
'4 byte payload
data1 = $04
cmd = $31
for i = 1 to 8
rX_MOSI = cmd.7
rX_SCK = 1
RX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
RX_MOSI = data1.7
RX_SCK = 1
RX_SCK = 0
data1 = data1<<1
next i
RX_CSN = 1
RX_CSN = 0
'set channel 2
data1 = $02
cmd = $25
for i = 1 to 8
rX_MOSI = cmd.7
rX_SCK = 1
RX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
RX_MOSI = data1.7
RX_SCK = 1
RX_SCK = 0
data1 = data1<<1
next i
RX_CSN = 1
RX_CSN = 0
'set address E7E7E7E7E7
data1 = $E7
cmd = $30
for i = 1 to 8
rX_MOSI = cmd.7
rX_SCK = 1
RX_SCK = 0
cmd = CMD<<1
next i
for j = 1 to 5
for i = 1 to 8
RX_MOSI = data1.7
RX_SCK = 1
RX_SCK = 0
data1 = data1<<1
next i
data1 = $E7
next j
RX_CSN = 1
RX_CSN = 0
'PWR_UP = 1
data1 = $3B
cmd = $20
for i = 1 to 8
rX_MOSI = cmd.7
rX_SCK = 1
RX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
RX_MOSI = data1.7
RX_SCK = 1
RX_SCK = 0
data1 = data1<<1
next i
RX_CSN = 1
RX_CE = 1
RETURN
reset_RX:
'Read RX payload
RX_CSN = 1
RX_CSN = 0
cmd = $61
for i = 1 to 8
rX_MOSI = cmd.7
rX_SCK = 1
RX_SCK = 0
cmd = CMD<<1
next i
for j = 1 to 4
data1 = 0
for i = 1 to 8
data1 = data1<<1
RX_SCK = 1
data1.0 = RX_MISo
RX_SCK = 0
next i
'CHECK is payload is 52
hserout [#data1]
if data1 == 52 then
portc.2 = ~portc.2
endif
next j
hserout [" "]
'Flush RX FIFO
RX_CSN = 1
cmd = $E2
RX_CSN = 0
for i = 1 to 8
rX_MOSI = cmd.7
rX_SCK = 1
RX_SCK = 0
cmd = CMD<<1
next i
RX_CSN = 1
RX_CSN = 0
'reset int
data1 = $40
cmd = $27
for i = 1 to 8
rX_MOSI = cmd.7
rX_SCK = 1
RX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
RX_MOSI = data1.7
RX_SCK = 1
RX_SCK = 0
data1 = data1<<1
next i
RX_CSN = 1
return
lookupregister:
RX_CSN = 1
RX_CSN = 0
data1 = $00
cmd = $00
for i = 1 to 8
RX_MOSI = cmd.7
RX_SCK = 1
RX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
data1 = data1<<1
RX_SCK = 1
data1.0 = rX_MISo
RX_SCK = 0
next i
RX_CSN = 1
RX_CSN = 0
hserout [#data1]
hserout [" "]
return
'****************************************************************
'* Name : Transmitter.BAS
'* Author : Matthew Reid
'* Notice : Copyright (c) 2013 [select VIEW...EDITOR OPTIONS]
'* : All Rights Reserved
'* Date : 10/24/2013
'* Version : 1.0
'* Notes : Testing with the new nRF24L01's
'* : PIc16F688
'****************************************************************
include "modedefs.bas"
'DISABLE ANALOG INPUT FUNCTIONS AND MAKE THEM SHIT DIGITALZ
OSCCON = %01101010
CMCON0 = %00000111
ADCON0 = %00000000
ANSEL = %00000000
OSCCON = %01101010
define OSC 4
trisa = %11011111
porta = %00000000
trisc = %00000000
portc = %00000000
'set up hardware serial port
define HSER_RCSTA 90H
define HSER_TXSTA 24H
DEFINE HSER_BAUD 19200
hserout [$80]
TX_CE VAR PORTC.0 'out
TX_CSN VAR PORTC.1 'out
TX_SCK VAR PORTA.5 'out
TX_MOSI VAR PORTC.3 'out
TX_MISO VAR PORTA.2 'in
TX_IRQ VAR PORTA.0 'in
i var byte
j var byte
data1 var byte
data2 var byte
cmd var byte
data_array VAR byte[4]
x var byte
y var byte
pause 1000
pause 1000
gosub configure_transmitter
mainloop:
gosub transmit_data
pause 1000
goto mainloop
'This sends out the data stored in the data_array
'data_array must be setup before calling this function
transmit_data:
TX_CSN = 1
TX_CSN = 0
'clear previous ints
data1 = $7E
cmd = $27
for i = 1 to 8
TX_MOSI = cmd.7
TX_SCK = 1
TX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
TX_MOSI = data1.7
TX_SCK = 1
TX_SCK = 0
data1 = data1<<1
next i
TX_CSN = 1
TX_CSN = 0
'PWR_UP = 1
data1 = $3A
cmd = $20
for i = 1 to 8
TX_MOSI = cmd.7
TX_SCK = 1
TX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
TX_MOSI = data1.7
TX_SCK = 1
TX_SCK = 0
data1 = data1<<1
next i
TX_CSN = 1
TX_CSN = 0
'clear TX fifo
cmd = $E1
for i = 1 to 8
TX_MOSI = cmd.7
TX_SCK = 1
TX_SCK = 0
cmd = CMD<<1
next i
TX_CSN = 1
TX_CSN = 0
'4 byte payload======
data1 = $34
cmd = $A0
for i = 1 to 8
TX_MOSI = cmd.7
TX_SCK = 1
TX_SCK = 0
cmd = CMD<<1
next i
'clock in payload
for i = 1 to 8
TX_MOSI = data1.7
TX_SCK = 1
TX_SCK = 0
data1 = data1<<1
next i
data1 = 63
for i = 1 to 8
TX_MOSI = data1.7
TX_SCK = 1
TX_SCK = 0
data1 = data1<<1
next i
data1 = 63
for i = 1 to 8
TX_MOSI = data1.7
TX_SCK = 1
TX_SCK = 0
data1 = data1<<1
next i
data1 = 63
for i = 1 to 8
TX_MOSI = data1.7
TX_SCK = 1
TX_SCK = 0
data1 = data1<<1
next i
TX_CSN = 1
'Pulse CE to start transmission
TX_CE = 1
pause 10
TX_CE = 0
return
'This sets up one RF-24G for shockburst transmission
configure_transmitter:
TX_CSN = 1
TX_CE = 0
TX_CSN = 0
'PTX, CRC enabled, mask a couple of ints
data1 = $38
cmd = $20
for i = 1 to 8
TX_MOSI = cmd.7
TX_SCK = 1
TX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
TX_MOSI = data1.7
TX_SCK = 1
TX_SCK = 0
data1 = data1<<1
next i
TX_CSN = 1
TX_CSN = 0
'auto retransmit off
data1 = $00
cmd = $24
for i = 1 to 8
TX_MOSI = cmd.7
TX_SCK = 1
TX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
TX_MOSI = data1.7
TX_SCK = 1
TX_SCK = 0
data1 = data1<<1
next i
TX_CSN = 1
TX_CSN = 0
'address width = 5
data1 = $03
cmd = $23
for i = 1 to 8
TX_MOSI = cmd.7
TX_SCK = 1
TX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
TX_MOSI = data1.7
TX_SCK = 1
TX_SCK = 0
data1 = data1<<1
next i
TX_CSN = 1
TX_CSN = 0
'data rate = 1MB
data1 = $07
cmd = $26
for i = 1 to 8
TX_MOSI = cmd.7
TX_SCK = 1
TX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
TX_MOSI = data1.7
TX_SCK = 1
TX_SCK = 0
data1 = data1<<1
next i
TX_CSN = 1
TX_CSN = 0
'set channel 2, this is default but we did it anyway...
data1 = $02
cmd = $25
for i = 1 to 8
TX_MOSI = cmd.7
TX_SCK = 1
TX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
TX_MOSI = data1.7
TX_SCK = 1
TX_SCK = 0
data1 = data1<<1
next i
TX_CSN = 1
TX_CSN = 0
'set address E7E7E7E7E7, also default...
data1 = $E7
cmd = $30
for i = 1 to 8
TX_MOSI = cmd.7
TX_SCK = 1
TX_SCK = 0
cmd = CMD<<1
next i
for j = 1 to 5
for i = 1 to 8
TX_MOSI = data1.7
TX_SCK = 1
TX_SCK = 0
data1 = data1<<1
next i
data1 = $E7
next j
TX_CSN = 1
TX_CSN = 0
'disable auto-ack, RX mode
'shouldn't have to do this, but it won't TX if you don't
data1 = $00
cmd = $21
for i = 1 to 8
TX_MOSI = cmd.7
TX_SCK = 1
TX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
TX_MOSI = data1.7
TX_SCK = 1
TX_SCK = 0
data1 = data1<<1
next i
TX_CSN = 1
return
lookupregister:
TX_CSN = 1
TX_CSN = 0
data1 = $00
cmd = $00
for i = 1 to 8
TX_MOSI = cmd.7
TX_SCK = 1
TX_SCK = 0
cmd = CMD<<1
next i
for i = 1 to 8
data1 = data1<<1
TX_SCK = 1
data1.0 = TX_MISo
TX_SCK = 0
next i
TX_CSN = 1
TX_CSN = 0
hserout [#data1]
hserout [" "]
return