My 2018 new year’s resolution was to learn difficult things.
I wanted to focus on learning things that are difficult to learn, push myself toward more facility with complex math and computer science. I’ve been spending a lot of time bashing my head against robotics, machine learning, and computer vision. It has been worthwhile and interesting. And hard.
But I needed a break. I wanted to learn something easy. Easy things are fun to learn, there is so much immediate progress. And, of course, easy for me is not easy for everyone. Arduino was easy for me but crocheting has not been (yes, I know you found it trivial and all I need to do is this than that then this again but, hey, look! An Arduino!).
I wanted to do something that didn’t involve brain-bending linear algebra, calculus, and 3D trigonometry. My husband (and Fitbit employee) Chris suggested I make a watch face for the Fitbit Versa that I stole from his work desk. I envisioned a jellyfish that lived on my wrist, softly drifting up (away from gravity). Perhaps my step count could influence the size (or number?) of the jellyfish.
He suggested something simpler. I decided that I’d have the time appear and then run Conway’s Game of Life on the pixels.
I went to dev.fitbit.com and logged in with Fitbit user credentials. They had examples, none of which were quite relevant but they were nice enough. I clicked over to Fitbit Studio, their development system, a web-based IDE. It had me create a new project, giving examples to start with. I based my new project on a clock face. I immediately wanted to see if it would run so I had to follow the steps in the Getting Started Guide. (Ok, Chris helped me through this but the guide actually gives you the steps in order.)
It was pretty fast to set up, easy to change background colors and plenty of examples. But then I wanted to read the pixels set by the time. Sadly, if that is possible, we couldn’t figure it out (Chris says it is not possible).
In Fitbit Studio, in my resources/index.gui XML file, I added a whole bunch of rectangle objects. These were going to be my conway-pixels. This was a bit of a pain, listing them all but that is one use for Python (or Excel). Also, there might have been a better way, but listing them out one by one was the way I did it. I did eventually make their location on the screen programmatic, along with their height and width so they were square and non-overlapping, covering the screen in a grid.
With some tweaking and fussing, I got the Conway code running. It ran very, very, very slowly. Really slowly. (Of course, it ran fine in the easy-to-use simulator.) I commented out different parts of my code to figure out where the slowdown was: for loops. The Versa screen is 300x300 pixels. With my conway-pixels at 10x10 of the Versa’s pixels, I had a grid of 30x30 conway-pixels. The watch wasn’t happy with that. I switched from 900 conway-pixels to 100 conway-pixels and did some cheating/optimization of the algorithm so I only had to pass through the loop a single time. And it worked. Well, mostly worked: given some pixels on the screen it would play Conway's game of life.
I got the fonts and font processing working. My fonts were 3 pixels wide and 5 pixels high, a little tight for a 10x10 conway-pixel screen. I made it work, almost legibly (but not really). Switching my rectangles to slightly overlapping circles gave me a retro-future look I liked.
The whole time I’m fussing with the code, I’m also testing, switching from my watch to the simulator and back again. That part was pretty easy. Well, it was pretty easy once I switched from the Build Output window to the Console output which showed me the runtime errors (so many typos!). And then I learned to used the console.log() for debug printing. Note: It was critical to use them sparingly when I was running on the watch, my system was slow enough just running Conway, adding printing did not help.
Eventually, I was happy with the way the time displayed and then dissolved into a Conway game using the time as the initial seed. I decided I was done enough to share it with Chris. I pressed Publish in Fitbit Studio which unexpectedly downloaded a file in my browser. A few minutes of searching in their forums led me to look on the Gallery Apps Manager site which seemed to take the file the Publish button downloaded. And then poof, I had a URL for my little Conway clock face.
It seemed like I was done. Of course, I wasn’t. There were bugs to fix and optimizations to do. Writing this up and cleaning up the code took more time than writing the initial version, probably because I found bugs and got irritated at the lagginess of trying to use other parts of my Versa. I found that the slowest part of my code was simply the for loops traversing the Conway cells. I’ve given up trying to fix it.
The Fitbit examples are good. Their documentation is ok… the information is there but difficult to understand except in retrospect. Their forums are awesome. If you don’t have your own Chris, maybe log into their Discord channel so you can get some hand-holding in the beginning.
There is so much more I could do with this (or you can, my code is open). My usual watch face updates the background with my steps/goal so I can see how close I am to my goal by how much of my watch face is blue vs. black. I could add heart rate or battery level on the face. I really should add a settings module so you can set your background to a color you like. I could put on a jellyfish that floats.
However, my goal was to learn how to make a Versa watch face. It wasn’t trivially easy but as I look at the trig and linear algebra I need to do to get to my next robotics lesson, well, it was pretty easy. Anything that takes less than ten-ish hours of learning seems sorta easy right now.