- watchface
DIN Black
Font- calendar events
- battery bar
- looks clean
- very wow
- scrolling menu by Alex Story
dark mode
toggle. Changes watchface, menus, apps (everything)- borders around the screen are syncronised to background colour. Based on findings from peanutman and gewoon_maarten on discord.
This Watchy works slightly different from the original. With each interaction (buttonpress), watchy wakes, does its thing, and goes back to sleep ASAP. No waiting around with the CPU awake. (There's also an ISR to catch button presses while Watchy is "doing its thing") The only exceptions to this are some legacy functions like setTime()
which stays awake while waiting for more inputs, and also waiting for the display to refresh.
-
Removed
display.init()
before each function. Is now called upon wake from sleep anddisplay.hibernate()
just before going to sleep. -
Added interrupts to check for buttonpresses.
handleButtonPress()
loops until all button presses are cleared -
Modified bootloader for faster wake from sleep (See this guide). settings changed:
general
- flash speed=80MHz
- timers used for
gettimeofday
function set tonone
bootloader config
- compiler optimization to
-O2
for speed Skip Image Validation
when waking from Deep Sleep- turned off all logging
Flash mode
QIO
doesn't work :(Not extensively tested, but seems to work for now. Sleep+wake together take ~50ms (based on my janky testing).
-
Modified the display library (GxEPD) to reduce unnecessary wait times.
A full loop (sleep>wake>sleep) is 300ms shorter nowUpdate: SPI transfers were sped up too, so now a full loop is 400 - 600ms faster than the orginal. 🙂
Before (ms) | After (ms) | With SPI improvements (ms) | |
---|---|---|---|
Partial Refresh | 894 | 592 | 497 |
Full refresh | 2637 | 2312 | 2040 |
Here is the refresh broken down (for a partial update):
Before (ms) | After (ms) | Reason | |
---|---|---|---|
display.init() |
240++ | Unnecessary 200ms delay was removed. 20ms faster after SPI transaction sped up (??) | |
graphics processing | 7-8 | 7-8 | display.print() and all that. Small enough not to bother optimising |
?? (probs j the SPI transfer) | ~50 | 27 | SPI transfer sped up |
_Update_Part() |
400 | 400 | can’t change anything here |
?? (probs j the SPI transfer) | 60 | 17 | SPI transfer sped up |
hibernate() | 110 | 0 | removed _Poweroff() and removed _wait_while_busy() since the ESP is also going to sleep anyway |
downclock CPU to 10MHzESP goes into light sleep while waiting for screen to update. (theoretically 0.8mA)- disable initialisation of BMA423 because I don't use it - seems to save a lot of battery!
- low/critical battery warning
- watch "ticks" only once an hour to save battery under certain circumstances:
- Late night (1am to 7am). I plan to make a user override-able setting to disable it for that hour/for that night in case I'm out late.
- critical battery (<5%).
- user-set power saver (not tested whether it works as intended)
In these cases, the watchface only shows (e.g.)
03:xx
instead of03:14
. (Actual time will show if you press the back button.)
- more accurate battery voltage. ADC callibration code derived from peanutman on discord (requires sign in to access).
- more accurate battery percentage, using a Look Up Table (LUT).
fastmenu
is not used anymore since the UI is much more responsive anyway. No more waiting for timeouts - Watchy goes to sleep immediately :)fast menu
used to force the code to wait for the timeout before entering sleep even when in an app. Changed it to only wait for the timeout when in the menu. Otherwise (i.e. in an app) enter sleep immediatelyCPU set to 80Mhz (in the hope of power saving)240MHz is actually faster (noticeable in the UI) so I'm keeping it to that. The CPU spends very little time awake anyway.
-
NTP time sync (set to sync every 3 days).
- seems like it works, am lazy to test but the time gets synced periodically so ain't complaining.
-
sync to google calendar (internet). Followed this tutorial.. The code for Google Apps Script is in
\others\share_calendar.gs
. (set to sync every 3 days). Next event also shows on watchface. -
DEBUG
modes which print stuff to serial. -
WiFi OTA to save your CP2104 USB chip.
-
stopwatch. Because of the screen refresh rate, it updates once a second, but internally it is counting the actual time (milliseconds). Not sure how much latency the start has though...
-
temperature appI disabled it because I have a hardware issue.
trying to configure the BMA423 properly, for low powerI think I'll just leave it uninitialised as I don't have any use for it now- (not working)RTC temperature sensor is messed up; shows 45 - 49dec C (I have a hardware issue with it so I've stopped working on temperature.). This is probably why my RTC drifts...~~Substituted with BMA423 temperature sensor (yes, the IMU has a temp sensor) but temp is still a bit off (34 ish dec C) ~~ (Update: Disabled the BMA423 sensor.) Maybe I should get the temperatre from the screen lol...
- weather is disabled. I don't use it so I didn't spend a lot of time developing it. It may or may not work.
- removed
FWUpdate
cos it's useless - removed
WiFiManager
library; now uses only defaultWiFi
library
BLE updates from phone (this is months or years away)Not happening. ESP32 can't sleep with BLE connected. Needs a 32kHz external crystal for lightsleep w BLE, which Watchy doesn't have.- on that note, I would like to eventually make a nrf52840 version of Watchy (but this is a long time away)
- put Watchy into lightsleep while waiting for screen to update. Use interrupt from display's
BUSY
pin to resume. - touchscreen hehe
- maybe improve RTC accuracy by changing PPM (?) (or I might just buy a new RTC chip and resolder)
- Anything that depends on the BMA423 will crash (I have since de-initialised it.)
WiFi seems to take a long time to initialiseIt is what it is :(- Battery drain is a bit uneven, I think (battery suddenly drops from 40% to 30%)
- GxEPD2 by Jean-Marc Zingg (highly modified, it's in
\lib
now) - Adafruit GFX Library by Adafruit
- Adafruit BusIO by Adafruit (I think)
- DS3232RTC by Jack Christensen
- Arduino_JSON by Arduino
WiFiManager by tzapuclone this directly from Github as PlatformIO library registry downloads the release version (v. old), which isn't compatible with ESP32removed; using the default WiFi library now
Note that this is untested! So there may be some missed steps along the way. Only attempt this if you're moderately familiar with using PlatformIO (or have a PlatformIO guide on hand).
- clone the repo
- rename
sensitive_config-template.h
in\lib\Watchy\
tosensitive_config.h
and input your WiFi etc - change relevant settings in
config.h
. For example:GMT_OFFSET_SEC
for NTP time syncINTERNET_SYNC_INTERVAL
NIGHT_HOURLY_TIME_UPDATE
(display updates once an hour)LOW_BATT_THRESHOLD
andCRIT_BATT_THRESHOLD
- (optional) To enable faster wake from deep sleep, copy
others\bootloader_dio_80m.bin
to\packages_dir\framework-arduinoespressif32\tools\sdk\bin
(and maybe make a backup of the originalbootloader_dio_80m.bin
). (Or use this guide to generate your own.) - Change
upload_port
inplatformio.ini
to match the COM port, and comment outupload_port
. - Once PlatformIO downloads all the necessary dependencies, you should be able to compile and upload the firmware to your Watchy. The first upload has to be through USB, but subsequently you can flash it via WiFi OTP:
- click WiFi OTP on Watchy. It'll connect to your WiFi SSID and show you its IP address (ensure you set up the WiFi correctly in
config.h
). - uncomment
#upload_port
inplatformio
and change the IP to the IP shown on Watchy's screen. - build n upload the project in PlatformIO.
- click WiFi OTP on Watchy. It'll connect to your WiFi SSID and show you its IP address (ensure you set up the WiFi correctly in
DPI is 141 Font converter for ttf fonts