The Challenge
I recently ordered this cool Arduino compatible watch from watchX and been trying to hook it up with my Zumo rover for our weekly challenge we have with the guys at the office. I dig the fact that this gadget ships bare bones and when put together, you get a fully functional smartwatch which you can code with Arduino and C++. My goal is to able to send commands to the rover by utilizing watchX’s bluetooth low energy capabilities and hence navigate the rover forward, back, left and right.. basic stuff.
So what is watchX ?
WatchX is an Arduino compatible watch designed and developed by guys from Turkey. Visit their site here, they also run a community site here. It’s built on MCU Atmega 32U4 chip and has a flash program memory of 32KB and supports Bluetooth Low Energy. Besides this, it also does come loaded with a bunch if sensors too.
Accelerometer & Gyroscope.
Temperature sensor & Barometric Pressure Sensor.
3 Axis Magnetometer.
For a full list of features, check this this link
For this project, I already have a fully assembled rover that’s also compatible with Arduino
Why Bluetooth and not RC
Bluetooth is a wireless technology standard for exchanging data between fixed and mobile devices over short distances using short-wavelength UHF radio waves. So given my operational requirements of less than 30 meters, Bluetooth ended up the cheapest and best option. I also happen to have an ESP32 dev board with BLE capabilities I bought earlier on for my bee hive connect project laying around and I guess it’s cheap and readily available for use.
When talking about Bluetooth Low Energy vs. Bluetooth, the key difference is in Bluetooth 4.0’s (BLE) low power consumption. Although that may sound negative, it’s extremely positive when talking about applications that run on a small battery life for years.
Bluetooth is not a good choice for long distance range communication signals and it will never replace RC receiver. Bluetooth usually range within 30-100m and RC receiver can easy go for 1000m.
Components needed for this project
ESP32 Dev Module – used this for intercepting BLE commands to the onboard Arduino Uno via UART (Universal Asynchronous serial communication)
WatchX – used as a peripheral device to advertise rover commands
Zumo robot fully assembled
Arduino UNO – Runs code to navigate the rover
Ok so let’s get started
Step 1 Configuring ESP32 Dev Board
Hardware
Small Breadboard
4 male to female jumpers
ESP32 Dev Board – We will connect RX and TX pins if the ESP32 board to the Arduino Uno TX and RX pins using the two jumpers swapped (RX->TX and TX->RX). The other two jumpers are for power and ESP32 dev board strictly requires 3.5v, So we mount 3.5v of the Dev board to 3.5v and GND to ground of the Arduino UNO.
Software Libraries
ESP32_BLE_Arduino – This library provides an implementation bluetooth low energy support for the ESP32 using the Arduino platform
Our Esp32 dev board will communicate with our watchX using serial UART service advertised by our watchX. These services uses GATT which stands for Generic ATTribute Profile, governs data organization and data exchanges between connected devices. One device (the peripheral) acts as a GATT Server, which stores data in Attribute records, and the second device in the connection (the central) acts as a GATT Client, requesting data from the server whenever necessary. Our Esp32 device will act as out GATT client constantly getting notified of the changes by our GATT Server watchX.
We will be subscribing to the UART service we advertised on watchX for two important characteristics for reading and transmitting data.
//Include ESP32 BLE support library
include "BLEDevice.h"
//We define ESP32 RX and TX pins to read and write from
#define RXD2 16
#define TXD2 17
// We define the remote UART service we wish to connect to.
static BLEUUID serviceUUID("6e400001-b5a3-f393-e0a9-e50e24dcca9e");
// The RX characteristic of the remote service we are interested in.
static BLEUUID charUUID_RX("6e400003-b5a3-f393-e0a9-e50e24dcca9e");
// The TX characteristic of the remote service we are interested in.
static BLEUUID charUUID_TX("6e400002-b5a3-f393-e0a9-e50e24dcca9e");
static BLERemoteCharacteristic* pRemoteCharacteristic_TX;
static BLERemoteCharacteristic* pRemoteCharacteristic_RX;
static BLEAdvertisedDevice* myDevice;
//We will get notified whenever the value on the BLE device characteristic changes and transmit that data to the host Arduino UNO RX and TX pins
static void notifyCallback (
BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData,
size_t length,
bool isNotify) {
//transmit commands to the host Arduino UNO via UART
Serial2.println((char)pData);
}
I’ve shared full source code for the ESP32 here
Step 2 – Configure watch X firmware
Github Download link: https://github.com/mtulu-argeX/Basic_Watch 113
Forked from https://github.com/kghunt/Basic_Watch 19
Developer’s original blog: https://www.reddit.com/r/watchX/comments/8vmotl/basic_watch_fairly_big_update/ 33
Installation instructions:
- Download the firmware from the Github download link
- Download the missing library: https://github.com/adafruit/Adafruit_SleepyDog 38 You can also import this library as follows: Sketch -> Include Library -> Manage Libraries then search Adafruit_SleepyDog and install.
I refactored the bluetooth header file to enable us to send direction commands to interested GATT clients using UART service. “AT+BLEUARTTX=
” command will transmit the specified text message out via the UART Service while you are running in Command Mode.
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);
void bluetoothinit() {
ble.begin(VERBOSE_MODE);
ble.factoryReset();
//name of our bluetooth device
ble.sendCommandCheckOK(F( "AT+GAPDEVNAME=LEXX" ));
//set our bluetooth device to data mode
ble.setMode(BLUEFRUIT_MODE_DATA);
ble.sendCommandCheckOK(F("AT+GATTCLEAR"));
ble.reset();
}
//move rover right
void moveRoverRight() {
ble.sendCommandCheckOK(F("AT+BLEUARTTX=R"));
}
//move rover left
void moveRoverLeft() {
ble.sendCommandCheckOK(F("AT+BLEUARTTX=L"));
}
//move rover forward
void moveRoverForward() {
ble.sendCommandCheckOK(F("AT+BLEUARTTX=F"));
}
// move rover back
void moveRoverBack(){
ble.sendCommandCheckOK(F("AT+BLEUARTTX=B"));
}
//stop rover
void stopRover(){
ble.sendCommandCheckOK(F("AT+BLEUARTTX=S"));
}
Download the rest of the project source here