This project utilizes a 22 x 13 matrix of addressable RGB LEDs to visualize a weather forecast pulled from the Weather Underground API.
A Raspberry Pi runs a python program designed to fetch weather forecast data from the API at regular intervals, parse the data into temperature, wind speed, and weather condition arrays, and then light specific sets of LED's that represent words in the LED matrix.
Mounted in its own enclosure, the project can set on a shelf, desk, or hang on a wall as a visual display for upcoming weather conditions over the next 12 hours.
The inspiration for this project comes from the beautiful LED Word Clocks that captured my imagination when they first began showing up on maker community forums. After a lot of research, tinkering, programming, and several failed attempts, I'm happy to have a version with a twist that I can share with the community that inspired me.
If you enjoy "Weather Words", please check out my previous weather visualization, "Weather Colors" here.
* Note that if you choose to use the Zero, you will need a USB hub, a Micro USB Male to USB Female Adapter, and a Mini HDMI to Standard HDMI Jack Adapter to interface with the Pi for software setup and troubleshooting.
* Note that my local copy shop did not carry the needed transparency film. I purchased the film online in a bulk quantity which was an expense that was not anticipated at the start of this project. You might get lucky or be able to negotiate with a shop in your area on carrying this material.
For this project, it will be important to center the bottom and top Weather Word Templates in the enclosure so that when the two are mounted together, the light baffles will lay between the rows and blocks of words.
Measure and record the innermost length and width of the enclosure. Mine measured 11" x 14-1/16". Cut a sturdy piece of cardboard to this dimension and check that it fits snuggly in the enclosure. This piece will serve as the base for mounting the LED's, light baffles, and assembled electronic hardware. Cut another sturdy piece of cardboard that is approximately 14" long and 4" wide. This piece will be cut into light baffle sides at a later step.
Print out two (2) copies of the "Bottom Word Template" on 11" x 17" paper. Be sure to print it at 100% scale (not "scaled to fit"). Measure and trim one of the templates to center it to the cardboard base. Glue this template firmly to the cardboard ensuring that the majority of the paper is adhered (this is important because the LED's and light baffles will be adhered to this base at a later step). Set the second copy of the Bottom Template aside for later reference (it will be useful for measuring and comparing your Top Templates at a later step).
Print out one (1) copy of the "Side Baffle Template" on 11" x 17" paper. Be sure to print it at 100% scale. The lines on this template are meant to align with the word rows on the bottom template and to serve as an aid for obtaining straight and square light baffle rows later in the project. Measure and trim the template to center it to the 14" x 4" piece of cardboard. Glue this template firmly to the cardboard ensuring that the majority of the paper is adhered.
Print out three (3) copies of the "Top Word Template" on 11" x 17" transparency film (acetate) using a laser printer (I utilized the local copy shop for this step). Again, be sure that these are printed at 100% scale. Also check that the top template is roughly centered on the width of the acetate (my enclosure width was exactly the width of my acetate ... maintaining centering at this step helped to ensure I was roughly centered to my bottom template). Before proceeding, compare the printed top templates to the saved copy of the bottom template. The two should be a close match (there will be some difference top to bottom as the acetate shrinks under the heat of the laser printing, but the difference should only be slight). Measure and trim each of the top templates to center them to the enclosure dimensions recorded previously and check that they fit snuggly in the enclosure. Align the words of each copy of the top template together and adhere the copies together using double sided tape.
The LED matrix consists of (22) rows of addressable RGB LED strips (13 LED's per row). Because the LED strips are purchased in meter plus lengths, each row for this project was cut across the copper terminal pads between the 13th and 14th LED of the purchased strip.
Use double sided tape to adhere each row of LED's to the bottom template. Start with the travel of the data from left to right on the top word row (look for the arrows on your LED strip) and then right to left on the next word row. Alternate the data travel in this fashion down through all 22 rows of the template.
The rows of LED's will be connected in groups of 5 (and then 2 at the end). All of the rows will be connected at the data points (to make a fully addressable block of 286 LED's) but the rows will only be powered in parallel groups of 5.
Before soldering the rows together, you might consider cutting holes or slots through the bottom template at the end of each row to feed the wire through. You can see from the pictures that I looped the wire directly between the rows and later needed to cut slots in the side baffles to accommodate. The baffle slots worked fine and did not cause any excess light bleed outside of the intended area, but they took extra time to cut and fit properly over the wires.
Now solder each row together using short (approximately 2") wire to connect GND-to-GND, DIN-to-DOUT, and VDC-to-VDC in the direction of data travel stopping at the end of the 5th row. Only solder the DIN-to-DOUT between the 5th and 6th row. Solder short wire to the GND and VDC of the 6th row and leave those free to connect power later. Continue in this fashion down all 22 rows of the template.
Obtain some thin(ish) cardboard for cutting into light baffle rows (I used cereal boxes). Measure and trim the cardboard into (46) strips that are 8-5/8" long x 1" wide. Use double sided tape to adhere the strips together in pairs to obtain (23) light baffle rows (the baffles seemed flimsy individually and I thought that two together would provide better stability across the rows ... in hindsight this may of have been overkill, but I can't speak for whether a single strip is sufficient).
Cut an extra (5) strips for use as word block baffles at a later step.
Use a hot melt gun and glue to adhere each light baffle row to the line on the bottom template. Be sure to use plenty of glue and work quickly to obtain strong adhesion between the baffle rows and the bottom template. Also be sure to try to keep each baffle row aligned along and end-to-end of the printed bottom template line.
Measure and trim the 14" x 4" piece of cardboard with the adhered side baffle template into two strips that are 13-1/4" long x 1" wide. Fit check the sides to the bottom template. Each line on the side baffle template should align with the word rows on the bottom template. There should also be some overhang of the side baffle at the top and bottommost rows.
Use a hot melt gun and glue to adhere the side baffles along the left and right hand sides of the bottom word template. Again being sure to use plenty of glue and working quickly to obtain strong adhesion between the sides and the bottom template. Now use the hot melt glue to adhere each end of the baffle rows to the baffle sides.
Next, cut and adhere the (47) word block baffles. These baffles will block the light between the lighted weather words. Using the bottom template as a guide, trim individual block baffles and use hot melt glue to adhere each into place. Trim each to obtain a snug fit ... enough to block the light but not enough to distort the baffle rows.
The final step in the light baffle process is to cut a black plastic garbage/trash bag to size that completely covers the light baffles. The bag serves two purposes ... it diffuses the light from the bright LED's that can be seen through the clear transparency lettering and it serves as an additional black barrier to prevent the light from showing through the black transparency layers and highlighting the baffles behind.
As an optional step, I cut vellum paper to size and curved it slightly over the LED's in each word cell. This method cancelled the effect of seeing each individual LED when viewed directly through the clear transparency lettering.
The Raspberry Pi Zero does not have headers assembled to the GPIO pads. You will need to solder at least one header to the Pin 12 location (GPIO18).
The basic hardware installation is an almost one-for-one implementation of the Level-converter Chip Wiring setup found on Adafruit's Learning System tutorial NeoPixels on Raspberry Pi. The breadboard setup is summarized as follows:
In addition to the above, I chose to add a capacitor(1000 µF, 6.3V or higher) across the + and – terminals and a data line resistor (300 to 500 Ohm) between the 74AHCT125 pin 1Y and the input to the first LED row DIN. The project was tested without the added hardware with no observable ill effect but were added as a precaution based on the Best Practices found in the "Adafruit NeoPixel Überguide".
Power is brought into the enclosure via a MicroB USB Connector Breakout and split to power both the Pi and the breadboard in parallel. Solder header terminals to VCC and GND. Solder the capacitor and two pair of wire to each header terminal (be sure that the capacitor leads are correctly matched to the positive/VCC terminal and the negative/GND terminal). Connect one pair of VCC and GND wire ends to the breadboard. Solder the Micro USB Connector Shell to the other pair of wire ends and connect it to the Raspberry Pi.
You should now be able to power up the Pi from the micro USB connections. However, the LED's won't do anything yet until the NeoPixel Library is installed in the next step.
*Note: It is not necessary to wire the Pin 6 location (GND) as shown in the reference picture when the Raspberry Pi and the LEDs share the same power supply. I originally wired the project this way and noticed that a large proportion of current was grounding through this pin. Removing this connection had no adverse effect on the operation of the LEDs.
First, before proceeding with the software installation, it will be necessary to blacklist the Broadcom audio kernel (onboard sound driver for the Pi). This is to eliminate a PWM conflict between the following library installation and the onboard audio which can cause some strange behavior in the LEDs (random mix of flickering or blinking pixels) or functioning of the Pi when the HDMI is disconnected. The Instructable "Disable the Built-in Sound Card of Raspberry Pi" will walk you through the blacklist steps.
Now, download and install the NeoPixel Library for Raspberry Pi (rpi_ws281x library), following the Software instructions from the Adafruit Learning System tutorial with one exception. In addition to the tutorial instruction to install the library to Python by executing:
sudo python setup.py install
You will also need to install the library to Python 3 by executing:
sudo python3 setup.py install
This is because the weather_word.py program that you will install in a later step was written in Python 3.
Continue the Software instructions with the Strandtest Example. Be sure to change the LED_COUNT constant to the reflect the number of pixels in your project (in this case 286) or else only the first row of your matrix will be controlled when you execute the example code.
If all of your connections are good, you will get a nice bright* demonstration across the entire matrix!
* Note that for the Strandtest example and using a brightness setting of 255 and a pixel count of 286, a 2 Amp power supply will be pushed to it's upper limit. I measured about 2.2 Amps for the LED's while running the rainbow sequence on a 2 Amp power supply and about 2.5 Amps while running on a 4 Amp power supply. However, use caution when playing with the code. An all white (255, 255, 255) setting could pull more than 17 Amps (reference the Powering NeoPixels section of the "Adafruit NeoPixel Überguide" for estimating NeoPixel power requirements). I ran an all white as a test and it tripped my Pi into a reboot sequence.
The Weather Word program is designed to fetch weather forecast data from an API in 15 minute intervals, parse the data into temperature, wind speed, and weather condition arrays, and then light specific sets of LED's that represent words in the LED matrix.
In order for the API to work, you will need to obtain an API key from the WeatherUnderground website (available here). This key will be entered into the apiboot.txt file at a later step.
From the Raspberry Pi terminal, execute the following command to download and install the needed apiboot.txt and weather_word.py program files.
You will now need to edit the apiboot.txt file to 1) add your API key, 2) choose (uncomment) one of the API query options, and 3) choose 'english' (degrees F) or 'metric' (degrees C).
Executing the following command will open the apiboot.txt file in the nano text editor:
sudo nano /home/pi/weather_word/apiboot.txt
By default, the city/state query is uncommented (Miami/FL). Choose and modify any query of your liking, just be sure to comment (#) any unused query. Reference the Weather Underground documentation for more examples about the query types and how to tailor the queries to work with your specific need. When you are done editing the nano file, Ctrl-X to exit and Y to save the file.
Now, to test the installation, execute the following:
sudo python3 /home/pi/weather_word/weather_word.py
Upon execution, the program will write its first log.txt file. Though, if you open the log file now, the log file will only indicate that the program is initializing with the rainbow color sequence.
The rainbow color sequence will chase across the LED matrix for 60 seconds. The weather_word program is intended to be launched upon Raspberry Pi startup. The 60 second delay is meant to give the Pi plenty of time to boot and connect to wifi before it makes the first API call.
After approximately 60 seconds have passed, the program will make its first API call. If all goes well, the current weather conditions will be displayed on the LED matrix. Every 20 seconds, the display will cycle to 'upcoming low' and then 'upcoming high' forecasted weather conditions based on results parsed from the next 12 hours of weather data.
Opening the log.txt file will reveal the data set from the API call. The program will continue to make API calls and update the LED matrix and log.txt file every 15 minutes until the Pi is shutdown or the program is terminated (Ctrl-C from the terminal).
If the API call fails to connect or returns an error, the program will wipe the LED matrix with a red display, write the error encountered to the log.txt file, and terminate.
If the API call times out during the boot sequence, the program will wipe the LED matrix with a yellow display, write a message to the log.txt file, and attempt to connect again in 3 minutes.
For the purpose of testing the quality of the light baffles in your project, I wrote the following test program to cycle through each word in the display.
sudo python3 /home/pi/weather_word/weather_word_test.py
Each word dwells for 5 seconds and then repeats when reaching the end of the display.
When you are satisfied with your setup, the final step in the software installation is to have the Pi launch the program at startup. This is accomplished by using the following terminal command to modify the crontab.
sudo crontab -e
Scroll to the bottom of the file and add the line:
@reboot sudo python3 /home/pi/weather_word/weather_word.py
When you are done editing the file, Ctrl-X to exit and Y to save the file. Now when you shutdown and reboot your Pi, the weather_word program will launch as intended. Be patient during launch as there will be no display for the first 15 seconds or so until the crontab is executed. You can now untether the project from your keyboard, mouse, and display and place it anywhere that you would want to see the current weather and forecast at a glance!