# OV-Watch: an STM32F411 smartwatch you build yourself

> OV-Watch is a GPL-3.0 smartwatch firmware and hardware project built on an STM32F411CEU6, FreeRTOS and LVGL 8.2. It is aimed at people who want to solder the board and then read or change the C code, not at anyone shopping for a finished watch.

**No-Chicken/OV-Watch** — A powerful Smart Watch based on STM32, FreeRTOS, LVGL.

- Repository: https://github.com/No-Chicken/OV-Watch
- Website: https://www.bilibili.com/video/BV1hh4y1J7TS/
- Stars: 2,522 · Forks: 348
- Language: C
- License: GPL-3.0
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/no-chicken-ov-watch

## What OV-Watch actually is, and who it is for

OV-Watch is a smartwatch you make rather than buy. The repository holds three separate things: Hardware, the board design; 3D Modle, the printed parts; and Software plus Firmware, the C code. The MCU is an STM32F411CEU6, the operating system is FreeRTOS, and the interface is drawn with LVGL v8.2. The licence is GPL-3.0, so the whole thing is source-available and copyleft. The README points readers to https://no-chicken.com for the manual and to a Bilibili video for the demonstration. The last push to the repository was on 2026-05-26, and the most recent tagged release is v2.4.3 from 2024-09-10, so the release cadence is roughly a few tags per year rather than continuous churn. This is a project for someone who owns a soldering iron and a debug probe and wants to read the C behind a wearable. It is not a product with a support channel, and the README does not describe one.

## Three power modes and the RTC wake-up trick

The README splits behaviour into three modes. In normal running the watch is fully on. In sleep, the MCU enters STOP mode while the MPU6050 keeps counting steps. In shutdown, the TPS63020 enable is turned off, so there is no 3V3 rail and only Vbat keeps the RTC alive. The interesting part is how the watch wakes. The author first tried the MPU6050 motion interrupt and found that it needed a large shake to fire, so the design switched to an RTC periodic interrupt that polls the current gesture state and wakes on a wrist-raise. That is a real trade-off: a timer poll costs a small amount of current continuously, but it gives predictable latency, whereas the hardware interrupt is cheaper but unreliable for subtle motion. The README also notes that the MPU6050 cannot simply use the DMP library because initialisation leaves power draw too high, so the code modifies it. Power figures quoted in the README are 70 to 80 mA running, about 1 mA standby, and near zero in shutdown with only the RTC active, all measured on the 3V3 rail. The author explicitly says the Vbat path through the DCDC was not measured, so those numbers do not predict battery life on a finished build.

## Heart rate, storage, and what is missing

The heart rate feature does not use the vendor library. The README says the official library was too slow, so the project replaced it with a simple peak-detection algorithm over the EM7028 PPG signal, with a measurement curve shown in the images folder. That is a reasonable call for a small MCU, but peak detection over PPG is sensitive to motion, and the README does not describe filtering or a motion-compensation path. Blood oxygen is simply not implemented; the README states the SpO2 section has not been written. Settings and similar data go to an external EEPROM, handled in Datasave.c. Anyone expecting a medically meaningful heart rate reading should treat this as a signal-processing exercise rather than a measurement device.

## Page navigation via a screen stack

Screen switching keeps a stack of page pointers so the back action can return to the previous screen. The README warns about a specific trap: you cannot push something like ui_HomePage directly, because the symbol's value changes at runtime, and it says this was a significant pitfall. The example pushes the address of the pointer instead. This is the kind of detail that costs an afternoon if you discover it yourself. The calculator follows the classic two-stack algorithm, one stack of operands and one of operators, described step by step in the README: push operands, compare operator precedence against the stack top, and reduce when the incoming operator is lower or equal. The README notes that the animation only covers integer arithmetic and that decimal handling lives in the code, which is a fair warning that the written description is incomplete.

## Flashing OV-Watch: use the prebuilt firmware first

The README is direct about this: use the firmware already in the Firmware folder rather than building it yourself, because compiling and downloading has its own caveats. The Software folder holds two Keil projects, the Bootloader and the APP. The step-by-step instructions live in Firmware/README.md, which is where the address offsets and download order are documented. If the Bootloader split in v2.4.0 feels like too much, the README suggests the ver2.3.2 branch, which predates it, or changing the APP address offset yourself. Start by cloning and reading the flashing notes before touching a probe.

```bash
git clone https://github.com/No-Chicken/OV-Watch.git
cd OV-Watch
ls Firmware Software
```

You should see the Firmware directory containing the release binaries and its own README, and Software containing the two Keil projects. Read Firmware/README.md before flashing anything, because the Bootloader and APP must be written in the right order at the right offsets.

If you want to change the UI without hardware, the repository includes lv_sim_vscode_win, a prepared LVGL simulator project for VS Code on Windows. The README says you should adjust the configured paths and then open it; the referenced blog post describes the setup. The porting rule is that UI work happens in the simulator, then the Func and GUI_App folders are copied into the User folder of the Keil project. A middle layer, HWDataAccess.c, isolates hardware access, and setting HW_USE_HARDWARE to 0 makes the same code run in simulation.

```c
#define HW_USE_HARDWARE 0
```

With that set to 0, the UI code compiles against the simulator rather than the board, which is the workflow the README intends for anyone editing screens.

## Bluetooth, IAP, and the hardware revision that enabled them

Version 2.4.0 changed the Back board so the Bluetooth enable circuit can actually cut power. Before that, Bluetooth could not be fully turned off, which forced the use of the KT6328A. With the revised circuit you can drop the KT6328A and use the KT6368A instead, which the README says supports SPP and wireless upgrades. That is what makes the IAP OTA feature possible: the Bootloader and APP are separated, and the APP can be replaced over Bluetooth. The same release added long-press KEY1 shutdown in both the Bootloader and the APP, and changed the key BSP so an action fires on release rather than press, to reduce accidental triggers. Version 2.4.1 fixed a high sleep current by de-initialising the UART pins during sleep and setting them as inputs, bringing sleep current to a little over 800 uA. Note that the OTA path depends on the revised Back board, so an older board cannot simply take the new firmware and gain wireless upgrades.

## Where OV-Watch is the wrong choice, and what to compare it with

If you want a wrist device that works out of the box, OV-Watch is the wrong tool. There is no app store, no companion phone app described in the README, and no finished enclosure sold as a product; the 3D Modle folder is there because you print it. Blood oxygen is absent. The heart rate path is a homegrown peak detector, and the README gives no accuracy claim. Sleep current is quoted at a little over 800 uA after the v2.4.1 fix, which is fine for a hobby build and high for a device meant to run for weeks on a small cell. For a comparable open source route, PineTime is the usual alternative, and the difference in approach is architectural: PineTime builds on a Nordic nRF52 with Bluetooth Low Energy as the primary radio and a community firmware ecosystem, while OV-Watch is an STM32F411 design where Bluetooth is an add-on module (KT6368A) used mainly for SPP and OTA, and where the interesting code is the LVGL interface and the power-mode handling. If your goal is to learn LVGL on a Cortex-M4 with FreeRTOS and a real power budget, OV-Watch puts that material in front of you. If your goal is a wearable that syncs with a phone, the STM32 plus SPP route asks you to build more of that yourself.

## Licence and the cost of keeping a fork alive

OV-Watch is GPL-3.0. If you distribute a modified watch or its firmware, the licence's copyleft terms apply to the source you ship, and the repository's LICENSE file is the authoritative text; this is a description of the licence, not legal advice. The upgrade cost is mostly in the toolchain. The two projects in Software are Keil projects, so a fork inherits that dependency, and the flashing procedure is documented in Firmware/README.md rather than being a single command. The v2.4.0 Bootloader split means an existing build has an APP address offset that must be kept consistent with the Bootloader you flash; the README offers ver2.3.2 as the pre-split alternative for anyone who does not want to manage that. With the last push on 2026-05-26 and the newest tag v2.4.3 from 2024-09-10, expect to maintain your own fork rather than pull frequent upstream fixes. Budget for that before you commit to a custom board revision.

## Conclusion

Adopt OV-Watch if you want to assemble the hardware, flash the prebuilt binary from Firmware, and then read C around FreeRTOS tasks, LVGL screens and an EEPROM settings store. Do not adopt it if you need blood oxygen, a finished enclosure, or a support contract; the README states the SpO2 section is not written yet. Before buying anything, open Firmware/README.md and confirm the BootLoader and APP address offsets match the branch you intend to build, because ver2.3.2 predates the split and uses a different layout.

## FAQ

### How do I flash OV-Watch?

The README recommends using the firmware already provided in the Firmware folder instead of building it yourself. Detailed steps, including the Bootloader and APP download order, are in Firmware/README.md, and the two Keil projects live in the Software folder.

### Does OV-Watch measure blood oxygen?

No. The README states that the blood oxygen section has not been written yet. Heart rate is implemented, using a custom peak-detection algorithm over the EM7028 PPG signal rather than the vendor library.

### Can I change the OV-Watch UI without the hardware?

Yes. The repository includes lv_sim_vscode_win, a prepared LVGL simulator project for VS Code on Windows, where you adjust the configured paths and open it. After editing, the Func and GUI_App folders are copied into the User folder of the Keil project, and setting HW_USE_HARDWARE to 0 lets the same code run in simulation.

## Sources

- [License: GPL-3.0](https://github.com/No-Chicken/OV-Watch/blob/main/LICENSE)
- [No-Chicken/OV-Watch on GitHub](https://github.com/No-Chicken/OV-Watch)
- [Project website](https://www.bilibili.com/video/BV1hh4y1J7TS/)
- [README](https://github.com/No-Chicken/OV-Watch/blob/main/README.md)
- [Releases](https://github.com/No-Chicken/OV-Watch/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/no-chicken-ov-watch
