One of the funniest parts of building a custom Pip-Boy clock is that the hard part is not always the hardware.

Sometimes the hard part is making a tiny thing feel civilized.

The clock itself was already working. The screen rendered the Pip-Boy UI, the buttons were alive, and the time could be updated over Bluetooth. But the actual sync flow was still stuck in “developer tool mode”:

  • reboot the device
  • open nRF Connect
  • find the right BLE service
  • find the right characteristic
  • remember the time format
  • send the payload
  • hope the device answers before the ePaper refresh finishes

That was fine for bring-up. It was not fine for a device I actually wanted to use.

So I changed the goal.

I did not want to build a full Android app yet. I just wanted a better way to tell the Pip-Boy what time it was.

The problem with the “works on my phone” version

At first, the BLE part looked finished.

The Pip-Boy exposed a Nordic UART service. My Samsung phone could connect. The firmware could parse a timestamp and update the internal clock. The display even refreshed with the new time.

And still, the whole thing felt awkward.

nRF Connect is excellent when you are debugging Bluetooth.

It is terrible when you are pretending to be a normal human being.

The flow had too much friction:

  • the UI is meant for diagnostics, not daily use
  • the payload format was easy to forget
  • you had to do too much manual tapping
  • the device sometimes updated the screen so slowly that the phone did not receive the confirmation message in time

That last bug was especially funny. The Pip-Boy would actually sync the clock correctly, but the web side would still say the sync failed because the quad-color ePaper refresh took long enough to delay the confirmation.

That was a good reminder that on a slow display, even “send OK after success” needs thought.

The shape of the better solution

The version I actually wanted looked like this:

  1. Turn on the Pip-Boy or tap reset.
  2. Open a web page on the phone.
  3. Press one button.
  4. Pick PipBoyClock from the Bluetooth chooser.
  5. Let the page sync the current phone time automatically.
  6. Disconnect cleanly and go away.

No app install. No manual timestamp typing. No BLE inspector UI.

That meant using Web Bluetooth instead of a dedicated Android app.

It is not the final answer for everything. It still depends on a supported browser and a manual connection prompt. But for this stage of the project, it is a much better tradeoff:

  • no app to maintain
  • no extra packaging work
  • no learning curve for the sync tool
  • works well on Android with Chrome

A small page is enough

The sync page now lives on zinchuk.online under /pipboy-sync.

It does a very small job:

  • requests a BLE device named PipBoyClock
  • connects to the Nordic UART service
  • turns the phone’s local time into the payload format the firmware expects
  • sends that payload
  • waits for an OK ... response from the Pip-Boy
  • disconnects automatically

That is it.

This is exactly the kind of task that benefits from being tiny. A complicated page would not make the device feel more polished. It would just create a second project.

Making the firmware cooperate

The page alone was not enough. The firmware needed a few UX-minded changes too.

The first improvement was making BLE available automatically for a short window after boot or reset.

Before that, I had to open a settings screen on the ePaper device just to enable Bluetooth. On a display that can take around 15 seconds for a full refresh, that is a bad bargain.

So now the Pip-Boy:

  • enables BLE automatically on startup
  • advertises for a short time window
  • lets the phone connect and sync
  • turns BLE back off if nobody connects

That feels much closer to a real tool. Reset the device, sync the time, move on.

The second improvement was moving the BLE confirmation earlier in the firmware flow.

Originally, the code updated the time, started the slow ePaper redraw, and only then tried to answer the phone. That meant the browser sometimes gave up waiting even though the clock had already changed.

The fix was simple and very satisfying:

  • apply the new time
  • send OK ... over BLE immediately
  • redraw the ePaper after that

The display can take its time. The phone just needs a prompt answer.

Why this feels better than a companion app, at least for now

I may still build a proper Android companion app later.

That would open the door to smarter features:

  • automatic time sync on reconnect
  • timezone-aware behavior while traveling
  • richer status reporting
  • maybe even simple settings management

But right now the browser page is the right level of ambition.

The Pip-Boy is still a broader project:

  • battery behavior is still being tuned
  • low-power behavior still needs more work
  • the case is not designed yet
  • the time system itself still needs stronger persistence across reboot

Adding a whole mobile app too early would only make the stack heavier.

The web page solved the real user problem without dragging in a second product.

The nice part

The nicest outcome here is not technical.

It is that the Pip-Boy now has a sync flow that matches the spirit of the object better.

It no longer feels like a dev board waiting for a serial monitor.

It feels more like a small standalone device that has one maintenance ritual:

  • wake it up
  • give it the current time
  • let it go back to being a weird little Fallout thing on your wrist

That is the kind of progress I like most in projects like this. Not just “feature added,” but “interaction became more believable.”

And as a bonus, it removed the one step I knew I would never want to explain to anyone else:

“Open this BLE debugging app and manually type an ISO timestamp into the right characteristic.”

No thanks.

At the end of all this, the Pip-Boy got to keep the Fallout Boy screen too:

Fallout Boy bitmap rendered from the firmware asset