This little project sort of builds upon the last one, perhaps making a more extensive usage of the Web rather than the hardware/Arduino bits themselves. In fact, hardware-wise, this project is incredibly simple (which was not the point, but it’s something I failed to notice initially).
Here’s the project (apologies for the bad video quality):
It’s not very clear in the video, but the LEDs are acting as a thermometer based on the temperature of that location. The servo then moves to represent the current weather on that location. Yes, the printed icons are crappy and a 6 year old could do better than this, but it’s what I could come up with on short notice!
We’re building an simple Web interface, running on a local (node) server, that accepts a location typed by the user. Using web sockets, we’ll capture this location, make an API request to OpenWeather API which will get us the weather data. Then, we’ll find a way to transform and represent the weather data into instructions for the hardware components.
What you’ll need
- Arduino board
- 7 RGB LEDs (or any amount)
- 1 breadboard
- Jumper wires
- 1 capacitor
- 1 servo
Here’s the schematic. It’s pretty straightforward; our servo is connected to the
PCM 11 port on the Arduino board.
If you’re wondering about the capacitor, here’s why.
In order to use OpenWeather’s API, we need an API key to use, otherwise we won’t have access to it. To get one, follow the instructions on their API page; after signing up, head other to their
/api_keys section and generate one. It should look something like the following (note that the following key is invalid, though):
For simplicity’s sake, we’re storing this key in a local variable in our file. Ideally, and on a production environment, you’d want to keep this key private by storing it on an
environment variable instead.
That’s it for the API. Save it, we’ll be using it in our main
index.js file as a variable.
You can find the full code on Github, but here’s a quick breakdown of what’s happening.
In order to simplify the logic, everything is written in chainable form using
Promises. Just by reading the function names that make up the whole demo, even without having written them, it’s pretty easy to see what we’re trying to achieve:
Sockets and johnny-five
We want all of those methods to run once johnny-five is running and the web sockets get some new data (meaning the user has entered a new location). So we’ll wrap the code above in johnny-five and socket.io connections, like so:
Calling the API
Great, so how can we fetch the weather data from the API? There’s a ton of libraries to choose from, but I like to stick with
fetch, since it should soon become the de facto API to use for external requests. The node.js implementation of it is called node-fetch and we can install it, just like socket.io, via npm:
npm install --save node-fetch socket.io
Here’s our function that requests the weather data:
fetch returns the data wrapped in a Promise, so we’ll resolve it using the data we fetched. If the request fails, we’ll
reject the Promise with the error.
Moving the servo
The servo motor is surprisingly simple to use using johnny-five and I highly encourage you to look at its API on the source documentation. There’s tons of methods you can use to make it move, but at its core, it’s as simple as telling it to move between an angle of
180 degrees, and providing an optional speed argument in milliseconds:
To move the servo based on the current weather condition, I’m being incredibly rude and nasty with the code, actually. OpenWeather responds with a specific weather code and text description for each situation, so I’m literally comparing the string value and mapping it to an angle that I previously checked based on the location of my physical, printed markers (through trial and error).
For the LEDs to work as a thermometer, I’m also being quite raw and literally defining breakpoints for them. If the temperature is less than
N degrees, return a lower number of LEDs; increasing it as the temperature value rises higher. In our code, anything above 27ºC lights up all LEDs. Why 27? Well that’s pretty hot in my book.
To make them light up as a range, we loop over them like so:
Serving the files
After wiring up all the bits and pieces (again, follow along the source code), we serve this code using Express.js, just like in the previous tutorial. We’re hardcoding the port to be
3000 but you can use whatever you want; please note that if your port differs, you’ll also need to change it in the front-end code, which we’ll get to next.
To run it, serve it with node:
And point your browser to
http://localhost:3000. If you download the other files from the repo (namely, the entry point
index.html) you’ll get the full markup in the browser.
The front-end code
We need some markup (and CSS, why not) and JS to allow the user to search for a location, send it over to our local server using web sockets, and get things moving (literally).
In the first line, we establish our connection to
socket.io. On each
input change, we send the value through the socket connection under the key of
search-weather, which just happens to be what our previous node.js code is listening to! What a happy coincidence!
If you decide to try this out, the only thing you’ll need to tweak are the angle values for your marker distribution. Get creative, hopefully more creative than I did, because that’s precisely the point of messing around with an Arduino! For this project, I focussed too much on the Web part and not so much on learning more about the hardware, which is something I’ll certainly work on for the next project.
If you got any questions or doubts, feel free to ping me on Twitter.