A project log for Chronio

Low power Arduino based (smart)watch

maxkMax.K 09/04/2016 at 16:560 Comments


The first step is burning the bootloader onto the Atmega328. I included some testpoints for the ISP pins, so it was just a matter of following the instructions on this site:

After this, the Atmega can be programmed using the serial interface. Including power, 5 pins are needed: TX, RX, Reset, Ground and VCC. The first version of my PCB simply had the footprint for a pin header on it, so I just soldered wires to it. For the later versions I wanted a proper adapter that can be connected to the PCB without soldering.

The interface on the PCB consists of 5 smd pads for the actual signals and two vias for centering the adapter. This design is based on the Protoprog: The adapter uses a 3D-printed part with pogo-pins. On the other end it has a pin header that can be plugged into a breadboard. Because I had trouble with the printed part, I ordered a tiny adapter board from OSH park. On the breadboard I used a simple level converter (CD74HC4050E), so the 3.3V components are not damaged by the 5V Arduino Uno that I am using to program the board.

Arduino Code

Clocked at 16 MHz, the ATmega328 consumes more than 3mA. This will drain a button cell in a matter of hours. Luckily there is a 100nA sleep mode. In this mode the Atmega is basically turned off and can only be activated again with external interrupts. One of the two available interrupts is connected to a dedicated pin on the DS3231 real time clock. The clock is programmed to generate a pulse once per minute. This makes it possible to only turn on the uC for a short period of time to update the time and display. The display itself is controlled over the SPI interface. I am using the adafruit gfx library, which has very nice functions for basic geometry and text:

To wake up the watch intentionally, the middle button is connected to the second hardware interrupt. The debouncing is handled by a library as well (

The user interface is organized in pages. The main screen is page 0, the menu page 1 and so on. The currently implemented features are a stopwatch, a menu for setting the time, a debug menu and a flappy-bird game.

The always-on watchface displays the time in big digits. Instead of using a font from the adafruit library, I wanted to create a custom font. It combines rectangles to create the digits and is easily readable even from a distance. Besides time and date the watchface show the temperature. This is done by reading the internal temperature sensor in the DS3231. Additionally ther battery voltage is displayed. For this, I am using the internal voltage reference of the Atmega. Most of the code is copied from here: On a lithium battery you get a very non-linear discharge curve. It should be useful as a low-battery-warning though.