Introduction: How to Use the Nordic NRF905 Transceiver With a Raspberry Pi

Picture of How to Use the Nordic NRF905 Transceiver With a Raspberry Pi

We will show you how to use the Nordic nRF905 Transceiver with a Raspberry Pi. We will also need the driver which provides a character device and a few sysfs attributes, allowing for simple wireless communication with another Raspberry Pi or perhaps an Arduino with the same nRF905 chip.

THIS GUIDE ASSUMES YOU HAVE BASIC KNOWLEGE OF THE LINUX COMMAND LINE.

What you will need:

  • Raspberry Pi (we tested on a Raspberry Pi 3, but any Pi should do)

Parts Info:

The Nordic nRF905 is a highly integrated, low power, multiband RF transceiver IC for the 433/868/915MHz ISM (Industrial, Scientific, and Medical) band. With an integrated +10dBm PA and sensitivity of -100dBm, the nRF905 is an ideal solution for applications requiring longer-range. In summary, the nRF905 integrates a complete 433/868/915MHz ISM RF transceiver, RF synthesizer, and baseband logic. No external loop filter, resonators, or VCO varactor diodes are required, only a low-cost crystal, matching circuitry, and antenna.

The Raspberry Pi is a series of credit card-sized single-board computers developed in the United Kingdom by the Raspberry Pi Foundation to promote the teaching of basic computer science in schools and in developing countries. The original model became far more popular than anticipated, selling outside of its target market for uses such as robotics. Accessories (including keyboards, mice and cases) are not included with the Raspberry Pi. Some accessories however have been included in several official and unofficial bundles.

Step 1: Hardware Setup

Picture of Hardware Setup

The Raspberry Pi Model A+ and B+ boards, Pi 2 Model B and the Pi 3 model, have a 40-pin header marked J8, arranged as 2x20 pins. The first 26 pins are the same as P1 on the A/B boards, with the remaining 14 pins providing additional GPIO and ground pins, and an EEPROM ID feature for auto-configuration with add-on "HAT" boards.

We will be using 10 of the pins, all of which are available on all of the models. If you have a Pi 2 or 3 reference the images above, if you have a Pi 1, reference this image. The pins on the nRF905 are visibly labeled.

You can download the Fritzing files used to create the layout image in Step 6. Both the finished layout and the nRF905 part are available (the nRF905 part is missing the Schematic and PCB layout).

The pin configuration is as follows (Raspberry -> nRF905):

  • GPIO 18 > resistor > DR
  • GPIO 17 > PWR
  • GPIO 27 > CE
  • GPIO 22 > TxEN
  • +3V3 > Ucc
  • GPIO10 / MOSI > MOSI
  • GPIO9 / MISO > MISO
  • GPIO11 / SCLK > SCK
  • GND > GND
  • CE0# / GPIO8 > CSN

Step 2: Raspbian Installation and Setup

Picture of Raspbian Installation and Setup

At the moment of writing, the current version is 2016-11-25 and the Lite edition has been used while writing this tutorial.

See raspberrypi.org guide for instructions on how to make a bootable SD card.

Note: If you are going to use Raspbian 11-25, you will need to manually enable and start SSH if you wish to use it

sudo systemctl enable ssh && sudo systemctl start ssh 

Update the system

sudo apt-get update
sudo apt-get dist-upgrade 

Install a kernel with exported symbols

sudo apt-get install linux-image-4.4.0-1-rpi2 linux-image-rpi2-rpfv linux-headers-rpi2-rpfv 

***Note: Use rpi instead of rpi2 if you have the original Raspberry Pi.***

Set the default kernel

Edit /boot/config.txt and add the following lines

# use the rpfv kernel
kernel=vmlinuz-4.4.0-1-rpi2
initrd=initrd.img-4.4.0-1-rpi2 followkernel 

***Note: Use rpi instead of rpi2 if you have the original Raspberry Pi.***

Boot with the new kernel

sudo reboot 

Verify the current kernel

uname -r 

If everything is correct, the output should be

4.4.0-1-rpi2

Step 3: Driver Installation

We need git in order to pull the latest driver from our github page, so let's install it

sudo apt-get install git

Clone the repository

git clone https://github.com/ICBTech/nRF905.git

Build the module against the currently running kernel

make
make dtb

Install the module and overlay

sudo make modules_install
sudo make dtb_install
sudo depmod -a 

Manually load the module

sudo modprobe nrf905 

Check that the module has been loaded

dmesg | grep nrf905 

If everything is correct, the output should be

[ 79.829085] nrf905_init 

The timestamp would, of course, be different.

Enable the overlay

Edit /boot/config.txt and add the following lines

# load our custom overlay
dtoverlay=nrf905 

In that same file, also uncomment the line to enable spi

# enable spidev
dtparam=spi=on 
sudo reboot 

Manually load the module

sudo modprobe nrf905 

Check that the module has been loaded

dmesg | grep nrf905 

If everything is correct, the output should be

[ 25.095296] nrf905_init
[ 25.096562] nrf905 spi0.0: nrf905_probe
[ 25.096615] nrf905 spi0.0: gpio_pwr_up: 17
[ 25.096627] nrf905 spi0.0: gpio_trx_ce: 27
[ 25.096638] nrf905 spi0.0: gpio_tx_en: 22
[ 25.096649] nrf905 spi0.0: gpio_dr: 18 

The timestamps would again, of course, be different.

Compared to the previous run of the same command, the output now also contains lines where the driver is probed (bound to the spi address defined in the dts file).

Automatically load the module at boot

Edit /etc/modules and add the following line

nrf905

For more info about the driver, check the github driver page.

Step 4: Testing the Driver

Picture of Testing the Driver

General configuration

This needs to be done only once per boot.

sudo sh -c "echo -n ABCD > /sys/bus/spi/devices/spi0.0/rx_address"
sudo sh -c "echo -n ABCD > /sys/bus/spi/devices/spi0.0/tx_address"
sudo sh -c "echo -n 434000 > /sys/bus/spi/devices/spi0.0/frequency"
sudo sh -c "echo -n 3 > /sys/bus/spi/devices/spi0.0/pa_pwr" 

Receiver

sudo dd if=/dev/nrf905 bs=32 count=1 2>/dev/null | hexdump -Cv 

Transmitter

sudo dd if=/dev/urandom bs=32 count=1 of=/dev/nrf905

For normal usage, you should change the permissions (see man 1 chmod), but that is out of the scope of this tutorial.

Step 5: Sources and Files

Comments

witali.urovski (author)2017-03-03

Hi! Thank you very much for these insights and no worries at all.

I have checked the crystal and it is the 16.000 model, so we are good there. As for the addresses, I now have much better a understanding than when I started using the module. I cannot help but wonder why Nordic did not consider it important enough to reference in their technical documentation. Maybe I have also overlooked it, who knows. Also, thanks for pointing out the aerial configuration which is different for any given frequency range. Since I am mostly interested in 433 MHz, the built-in aerial was a perfect fit. :-)

Part of the confusion I had over not receiving anything at all is due to the fact that I was initially experimenting with very simple hardware such as those RF-enabled wall sockets you can buy everywhere. The thing is however, they are so simple that they do not make use of any addresses or checksums and the signal itself is OOK coded. No wonder nRF905 could not pick up any of it with its GFSK modulation.

Would it be possible to operate the circuit in some sort of promiscuous or raw mode where you could directly see any of the preambles or what you call distinguishable structure, e.g. the 0101010101 sequence?

With regard to the inline resistor, I had actually thought as much before I even considered asking this question. The thing is though, a single RPi GPIO port or pin can take a current as high as 16 mA or if you were to use them all at once this value would even go down to 2 mA per port. Those are at least the parameters I once stumbled upon. Now, since you have opted for a 220 Ohm resistor the resulting current in the example you have mentioned would be 15 mA, which is pretty darn close to the maximum value. ;-)

Many thanks again for your time, much appreciated!

ICBTech (author)witali.urovski2017-04-11

Hey witali, please see the answer above :)

CarlosE121 (author)2017-04-07

Hello, I'm very noob on this matter. I need to get a 433mhz code which is being generated by a sensor from my house. I already made all the tests but I never read any code when my sensor gets active. Can you let me know if can I do that with this module? I saw that this module waits for an initial code but I just need to read a signal. How can I do that? Thank you.

ICBTech (author)CarlosE1212017-04-11

Hello,

Unfortunately, the nRF905 chip is quite limited when it comes to configurability and reading the raw data is not possible. I'm guessing this is what you mean by "I just need to read a signal".

Poking around with configuration parameters and hoping to catch something does not really work great with RF. You either need to know what to expect, or you need a more sophisticated receiver which would be able to give you the raw data, which you can then analyze and use the results to configure a simple receiver.

Even if you would know what the sensor transmits, it might still not be possible to configure the nRF905 chip to receive data from it, e.g. different data rate, modulation, channel bandwidth...

witali.urovski (author)2017-02-22

Hi. I have followed your instructions up to the point of successfully compiling and loading the kernel driver, but I cannot receive anything at all with my nRF905-based PTR8000+ module. The configuration I am using is the one you have provided above. Can you please explain what the TX and RX addresses are for and what "ABCD" really means in that context?

Is there anything I can do to get error-related / debug information out of the driver?

Can you please also explain what the 220 Ohm inline resistor is for at the DR pin connection? According to specs, the DR current is limited to 0.5 mA, so that ideally no limiting resistor is required at all.

Many thanks for your excellent work!
ICBTech (author)witali.urovski2017-03-02

Hi witali! Sorry for the late reply.

In order for a packet to be detected, it needs to have an easily distinguishable structure. Most RF chips do this by first transmitting a 0101010101... sequence, followed by what is usually called address bytes or a sync word, then the actual payload (32 bytes) and finally a checksum.

On the transmitting side, these address bytes are set with the TX address in this chip.

On the receiving side, the chip initially listens for the 0101010101... sequence, followed by the RX address. When such a sequence is detected, whatever follows is then treated as the payload and verified against the checksum. If all of this succeeds, a DR (data ready) interrupt is signalled by the nRF905 chip so that the host (Raspberry Pi in our case) can read out the payload from the buffer.

In order for the two devices to be able to communicate, these address bytes need to match. At least TX on the 1st device with RX on the 2nd and vice versa.

If you have a very simple network (e.g. only 2 devices) and don't want to complicate your life, you can set both TX and RX addresses on all devices to be the same. This could become problematic in a larger network, because every device would receive everything. In order to avoid this, you can group devices by matching TX and RX address pairs.

The inline resistor is just a safety. The DR pin is an output from the nRF905 and, depending on what exactly you have done before loading the driver, your GPIO on the Raspberry Pi side could also act as an output (most GPIOs act as inputs when the Raspberry Pi is powered on, unless you reconfigure them). If both sides act as outputs and they are set to different levels (one to 0V, the other to 3.3V), the energy produced by the current flowing between them would need to go somewhere. With the resistor in place, it would get converted to thermal energy. Without the resistor, there is a chance that one of the outputs would burn out.

One more thing to check is whether the crystal on your PTR8000+ module is also 16.000MHz. If not, the line `nrf905_spi_w_config(spi, 9, 0xDF);` in the code is wrong and would need to be changed.

Also, the antenna might be made for a different frequency range than the one you are trying to use (433MHz, 868MHz and 915MHz are common, depending on where you live).

Some debug info is available if you execute `dmesg` (or `dmesg --follow` if you want to show all new messages as they arrive). If you need more output, you are free to add `pr_*` or `dev_*` calls yourself.

Good luck :)

tWilhelmWeiter (author)2017-01-18

Hello, I have some problems with your instruction:

I have 2 Arduinos which uses the nRF905 to send data with http://blog.zakkemble.co.uk/nrf905-avrarduino-libr... . But my raspberry doesn't receive anything. I don't know what to do. Arduinos Frequency = Raspberrys frequency.

Do you have any idea ?

ICBTech (author)tWilhelmWeiter2017-01-23

Hello tWilhelmWeiter. Can you describe how you are sending and receiving?

Swansong (author)2017-01-06

Neat :) This would be fun to turn into a kids' spy toy!

ICBTech (author)Swansong2017-01-07

It can indeed be turned into a spy toy. The beauty of this project is that the applications are vast. We can't wait to see what people will use this for :)

DonnH1 (author)2017-01-06

Any idea what sort of range could be expected between a pair of these?

ICBTech (author)DonnH12017-01-07

Hey DonnH1. Thanks for taking an interest in this project :)
The range depends on the range of the antennas, as well as the quality of the signal that your project would require. You can always just attach a stronger antenna since the module uses a standard SMA connector. Our tests between a pair of these with the antenna that comes with the module were done at a range of about 4-5 meters and we experienced no packet loss.

About This Instructable

5,084views

37favorites

License:

Bio: The company's core competencies are in embedded system programming, Android platform programming, development and implementation of complex embedded systems.
More by ICBTech:How to use the Nordic nRF905 Transceiver with a Raspberry Pi
Add instructable to: