by Luka Sherman
The concept behind this piece is to experience other locations around the world through light. Maybe it's a place you're homesick for, a place where a person you're close to is right now, or someplace you want to travel. It could also be set to your current location, and help connect you to the outdoors, instead of solely using artificial light in the home in lieu of what's happening outside, further reinforcing a barrier between us and our environment.
It seeks to connect us to places and people that are meaningful to us through sharing the experience of live meterological conditions.
A user switches it on and points the rotary dial to one of the labeled cities, and a neon-like LED strip will illuminate and animate based on what the weather is like right now at that location.
Weather conditions correspond to different primary and secondary colors that are cycled down the strip (sunny is yellow, clouds are grey, rain is blue, snow is grey and blue). Shade and hue are used for scale, for instance if it is warmer it will be a deeper shade. The animation speed of the light cycle corresponds to the wind speed. If it is nighttime in that city, the brightness will be lowered. If the air quality is unsafe, the light will pulse red, a practical alert if you're currently in that city. Svalbard will always depict the northern lights (green, blue, purple). Every ten minutes it will check the latest weather and adjust if necessary.
Twelve cities were picked on the basis of having representation of all continents, for having a variety of weather, and some for being significant places in my life. LED strands that are popularly used today have a remote that allows the resident to pick from different colors, and one could similarly dupe this by selecting a typically sunny city if you wanted a warm yellow/orange light, or a rainy city if you wanted a cooler blue light.
This two-week project was done for Andy Davidson's HCDE 539 Physical Computing and Prototyping course at the University of Washington.
For display purposes, the piece is sitting on a pegboard shelf, and the LED loosely bent around hooks. The LED is flexible and can be arranged to fit any space.
- Arduino Uno WiFi Rev2
- Adafruit Perma-Proto Half-sized Breadboard PCB
- Adafruit NeoPixel RGB Neon-like LED Flex Strip with Silicone Tube - 1 meter
- Power Supply 12V 1A
- Push button Latching Switch with LED indicator
- Rotary Selector Switch 1 Pole 12 Position 6mm
- Rotary Control Knob Machined Aluminum Alloy 6mm
- Resistors: 220 ohms x2, 10k ohms x1
- Capacitor 1000uf
- Wire 22 gauge, solder, heat shrink tubing
I wanted the piece to be able to be displayed in a home, so formed several constraints around
- Power: It had to be powered without USB connection to a computer, and only one power input for practicality. This model of NeoPixel already required 12V of power, more than the 5V the Arduino could supply, so I used the same power source to power the Arduino with the Vin port. This works because the Vin pin goes to the Arduino's 5V regulator, and the power supply is within the 7-12V unregulated range permitted.
- Robust: I wanted everything to be firmly secured, and not delicate. The metal switches are heavy-duty and give a satisfying tactile feel. Everything is firmly held in place by an acrylic housing. The 1/4in acrylic is cut into two 5in x 7in sides, with holes cut in the top piece for the two switches, and holes cut into the bottom piece to screw in the Arduino and breadboard. 3in screws were used to connect the pieces, with plastic spacers between them to fill the empty space, and to lift the breadboard to the appropriate height in reference to the Arduino. All screws are affixed to washers on the back side of the acrylic. It is portable, and can be moved around without impact to the internals, while still being able to reach the components and adjust parts as needed.
- Artistic: I wanted it to have an industrial feel, and the high-quality thick acrylic allows the internals to be on display. I soldered all components and attempted to arrange them in a visually appealing way. I used an old-school manual label maker to label the rotary positions with cities (arranged from clockwise latitude coordinates, clockwise around the dial), and pointed the edges at the precise rotary marker to minimize the need for additional arrows. The LED strip was selected for its finished quality that matched the feel of the overall piece. The LED on the power button adds an additional level of user feedback.
- The
loop()
function primarily listens for weather or not the power switch is pressed on. It reads the power switch, delays 30ms, and reads it again, to account for a consistent state and making sure that both values are equal. If the switch is now off but was last on during the last loop iteration, it will turn off the LED switch and disconnect from WiFi. If the power switch is on, it will proceed with the sequence: - If the WiFi is not already connected, it will connect. It uses the WiFiNINA library by Arduino, and uses the WiFi network name and password hard-coded in the secrets.h file that is located at the same directory as the .ino file.
- The script will then check to see which city the rotary selector switch is pointed to. It loops through pins 2-13, gets the corresponding String from a const array
PIN_CITIES
at the same position as the pin number, and updates the global StringcurrentCity
accordingly. - If there is a new
currentCity
(i.e. it has changed since the loop's last iteration) or it has been over 10 minutes since the last API call, it will make anhttpRequest
to the API to get the current weather. Using the WiFiNINA connection already established, it will send a GET request to the OpenWeatherMap.org server, specifying the city, my personal OpenWeatherMap.org free API key, output mode (JSON), units (imperial), and the info that I don't need (daily and hourly forecasts). If the client is available, it will start saving the API's JSON response as soon as it detects the first ''{'' to a global String variablejsonText
. When the client is no longer available it will close the connection so it will be ready for the next call. - The raw JSON is now coded into integers that will be used by the LED display. The JSON is deserialized into a
DynamicJsonDocument
from the ArduinoJson library. The values temperature (float signifying degrees Fahrenheit), description (String i.e. "Clouds" "Rain" "Clear" "Snow" etc), cloud level (int 0-100), probability of precipitation (float 0.00 to 1.00), wind speed (float 0.00 to 1.00), snow fall in the last three hours (float signifying inches), rain fall in the last three hours (float signifying inches), and if it is day or night (boolean). Those numbers are used to calculate variables that will be used for the LED display:speed
(based on wind),color
(based on current weather), andbrightness
(based on day vs nighttime). - The NeoPixel strip is illuminated with use of the
Adafruit_NeoPixel
library. The strip was instantiated as a global variable on upload, with parametersLED_COUNT
(this strip has 60 LEDs, although they are grouped in threes, so it only recognizes 20 LED addresses), theLED_PIN
it is connected to, and the pixel type flags (this strip uses two that are added together,NEO_GRB
per the RGB bitstream andNEO_KHZ400
per the 400 KHz pixels using WS2811 drivers). The script iterates through the 20 addresses, setting the color for each pixel, brightness, at the signified speed. - The strip will continue with the same animation profile until either a new rotary position is selected, or if 10 minutes have elapsed since the last
httpRequest
. The free version of the API key can be used 60 times a minute, or 1,000,000 times a month. I have two API personal keys in case of capacity or for demo purposes. - If the power switch is turned off, the LED strip will turn off after it finishes the current cycle (0-3 seconds) and it will disconnect from WiFi.
- OpenWeatherMap free API to get current weather conditions at a given location.
- Adafruit_NeoPixel to send commands to light the LED strip.
- ArduinoJson to parse the JSON API response.
- WiFiNINA to connect the Arduino to WiFi.
- Fritzing to draw the above circuit breadboard and schematic diagrams.
Candid demonstration of an unintentional side effect - my cat loves watching the light cycle.
† This project is dedicated to the brave Arduino Uno WiFi Rev2 that I accidentally fried in the process, may she rest in smoldered pieces.