Low-Power Microcontroller Applications in Smartwatches

Introduction

The main motivation behind this project was to see how much hardware and software I could cram into a small, watch-like device. I chose an OLED display because it’s only 1.5mm thick, doesn’t require a backlight, and each pixel emits its own light, making it look really cool. Initially, I planned to use a 0.96-inch display, but it turned out to be too small to fit all the components I wanted. Increasing the size to 1.3 inches proved to be the perfect solution.

https://youtube.com/watch?v=KrUJlZK1ct0

Hardware

The hardware components of this watch include an Atmel ATmega328P microcontroller, a 2.5V voltage regulator, a Maxim DS3231M RTC, a 1.3-inch 128×64 monochrome OLED, 2 LEDs (red and green), a buzzer, a 3-route navigation switch, powered by a 150mAh LiPo battery, and charged via USB and 2 PCBs.

The microcontroller ATmega328P uses its internal 8MHz oscillator and runs at 2.5V. It consumes approximately 1.5mA in active mode and 100nA in sleep mode.

The DS3231M RTC is a high-precision clock chip with a small 8-pin package, including a built-in temperature-compensated MEMS resonator, with an accuracy of ±5ppm (±2 minutes 40 seconds per year). The RTC is connected in a way that the power is not applied to the VCC pin, but to the Vbat pin, reducing its current consumption from approximately 100uA to 2.5uA.

The battery charging circuit uses Microchip MCP73832 to achieve load sharing, allowing the battery to charge without interference from other parts of the watch.

The LEDs are connected directly to the microcontroller without any resistors. The microcontroller’s internal MOSFET has a conduction resistance of approximately 40Ω, so when the power voltage is 2.5V and the LED is 2Vf, approximately 12.5mA of current flows through the LED.

Since the microcontroller runs at 2.5V, the battery voltage needs to be slightly reduced to obtain an ADC reading. This can be achieved with a simple voltage divider. However, when the voltage divider is connected to the battery, approximately 350uA of current constantly flows through it, wasting a lot of power. A P-MOSFET was added to turn on the voltage divider only when needed.

The 2.5V voltage regulator used is the Torex XC6206, mainly because its static current is only 1uA. I chose a linear voltage regulator over a switching voltage regulator because switching voltage regulators have low efficiency at low loads. The 2.5V linear voltage regulator has an efficiency of 60% at 4.2V input and 83% at 3V input.

Software

With a beautiful OLED display and 32KB of program space, we can certainly do more than just display the time and date, right?

Animations are ubiquitous

we spent a lot of time optimizing the rendering code. In short, it’s about copying bitmap images from flash memory to the RAM-based frame buffer and then sending the frame buffer to the OLED via SPI. The final result is that almost all areas of the watch can maintain a smooth 100+ FPS using an 8MHz AVR. However, to conserve power, the frame rate is limited to 60FPS.

We also implemented some major animation effects, such as:

  • A CRT animation when entering and exiting sleep mode, similar to some Android smartphones.
  • A rolling effect for the main time digits, providing a visually pleasing experience.
  • A scrolling animation for the menu, where selecting an option causes the current menu to fall off the screen and the next menu to fall into place, providing a smooth user experience.

Alarms

  • Set up to 10 alarm times.
    Number of alarm times is only limited by the amount of available EEPROM
  • Each alarm has the hour, minute and which days of the week it should be active on.
Alarms menu

Games

Apps

Plenty of options

  • 3 Channel volume control
    • UI
    • Alarms
    • Hour beeps
  • Sleep timeout
  • Display brightness
  • Animations
    You’re not going to turn them off, right?
Volume settings

Power saving

The microcontroller has two low-power modes: active mode and sleep mode.

In active mode, the microcontroller tries to enter idle sleep state as much as possible. In idle sleep state, it wakes up every millisecond to check if any updates are needed. If not, it returns to idle sleep state. This usually takes less than 100 microseconds. In this mode, the current consumption is between 0.8mA and 2mA, depending on the time required for frame rendering.

In sleep mode, the microcontroller shuts down the OLED and enters power-down sleep mode, and can only be woken up by pressing a button, an RTC alarm, or inserting a USB. In this state, the microcontroller’s current consumption is approximately 100nA. This is a very low-power mode, suitable for scenarios where no operation is required for a long time.

Power Consumption

In sleep mode the overall current draw of the watch is around 6uA. In active mode the current draw can vary from 2mA to over 70mA, though 10mA is the typical current draw.

Battery life in various modes
Battery capacity: 150mAh

Minimum
(sleep mode)
Typical
(main time display)
High
(flashlight)
6uA
2.85 years
10mA
15 hours
64mA
2 hours, 20 minutes

If the watch is in active mode for an average of 1 minute per day (with a 5 second sleep timeout that would be checking the time 12 times a day) and all volume channels set to minimum the watch should last for around 1 year and 4 months on a single charge.

Current draw breakdown (typical):

PartCurrent
ATmega328P (sleep / active)100nA / 1.5mA
OLED (sleep / active)500nA / 8.5mA
DS3231M RTC2.5uA
Schottky diode (D1) (reverse leakage)1uA
Regulator (quiescent current)1uA
Other (MOSFET and capacitor leakage etc)1uA
Total (sleep / active)6.1uA / 10mA

v1 to v1.1 changes

The first version had a few problems:

  • Added level conversion for the ADC P-MOSFET.
    Without level conversion the P-MOSFET was always stuck on. To turn of the P-MOSFET off the gate voltage needs to be at around the same level as its source voltage (which is connected to the battery), but the microcontroller was only providing 2.5V.
  • Added a gate pull-down resistor for the MOSFET driving the sounder.
    The MOSFET gate was floating when the microcontroller was being programmed which was causing the MOSFET to turn on and allow non-pulsed current to flow through the sounder, which probably wasn’t good for it.
  • Larger solder pads for MicroUSB connector.
    Normally SMD MicroUSB connectors have solder tabs at the sides and should have extra solder pads underneath, but since this is soldered by hand the underneath is unreachable. With out the extra solder pads the USB connector was wobbly so some of the connector pins eventually broke their solder joints. To fix this issue I enlarged the side solder pads so that the connector can be soldered all along its side instead of just the tab. No more wobbly connectors.

Other Problems

Out of 3 OLED displays, 2 died after a few minutes of being attached to the watch. One from Ebay and the other from AliExpress. I’m still not sure why they died, maybe just China quality? The one that worked was also from Ebay.

Future Improvements

  • Programming via USB.
    At the moment 4 wires need to be poked into the board (SPI programming) and then hope they don’t fall out while programming.
  • Add a fuel gauge IC.
    At the moment the battery level is determined by its voltage, this isn’t a very accurate method of getting the remaining battery charge.
  • Different microcontroller.
    The current firmware is using ~28KB out of the 32KB of available program space in the ATmega328P, a different microcontroller with more program space and probably more RAM would be needed to add more things like a calculator (floating point stuff eats up a lot of program space). However, the ATmega328P has the most program space for an AVR in a 32 pin TQFP package, to have more program space I would have to use a 44 pin AVR. The ATmega1284 looks interesting.
  • Switching regulator, charge pump regulator or maybe a hybrid solution?
    The linear regulator in use at the moment isn’t particularly efficient and switching regulators don’t seem to be very good with low current draw. Perhaps a charge pump regulator or a hybrid solution to swap between a linear regulator for sleep mode and a switching regulator for active mode?
  • A case of some sort?

Sources available at GitHub

Parts List

SchematicPart/valueDescriptionQuantity
U1Atmel ATmega328PMicrocontroller1
U3MCP73832Lithium battery charger IC1
U4XC6206P252MR2.5V LDO Regulator1
U2DS3231MZ+RTC1
Q1, Q2DMP1045UP-MOSFET2
Q3, Q4DMG6968UN-MOSFET2
D1ZLLS410Schottky diode1
D2TS4148High speed diode1
C54.7nFCapacitor1
C4, C6, C7100nFCapacitor3
C3, C8, C9, C101uFCapacitor4
C122.2uFCapacitor1
C1, C2, C114.7uFCapacitor3
R4, R8, R10100RResistor3
R62.7KResistor1
R57.5KResistor1
R710KResistor1
R122KResistor1
R2, R3, R1147KResistor3
R9390KResistor1
RN110K networkResistor network (4x resistors)1
LED1LED (green)LED1
LED2LED (red)LED1
LS1SounderMagnetic sounder1
SW13 Way navigation switch1
MicroUSB connector (Ebay)1
OLED1OLED (Ebay / AliExpress)1
Battery (Ebay)1
Main PCB1
Display raiser PCB1
Watch strapG10 NATO 22mm1

Featured at
AtmelHackADay,Electronics Labadafruit

Water proof down to 0m!