Introduction: Starting an ESP32 Experimentation Journey With TTGO T-Watch

To me, TTGO T-Watch is not a stylish smartwatch to wear daily. Rather, it is an ESP32 microcontroller board pre-wired with many electronic components for Arduino experiments.

To hobbyists like me, who don't really enjoy wiring; who only buy electronic gadgets pre-soldered; and who love programming microcontrollers; TTGO T-Watch is a good choice of microcontroller board for easy setting up for experimentation.

In this post, which is the start of my TTGO T-Watch experimentation journey, I will show the essential -- restoring factory firmware -- and the very basic -- developing a "blink test" sketch -- in a Windows environment with VSCode / PlatformIO in WSL.

You may wonder why I choose WSL while using VSCode / PlatformIO in Windows without WSL is even simpler. Yes, I normally do not resort to WSL for the purpose of microcontroller program development. However, for some particular reasons when it is better off using Linux, WSL is a good choice to consider for Windows users.

For reasons like, as mentioned in the source of the TTGO T-Watch factory firmware

This issue has not been seen on Linux or other platforms. If you must compile on Windows you may work around this linker issue by removing apps you do not use from the .\src\main.cpp file.

Hmm. I would prefer to try WSL.

Talking about using WSL for microcontroller programming with VSCode, I agree that it is a bit more tedious than simply using Windows -- you need to specially do something for WSL to access your USB port.

Step 1: WSL Connecting Connect USB Devices

As hinted by Microsoft's doc on connecting USB devices from WSL, such so expected capability does not come out of the box. Here I will list the steps to enable such capability.

In Windows:

  1. Go to the latest release page for the usbipd-win project.
  2. Select the .msi file, which will download the installer. (You may get a warning asking you to confirm that you trust this download).
  3.  Run the downloaded usbipd-win_x.msi installer file.

In WSL:

sudo apt install linux-tools-generic hwdata
sudo update-alternatives --install /usr/local/bin/usbip usbip /usr/lib/linux-tools/*-generic/usbip 20

Now, you are ready to attach your TTGO T-Watch to WSL.

Some comments about powering T-Watch up:

  • It might not be apparent whether your T-Watch is powered ON or OFF; since the T-Watch (2020 V3) doesn't seem to have any light for indicating ON / OFF state. It is kind of a pain when you are not sure whether your T-Watch is ON or OFF
  • You can try pressing and holding the power button for 5 seconds, which is supposed to turn it OFF. Too bad that if your T-Watch is already OFF, pressing the power button for 5 seconds will turn it ON as well.
  • However, from my experience, when you plug your T-Watch to a USB port, it will be powered ON. So, when in doubt, unplug and re-plug your T-Watch.
  • Another thing is restarting (resetting) the T-Watch. T-Watch doesn't have a reset button. Since the T-Watch is battery-powered, you cannot simply unplug your T-Watch to power it OFF hoping that when you re-plug your T-Watch it will be reset. Instead, in order to reset your T-Watch, you need to press the power button for 5 seconds to turn it OFF, then press 2 seconds to turn it ON again.

With Windows' Command Prompt (cmd) run as administrator, running usbipd wsl list should allow you to see the list of USB devices recognized by Windows

C:\Windows\System32>usbipd wsl list
BUSID  VID:PID    DEVICE                                                        STATE
1-4    04f2:b6d0  Integrated Camera, Integrated IR Camera, Camera DFU Device    Not attached
3-3    06cb:00bd  Synaptics UWP WBDI                                            Not attached
3-4    0489:e0cd  MediaTek Bluetooth Adapter                                    Not attached

Plug your TTGO T-Watch to a USB port of Windows, and run usbipd wsl list again, you should see the added USB device of your T-Watch

C:\Windows\System32>usbipd wsl list
BUSID  VID:PID    DEVICE                                                        STATE
1-4    04f2:b6d0  Integrated Camera, Integrated IR Camera, Camera DFU Device    Not attached
3-1    1a86:55d4  USB-Enhanced-SERIAL CH9102 (COM5)                             Not attached
3-3    06cb:00bd  Synaptics UWP WBDI                                            Not attached
3-4    0489:e0cd  MediaTek Bluetooth Adapter                                    Not attached

Note down the BUSID (in my case 3-1). You attach your T-Watch to WSL with the BUSID, like

usbipd wsl attach --busid 3-1

After running the command, you should see something like

C:\Windows\System32>usbipd wsl attach --busid 3-1
usbipd: info: Using default WSL distribution 'Ubuntu-20.04'; specify the '--distribution' option to select a different one.

That is it. Your TTGO T-Watch is attached to WSL.

BTW. You can detach it like

usbipd wsl detach --busid 3-1

Note that every time you unplug and re-plug your T-Watch, you will need to run the command again.

The good news is, usbipd tool comes with an option to stay watching the same USB port and reattach when you re-plug it.

To enable this option, the first time you attach, you run usbipd like

usbipd wsl attach -a -b 3-1
  • the said option is specified with -a
  • -b 3-1 is equivalent to --busid 3-1
  • you can combine the two like -ab 3-1

It will then attach your T-Watch to WSL, and stay watching the port for any unplugging and re-plugging, like

C:\Windows\System32>usbipd wsl attach -ab 3-1
usbipd: info: Using default WSL distribution 'Ubuntu-20.04'; specify the '--distribution' option to select a different one.
usbipd: info: Starting endless attach loop; press Ctrl+C to quit.
Attached
Detached
usbip: error: Attach Request for 3-1 failed - Device not found
Attached
Detached
usbip: error: Attach Request for 3-1 failed - Device not found
Attached

Just keep the prompt running.

Step 2: Build the TTGO T-Watch Factory Firmware

The official TTGO T-Watch GitHub repository TTGO_TWatch_Library is the library that you use for developing software for the T-Watch. Nevertheless, you cannot build the factory firmware (the program that comes with T-Watch) with it.

The latest factory firmware is made by sharandac/My-TTGO-Watch

It certainly is a good idea to clone TTGO_TWatch_Library, However, you actually need to clone My-TTGO-Watch to build the factory firmware.

Hence, the first step is to clone My-TTGO-Watch in WSL using git

trevorlee@TrevorP14s:~/pio$ git clone https://github.com/sharandac/My-TTGO-Watch.git

This will clone the source into the directory My-TTGO-Watch

CD into My-TTGO-Watch and start VSCode from the current directory

 trevorlee@TrevorP14s:~/pio/My-TTGO-Watch$ code .

If your VSCode has no PlatformIO extension installed, install it. (Note that even if you have PlatformIO installed for Windows, you still have to install it again for WSL.)

Choose the PlatformIO environment for your version of T-Watch. For me, it would be env:t-watch2020-v3.

You need to choose the environment since the source can be targeted to multiple versions of T-Watch, as well as to others.

Assuming you have plugged in your T-Watch and attached the USB port to WSL as described in the previous section, you should be able to upload the program to your T-Watch.

If you are able to build and upload without error, then it shows that you can restore your T-Watch factory firmware to its latest version. And you are much assured that you can go back after your experimentation, which will be started next.

Step 3: Build a Sample Sketch -- TFT_Clock

All libraries, like TFT_eSPI for drawing to the 240x240 1.54 inch TFT screen, come bundled with TTGO_TWatch_Library. In other words, you don't need to add additional dependencies to your project for accessing the components of the T-Watch.

In fact, you do not directly initialize the components the usual way. Instead, you will do this through a wrapper object (API object). We will see the basic steps how this is done later. Before that, in this section, I will show how you can build one sample sketch that comes with TTGO_TWatch_Library -- TFT_Clock

Let's first create a PlatformIO project, say TWatchClock.

  • In WSL, say at the same level as My-TTGO-Watch project, create the directory TWatchClock -- mkdir TWatchClock
  • CD into the directory TWatchClock -- cd TWatchClock
  • Create an empty PlatformIO INI file -- touch platformio.ini
  • Start VSCode from the current directory -- code .

With VSCode, open the empty platformio.ini

Put in the config

[env:ttgo-t-watch]
platform = espressif32
board = ttgo-t-watch
framework = arduino
lib_deps =
    https://github.com/Xinyuan-LilyGO/TTGO_TWatch_Library
build_flags =
    -D LILYGO_WATCH_2020_V3

Notice:

  • TTGO_TWatch_Library is added as a dependency, since as said, you will need this library to access the components of the T-Watch
  • The macro LILYGO_WATCH_2020_V3 is defined for T-Watch 2020 V3. This macro will save you from having to config it with config.h which is often used in the library's samples

Then create the source file src/main.cpp.

#include "../examples/TFT_eSPI/TFT_Clock/TFT_Clock.ino"

Yes, only a single INCLUDE line that includes the TFT_Clock.ino sample sketch, which is bundled with the TTGO_TWatch_Library source downloaded by PlatformIO

  • This is actually just a trick. It works because the downloaded library's src directory is one of the INCLUDE search paths -- .pio/build/ttgo-t-watch/src/.
  • Hence, ../examples/ resolves to .pio/build/ttgo-t-watch/examples/, which is where the library's samples are stored.
  • You can try out any included sample similarly.

Step 4: TTGO T-Watch "Blink Test"

It doesn't seem complete without trying a blink test sketch. Unluckily, there doesn't seem to be a LED on the T-Watch that you can program it to blink. Nevertheless, you can simulate a LED with the TFT screen. This is the exact approach we are taking here.

As in the previous section, let's create a PlatformIO project, say TWatchExperiments.

  • In WSL, say at the same level as My-TTGO-Watch project, create the directory TWatchExperiments -- mkdir TWatchExperiments
  • CD into the directory TWatchExperiments --cd TWatchExperiments
  • Create an empty PlatformIO INI file -- touch platformio.ini
  • Start VSCode from the current directory -- code .

With VSCode, open the empty platformio.ini

Put in the config

[env:ttgo-t-watch]
platform = espressif32
board = ttgo-t-watch
framework = arduino
lib_deps =
    https://github.com/Xinyuan-LilyGO/TTGO_TWatch_Library
build_flags =
    -D LILYGO_WATCH_2020_V3

In VSCode, create the sketch src/blink/blink.ino

#include <LilyGoWatch.h>

void setup() {
  // create the T-Watch API object
  TTGOClass *ttgo = TTGOClass::getWatch();

  // init the T-Watch API object
  ttgo->begin();
  ttgo->openBL();

  // from the T-Watch API object, get the TFT_eSPI object
  TFT_eSPI& tft = *ttgo->tft;

  tft.fillScreen(TFT_LIGHTGREY);
}

void loop() {
  // get the T-Watch API object (only the first call will create)
  TTGOClass *ttgo = TTGOClass::getWatch();

  // from the T-Watch API object, get the TFT_eSPI object
  TFT_eSPI& tft = *ttgo->tft;

  tft.fillCircle(120, 120, 30, TFT_PURPLE);
  delay(1000);                    
  tft.fillCircle(120, 120, 30, TFT_LIGHTGREY);
  delay(1000);                    
}

The essences are:

  • Include the header file LilyGoWatch.h
  • Call TTGOClass::getWatch() to get the T-Watch API object. The returned API object is a singleton, meaning that only the first time you call TTGOClass::getWatch() will the API object be created, subsequence calls will simply return the same API object.
  • You initialize the API object in the setup() block by calling the begin() method of the API object.
  • The API object provides mechanisms for accessing the components of the T-Watch. For example, like in this case, the TFT_eSPI object is got from the API object.
  • With the TFT_eSPI object, you can do the normal as usual.

Finally, create src/main.cpp, which is the main entry of the PlatformIO project

#include "blink/blink.ino"

That is it. Build and upload the program/sketch to your T-Watch.


Step 5: Enjoy!

Hopefully, this is a good start. Hopefully, I will have some more interesting experiments to share in the near future. Until then, enjoy!

Peace be with you! May God bless you! Jesus loves you!