In this part of the prototype, we will build a “base station” that will (eventually!) receive sensor data from sensors spread throughout the house and then send the data to a web service.
The base station will be built using an Arduino, Adafruit’s cc3000 breakout board, and an nRF24L01.
We’ll need:
- An Arduino
- A cc3000 breakout board
- An nRF2401. I purchased mine from Yourduino.com.
Why the nRF24L01?
I’m exploring different wireless technologies that are best suited for in home communications. Picking a technology is all about knowing which trade offs are important. This is true with wireless communications. There are many different wireless options – 802.11, BTLE, Zigbee, nRF24L01, 433 MHZ RF…
Each one is optimal for a few scenarios. It has been my experience (30 years of shipping software products – from millions of copies to 10,000’s) to define a scenario with metrics around the technology in question then match these metrics to the technology that best fits the scenario/metrics. For example, my playing around with writing BTLE apps for iOS cemented for me how ideal BTLE is for a PAN (Personal Area Network). I can see why Apple has an optimized BTLE API and why most wearable devices talk with Smart Phones via BTLE. My years with 802.11 and Ethernet has cemented my thoughts that these more beefy protocols are well suited for the wild and wooly world of Internet traffic.
I am new to in-home networks. I have read a bit about all the options, but the only way I can understand the trade-offs of an RF technology for in-home use is to experiment with it. Lucky for us the Arduino plus RF components makes it easy to do so. I’ll be trying other in-home technologies, but this post is about the nRF24L01. This blog entryprovides good information on the nRF2401 as well as pointers to sketches that use the chip.
Wiring Up the nRF2401
Time to connect the nRF2401 to a breadboard. The nRFL2401 has 8 pins:
I decided the simplest way to connect the nRF2401 to the breadboard was by using a solid ribbon of male to female cables.
I separated out 8 – which made it easy to follow the cable connections based on the information in this post. I used the pin settings for the RF24 Library.
Top View
Bottom View
Pinout
We can tell from the above that the nRF2401 uses SPI to communicate with the Arduino. As is typically the case, the Arduino pins 10,11,12,13 are used for SPI communications.
Here is the chip connected to the female end of the cables.
Next, the Arduino and nRF2401 are in a circuit together:
The test sketch we will use is provided by the nRF2401 Arduino library. Download the zip file and place the files in the place where Arduino libraries need to go to be recognized by the Arduino IDE.
Hook up the Arduino to your Mac/PC and load the GettingStarted.pde example sketch. Run the sketch. If the nRF2401 is hooked up correctly, you’ll see something like this:
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0 RX_ADDR_P0-1 = 0xe7e7e7e7e7 0xf0f0f0f0d2 RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6 TX_ADDR = 0xe7e7e7e7e7 RX_PW_P0-6 = 0x00 0x20 0x00 0x00 0x00 0x00 EN_AA = 0x3f EN_RXADDR = 0x03 RF_CH = 0x4c RF_SETUP = 0x07 CONFIG = 0x0f DYNPD/FEATURE = 0x00 0x00 Data Rate = 1MBPS Model = nRF24L01+ CRC Length = 16 bits PA Power = PA_HIGH
on your serial debug monitor.
As noted in this blog post, if you see zeroes where values should be, double check how your wires are connected. It is very easy to connect the wrong wires between the Arduino and the nRF2401.
Better Together: Wiring Up the nRF2401 and the 802.11
We’ll be adding the nRF2401 to the 802.11 circuit we wired up in this prototype. There is only one “gotcha” to be careful about. Both use SPI, running as slaves to the Arduino master SPI device. As noted in this blog post on wiring multiple SPI components to the Arduino:
SPI bus consists of 3 shared data lines – SCK, MISO and MOSI, plus one “Slave Select” AKA SS line per each device.
What this means is each component that talks to the Arduino using the SPI must have a unique pin for the SS line (note the nRD24L01 refers to the SS line as the CSN or Chip Select line. CSN is a different name for SS).
Most components I have purchased that uses the SPI defaults to pin 10 for the SS line. In some unfortunate cases, either the hardware and/or the software prevents moving the SS line from pin 10. That stinks because if there are two components that refuse to move off pin 10, only one can talk to the Arduino through the SPI.
We are in luck! The great folks at Adafruit made it easy-peasy to change the SS line’s pin. I’ve chosen to use pin 8 for the SS line. To do this is simple. Just change this line within sketches that use Adafruit’s cc3000 and libraryto the SS line’s pin (Adafruit refers to the pin as CS).
#define ADAFRUIT_CC3000_CS 8
We are in even more luck! It is as easy to change which pin to use for the SS line with the RF24 library. I discuss this more in this post.
index.php?p=299And there we have it! A mess of cables! Admittedly, my prototypes are U-G-L-Y!
This wasn’t possible to read so I tried out the Fritzing software to document our prototype. I think I was scared into using Fritzing after attending a short course on kicad. Now – kicad seems like a great tool. But is geared towards the person that knows their way around building PCBs. I aspire to build PCBs, but have not yet. Also, surprisingly (at least to me), the Mac version is hard to install and less stable than the Windows and Linux version.
On the other hand, Fritzing seemed inviting, as their home page notes:
Fritzing is an open-source hardware initiative to support designers, artists, researchers and hobbyists to work creatively with interactive electronics. We are creating a software tool, a community website and services in the spirit of Processing and Arduino, fostering an ecosystem that allows users to document their prototypes, share them with others, teach electronics in a classroom, and layout and manufacture professional pcbs.
Oh happy day!
And – another YIPPEE! moment – Adafruit actively puts their components into Fritzing libraries. This makes it easy-peasy to add the cc3000 to the diagram.
Here’s an image of our prototype I did using the Fritzing software:
The nRF24L01 chip is used instead of the breakout board. This is because the only nRF24L01 I could find was in one of Sparkfun’s libraries. Hopefully, I matched the pins correctly. I followed the pin assignment documented in the nRF24L201 product specification.
Pin Connections
I am hoping you can follow the pin layout in the diagram. If not, please leave a comment and I will write out which wire is connected to what pin. The main elements are the SPI, GND,PWR wiring.
Verify
Now the fun begins – does everything work? We tested each RF component separately. What about together? Run the sketch for the nRF24L01 we ran earlier. Then run the cc3000 sketch we ran while building this prototype.
This should work! When I led a team of software developers, there were times when I couldn’t get their code to work. A typical response was “well – it works on MY machine.” My reply was “great, but how do we get your machine to each customer?” For my stuff, it is rare that my prototypes work the first time. If this happens to you, my challenges typically were in the wiring. So double check this. I must have made at least 5 wiring mistakes until I got it right.
If either one of the sketches did not work, double check the wiring. I must have made at least 5 wiring mistakes until I got it right.
So that’s it for this prototype. The next one will set up another nRF24L01 to transmit sensor data to our Base Station.
farcaller said:
Did you ever consider 802.15.4 (the thing, zigbee is based on) or its extensions (6lowpan & zigbee)?
I’d like to hear your points against them if that was the case. I feel that mesh-based network is more suitable for sensor networks spanning more than one room.
bitknitting said:
I am definitely open to an 802.15.4 solution. Right now I am in exploration mode. At this stage I don’t want to discount any but I do want to focus on metrics for choosing a home sensor network. The metrics I have identified include:
– ease of use
– reliability and maintenance (for example: what happens when a station gets flaky/goes down?)
– BoM
– power consumption
– parts availability
– software libraries (and their maturity)
Would you modify this list?
I have read about home sensor networks that are happily running on either. Because of my background in what I consider more mainstream/beefier networking (Ethernet, 802.11,BlueTooth…), I could visualize a ZigBee sensor.
I have no experience with the nRF24L01 so I felt I needed to build a sensor network out and verify that the sensor network worked. I found this article: http://geekboy.it/projects/home_automation/home-automation-design about a nRF24L201 home sensor network that I thought summed up my current knowledge (and pointed out an nRF24L01 could be made into a mesh network.
The two positive features in my research regarding “versus” ZigBee/nRF24L01 which favors the nRF24L01 are:
* low BoM
* ultra low power consumption
Regarding power consumption: I see the sensors + Arduino (a station) being powered by battery. Given that, I keep thinking of the experience of changing batteries. Heck, isn’t it annoying to change a battery in a smoke detector? So – shouldn’t a station be able to run on a battery for at least a year? I haven’t done the math here (and given my degrees in Geology I would probably get it wrong anyways…but when I get further along, I hope to tap into the math whizzes to helping me figure out optimum battery life).
Bottom line – I am open to recommendations and knowledge in this area particularly around the metrics noted above.
farcaller said:
Well, I’m not that experienced in this field myself (also evaluating my options). The cheapest solution I could find for 802.15.4 is mrf24j40ma, which is about triple the price of nRF24L01. It talks SPI, so you can hook it to anything.
ZigBee hardware is pretty expensive overall, and using my own protocol on top of 802.15.4 doesn’t seem to differ much from nRF24L01 solution, so my stakes are at 6LoWPAN, which is IPv6 for low-powered networks.
Pros:
* devices can be set to discover the gateway easily, so extending the network is simple;
* encryption;
* seems to be kind of industry standard for the “Internet of things”.
I’m totally into the low power requirements and run stuff from batteries, but I still need the routing part, as I don’t have wireless signal “visibility” between all the interesting points (damn you walls!)
snapDan said:
Do you have any code that uses the nrf24l01 and cc3000 in the same sketch? I’ve managed to get them working separately but when I try to put them in the same sketch the nrf24l01 spits out an endless stream of nonsense. I’ve made a thread on the Adafruit forums but haven’t been able to resolve it. http://forums.adafruit.com/viewtopic.php?f=22&t=44459
bitknitting said:
I’ll post the code I’ve been playing with. Unfortunately, my cc3000 “broke” the other day before I had a chance to complete the test so I’ll know more once Adafruit’s replacement comes. As it stands, I was initializing the two (which worked before) but the chip failed during initialization.
Things I would verify and double check:
– I don’t know where you are viewing results. If it is the serial monitor check the baud rate setting of the serial monitor and verify it is the same setting as in your sketch. Are they identical?
– check to see that the SPI lines for SS (CSN) in particular are not using the same pin. Both in your wiring and in your sketch (I cover this in one of the posts).
– As always check and double check the wiring!!!
——————————
Here’s the sketch I’ve been using
#include
#include
// ce,csn pins
//RF24 radio(9,10);
//stuff for Adafruit’s cc3000 breakout board library
#include
// Define CC3000 chip pins
#define ADAFRUIT_CC3000_IRQ 3
#define ADAFRUIT_CC3000_VBAT 5
#define ADAFRUIT_CC3000_CS 8
// WiFi network (change with your settings !)
#define WLAN_SSID “myNetwork”
#define WLAN_PASS “myPassword”
#define WLAN_SECURITY WLAN_SEC_WPA2 // This can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
// Buffer for float to String conversion
// The conversion goes from a float value to a String with two numbers after the decimal. That means a buffer of size 10 can accomodate a float value up to 999999.99 in order for the last entry to be
char buffer[10];
//const unsigned long
//dhcpTimeout = 60L * 1000L, // Max time to wait for address from DHCP
//connectTimeout = 15L * 1000L, // Max time to wait for server connection
//responseTimeout = 15L * 1000L; // Max time to wait for data from server
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
SPI_CLOCK_DIV2);
// PHP’s server IP, port, and repository (change with your settings !)
uint32_t ip = cc3000.IP2U32(192,168,1,128);
int port = 8888;
//MAKE SURE TO SET THIS TO THE FOLDER YOU ARE USING IN htdocs FOR THE SERVER SIDE FILES
String repository = “/wifiweather/”;
uint32_t t;
// set up the data buffer to receive the sensor type byte and the uint16_t sensorValue
unsigned char data[10] = {
0};
void setup(void)
{
// init serial monitor and radio
Serial.begin(57600);
Serial.println(“**************V2 Receive Sensor Data (nrf24ReceiveSensorData.ino) ***********”);
radio.begin();
radio.setPALevel(RF24_PA_LOW);
radio.setChannel(0x4c);
// open pipe for reading
radio.openReadingPipe(1,0xF0F0F0F0E1LL);
radio.enableDynamicPayloads();
radio.setAutoAck(true);
radio.powerUp();
radio.startListening();
Serial.print(F(“Initializing 802.11…”));
if(!cc3000.begin()) {
Serial.println(F(“failed. Check your wiring?”));
return;
}
Serial.print(F(“OK.\r\nConnecting to network…”));
cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
Serial.println(F(“connected!”));
Serial.print(F(“Requesting address from DHCP server…”));
for(t=millis(); !cc3000.checkDHCP() && ((millis() – t) < dhcpTimeout); delay(500)) {
Serial.println("….waiting");
}
if(cc3000.checkDHCP()) {
Serial.println(F("OK"));
}
else {
Serial.println(F("failed"));
return;
}
Serial.println("…Listening");
}
void loop(void)
{
// receive data from other nRF24L01 sensor
// send data to PHP service
}
snapDan said:
Thanks. Still had the same problems with that code and I ended up having to use a different RF24 library that lets you use other pins for the nrf’s SPI lines: https://github.com/andykarpov/iBoardRF24
Kendrick Clark said:
bitknitting
Did you ever get your replacement? Were you able to get both the CC3300 and the NRF working in the same sketch?
bitknitting said:
Hey Kendrick,
Are you referring to the cc3000? Yes I did. Adafruit support is excellent. I did not go back to getting the cc3000 + NRF working in the same sketch. This is because I am not going to continue with the NRF. I found the chips I got too flaky and lacked the rich,robust libraries of the RFM12 (and now the RFM69) chips.
Goose said:
Did you have any problem with the RM69 and CC3000 working together? Do you happen to have a sketch available with the two working on a single arduino
bitknitting said:
Hey Goose,
It is MOST EXCELLENT to hear from you. Thank you!
I didn’t have problems. This is most likely because I started using the CC3000 shield instead of the breakout board. The shield is more “SPI friendly. I do have a sketch. It will be in a future posting on the base system. I’m pretty excited about that post because it will include a spot of HTTP Get to send data to an iPhone app. I have one other post to do first (on my hydro station) so I won’t be getting to this immediately, unfortunately. I’m challenged to release before hand because posting makes me think stuff through.
Pingback: nRF24L01 - 2.4 GHz mit dem Arduino | Arduino-Blog.de