06/10/2021 at 04:34 •
Now that we're entering the stormy part of the year, I thought it was about time the Weather Radar had the ability to capture my attention when severe weather was heading my way (other than all the colourful alerts that flash across the display).
I decided on adding a pancake-style vibration motor because 1) it's less grating than a tone alarm, 2) it would completely validate my spontaneous purchase of a pancake-style vibration motor a few weeks prior.
To drive the motor I'm using a DRV2605L Haptic Motor Controller breakout from Adafruit, which comes with several inbuilt vibration effects as well as a CircuitPython library which makes this 178% easier. It uses I2C, so I chained it to the other I2C boards I'm using.
The vibration motor is a slightly beefy one I got from Electronic Goldmine (although it's no longer in stock!) and can be driven from 3 - 6 volts.
Thanks to Adafruit's DRV2605L product tutorial, the code is pretty simple!
After initialising the board and the DRV2605 chip, I created a vibrate function (so I could define different vibration sequences in the future).
My "alert" sequence uses several of the inbuilt effects, starting with a ramping up transition (effect #113) so I don't startle myself or my partner when the 750ms & 1000ms alerts kick in (effects #15, #16).
import board import adafruit_drv2605 i2c = board.I2C() drv = adafruit_drv2605.DRV2605(i2c) drv.library = 3 #TS2200_library_Cdef vibrate(vibration_sequence): """Play a vibration sequence.""" if vibration_sequence in [0,"0","alert"]: drv.sequence = adafruit_drv2605.Effect(113) drv.sequence = adafruit_drv2605.Effect(119) drv.sequence = adafruit_drv2605.Pause(1) drv.sequence = adafruit_drv2605.Effect(15) drv.sequence = adafruit_drv2605.Pause(1) drv.sequence = adafruit_drv2605.Effect(16) else: pass drv.play()
In my main loop, the Weather Radar checks for local weather warnings every 5-10 mins (depending on weather conditions) and makes a list of them.
If the list is populated (because of a severe thunderstorm or tornado watch/warning) the alert vibration sequence runs.
### Get local warnings and alerts local_warnings, local_alerts = get_all_alerts(coordinates=(lat_long,lat_long)) ### If there's any local warnings (severe weather) ### run the alert sequence if len(local_warnings) > 0: vibrate("alert") else: pass
Here's an example of it and the visual alerts in use, letting me know of a severe thunderstorm warning over a part of Montana (after setting the local coordinates for that area).
With so many vibration effects, I might experiment and add some subtle haptic feedback, especially when using the navigation switch.
02/13/2021 at 03:34 •
I've slowly been making improvements over the past few weeks!
The code is becoming more refined with every new problem I find (including when my local NWS radar station was down for 5 days for repairs).
- The navigation switch is more response, the zoom potentiometer is more zoomy, and things are failing more gracefully than before.
- There's now example code! For those that would like to see how I'm obtaining and displaying NWS radar images, there's now example code on the project's GitHub page. Currently it doesn't show the button handling or the OpenWeather/NWS forecast stuff, but as soon as I can stop myself from testing out new features, I'll debug everything and add those elements too!
- In addition to OpenWeather data, I'm now using NWS forecast data to provide a longer, text-based forecast for every forecast period. This is mostly handy for getting nuance from the forecast that OpenWeather doesn't provide (especially snow and ice accumulations!).
- Depending on the mood of the servers, this can sometimes be temperamental to get. I'm having a lot of fun with Try, Except, and Else statements.
- The forecast URLs can be easily obtained from the latitude/longitude point file that gets read when the Weather Radar gets the local radar station based on the target latitude and longitude.
- I'm now using the Omzlo PiWatcher TB to monitor the Raspberry Pi and give me an external on/off button on the rear of the case.
- Along with the on/off button, I made a cover and put an external micro USB connector on the rear (instead of the hole I had before). This makes everything a lot neater and allows me to easily disconnect the USB cable.
- I 3D printed a black bezel for the hole for the navigation switch.
- Inside, there's now a mount for the PCF8591 and the PiWatcher.
- Because the Weather Radar spends most if it's time on my desk (looking very pretty and spitting out errors I hadn't considered), I've been propping it up to give it a slight angle. Instead of using whatever random thing I had on my desk, I designed and printed a leg to do this for me.
Mostly a to do list for me:
- Refine and tidy up more of the code… and release it on Github!
- Clean up some aspects of the UI.
- Incorporate more data!
- I've been taking a look at the NWS graphical forecasts and thinking how I can include those images into the Weather Radar too!
- I'd like to add 511 traffic data for parts of a monthly commute where current road conditions help me to plan which route I'd like to take. Fortunately this looks like it'll be relatively easy to obtain from my state's Department of Transportation!
- Threading! It would be super handy to download new radar images while also displaying the previous images too.