Posts Tagged ‘Arduino’
NRF24L01 Transceiver and Arduino
This one’s for techies only! The NRF24L01 2.4Ghz transceiver.
So you have your Arduino (single-chip micro with bootloader) or similar (could be a PIC project really but you’d have to understand and re-hash the libraries) up and running and you need two of them to communicate. How do you do it?
One way is the excellent EASYTRANSFER library (just look up ARDUINO EASY TRANSFER) which among other things lets you define 2 wires for serial communication.. the library can let you transfer arbitrary blocks of data back and forth reliably and at speed, but placing that cable can be a pain depending on location and/or the patience of your spouse.
If you need wireless communication at low cost, then perhaps the NRF24L01 modules are for you. I must stress that the really cheap units with PCB aerials do not have a lot of range (ignore the crap people put in print about range – such comments are about as reliable as the ads that claim 96 hours standby on your smartphone – yeah, right).
The problem I found is that there is SO much incorrect or contradictory information out there I decided to write my own blog on the subject. As I sit here, I have two dissimilar Arduinos (one is a NANO, the other is simply built from scratch on a breadboard, both use the 328 chip, a marvellous if limited device that costs just a few ££s) and I have the two passing messages across to each other reliably – when I say reliably, we’re talking about radio but what I mean is that only accurate information is being sent – you can rely on it within the limits of range of the devices (and the weather and walls and WIFI signals etc.).
Often when radio people write such stuff you get how to send a character across and the rest is left to you on the assumption you know your stuff – well we’re all beginners at SOME point. What I’ll describe here is sending an arbitrary BLOCK OF DATA across – that data can be whatever you want but let’s say a character string like “Hello world” or an integer containing the time – or both.. you might want a wireless display board or weather station etc.… who knows – this will let you send whatever you need to send back and forth.
So, do you need wireless transfer and you’re happy with maybe 20-30ft with no walls or maybe the next room? This article is for you (and if not you might be looking at the same thing with and external aerial so this article is STILL for you).
So firstly lets take a look at the radio hardware. The NRF24L01 radios comprise a unit smaller than your average thumb with either an 8-way or 10 way connection depending on which module you go for – makes no difference, you need in total 7 wires to do the job including power and ground.
The connection details are here and you need the RF24 library – rename it simply to RF24 so the Arduino IDE doesn’t kick up a fuss. There are a couple of variations of this library – mostly unfinished – it’s a shame people take all the time to make a library – put it out there – admit the library has a long way to go – and then forget about it! An example is the RF24SH library – “needs work” – and no updates for a year! What!!?
Gregg Copeland has done mods to the RF24 library but the one I’d check out now is here. He has also done mods to the RF24NETWORK library. http://tmrh20.blogspot.co.uk/2014/03/high-speed-data-transfers-and-wireless.html
First thing to note – these unit run on 3.3 volts – and will EXPLODE (slight exaggeration, more like smell for a while then pack in) on 5v so don’t even think about it. One of them is running on the 3.3v output from the NANO, for the other I simply dropped the 5v supply through 2 4001 diodes – that’s it – you don’t have to worry about the data lines, just don’t feed 5v into the power lead. On reflection (August 2014) the diode dropper wasn’t a good idea – and I’ve recently learned about all sorts of issues with current spikes on these radios so I consider it a MUST to attach a capacitor across the power lines ON the board, a 6.3v 330u cap works for me. Without this expect all manner of strange issues of range.
Using the library I mentioned above (you need the RF24, NOT the MIRF library from that website) you’ll find an example of how to send the time from one board to the other wirelessly… but that leaves SO many questions including how much RAM does this use etc.. well, here are some quick wins for you. The library uses only something like 16 bytes and the chip will retry messages 15 times – if you want more data it’s over to your code. The chip will send and receive it’s own buffer of up to 32 bytes… that is – your code can be doing something else while it’s buffering up 32 characters. Great!
Of course you need to store the data somewhere – if you’re sending you need to store the output buffer, if you’re receiving you need to store the input buffer and in their time example the same code handles both transmitter and receiver, using an Arduino pin to select what job the board is doing (GREAT way to knock up a test). So – I decided to allocate 64 bytes of RAM to this in total – 32 in one direction, 32 in the other. I knew I wanted various types of data so I created a simple STRUCT…
union radpack
{
byte package[32];
int myints[16];
float myfloats[8];
};
radpack radio_in;
radpack radio_out;
So what’s a UNION – you don’t see much about these but they’re dead handy.. a UNION is a block of memory and it’s size is dictated by the largest item in it – they overlap so you can’t use them at the same time – but for a buffer they’re ideal as you don’t then have to do all sorts of conversions depending on the data you need. I could have just used a struct but in this case I wanted to experiment sending different types of data at different times.
In this case, if I wanted to populate RADIO_OUT
buffer with text I might simply do this…
strcpy((char *)radio_out.package,"Peter calling breadboard.......");
So, look at the example in the RF24 library which lets you bounce the time back and forward between two modules – and then instead of sending the time – send this data… if you look at the library example you’ll see where this belongs…
bool ok = radio.write( &radio_out, 32);
You’re sending the address of the union (block of data) and it’s size (32 bytes in this case – note the reference to 32 above – that tells radio.write how much data I’m sending – and remember the chip’s internal buffer will handle no more than 32 bytes at once – if you want more, send more than once package one after the other – but remember you’ll have to buffer that too and the Arduino with 328 only has 1K of RAM IN TOTAL). You could send less if you don’t need that much but I figured as the chip is capable of processing 32 bytes and I needed to send text – why not. It might be that I’d want to send a bunch of integers …. same send code but populating as:
radio_out.myints[0]=456;
radio_out.myints[1]=500;
radio_out.myints[2]=1;
// OR…
radio_out.myfloats[0]=56.45;
radio_out.myfloats[1]=567.9;
// etc
In the note above I’m referring to the UNION – don’t use all it’s innards at the same time as they overlap each other and are merely a convenience for you.
So assuming you got the demo running sending time back and forth, now you have the information to send arbitrary data up to 32 bytes at a time – you might use that to make a wireless message board using a 16 character by 2 line display (but remember- there’s a zero on the end of C strings so you’d only be able to send a pair of 15 byte messages unless you then later added a zero in your own buffer).
Update August 2014: Elsewhere you’ll find information on the RF24NETWORK – this works well but has a strange numbering system – an alternative is the RADIOHEAD network – but beware – the latter has a full mesh network option – tried that – had varying results until I realised that the NRF24L01 chips do not have any means of detecting signal strength – which begs the question – how does the network know how to pick the strongest signals! I went for the intermediate option with that library and defined the nodes and their connections manually. At the time of writing I’m still having reliability problems with the large (NRF24L01+PA) radio modules but the little cheap ones work just fine.
I did a short video on this showing this in action at the end..
This article is part of a chain or articles which started back early 2012 with my cottage thermostat article. How things change. This was followed up by the original UberBareBoard article detailing a 328-based Arduino clone. The next article after this is called home control over the Internet.