MetaWatch Teardown and Arduino Hookup

Contributors: jimblom
Favorited Favorite 4

Connecting Arduino (Firmware)

Download the SFE_MetaWatch Library

We wrote a simple library to interface from Arduino to BlueSMiRF to MetaWatch. Click here to download the library (or visit the GitHub repo to help contribute!). If you need help installing it, check out our How to Install an Arduino Library tutorial.

The library includes a couple pieces of example code, we'll be discussing the SFE_MetaWatch_Menu.ino example in this tutorial. You can go to File > Examples > SFE_MetaWatch > SFE_MetaWatch_Menu within Arduino to open it.

A few things on the library:

  • It assumes you have a BlueSMiRF Silver (based on the RN-42 bluetooth module) connected as shown in the Hardware portion of this guide (Arduino pins 10 and 11).
  • It defines a class called SFE_MetaWatch, which has a range of member functions you can call to interact with the watch.
  • It does its best to automatically connect to the watch, but sometimes this'll need to be done manually from the Serial Monitor (see the directions below).

Connecting BlueSMiRF to MetaWatch

The toughest part of all of this is getting the BlueSMiRF connected to the MetaWatch. Before uploading, make sure you set the btBaudRate variable near the top of the sketch to the baud rate of your BlueSMiRF (115200 is the module's default). Then set the metaWatchAddress variable to the 12-digit HEX address of your watch (press button D (bottom-left), the address is the xxxx-xxxx-xxxx formatted number at the bottom).

After uploading the code, open up the serial monitor (set at 9600 bps). When the code first starts, you can enter k (case-sensitive) to attempt to connect between BlueSMiRF and watch. If it succeeds, the BlueSMiRF's green, "Connect" LED should turn on.

If the connect fails, you'll enter into echo mode. Here, anything you send to the Serial Monitor will be relayed to the BlueSMiRF. If you're in echo mode, follow these steps to connect:

  1. Make sure No line ending is selected in the Serial Monitor.
  2. Enter command mode by sending $$$. The BlueSMiRF's stat LED should blink very fast to show that it's in command mode. If it doesn't double-check that the btBaudRate variable is correctly set.
  3. Switch the line-ending drop down in the Serial Monitor to Newline.
  4. Type C, and click "Send". should be the 12-digit HEX string (0-9, A-F) matching the watch's BT address.
  5. The BlueSMiRF should respond "TRYING", and in a few seconds the BlueSMiRF's green connected LED should illuminate.

Animated GIF of connect process

If it still doesn't connect after you see "TRYING", double-check the metaWatchAddress variable. Also make sure both devices are in range of each other. If all else fails, restoring factory default values to the BlueSMiRF may be a last resort.

Using the Library

Once connected, you can play around with the menu choices to adjust stuff on the watch. You should definitely try out setting up the clock widgets (send w), setting the time (send t, then HHMMSS), vibrating (v), and controlling the backlight (l for off, L for on). For more information on what's going on, check out the comments in the code.

There are a few parts of the code to highlight:

Include the Library and Create a Watch Variable

These two pieces of code are required. Include the library near the top of your sketch. Then, sometime before setup() create an SFE_MetaWatch instance (we called it watch), which you'll refer to through the rest of the sketch. The two parameters for this constructor are the Watch's BT address, and the baud rate of your BlueSMiRF module.


#include <SFE_MetaWatch.h>
SFE_MetaWatch watch(metaWatchAddress, btBaudRate);

Begin and Connect

The begin() function should be called before you do anything else with the watch.

The connect() function will attempt to connect the BlueSMiRF to the MetaWatch. If successful, it should return a 1. If it fails it will either return a negative number.

if (watch.connect() < 0) // If connect fails, enter echo mode to manually connect
  Serial.println("Connect failure. Putting you into echo mode.");
  Serial.println("Type $$$ (no line ending) to get into command mode, should respond CMD");
  Serial.println("Type C,<BT address> (newline) to connect to watch. No dashes in address.");
  Serial.println("Type ~~~ to exit echo mode");
  watch.echoMode();  // echo mode, will loop forever until it receives ~~~

If you're having trouble connecting, the echoMode() function is a handy tool to try to communicate directly between the Serial Monitor and BlueSMiRF.

Useful Watch Control Functions

The library can be used to control the watch's vibration motor, backlight, and the display. You can also read from the watch's light sensor, accelerometer, and battery gauge. And of course, since it is a watch, you can set the real-time clock's (RTC) hours, minutes, seconds, and date variables.

Here are a few handy functions to interface with the watch.

Set the RTC

The setTime(year, month, date, day, hours, minutes, seconds) function should be used to set the watch's clock. Each parameter is required. year and month are pretty self-explanatory, as are hours, minutes and seconds. Date is the date of the month (e.g. August 15). day is the day of the week, and it should be a value between 0 and 6 (Sunday is 0, Saturday is 6).

Draw on the Display

The watch has four different idle pages you can play with, and cycle through by pressing the B button (middle-right). Eventually, we'll get to writing a sprite drawing function on the display, but for now here are some functions you can play with:

The display can be cleared completely black or white using the clear(x) function. If x is 0 it'll make the screen white, and if it's 1 the screen will black-out.

Pre-defined widgets can be drawn on the screen using the setWidget(msgTotal, msgIndex, widgIDSet[], numWidg) function. Most of these widgets are clock-related. You can draw full-screen clocks, quarter-screen and half-screen. The widgets aren't super-well documented in the API, so it takes some guess-and-check to find out which widget ID does what. The example code throws all four of the full-screen clock widgets on the screen. Check out the code and comments to see how it does that.

Before sending the setWidget() function, make sure to send the watch.fullScreen(0) command. That tells the watch that the Arduino will be drawing on the full screen of the watch.

After either the clear() or setWidget() commands, you need to send the watch.update() message, which tells the watch to draw what we've been putting in its buffer.

watch.fullScreen(1); // Two options here are 0 for 2/3rd screen or 1 for full-screen
watch.setWidget(1, 0, fullClockWidget, 4);
watch.update(0, 0, 96, 0, 1, 0); // Update display to make it happen.
Serial.println("Widgets updated");

Those four lines, for example, will get your watch to draw four clock full-page clock widgets on four different pages.


You can control the watch's vibration motor using the vibrate(timeOn, timeOff, numCycles) function. timeOn determines how many milliseconds the watch vibrates, timeOff determines how many milliseconds to not vibrate, and numCycles tells the watch how many times to repeat that process.

The example, vibrate(100, 100, 5) will vibrate 100ms, then stop for 100ms, and repeat five times.


If your watch goes crazy, or gets into an unknown state, the reset() function will start you over. After sending reset() you'll need to re-connect to the watch.

If you'd like to contribute to the SFE_MetaWatch library, or add some example code of your own, check out the GitHub repository.