www.makeworld.space

Wordle on the Badger 2040

Mar 24th, 2022
by makeworld

photo of badger 2040 with completed wordle game

When I first saw the Badger 2040 on Hacker News, I knew I had to get it. It seemed like a great little package to hack on, with an e-ink screen, buttons, and an LED, all for a good price. And finally I’d get my hands on an RP2040, which has interested me since it first came out.

Development

The development experience on the Badger 2040 is really fantastic, and great for beginners. As someone who’s only experienced embedded development from the side of firmware loading and C++, this was a welcome change. Here’s how I add a feature to some code on the Badger 2040:

  1. Plug it in
  2. Open Thonny
  3. Open the main.py file (or any other file on the device) from within Thonny
  4. Change the code
  5. Press the Run button in Thonny and watch the Badger reset instantly and load my new code
  6. Unplug the Badger once I’m satisfied with my changes

It’s super simple and fast, and makes for really efficient development cycles. Combine this with MicroPython, and overall writing code for the Badger is really fun and fast, which is exactly what I want for a hobby project. 😁

See the getting started guide for more about coding on the Badger 2040.

Wordle

Although the Badger is designed to be used as a badge, I’m not going to a conference any time soon. So I decided to make a project that subverted things a little bit. The obvious choice was Wordle, which seems to be the project du jour. As someone who plays Wordle on the computer, I was excited to create a portable Wordle-playing device. Sure phones exist, but playing on e-ink is way cooler!

Here’s a demo video. Note I’m using my Badger on its side, the marketed orientation is landscape.

This input method obviously has some limitations, but it’s not as tedious as I thought it would be. It takes longer to enter, but in my experience not so much longer that it’s annoying to use.

You can play as many games as you like. With no RTC or Wi-Fi support, there was no way to keep track of the what day it was anyway, so I figured I might as well turn it into a feature.

I was impressed with the update speed. There are a variety of options, and the fastest one (UPDATE_TURBO) is really quite fast, and works well for scrolling through letters. There is definitely some ghosting (although it looks worse in the video than in person), but that goes away after a slightly longer update when moving to the next cell.

Words

For word data, I extracted the two wordlists from the original Wordle javascript: the list of winning words and the list of all five-letter English words. With some grep, sed, and Python, I converted these into two text files, where words were stored concatenated. Since they’re all 5 bytes long, there’s no need for any separator.

Strangely, the winning words were missing from the total wordlist, so I added them back in and resorted the list, before saving to a text file. In total the two files were 76,405 bytes (~75 KiB), but the Badger has lots of flash space so I didn’t need to apply any compression.

To load the files on to the Badger, all I had to do was upload them to the filesystem through Thonny. Having a native filesystem makes loading data like this a breeze. And I can read data from the files just like I would with regular Python, using open() and .read(). This is a big difference from what I’m used to with embedded development, where I’d have to put the data in a variable in some header file somewhere, or use some sort of preprocessor that would add in the data.

I also ended up having to implement a binary search, which I used to check if the word submitted for that row was actually a valid word. Another fun part of embedded developement: getting back to basics!

Improvements

There are a few improvements I’d like to make to the project. One abstract improvement would be to improve the UX/UI – making it easier to tell which cell you’re currently working on, for example, and/or highlighting the current row.

I’d also like to switch to using partial updates instead of fullscreen updates where possible. I don’t think these are any faster, but it would make for a less jarring effect than the whole screen flashing in front of you. Unfortunately for some reason the Y and height of the update region both have to be a multiple of 8, so it’s not as simple as just updating the area that changed.

Badger library

Python documentation for the Badger 2040 is available here.

The dev seems to be on top of things and responded very quickly to my issues, so that was great. Overall the API is good, I was impressed to see things like decimal text scaling and arbitrary text rotation. But it would be nice to have the ability to provide your own custom font, like Adafruit display libs allow. The fonts provided are nice, but none of them are monospace, for example. And they all seem to be converted from vector fonts. Using a bitmap font, where pixels are hand-chosen for a specific size, would provide much cleaner glyphs, at the expense of decimal scaling of course.

Conclusion

I had a lot of fun working on this simple self-contained project, and was happy to fully complete a personal project. Thanks to Pimoroni for creating this product! I hope to see people doing cool things with the Badger 2040 in the future as more people get their hands on them, I think they have a lot of potential.

Code is available on GitHub here.

Thanks for reading!