DIY Wearables

Oliver Higgins

Issue 9, March 2018

This article includes additional downloadable resources.
Please log in to access.

Log in

We live in an age where wearable tech is in abundance. It’s in our watches, our shoes and even our clothes. So what if we want to fully embrace this technology and develop our own wearable solutions?

BUILD TIME: 3 hours

The original idea for this project was born out of the need to transmit accurate speed data to an iPad training program. But maybe you have a great idea for a fitness tracker, or something pertaining to your own favourite pursuit such as fishing, golf or even surfing; anything is possible. In the case of the original problem, we needed to create a way of transmitting BLE (Bluetooth Low Energy) running data in place of a treadmill that did not include this. However many fitness devices do not have Bluetooth. Take for example a rowing machine where we have two things to measure: rowing cadence and speed. On a treadmill, we have running cadence and speed. These are all similar sets of data, so how can we find a simple readily acceptable protocol to use to transmit it?


The fitness industry has embraced wearable tech over the last few years. The consumer-led revolution was based around the Fitbit step tracker, but Garmin have risen to the challenge and produced some exceptional GPS-based running and cycling devices over the last few years. As these units increased in popularity so too did the available sensors we could use. The heart rate monitor was a revolution for training, but quickly we saw power meters, cadence meters and ways to measure just about anything. All these sensors use the 2.4GHz band with ANT+ and BLE being the most popular protocols. It was not long before software companies realised they could read this data, and we saw a rise in the use of training apps. These apps let everyday people suddenly have access to high-end training plans with constant on-screen feedback of their progress. For many, this was the realisation of long-held dreams. Suddenly a father of three working full-time could train at 11 o’clock at night and be able to represent his country!

However, not everything is there yet and many devices that could benefit from this technology have not been adapted accordingly just yet. In this article, we will examine what BLE is, in reference to these devices, and how we can leverage this to work with anything from a step tracker to a fitness interface.


The Arduino 101 is part of the new breed of micro-controllers that encompasses BluetoothLE, a gyroscope, accelerometer and even a neural network on a single chip. The examples given here are translatable using a normal Arduino Uno with the use of an accelerometer, a BLE module and some work. We have chosen to use the 101, primarily as all of these components are onboard making development much easier.

The primary communication used in this project is Bluetooth, more specifically Bluetooth Low Energy or “BLE”. BLE is a personal wireless area network technology aimed at novel applications in the healthcare, fitness, beacons, security, and home entertainment industries. Compared to your normal Bluetooth, BLE is intended to provide considerably reduced power consumption and cost, while maintaining a similar communication range.

BLE also includes GATT (which stands for “Generic Attributes”). GATT services are collections of characteristics and relationships to other services that encapsulate the behaviour of part of a device. A GATT profile describes a use case, roles, and general behaviours based on the GATT functionality, enabling extensive innovation while maintaining full interoperability with other Bluetooth devices. In our case, this means we can specify what type of device we want to emulate, get our data and then transmit it in a way that the receiving BLE device will understand “what” it is we are sending. GATT profiles cover a huge array of items; we recommend reading the resources at for more information.

Parts Required: Jaycar Altronics
1 x Arduino / Genuino 101 - -
1 x 10k Potentiometer RP3510 R2243
1 x LED ZD0130 Z0707
1 x 220Ω Resistor RR0556 R7582
1 x OLED Display XC4384 -
8 x Micro Switches SP0600 S1120
8 x 10k Resistors RR0596 R7582
1 x Prototype Board (Shield Type v5) XC4482 -
1 x Small SPDT Switch SS0834 S2075
1 x 9V Battery Snap PH9232 P0455
1 x 9V Battery SB2423 S4970B
APPS Required:
NRF Toolbox
NRF Connect


The 101 is not a standard install board. We need to add it to our desktop environment to allow us to start programming (if you are using the web environment feel free to ignore this step). If you want to program your 101 while offline you need to install the Arduino Desktop IDE and add the Intel Curie Core to it. This simple procedure is done selecting Tools>Boards>Boards Manager. Here you can search Intel Curie or 101 to find the core. Click on its box and click on the Install button. On the bottom bar of the window, you can follow the download and install procedure, including the installation of the proper driver, needed by the operating system to use the 101 board.

Now that the Curie Core is installed, you can connect the board to the computer using a standard USB cable. The very first time your computer may go through the new hardware installation process. From Tools select the Board Arduino / Genuinio 101. Everything is now ready to upload your first sketch.

Go to File on the Arduino Software (IDE) and open the Examples tree; select 01. Basic, and then Blink. This sketch just flashes the built-in LED connected to digital pin 13 at one-second pace for on and off, but it is very useful to practice the loading of a sketch into the Arduino Software (IDE) and the Upload to the connected board.


For this project, we need to have three libraries installed in addition to the standard Arduino libraries. We need to utilise the U8g2 and the 101 Curie libraries. In this case, both are available in the Arduino package manager, and we would recommend that you utilise this feature to install them. To do this open up the Arduino IDE and go to the menu bar and open the library manager by selecting Sketch>include library>manage library. Once you have this open type in “Curie”, you will then find CurieIMU and CurieBLE, both of which will be used in these sketches. Depending on your version of the desktop environment these may already be installed when you install the 101 core.

Search again for “U8g2” and then find the library of the same name. U8g2 is a monochrome graphics library for embedded devices, with support for controller based (for example SSD1306) monochrome OLEDs and LCDs (see the U8g2 setup guide for a complete list of supported display controllers). The Arduino library U8g2 can be installed from the library manager of the Arduino IDE. U8g2 also includes the U8x8 library. The U8g2 library includes all graphics procedures such as line/box/circle draw. It supports many fonts and a full list is part of the GitHub wiki. It does require some memory in the microcontroller to render the display.

At the time of writing, this is version 2.20.13. Click on the item then click on the install button.

Part 1: BLE Heart Rate Monitor


This circuit is quite simple having only three components in addition to the 101 board. You will need to have at least the NRF Toolbox for BLE installed on your iOS or Android device. This piece of software looks for the specific BLE profiles and reads their data. Using a breadboard connect the LEDs negative leg to ground, the positive leg to the 220 ohm resistor then the resistor to pin 13 (you can use the built-in LED if you wish). Take your potentiometer and connect the middle leg to A0, connect the left outermost pin to 3.3V and the right outside pin to ground. Turing the potentiometer will act to simulate an increase in heart rate, the LED will flash when the BLE is connected.

showing on device


The code for this is included in the CurieBLE library, but we will take the time to dissect the basic parts of establishing and using a BLE service to transmit our data. We start the code by including the CureBLE library. This contains all the functions and heavy lifting for us.

Next, we create the BLE Peripheral Device (the board you’re programming) object. Here we are telling the 101 that it will be a BLE peripheral device. Next, we create a BLEService object, in this case, we are calling it heartRateService, but it is the next part, “180D” that is the standard 16-bit characteristic UUID that identifies itself as a Heart Rate BLE device. Any other BLE device that reads this data stream will know to interpret the next characteristic or chunk of data as the defined data for heart rate, that is beats per minute (BPM). Finally we setup the characteristic itself. Some BLE devices, such as cycling trackers can deliver multiple values in a single packet of data. In this case, we have just the one, and that is “2A37” or beats per minute. We then specify BLERead and BLENotify, this will allow remote clients to get notifications if this characteristic changes.

#include <CurieBLE.h>
BLEPeripheral blePeripheral;
BLEService heartRateService("180D"); 
BLECharacteristic heartRateChar("2A37", BLERead | BLENotify, 2); 

Note: This code is abbreviated; refer to the full file for the complete code.

The setup section of code requires us to put the service together. We start by setting a local name then adding the UUID, add the BLE Heart Rate service, and finally add the Heart Rate Measurement characteristic. The last step is to then start the object.

blePeripheral.  setAdvertisedServiceUuid(heartRateService.uuid());

The main loop section has two key elements; firstly we listen for BLE peripherals to connect.

BLECentral central = blePeripheral.central(); 

We have a function in the code called updateHeartRate() We call this to read the current voltage level on the A0 analogue input pin, this is used here to simulate the heart rate’s measurement. The below is an abbreviation of that code. The current heart rate has been read and is located in the “heartRate" variable. The key part that is highlighted here is what we do with this data once we have it and how we get it transmitted. The first line here converts our integer into a char array. While there are some functions that work with integers and strings, it is the best practice that anything you plan on transmitting in any project is transmitted as single-byte chars. In this case, we need to create a two-byte char array, the first byte is 0 and the second byte is the char version of our integer, which is our measured BPM.

In the next line, we update the value of our heart rate measurement characteristic by using the .setValue function. We change the bytes here then at the end of our main loop the BLE service transmits what data it has in its buffer. A word of warning: it will continue to transmit this value until it is changed, so if one part of your code stops but you do not change the value in this buffer, the old value will continue to be transmitted.

void updateHeartRate() 
  const unsigned char heartRateCharArray[2] = { 0, (char)heartRate }; 
  heartRateChar.setValue(heartRateCharArray, 2);

Upload the full version of this sketch, change your board to 101, and select the correct port that your device is connected to. You may need to press the master reset button on the 101 if you have any communication issues. We would recommend closing the serial monitor as well and reopen after 5 to 10 seconds after the upload has finished. The device will boot and be waiting for a connection.

Open the NRF toolbox app. NRF Toolbox is an app designed by Nordic Semiconductors for working with Bluetooth low energy (BLE) devices. It contains applications demonstrating the following profiles: Cycling Speed and Cadence, Running Speed and Cadence, Heart Rate Monitor, Blood Pressure Monitor, Health Thermometer Monitor, Glucose Monitor and Proximity Monitor. All these profiles support any Bluetooth device and manufacturer, as long as the Bluetooth profiles are properly configured.

Select Heart Rate Monitor (HRM); this will open up a graph, touch the "Connect" button down the bottom, give the unit a few seconds and you will see your device on the list. The graph will start changing as you change the potentiometer.

Bluetooth: A History

Bluetooth wireless technology’s history starts in the Second World War, or in the early 90s depending on who you ask. The frequency hopping spread spectrum (FHSS) technique upon which Bluetooth wireless technology bases its communication protocol, is credited to a patent issued in August 1942. The patent details an FHSS technique for a radio-controlled torpedo. Because the radio signals hopped across the radio spectrum, an enemy couldn’t jam the signal.

But it is in 1994 that Bluetooth wireless technology traces its roots. That year, Ericsson, the Swedish telecommunications company, came up with the idea of replacing RS-232 cables that were then commonly used to communicate between instruments with an RF-based “wireless” alternative.

Intel and Nokia met with Ericsson in Sweden in 1996 to agree on the formation of a Special Interest Group (SIG). It was at that meeting that the technology got its name, codenamed “Bluetooth”. The suggestion was that Bluetooth would continue to be used until the marketing people came up with something better. They never did.

The Bluetooth SIG was officially formed with five companies (Ericsson, Nokia, Intel, Toshiba, and IBM) in 1998 and version 1 of the technology was launched in 1999. By 2010, version 4.0, which included Bluetooth low energy was ratified and soon after the two types of chip described in the core specification – Bluetooth v4.0 and Bluetooth low energy ICs – became available.

Today, Bluetooth low energy is aimed to encourage rapid deployment of ultra low power (ULP) wireless by providing a technology that is widely interoperable. Moreover, Bluetooth low energy-equipped products will be able to communicate with mobile phones and PCs featuring Bluetooth v4.0 transceivers.

The technology operates in the globally accepted 2.4GHz Industrial, Scientific and Medical (ISM) band. It features a physical layer bit rate of 1Mbps over a range up to 15m. Ultra low power consumption is critical to Bluetooth low energy’s success. Because the technology is optimised for devices requiring maximum battery life instead of a high data transfer rate, it consumes between 1 and 50 per cent of the power of Classic Bluetooth technology. Bluetooth low energy devices will be expected to run for many months or even years on standard coin cells. The chips will typically operate with low duty cycles, entering sleep modes, to wake up periodically to send a communication burst.

Part 2: BLE Running Cadence Speed (RCS)

heart rate monitor

The Heart Rate Monitor is one of the simplest BLE devices we can create as it has just the one characteristic. However, the GATT BLE profiles allow us to build a large number of these fitness and everyday objects. For this example, we will build a BLE running and cadence speed (RCS) sensor. This comprises of multiple values being sent to the receiver. The below project is designed to be a hybrid of a daily steps tracker and a running “pod”. There are several commercial running pods available, but in short, they measure speed and cadence (steps or strides per minute). Calculating speed is quite complex and depends on an individual’s, height, stride length and speed (e.g., if they are running or walking). In this case, we have a simple algorithm to calculate the speed at a walking pace. The circuit has a small OLED display and LED and eight buttons. These buttons are used to send some dummy data to any training apps that require running speed. This is quite effective as most modern treadmills do not transmit their speed via BLE.


For this circuit, you could choose to delete the parts of the code relating to the buttons and the OLED and just use the step and speed function. If you choose to do this, you will not need any other parts of the circuit other than the 101 board. We have added eight small micro push buttons here to allow user interaction. If you are using the V5 board, we have added them along the centre part to allow versatility and easy layout. Each button has one contact that is connected to a 10k resistor and then connected to ground. The other contact is connected to 3.3V. Remember, the 101 is a 3.3V board and as such when being used with a board like this, the 5V rail is in fact 3.3V.

Even though this is a prototype we have tried to keep the visible side as clean as possible for human interaction and therefore, have put all the interconnecting links on the underside of the board. The buttons are connected from pin 4 through to pin 11. Connect each pin to the middle connector pad of the switches before shorting them on the link between the resistor and the switch contact. Take the time to test all your links with the continuity setting on your multi-meter.

Next, we install a light emitting diode (LED). If you are using the prototype board, you just need to install the LED and 220 ohm resistor into the designated spot. Remember to align the polarity on the LED to align with the board. After the LED, install the power switch if you plan on using an external power source. In the case of this unit, we have used a standard 9V battery, but this is for convenience more than anything. If you wanted to create a smaller solution you could use the CurieNano and a 3.7V lithium polymer battery to power the unit. Connect one end of the switch to the VIN port and the centre to the positive (red) line on the 9V battery snap. Connect the black lead of the battery directly to the ground pin.

The last component is the OLED screen. The screen requires just four pins, VCC connects to the 3.3V rail, GND goes to ground on the board. SDA to A4 and SCL to A5. The 101 board has a dedicated SDA and SCL inputs if you want to use them but a quick check with your multimeter will reveal they are connected directly with A4 and A5. The OLED code also puts it to sleep after five seconds to save battery. Any button press will wake it again.

shown on device


You will find the complete code listing the BLE_RCS_9_010.ino file. We will not go into a line-by-line dissection of the code, but rather cover some key points.

Similarly to the heart rate monitor we discussed we need to establish what our service is. In this case, we need to say that our data is that of a RCS sensor. To do this, we specify “1814” as the relevant bytes. Next, we need to establish the characteristics; that is, what type of data will be in this sensor? We need to use “2A53”, we then specify the “notify” and “read” before finally stating that there will be four bytes of data sent.

BLEPeripheral blePeripheral; 
BLEService RSC("1814"); 
BLECharacteristic RSCMeasure("2A53", BLENotify | BLERead , 4); 

The code is set by default to transmit a speed. We are using integers rather than floats due to the data transmission requirements. The default here is 80, which translates to 8.0kph. If you wish to use a different speed then just change this figure and remove the decimal point.

int setSpeed1 = 80; 

We then create the BLE peripheral services; in this case, we are going to give the sensor a local name of DIYODE, feel free to change this. The additional lines bind the data we need to the peripheral in the same way as the HRM unit.

//Name of BLE 
blePeripheral.setAdvertisedServiceUuid (RSC.uuid()); 

The CurieIMU library supplies us with the step count detail. However we first need to set this up. The following code starts the unit and then specifies the behaviour we seek to see.

CurieIMU.setStepDetectionMode (CURIE_IMU_STEP_MODE_NORMAL); 

Now there is a substantial amount of code between the last block and this block, but it mainly concerns itself with reading the buttons and the actions we need it to do. The below section is the data we are actually getting into the BLE’s buffer for transmission.

First, we create an array of 4 integers and make them all 0. You will also notice that we have specified that they are 8-bit integers, not 16, so the payload of data will be 4 bytes. The first byte is left as 0. The final byte is our steps per minute (SPM). This is defined as “1/minute (or RPM) with a resolution of 1 1/min (or 1 RPM)”. Se we need to calculate our SPM as the number of steps in a given period, then extrapolate it out to 60 seconds.

The middle two bytes are used for speed. Now speed is defined as “Unit is in m/s with a resolution of 1/256 s” and it is a 16bit integer. For those doing the math at home that does mean 2 bytes of data. The receiving unit expects the data pack to be 8 bits, 16 bits, 8 bits; however, we cannot define this in our array. To get around this, we create 16-bit integer and calculate our meters per second at a resolution of 1/256 then we use the Arduino built-in lowByte and highByte functions to allocate the 8-bit bytes we need to the array. We can then send our payload of bits away.

static uint8_t data[4] = {0, 0, 0, 0}; 
data[1] = lowByte(CurrentSpeed); 
data[2] = highByte(CurrentSpeed); 
data[3] = spm; 

The final part is to take our data array and place it into the RCSMeasure object, which is our BLE Characteristic. We use the setValue function and specify how many bytes are in the array. Once this is done, the BLE data is transmitted. The delay after is just to ensure that the system has enough time to complete the transmission. During testing different devices required different (or none at all ) delays here. 50ms work on all the tested devices.

RSCMeasure.setValue(data, 4); 

Upload the INO file to your 101. The LED will blink slowly. If you are testing the device using the OLED or the serial monitor there will be some delay. This is due to the “sit and wait” aspect of the code with the LED flashing. Open the NRF Connect tool and locate the RCS profile. Use the connect button to search for your device and locate it in the list. Depending on the device you may see it called “Genuino” or it may be DIYODE. If you left the default settings in place you will have a speed of 8kph and cadence of 0. Shake the device in a rhythmic fashion and you will start to see the calculated steps per minute come through.


There will be some error in the calculations for speed and cadence. You need to decide if you are going to use it running or walking. This is common with all but the very expensive versions of these devices.

Another solution would be to use more advanced timing code and measure the change in cadence strikes and foot travel time to establish if the person is running or walking, then change the speed calculation accordingly. The idea behind this would very easily transfer to any fitness devices that had any form of rhythmic movement.

Currently, only commercial rowing machines or elliptical devices have this type of technology. Using simple hall effect sensor you could easily convert one to transmit in BLE as a RCS sensor or a cycling sensor. The CurieIMU library has lots of examples of detecting double taps and axis rolls. What about detecting a wrist roll to turn the display on?

Of course, this is only the tip of the iceberg when it comes to BLE technology. There's endless ideas that can leverage this amazing platform - imagine it, and you can probably build it.