Smart Watch V1

Note: This project is ongoing and I will continue to add posts about its progress

Background

So to give a little context surrounding the origins of this project, back in 2014/15 I was learning how use Arduinos. I had just begun experimenting with Attiny85 microcontroller and I had the idea to use the attiny85 in addition to a HC-05 Bluetooth module to create my own smart watch. To be perfectly honest I think I got the idea when I saw a round LCD for sale on eBay. At this point in time smart watches were still pretty new with only the Samsung galaxy gear and Motorola 360 being the only smart watches available from big brand companies (at least as far as I knew at that time). Because of this finding a round smart LCD on eBay was pretty shocking to say the least. My plan was to use two attiny85’s one a CPU and once as a GPU then connect to the phone using the HC-05. sufficed to say that my plan had many flaws and the project got put on hold. Fast forward to 2020 I discovered the esp32, a dual core microcontroller running at 240 MHz with built in WIFI and Bluetooth 4.0. In addition to discovering the esp32 I found that there was an abundance of round LCD’s now available online. This is likely due to the fact that smart watches are actually pretty cheap now and you could probably pick a decent one up for less than £50. So there is no real economic advantage to this project, honestly I just wanted to see if I could make my own smart watch that functioned as well as commercially available models.

Project Goals

When I first decided to take on this project, I thought it would be best to decide upon a set of features that I wanted the watch to have. Throughout this project some of those features were changed or ignored but having a list of outcomes helped with organising such a mammoth project. initially the features I wanted to incorporate were:

  • Telling the time and date (obviously)
  • A round LCD (Not really a feature but this was something I felt was important but also resulted in some issues)
  • Displaying notifications (once again pretty basic)
  • Setting Alarms
  • Controlling music from the watch
  • Being able to see the current song in spotify from the watch (this is a featured that had to be dropped)

Initial Research

Upon discovering the esp32 I found some example code by “S-March” that allowed the esp32 to connect to an iOS device and subscribe to ANCS (Apple Notification Center Service):

https://github.com/S-March/esp32_ANCS/blob/master/ANCS/ANCS.ino

This allowed the esp32 to receive notifications from the devices. later discovered that there is an ANCS example from Espressif the manufacturer of the esp32 however this required using the ESP-IDF and I was much more comfortable using the Arduino IDE. The code by S-March only allowed for the esp32 to subscribe to the notification source characteristic but not the data source characteristic. Essentially, this meant that the Esp32 would know then the device received a notification and of what type said notification was but it wouldn’t get the details of the notification. To rectify this I altered S-March’s code, referring to the ANCS example given by Espressif.

Version 0.1

Once I was able to receive notifications and the details of said notifications I moved on to implementing another feature, controlling music from the watch. This was accomplished by having the watch act as a HID device (although not a HID keyboard) and sending media commands to the phone. This was slightly tricky as most examples I found online made the esp32 act as a Bluetooth keyboard that once connected to my phone (I was using an iPhone 11 running iOS 13 at the time) would stop the onscreen keyboard from appearing (This is just one of those things in iOS that would be a cool feature in any other situation). I eventually found some code by “sabas1080” that I was able to send media commands without registering as a Bluetooth keyboard. I combined this code with the ANCS code and this was the foundation of the smart watch back end.

The next step was to display the data, initially I used a 16×2 LCD screen. For some reason I spent a lot of time working with this display making sure it looked right, even going so far as to create custom auto scrolling.

Version 0.4

(FYI there is no reasoning behind the version numbers before version 1)

I purchased a screen from AliExpress that I intended to use for the final version, it was a round 1.3 inch LCD screen that communicated used SPI and had an ST7789V driver board which is pretty widely supported (turns out this display would go on to cause a lot of sleepless nights and misery but more on that later). This display was shipping from china to the UK amidst the coronavirus pandemic so as you can imagine I knew I would be waiting quite a while for it. Since I am a very impatient person and had literally nothing to do other than work on projects during quarantine I decided to order what I thought was almost the same display just rectangular from Adafruit (it would turn out that despite using the same driver the displays could not work interchangeably).

Using the Adafruit display as a substitute for the final display I began work on displaying the notifications. For this I utilised the TFT_ESPI library and despite having to move away from that library I do recommend the library if you have a project involving an LCD display due to its wide use of sprites. I spent a lot of time working on displaying the notifications and eventually the time using the TFT_ESPI library however most of that work became useless so I won’t cover it here, however if people are curious contact me and I will make another post about it.

In addition to displaying the notifications, I also incorporated the displaying time in this version. This was accomplished by using a Ds3231 real time clock. Utilising the real time clock (rtc) was pretty easy as it communicates over i2c so there are only two wires connecting it to the esp32. The rtc will accurately keep track of the time however it must be set to the correct time after any power loss. I accomplished this by subscribing to the current time service of my phone and every time the esp32 connects to my phone it will set the time of the watch to the time of my phone. This also means that the watch automatically will respond to time zone changes. Displaying the time (in analogue form) was achieved relatively easily using sprites and the TFT_ESPI library so I when I eventually had to abandon all of that work I was quite upset (so much so that I worked on a different project for an entire month). However, in the end it was for the best as in later versions I created a watch face display that looked much nicer.

Display Drama

As I have alluded to, most of the problems with this project came from the display that I purchased from AliExpress. Despite both having an ST7789 driver board and communicating via SPI, the round display from AliExpress could not be used interchangeably with the rectangular display from Adafruit. This was due to the round display using 3 wire, 9 bit spi instead of the more common 4 wire, 8 bit spi. This meant that the display was not supported by the TFT_ESPI library. finding a library that supported 9 bit spi was very difficult especially one that was fast enough that it could be used for the watch whilst not making the watch seem sluggish or “laggy”. To achieve this hardware SPI had to be utilised however the only library that I found that supported 9-bit SPI only did so if software spi was used. Luckily during the time I was looking for the library moononournation released the Arduino_GFX library which supported 9-bit spi using hardware SPI and was also comparably fast to the the TFT_ESPI library.

Verison 0.7

After finding the Arduino_GFX library recreated the UI I had previously made using the TFT_ESPI. Unfortunately the Arduino_GFX library did not have an equivalent to the sprites of the TFT_eSPI library, as such I was unable to recreate the autoscrolling feature of when displaying a message larger than the screen however there are physical buttons that you can use to scroll. Although the Arduino_GFX library does not have sprites it is much better at drawing bitmaps. This allowed me to create much better looking user interfaces and watch faces that do not have to be created by code but instead can be imported as images. I also created a couple different screens such as a screen to display a list of all the notifications received, a screen that allowed you to change your watch face and a screen that lets you set an alarm. Using bitmaps for watch faces allows for easy implementation of new analogue watch faces. For the digital watch face I incorporated counters that let you easily see how many notifications you have from specific applications. Although the use of bitmaps makes it easier, creating new custom watch faces still requires a bit of effort and a tedious work flow therefore one of the things to improve in the future would be to make this process much easier.

Dropped features

As mentioned above, I initially wanted to be able to see what song is currently being played by a connected iOS device. Unfortunately, due to the way in which IOS works it is impossible for this to work in such a general way, instead I decided to focus on what song was being played by Spotify. Although I did figure out a way that this could be achieved it would require either having the phone act as a Wi-Fi hotspot at all times or a custom IOS app would be needed. I do have some experience with iOS programming however to publish an app to the app store or even just permanently load an app you have developed on to your own phone you must be part of the apple developer program which costs ~£100 a year. Without the apple developer program you would need to reinstall the app every week which would get very annoying very quickly but more importantly for this app to work in the background push notifications would’ve been needed however only developers apart of the apple developer program have access push notifications. Therefore one feature would essentially cost £100 a year which is a little bit to expensive for me as a university student.

Next Steps

The next steps of this project are to:

  • Implement an accelerometer to allow the watch to act as a pedometer
  • Implement wireless charging this will be done using a BQ51050BRHLR
  • Design a custom PCB for the watch
  • Have the pcb manufactured
  • Design and print a housing for the watch in PETG or a carbon fibre filament (In the future I may make the housing out of wax like material using SLA 3d printing and try my hand at lost wax casting)