In this prototype we’ll send data from one nRF24L01 to the base station we built.
More Prototype Hardware Needed
What we’ll need in addition to the base station includes another:
- Arduino
- nRF24L01
- breadboard
- wires
Use the steps outlined in this post to set up the Sensor Station.
Before Writing the Sketches – Debugging Aids
Because my goals are very simple – send data from one nRF24L01 to the other – I hooked the boards up to my Mac’s USB ports.
I wanted to watch the sends from one RF and the receives to the other RF in two separate windows on my monitor. Unfortunately, the Arduino IDE is restricted to showing output from one serial port at a time:
Thus, after uploading the TX code to one Arduino, we have to switch serial ports and upload the RX code to the other.
Debugging was tedious. I had to switch to the serial port then only see that Arduino’s debug Serial() output.
I wanted two serial monitors – one for each Arduino so that I could follow the debug Serial() statements I put into the sketches. But how? Clearly I could put a separate LCD on one. However, it would be easiest to have two windows on my display.
I asked how I might do this on the Arduino subreddit. Another YIPPEE! moment. I found skootle’s response particularly helpful.
I wanted to automate opening and closing the two serial outputs. Here is the AppleScript I run to open the terminal windows and start a serial session:
tell application "Terminal" do script with command "screen -t \"usbmodemfa1331\" /dev/tty.usbmodemfa1331 57600" tell window 1 set number of rows to 50 set number of columns to 100 set background color to "white" set normal text color to "blue" set custom title to "usbmodemfa1331" set position to {300, 100} end tell do script with command "screen -t \"usbmodemfd111\" /dev/tty.usbmodemfd111 57600" tell window 1 set number of rows to 50 set number of columns to 10 0 set background color to "white" set normal text color to "black" set custom title to "usbmodemfd111" set position to {1200, 100} end tell end tell
And to close the two terminal sessions, I run this AppleScript:
tell application "Terminal" activate tell window 1 tell application "System Events" keystroke "a" using control down keystroke "k" keystroke "y" keystroke "w" using command down end tell end tell tell window 1 tell application "System Events" keystroke "a" using control down keystroke "k" keystroke "y" keystroke "w" using command down end tell end tell end tell
In the open script, I set one window to show the serial output of /dev/tty.usbmodemfa1331 and the other window to show the serial output of /dev/tty.usbmodemfd111 and the baud rate to 576000. You will need to change these settings to match the serial ports you are using for your Ardoinos’ serial out as well as set the baud rate to whatever you used for Serial.begin() in your sketch.
And here is the Yippee! for me. I use Alfred to automate my workflows. So I just created a keystroke workflow for both the open and close scripts that runs based on a keystroke combination I chose when creating my Alfred workflow. Now, after uploading the sketches, I can open the two serial monitors with a keystroke combination and just as easily close them.
Perhaps you are like me and have never used AppleScript. I was able to take the info given by skootles and bumble my way around Googled articles that got me enough of what I needed. You may also have to Google your way towards running these scripts if AppleScript is also new to you.
Something to keep in mind, as noted on the man page for screen:
“Screen is a full-screen window manager that multiplexes a physical terminal between
several processes (typically interactive shells). Each virtual terminal provides
the functions of a DEC VT100 terminal…” Sometimes a terminal window wil be shut but Screen will keep running. If this happens, you will need to kill the screen processes. I do this through Activity Monitor.
The Arduino Sketches
The two sketches I used built upon the sketches used for the base station prototype and Simon’s freshly minted sketch.
- nRF24SendSensorDatav1 – simulates sending sensor data by generating a uint16_t and sending it. I send over three bytes of data the first byte is a “sensor type” byte to differentiate between the different types of sensor data that could be sent (temperature, moisture, etc.). I then generate a uint16_t random number to simulate sensor data. We’ll add “real readings” in the next sketch. I then pack up the sensor value in the second two bytes – using little endian memory storage.
uint16_t sensorValue = random(10,1001); //assign 'T' to represent a Temperature reading data[0] = 'T'; //do the bit shift to put uint16 into uint8 array data[1] = sensorValue >> 8; data[2] = sensorValue;
- nRF24ReceiveSensorDatav1 – receives the sensor data. If the sensor data is a Temperature reading, the other bytes are unpacked
it into a uint16_t sensor value.
if (data[0] == 'T') { //put the uint16_t back together uint16_t sensorValue = data[2] | data[1] << 8;
Here is a screen shot of the two serial monitors – one running the Serial.print()’s of the nRF24SendSensorDataV1.ino sketch the other running the Serial.print()’s of the nRF24ReceiveSensorDataV1.ino sketch.
Simon’s sketch cleaned up the GettingStarted.pde example from the RF24 library as well as added additional nRF24L01 and pointed out that yes INDEED the CE and CSN can be easily set within the sketch upon initializing through the parameters sent in radio().
// ce,csn pins RF24 radio(9,10);
Here the CE pin is set to 9 and the CSN/SS pin is set to 10.
I’ve added nRF24SendSensorDataV1.ino and nRF24ReceiveSensorDataV1.ino to GitHub.
That’s it for now. Next we’ll gather “real sensor data” and send that data to a PHP service.