I've been working on the watch a fair amount, but I realized I've been bad about project logs. So here's a sort of omnibus update:
Highlights
- I've been wearing the watch daily for the last two weeks. Aside from plugging it into the computer to program and debug it, I haven't charged it. The battery reports 58% / 3.9V, and appears to be losing somewhere around 4% per day. Bluetooth is currently not active, so the power draw is primarily from the MCU waking up to redraw the screen once / second, plus the quiescent current of the components and occasional use of the backlight and flashlight.
Mechanical
- The biggest mechanical issue I've had is best evidenced in a picture:
That's me, having just washed my hands. The cloudiness you see is not, unfortunately, a trick of the light, but a bit of water that got in (presumably through the flashlight hole) and stuck between the acrylic protector and the screen. Luckily this didn't damage anything, and eventually it cleared up on its own. It did, however, demonstrate the need for something a little more robust than a hole with an LED poking out.
Adding a small protrusion for the light turned out not to impact the aesthetics nearly as much as I'd expected. I cut a small circle of clear acrylic and sealed it into the hole with a healthy drip of superglue, and I haven't had water issues on that side since. I do occasionally get a bit of water seeping in around the white button bar on the other side of the watch if I'm not careful, so the next revision of the case will likely include a better buffer there (or perhaps just make the TPU fit more snugly to keep water out). I don't need the watch to be fully submersible or waterproof, but it needs to be able to stand up to handwashing without damage.
Thermal
- This definitely could have gone in a different section, but I didn't want to pass up the opportunity to have a "thermal" update. In a previous revision, running the flashlight LED for more than 15 seconds or so melted the solder joint on its current-limiting resistor. I'm not sure what I did differently this time (maybe there was a short in that revision?), but I can run the flashlight for a minute or more without any noticeable thermal effects. It's still plenty bright, and extremely useful to have on hand (pun intended).
Electrical
- No changes to the electronics in a while, except for moving everything over to a new PCB (same revision) when I finally tracked down an issue to a trace that I'd inadvertently cut at some point.
- As I've started implementing a real UI (see below), I've noticed that I need debouncing caps on the buttons. The bounce I'm seeing isn't awful, so this is a "when I do the next rev" change rather than a "why I do the next rev" change.
- The vibration motor isn't working in the version of the watch I'm wearing. It's worked in previous iterations, so I think there must be a short. I'm away from my bench this week, but I'll investigate more at some point.
Bootloader
- I hadn't updated the bootloader in a long while, but I noticed in the latest release of the Adafruit nRF52 bootloader, they fixed a bug that reportedly caused firmware updates to fail sometimes. That's a behavior I've seen a fair amount, but not at all since I updated :)
- I'm considering abandoning my custom fork of the Adafruit bootloader (no code changes other than a custom board definition) and instead using the stock version with some compiler directives to change the USB name and ID. More on that if I do it, but it's low priority since USB ID is really just a vanity thing.
Firmware
- I've started developing a UI framework for the watch. The core concept is the idea of a "view". From the code comment:
/* * Views are the primary UI structure. A view is a bit like an "app" on a * smartphone. The active view's draw() method is called (by the system * controller object) when the screen updates, and when user events happen (like * button presses), the active view handles them. * * Inactive views still get their update method called, but they are not drawn. * * Views can create child views, then add them with sys->switchToNewView() * The system is responsible for `delete`ing views when they exit. */
(I will note I haven't actually done anything with the `update()` but yet, and may remove it. We'll see.)
A good example of a View is WatchFace, which is the "home" view (it, unsurprisingly, shows the time and date). Near the bottom of that file is a hacked-together main menu view, which is created and drawn when one of the buttons is pressed from the watch face. Menu is its own view type, and I'm making heavy use of C++ lambdas to populate it. I'm sure I won't regret this at all, and it won't come back to bite me. Various menus will probably eventually be encapsulated in their own source files (and thus maybe use statically-defined functions rather than lambdas), but this is fine for now.
I'm pretty happy with the concept of views and the "View Stack" (exactly what it sounds like), which should give me enough of a framework to be useful without constraining what I can do when I start getting BLE notifications.
- To make views work, I've basically implemented my own event handling and dispatch system. It seems to work fine, except that button press events (which are currently the only kind) are handled within ISRs. This so far hasn't been a problem, but it does somewhat limit what I can do on a button press. I will probably eventually move to deferred interrupt handling, but not until I have to.
- I've started working on BLE, using an nrf52840 dev board and my android phone rather than flash unknown code onto my wrist. It's going well, but nothing worth putting on the watch yet. I'm learning more than I ever wanted to know about BLE and HID, though. Specifically, it seems as though android forces a relatively quick connection interval when your peripheral device uses an HID profile. I'd hoped to use HID Consumer Keys for play/pause and similar, but since a small connection interval means more wakeups and more transmit power, I think I'll likely abandon HID and do play/pause using a companion app. I would still like to have the ability to turn on HID, to use the watch as a "clicker" to advance slides, so I'll need to investigate that more.
- I'm very curious to see what BLE does to my battery life. Roughly 4% of the 500mAh battery used per day translates to an average current draw of ( (0.04*0.5) / 24) = 833uA which is.... fine? This is a very coarse estimate and I'll do more power profiling once I have a featureset worth optimizing, but I am hoping to get the draw down to at most half that.... and I still have to add in BLE rx/tx. I'm also curious how much is the flashlight/backlight; if my math is right, running the flashlight draws about 1.25A, and even 30 seconds of that per day would account for half of my estimated draw. We'll see, I suppose.
I'll try to post more frequent updates as time and life allow. Thanks for all the comments and suggestions; keep them coming!
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
Glad to hear the water didn't manage to fry anything! I've been casually glancing at some sealed button solutions, but there's a pretty short list at this form factor. I'm aware most G-Shocks have little o-rings around each button pushrod that seem to do the job. Maybe you could include something similar.
I have immense jealousy for your hardware progress. I need to put the time in and get a pcb together for my design so I can get to the fun casing stuff you're working through now. Best of luck!
Are you sure? yes | no
Thanks for the kind words! It's hard to conceptualize how to put an o ring around a soft piece (the white bar is TPU), but I think I should be able to work something out.
As for the hardware: I've been locked in to a particular PCB form factor for quite a while because of the shape of my display; I've been able to iterate on the case somewhat independently because I know that there's very limited wiggle room in the shape of the board. The initial schematic was largely copied from an existing board (I think the sparkfun nrf52840 one) with stuff added to the i2c and spi busses, so that was a great way to hit the ground running.
Are you sure? yes | no