Arduino Example -WeatherBot
ℹ️ NOTE
The Arduino SDK is no longer being actively developed. We've left the links here for anyone who would like to continue to use it anyway.
Check out our Raspberry Pi Python SDK for all the latest RVR+/RVR features.
Turning Your RVR+ or RVR into a WeatherBot Using Arduino Uno
Turn your RVR+/RVR into your very own WeatherBot! While it can't control the weather, it can measure and show the current temperature on an alphanumeric display, and also set its ([RVR]'s) LEDs to a color that corresponds to the temperature 🌈🌡️
This example will show you how to incorporate several different technologies into a single project. Consequently, it requires lots of assembly! Take your time and follow the instructions carefully, especially if you haven't put together a circuit before!
Note: The battery in your RVR+/RVR may fail if exposed to temperatures below -20C (-4F) or above 60C (140F), so don't go crazy when you're testing out your WeatherBot! Also, if you decide to test the humidity, as well, keep in mind that your RVR+/RVR shouldn't be in an environment more humid than driving through wet grass.
Parts List
Here's a list of everything you'll need to make your own WeatherBot:
Adafruit Feather (any type will do, we used a HUZZAH)*
Micro B USB Cable
DHT22 temperature-humidity sensor (comes with a resistor)**
Dual Alphanumeric Display (pick your favorite color!)
Breadboard
29 Jumper wires***
Solder and soldering iron
* There are three different versions of the HUZZAH. We used the Assembled Headers version (just because that's what we had on hand), but any of the three versions will do. In fact, the Stacking Headers version would eliminate the need for a lot of jumper wires and give you a much cleaner final product!
** You could also use a DHT11 instead.
*** You'll notice from the picture of our circuit that we didn't actually use jumper wires, but cut and stripped wire to fit more nicely in the circuit. Jumper wires will work just fine, but if you want to do what we did you'll need some hook-up wire, wire strippers, and wire cutters. Also, depending on the version of Feather board that you use, you may need fewer than 29 wires.
Hardware Assembly
As you can see from all the asterisks in the Parts List above, there's a lot of wiggle room in how exactly you want to build your circuit. The remainder of this tutorial will walk you through the way we did things; if you don't have much experience with this type of project we recommend following along exactly, but if you know your way around a breadboard then feel free to make whatever changes you see fit!
First things first, we need to assemble our alphanumeric display. Here's the tutorial we followed to accomplish this task, and we recommend you do the same! There is, however, one note we'd like to add: once you're done soldering, be sure to hold on to the wires (with tweezers if you have them) when you clip them short to keep them from flying all over the place! It would also be a good idea to wear safety goggles during this step.
Once you have your alphanumeric display assembled, you can start putting together your circuit! Follow this wiring diagram:
It looks like a lot! If you're cutting and stripping your own wires, this is the most time-consuming part of the project. So take your time, follow the diagram carefully, and be patient! When you're done you should have something like this:
Software
Phew! Take a deep breath, the hard part is over.
If you haven't done so already, download the Arduino IDE. We'll use this IDE for both the Arduino and the Feather.
Since we're working with two different development boards (Arduino Uno and Adafruit Feather), there are two separate files you'll need to download. weather_bot.ino will go on the Arduino, and weather_bot_display.ino will go on the Feather. Let's start with the Arduino.
Arduino Code
If you aren't interested in walking through the code we'll load on the Arduino, you can just open the weather_bot.ino file (from the demos/weather_bot directory in the Sphero Arduino SDK GitHub) in the Arduino IDE, and then jump to loading the file on to your Arduino. Otherwise, let's do a little runthrough!
We'll start by making all of the necessary imports to allow us to set the info for the pins on the Arduino and to communicate with the RVR+/RVR. We'll then use this info to set the DHTPIN that is connected to the data pin of the sensor and set the type (DHTTYPE) of the sensor you're using (if you are using a sensor other than the DHT22 temperature-humidity sensor, you'll have a different value here than we will). We'll also add a bitmask that indicates to the RVR+/RVR that we want to set all the LEDs. As the final part of our imports and definitions, we'll initiate the temperature/humidity sensor:
#include "DHT.h"
#include <SpheroRVR.h>
#define DHTPIN 4
#define DHTTYPE DHT22
#define ALL_LEDS 0x3FFFFFFF
DHT dht(DHTPIN, DHTTYPE);
The next part of our code is a setup method, in which we'll turn on the temperature-humidity sensor, set up our connection with the RVR+/RVR and pause to let the RVR+/RVR wake up so that we can begin sending it commands:
void setup() {
dht.begin();
rvr.configUART(&Serial);
delay(2000);
}
Our loop is where our actual actions take place. Our loop is set to take place every two seconds. When the loop runs, we'll read the temperature from the sensor in Fahrenheit (though, if we get a bad reading, we'll start the loop over) and translate the read temperature (ranging from 0F-100F) to a red or blue value ranging from 0-255. To set the LED colors to correspond with our temperature, we'll need an array of 30 values (10 LEDs, each with a 1) red, 2) green and 3) blue value), which we'll populate so that each LED will be the same color (and the green value will be 0 in all cases, since we are just working with red and blue to indicate hot and cold). Once the array is populated, we'll use it with our setAllLeds method to change the colors of your robot's LEDs:
void loop() {
delay(2000);
float temperature = dht.readTemperature(true);
if (isnan(temperature)) {
return;
}
uint8_t redValue = static_cast<uint8_t>(temperature / 100 * 255);
uint8_t blueValue = static_cast<uint8_t>((100 - temperature) / 100 * 255);
uint8_t ledValues[30] = {0};
for (int i = 0; i < 28; i = i + 3)
{
ledValues[i] = redValue;
ledValues[i + 1] = 0;
ledValues[i + 2] = blueValue;
}
rvr.setAllLeds(ALL_LEDS, ledValues, 30);
}
Loading the File onto Your Arduino
Under the Tools tab, be sure your Board is set to "Arduino/Genuino Uno". Also make sure your Port is set to the USB port you're going to plug your Arduino into. Connect your Arduino to your computer using the A/B USB Cable, then click the Upload button in the top left corner of the IDE. Wait a few seconds until the IDE tells you it's done uploading, and then you're good to go!
Feather Code
Using the Feather with the Arduino IDE is a little more complicated. Follow this tutorial to get everything set up. Once that's done, we can add the code; the upload process will be exactly the same here as for our Arduino code! Just use the Micro B USB cable this time instead of the A/B cable.
Let's take a look under the hood of the program we built for the Feather... (If you would prefer just to use the program we already created, you can find it in the demos/weather_bot directory in the Sphero Arduino SDK GitHub).
The first thing we'll do for our Feather code will also be to import a few things, in order to allow us to define the connections between the Feather and the Arduino, as well as access the Feather, itself. We'll set the pin connected to the data pin of the sensor, and the type of sensor, again, and then set the bitmasks that tell the display which segments need to be turned on for each character. We'll also create an object for the alphanumeric display and one for the temperature-humidity sensor:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
#include "DHT.h"
#define DHTPIN 12
#define DHTTYPE DHT22
#define ZERO 0x0C3F
#define ONE 0x0006
#define TWO 0x00DB
#define THREE 0x008F
#define FOUR 0x00E6
#define FIVE 0x2069
#define SIX 0x00FD
#define SEVEN 0x0007
#define EIGHT 0x00FF
#define NINE 0x00EF
#define DECIMAL 0x4000
#define OFF 0x0000
Adafruit_AlphaNum4 output = Adafruit_AlphaNum4();
DHT dht(DHTPIN, DHTTYPE);
In our setup method, we'll turn on the alphanumeric display and the temperature-humidity sensor, then turn off all the segments of the display, so they are clear and ready to display our readings. Our final setup step is to pause for a moment to allow the RVR+/RVR to wake up:
void setup() {
output.begin(0x70);
dht.begin();
output.writeDigitRaw(0, OFF);
output.writeDigitRaw(1, OFF);
output.writeDigitRaw(2, OFF);
output.writeDigitRaw(3, OFF);
output.writeDisplay();
delay(2000);
}
Now for the good stuff! For our loop method, we'll also set it to occur every 2 seconds and will read the temperature from the sensor, in Fahrenheit. Again, if we don't get a good reading, we'll just start the loop over. This time, rather than converting the temperature to a color, we'll convert it to characters that can be displayed on our alphanumeric display by creating an array where each digit (decimal included!) has its own place in the array and then looping through the array to create and display each character. After we've finished determining what to display for each character, we'll update the display with the whole number:
void loop() {
delay(2000);
float temperature = dht.readTemperature(true);
if (isnan(temperature)) {
return;
}
char temperatureBuffer[5];
dtostrf(temperature, 5, 2, temperatureBuffer);
for (int i = 0; i < 5; i++)
{
// skip the decimal point
if (i == 2)
{
continue;
}
// set the display index
int index = i;
// offset the display index by 1 if we're past the decimal point in the char array
if (i > 2)
{
index = i - 1;
}
// get the bitmask for the current digit
int digit = getDigit(temperatureBuffer[i]);
// add a decimal point after the second digit
if (i == 1)
{
digit |= DECIMAL;
}
// write digit to the given index of the display
output.writeDigitRaw(index, digit);
}
output.writeDisplay();
}
You may have noticed that we used a "getDigit" method to define digit in our code to display the temperature above; let's define that method! getDigit just converts the digit (in the form of a char) to one of the digit bitmasks we defined at the start of our program:
int getDigit(char digit) {
switch (digit) {
case '0':
return ZERO;
case '1':
return ONE;
case '2':
return TWO;
case '3':
return THREE;
case '4':
return FOUR;
case '5':
return FIVE;
case '6':
return SIX;
case '7':
return SEVEN;
case '8':
return EIGHT;
case '9':
return NINE;
default:
return OFF;
}
}
That is all for our Feather program; go ahead and load it up so we can test it all out!
(Psst! If these explanations aren't enough for you, here are some links with more info about DHT22 Usage and Alphanumeric Display Usage.)
Bringing It All Together
Now that our circuit is built and our dev boards are flashed with code, we can finally use our WeatherBot! All you need to do is plug the Arduino into [RVR]'s USB port using your A/B USB cable, and turn on the RVR+/RVR! It'll take a few seconds before the [RVR]'s LEDs change colors, so be patient. It may also take several seconds before you see the alphanumeric display light up. If it's been a while and you still don't see anything, try hitting the reset button on the Feather and wait another several seconds. Hitting the reset button on the Arduino can also help if that didn't work.
Congratulations on a job well done!
Now What?
See if you can build a better bot! Here are some ideas we had for ways you could improve your WeatherBot:
The DHT22 has a humidity sensor that we didn't use, find a way to incorporate that!
We mentioned several different options for building your circuit. Now that you've done it one way, see if you can do it a different way!
Change up the code to have the LEDs turn every color of the rainbow instead of just ranging from red to blue!
Try our other activity, PartyBot or the Software Serial Library.