Qwiic Flex Glove Controller Hookup Guide
Introduction
Flex sensors are great for telling how bent something is in a project, but we've been running into issues with durability when using them in wearable applications like gloves. The Qwiic Flex Glove Controller isolates the weak point to allow for more permanent flex sensor applications. The board has an onboard ADS1015 ADC to I2C so we can get a whole bunch of analog inputs without touching our microcontroller's ADC pins.
In this hookup guide, we'll figure out how to pull values from our fingers as well as calibrate the sensor for our range of motion. We'll also cover recommended placement and installation to implement these into gloves.
Required Materials
To get started, you'll need a microcontroller to, well, control everything.
Now to get into the Qwiic ecosystem, the key will be one of the following Qwiic shields to match your preference of microcontroller:
You will also need a Qwiic cable to connect the shield to your sensor, choose a length that suits your needs.
If you don't have a sewing needle, we'd recommend grabbing one if you're trying to add these flex sensors to some gloves.
Suggested Reading
If you aren't familiar with the Qwiic system, we recommend reading here for an overview.
Qwiic Connect System |
We would also recommend taking a look at the hookup guide for the Qwiic Shield if you haven't already. Brushing up on your skills in I2C is also recommended, as all Qwiic sensors are I2C.
Serial Terminal Basics
Qwiic Shield for Arduino & Photon Hookup Guide
You'll also most likely want to sew these boards into a wearable project, so if you've never picked up a needle and thread before, we'd recommend checking out a how-to on hand sewing.
Hardware Overview
Let's look over a few characteristics of the ADS1015 so we know a bit more about how our glove controller behaves.
Characteristic | Range |
---|---|
Operating Voltage | 2.0V - 5.5V |
Operating Temperature | -40°C - 125°C |
Resolution | 12 bit |
Sample Rate | 128 Hz - 3.3 kHz |
Current Consumption | 150 µA (Typ.) |
I2C Address | 0x48 (default), 0x49, 0x4A, 0x4B |
Pins
The characteristics for the pins of the Qwiic flex glove controller are outlined in the table below.
Pin Label | Pin Function | Input/Output | Notes |
---|---|---|---|
3.3V | Power Supply | Input | Should be between 2.2V - 3.6V |
GND | Ground | Input | 0V/common voltage. |
SDA | I2C Data Signal | Bi-directional | Bi-directional data line. Voltage should not exceed power supply (e.g. 3.3V). |
SCL | I2C Clock Signal | Input | Master-controlled clock signal. Voltage should not exceed power supply (e.g. 3.3V). |
Optional Features
The Qwiic Flex Glove controller has onboard I2C pull up resistors; if multiple sensors are connected to the bus with the pull-up resistors enabled (which they most likely will be if you're creating a full set of gloves), the parallel equivalent resistance will create too strong of a pull-up for the bus to operate correctly. As a general rule of thumb, disable all but one pair of pull-up resistors if multiple devices are connected to the bus. If you need to disconnect the pull up resistors they can be removed by cutting the traces on the corresponding jumpers highlighted below.
The I2C address of the board can be changed using the jumpers on the back of the board. The address selection pin is connected to the center pad of each jumper, the below table shows the addresses available when the address selection pin is tied to each of the 4 available pads.
Pin | Address |
---|---|
GND | 0x48 (Default) |
VCC | 0x49 |
SDA | 0x4A |
SCL | 0x4B |
The location of the jumpers is shown in the below image.
The holes in the bottom corners of the board are used for sewing the board into the gloves of your choice.
Make sure you don't crease the flex sensors as this will break the sensor!
Hardware Assembly
If you haven't yet assembled your Qwiic Shield, now would be the time to head on over to that tutorial.
With the shield assembled, SparkFun's new Qwiic environment means that connecting the sensor could not be easier. Just plug one end of the Qwiic cable into the Flex Glove Controller breakout, the other into the Qwiic Shield of your choice and you'll be ready to upload a sketch and figure out how bent your fingers are. It seems like it's too easy to use, but that's why we made it that way!
You may want to integrate this board into some gloves, after all, that's what it was originally designed for. If you're looking to get sensors on 8 fingers, you'll need 4 glove boards, and if you have 4 boards on the same IsC bus, you'll need to use every address available to the ADS1015. So get started by changing the addresses of your boards so no two boards share the same address.
Now we want to attach our boards to our gloves. We've found it best to sandwich the board between two layers of gloves to keep the sensor flush with the finger. To accomplish this, we'll sew the board to the outer layer of the inner glove. First, lay the glove out flat and place the board on the glove so that the ends of the flex sensors reach the tips of the fingers.
Once you have the sensor laid out on the glove, take a marker and mark the point where the sewing hole touches the glove.
Now simply sew the points to the available mounting holes on the sensor, The finished product should look like the below glove.
Now it's time to hide the circuitry under a second glove. Go ahead and put the just the fingers of the second glove on, then slip the flex sensor down the gap between the the two layers of fabric. Sensors are shown at various states of this process in the image below.
Now just plug Qwiic cables to connect both boards together, then plug one board into your microcontroller so we can get readings from the glove.
Library Overview
Note: This example assumes you are using the latest version of the Arduino IDE on your desktop. If this is your first time using Arduino, please review our tutorial on installing the Arduino IDE. If you have not previously installed an Arduino library, please check out our installation guide.
Before we get into getting data from our flex sensors, let's look at the available functions in the library. We've written a library to control the flex sensors. You can snag this library through the Arduino Library Manager. Search for SparkFun ADS1015 Arduino Library and you should be able to install the latest version. If you prefer manually downloading the libraries from the GitHub repository, you can grab them here:
Let's get started by looking at the functions that set up the flex controller.
Setup and Settings
boolean begin(uint8_t i2caddr = ADS1015_ADDRESS_GND, TwoWire &wirePort = Wire);
--- By default use the default I2C address and use Wire port. Otherwise, pass in a custom I2C address and wire port.uint16_t getAnalogData(uint8_t channel);
--- Returns the uncalibrated analog value from the sensor.float getScaledAnalogData(uint8_t channel);
--- Returns a value between 0 and 1 based on calibration. Won't work properly without first runningcalibrate()
void calibrate();
--- Used to calibrate the sensor and map the flexible range to values given by the user. While running calibration, simply flex each sensor to the minimum and maximum that it will be used in your project.void setMode(uint16_t mode);
--- Set mode of the sensor. Mode 0 is continuous read mode, mode 1 is single-shotuint16_t getMode();
--- Get's the read mode of the ADS1015.getCalibration(uint8_t channel, bool hiLo)
--- Get the high or low calibration value for a certain channel. ifhiLo
is true,getCalibration()
will return the high calibration for the given channel.setCalibration(uint8_t channel, bool hiLo, uint16_t value)
--- Sets the high or low calibration value of a channel without using the automatic calibration function. Allows for manual calibration.resetCalibration()
--- Resets the calibration to 0.void setGain(uint16_t gain);
--- Pass in different values for different gainsuint16_t getGain();
--- Get's the gain of the ADS1015. This will return 16-bit hex value. The values and their corresponding gains are listed below.0x0E00
: ± 0.256V0X0000
: ± 6.144V0X0200
: ± 4.096V0X0400
: ± 2.048V0X0600
: ± 1.024V0X0800
: ± 0.512V0X0A00
: ± 0.256V
void setSampleRate(uint16_t sampleRate);
--- Sets the sample rate for the ADS1015, pass in the below 16-bit values to change to the corresponding sample rate.0X0000
: 128 Hz0X0020
: 250 Hz0X0040
: 490 Hz0X0060
: 920 Hz0X0080
: 1600 Hz0X00A0
: 2400 Hz0X00C0
: 3300 Hz
uint16_t getSampleRate();
--- Returns the sample rate according to the above list of sample rates.
Example Code
Now that we know how our library works, let's go ahead and get started pulling values from our flex sensors.
Example 1 - Basic Readings
To get started with the first example, open up File > Examples > SparkFun ADS1015 Arduino Library > Qwiic Flex Glove Controller > Example1_BasicReadings. In this example, we begin by creating an ADS1015
object called fingerSensor
and then initializing our sensor object in the setup()
loop. We then get the values from each finger by looping through and reading each channel on the ADS1015. The code for this is shown below.
language:c
#include <SparkFun_ADS1015_Arduino_Library.h>
ADS1015 fingerSensor;
void setup() {
Wire.begin();
Serial.begin(115200);
if (fingerSensor.begin(Wire, 100000, ADS1015_ADDRESS_GND) == false) {
Serial.println("Device not found. Check wiring.");
while (1);
}
}
void loop() {
uint16_t data;
for (int finger = 0; finger < 2; finger++) {
data = fingerSensor.getAnalogData(finger);
Serial.print(finger);
Serial.print(": ");
Serial.print(data);
Serial.print(",");
}
Serial.println();
}
Uploading this sketch and opening the Serial Monitor to 115200 bps will yield an output somewhat like the below image.
Example 2 - Setup hand
In this example, we'll see how to setup an entire hand of flex sensors. To get started with this example, open up File > Examples > SparkFun ADS1015 Arduino Library > Qwiic Flex Glove Controller > Example2_SetupHand. In this example, we create two ADS1015
objects, naming them indexSensor
and pinkySensor
to correspond with their locations on the glove. We also create an array with 4 spots to hold the data for the hand called hand
. We then populate hand
with values from each sensor. The code that accomplishes this is shown below.
language:c
#include <SparkFun_ADS1015_Arduino_Library.h>
ADS1015 pinkySensor;
ADS1015 indexSensor;
uint16_t hand[4] = {0, 0, 0, 0};
void setup() {
Wire.begin();
Serial.begin(115200);
if (pinkySensor.begin(Wire, 100000, ADS1015_ADDRESS_SDA) == false) {
Serial.println("Pinky not found. Check wiring.");
while (1);
}
if (indexSensor.begin(Wire, 100000, ADS1015_ADDRESS_GND) == false) {
Serial.println("Index not found. Check wiring.");
while (1);
}
}
void loop() {
uint16_t data;
for (int finger = 0; finger < 2; finger++) {
hand[finger] = indexSensor.getAnalogData(finger);
hand[finger + 2] = pinkySensor.getAnalogData(finger);
}
for (int finger = 0; finger < 4; finger++)
{
Serial.print(finger);
Serial.print(": ");
Serial.print(hand[finger]);
Serial.print(" ");
}
Serial.println();
}
Uploading this sketch and opening the Serial Monitor to 115200 bps will yield an output somewhat like the below image.
Example 3 - Calibration
The second example will show us how to calibrate our flex sensor so we get 0 when our finger is closed and 1 when it is open. To get started, open up File > Examples > SparkFun ADS1015 Arduino Library > Qwiic Flex Glove Controller > Example3_Calibration. In this example we will calibrate our sensor's maximum and minimum values in order to find the range for our sensor.
language:c
#include <SparkFun_ADS1015_Arduino_Library.h>
#include <Wire.h>
ADS1015 fingerSensor;
void setup() {
Wire.begin();
Serial.begin(115200);
if (fingerSensor.begin(Wire, 100000, ADS1015_ADDRESS_GND) == false) {
Serial.println("Device not found. Check wiring.");
while (1);
}
Serial.println("Calibrating, send 'e' when finished");
}
void loop() {
uint8_t incoming;
do
{
fingerSensor.calibrate();
if(Serial.available())
{
incoming = Serial.read();
}
} while (incoming != 'e');
Serial.println("Calibrated");
for (int channel; channel < 2; channel++)
{
Serial.print("Channel ");
Serial.print(channel);
Serial.print(": ");
for (int hiLo = 0; hiLo < 2; hiLo++)
{
switch (hiLo)
{
case 0:
Serial.print("Low: ");
Serial.print(fingerSensor.getCalibration(channel, hiLo));
break;
case 1:
Serial.print(" High: ");
Serial.print(fingerSensor.getCalibration(channel, hiLo));
break;
}
}
Serial.println();
}
}
The sensor is initialized in the same manner as the first example, then our loop()
begins calibrating the sensors. To calibrate the sensors, simply flex them to their maximum and minimum bend radii, then send an e
over the Serial Monitor when you're finished. This will save the current calibration and show you the values that have been saved. Uploading this sketch and opening the Serial Monitor to 115200 bps will yield an output somewhat like the below image once you've sent e
and saved the calibration.
Example 4 - Calibrated Hand
You don't necessarily want to calibrate your hand every single time you put on a glove with the flex controllers built in, so let's figure out how to manually set our calibration if we know it already. To get started, open up File > Examples > SparkFun ADS1015 Arduino Library > Qwiic Flex Glove Controller > Example4_ManualCalibration. We can see in the preamble to our code that we have an array of all of our calibration values, which were obtained using the previous example sketch. We then use a loop in the setup function along with our setCalibration()
function to set the individual calibration values. The code for this is shown below.
language:c
#include <SparkFun_ADS1015_Arduino_Library.h>
#include <Wire.h>
ADS1015 pinkySensor;
ADS1015 indexSensor;
float hand[4] = {0, 0, 0, 0};
uint16_t handCalibration[4][2] = {
//{hi , low}
{722, 1080},//index
{600, 980},//middle
{680, 900},//ring
{736, 907} //pinky
};
void setup() {
Wire.begin();
Serial.begin(115200);
//Begin our finger sensors, change addresses as needed.
if (pinkySensor.begin(Wire, 100000, ADS1015_ADDRESS_SDA) == false)
{
Serial.println("Pinky not found. Check wiring.");
while (1);
}
if (indexSensor.begin(Wire, 100000, ADS1015_ADDRESS_GND) == false)
{
Serial.println("Index not found. Check wiring.");
while (1);
}
//Set the calibration values for the hand.
for (int channel; channel < 2; channel++)
{
for (int hiLo = 0; hiLo < 2; hiLo++)
{
indexSensor.setCalibration(channel, hiLo, handCalibration[channel][hiLo]);
pinkySensor.setCalibration(channel, hiLo, handCalibration[channel + 2][hiLo]);
}
Serial.println();
}
}
void loop() {
for (int channel = 0; channel < 2; channel++)
{
//Keep in mind that getScaledAnalogData returns a float
hand[channel] = indexSensor.getScaledAnalogData(channel);
hand[channel + 2] = pinkySensor.getScaledAnalogData(channel);
}
for (int finger = 0; finger < 4; finger++)
{
Serial.print(finger);
Serial.print(": ");
Serial.print(hand[finger]);
Serial.print(" ");
}
Serial.println();
}
Uploading this sketch and opening the serial monitor will show a stream of calibrated values. Use these to scale any other variable you'd like in your project.
Resources and Going Further
Now that you've successfully got your Qwiic Flex Glove Controller up and running, it's time to incorporate it into your own project!
For more information, check out the resources below:
- Schematic (PDF)
- Eagle Files (ZIP)
- ADS1015 Datasheet (PDF)
- Qwiic Landing Page
- GitHub Repos
- SparkFun Product Showcase: Qwiic Flex Glove Controller
Need even more inspiration for your next project? Check out some of these related tutorials:
SparkFun Qwiic MicroPressure Hookup Guide
RFID Beginners Tutorial
Qwiic SHIM Kit for Raspberry Pi Hookup Guide
Qwiic 6DoF (LSM6DSO) Breakout Hookup Guide
Or check out this blog post for inspiration.