In August 2021, I made a tool for displaying miscellaneous info about the world (current time, weather forecast, stock / crypto prices), generating an image displaying that info, and drawing it to an e-paper display I have. It’s been sitting on my desk for the last year, working great, but half-finished this whole time.
Here’s an older picture of the current state of the project sitting on my desk!
It works by displaying a list of “cards”, each tasked with displaying one piece of info - time, weather, stock price, etc.
My goal is to finish all the TODOs I’ve carried around for the last year, and build a second in time to give to a friend for Christmas. To list a few TODOs:
Build a card layout manager so I don’t manually place cards at specific pixels
Make cards reconfigurable, less hard-coding everything
Make the day/night cycle for weather data look better - have a night sky during night time, create night versions of weather sprites with a moon instead of a sun, etc.
Have the price cards actually turn red when prices go down (which is a lot)
Get partial display updates working, so I can update the clock every 5 minutes and update the other stats every 15 minutes
Add a “daily Kanji character” card for showing a Kanji character, stroke order, and meaning, every day. My friend is a weeb, he’ll appreciate it.
Wrap everything up into a Nix flake with outputs for both the package and system configuration, to generate pre-configured disk images ready to burn to an SD card.
Write enough documentation that people can build their own without relying on me or understanding the code.
Make a web configurator - rather than requiring users to SSH into the pi to change configuration, create a basic web UI for configuring and reordering cards, and run a webserver on the device
I have a neat idea for generating some sprite scenery based on the last week of weather - make some sprites for trees, grass, flowers, rain, snow, etc, and simulate a little environment that piles up snow and melts based on the weather and the current season. That’s probably a whole devember project on its own, maybe next year…
3D print a case for it
The code is currently kept on my gitlab instance, here. Maybe I’ll push it to the official gitlab instance, maybe not, we’ll see.
I wound up writing my own display driver for the EPD 5.65" displays, because the one waveshare ships is terribly slow. For instance, it sends pixels one byte at a time, when SPI can handle sending the entire buffer at once. On a low-power Raspberry Pi Zero, I was able to cut down the process of sending an image from 50 seconds to 5 seconds.
I haven’t touched partial updates since last August, but I almost got them working. No guarantee my current implementation works, but it should be close. You can see my implementation for partial updates here, but in short, I just have to set the window mode for the SPD1656 chip controlling the display before uploading the buffer.
It shouldn’t be too hard to cut out my display driver as a standalone thing, that might be worth releasing on its own.
Haha, I just got used to it, and accepted just updating it once every 5 minutes. After a few days, I stopped noticing it in my peripheral. That long update time is why I want to try getting partial updates properly integrated, so I can update the clock more regularly than everything else.
For a while I did experiment with flashing custom LUTs to the display for fast refreshes. I found some very basic documentation on the SPD chip (it’s in my repo, in the docs folder) for how the LUT works (it’s basically a state machine), and there was a project on Hackaday with some great research into it, but I was never able to do anything other than display garbage. As it turns out, epaper is really complicated, and temperature sensitive!
Oh, cool! I’ll have to read that hackaday post later.
If you haven’t seen it yet, Ben from Applied Science has a video where he got some pretty impressive results with the greyscale and 3-color panels:
I’m not surpised about waveshare’s code. The arduino examples only support the Uno, and nothing else. I had to rewrite a lot of their code to make SPI work on the ESP32, Teensy, and Pico. I may try and tidy that up into its own library in the future.
I think that since your code is significantly faster, you should definitely release it as a python library. I think more people would enjoy developing with these things if they had a quicker update cycle.
I’ve finished some non-visible items on my TODO list.
I wrote a card layout manager, so much like a layout manager for any other UI kit, I can add cards with either an explicit size (in y pixels) or a given number of x/y shares. Once all the explicitly sized rows are taken into account, the remaining space is divvied up between the remaining rows depending on how many shares they take.
I added a configuration generating / loading utility. Cards can now generate a config based on their current setup, and be deserialized from a config. Thanks to some very light recursive magic, the entire runtime config (current display type, update frequency, cards, layout) is described in a single .json object. Configs are now saved as .json files in ~/.config/worldmon.
Added day/night for the weather card. See my pictures below. Each night, a different starfield is generated, with variously sized white, yellow, and red stars. On about 15% of nights, at least one black hole is spawned as well, which you can see in my close-up photo. I still have more I want to add to the day/night cycle, but this is a good start.