Another exciting thing about Arduino/Genuino 101 is its on-board six-axis accelerometer and gyroscope. In this chapter, we will guide you through getting data from the accelerometer and gyroscope and interpreting them as real-time gesture. Eventually, we will teach you how to control the servo through gesture.
Read values from the six-axis accelerometer and gyroscope
To read values from the accelerometer and gyroscope, we will use the library “CurieIMU.h” provided by Intel. This library comes installed with Curie board core, so you don’t need to import it manually.
Get Data from Accelerometer
Theory
Accelerometer measurements are results of gravitational force and acceleration in three orthogonal directions (Front, Left and straight up). When the board is placed in still, it will have a positive constant value along the vertical direction due to the pointing down gravitational force; when it’s in motion, the total result will be the victor sum of the gravitational force and its acceleration.
CODE
The sample code comes in “CurieIMU.h” library and can be found under Menu Bar > File > Examples > CurieIMU > Accelerometer
You can also copy and paste the code from below.
#include "CurieIMU.h"
void setup() {
Serial.begin(9600); // initialize Serial communication while (!Serial); // wait for the serial port to open
// initialize device
Serial.println("Initializing IMU device...");
CurieIMU.begin();
// Set the accelerometer range to 2G
CurieIMU.setAccelerometerRange(2);
}
void loop() {
int axRaw, ayRaw, azRaw; // raw accelerometer values float ax, ay, az;
// read raw accelerometer measurements from device
CurieIMU.readAccelerometer(axRaw, ayRaw, azRaw);
// convert the raw accelerometer data to G's
ax = convertRawAcceleration(axRaw);
ay = convertRawAcceleration(ayRaw);
az = convertRawAcceleration(azRaw);
// display tab-separated accelerometer x/y/z values
Serial.print("a:\t");
Serial.print(ax);
Serial.print("\t");
Serial.print(ay);
Serial.print("\t");
Serial.print(az);
Serial.println();
}
float convertRawAcceleration(int aRaw) {
// since we are using 2G range
// -2g maps to a raw value of -32768
// +2g maps to a raw value of 32767
float a = (aRaw * 2.0) / 32768.0;
return a; }
Read Measurements in Serial Monitor
Once the code is uploaded, wait for a few seconds till 101 completes booting up, then open the serial monitor. When the board is placed on a flat surface with its topside facing up, the data will mostly be like as following. Measurements are in the unit of g = 9.8m/s2.
Code Analysis
CurieIMU.readGyro(gxRaw, gyRaw, gzRaw);
Reads raw gyroscope measurements from device and puts the data into variable “gxRaw”,” gyRaw” and “gzRaw”.
gx = convertRawGyro(gxRaw);
Converts the raw gyro data into degrees/s.
Additional function
The library also comes with a calibration function for gyroscope. Different from accelerometer, you may place 101 anyway you want but has to be in still, and no parameter will be needed to define its orientation. To do this, add the code below right after “CurieIMU.begin();” . CurieIMU.autoCalibrateGyroOffset();
Measurements after calibration will be like as following.
Control servo using gesture
Here, we will use our 101 to control the servo through gesture. When 101 leans to left, servo turns to one direction; when leans to right, servo turns to another.
COMPONMENT LIST:
1× TowerPro SG50 Servo
HARDWARE CONNECTIONS
Connect the TowerPro SG50 to digital pin 9
Review the diagram below for reference:
Be sure that your power, ground and signal connections are correct or you risk damaging your components.
Theory
When 101 is only under the effect of gravitational force (no acceleration), the measurements along an axis ranges from –g to g. The more an axis tilts away from the horizontal plane, the larger the gravitational force is. Therefore, controlling of the servo through gesture can be simply accomplished by mapping the measurement alone an axis to the angular position of the servo.
CODE
#include "CurieIMU.h"
#include <Servo.h>
int pos;
Servo myservo; // create servo object to control a servo void setup() {
// attaches the servo on pin 9 to the servo object
myservo.attach(9);
// initialize device
CurieIMU.begin();
CurieIMU.autoCalibrateAccelerometerOffset(X_AXIS, 0);
CurieIMU.autoCalibrateAccelerometerOffset(Y_AXIS, 0);
CurieIMU.autoCalibrateAccelerometerOffset(Z_AXIS, 1);
// Set the accelerometer range to 2G
CurieIMU.setAccelerometerRange(2);
}
void loop() {
int axRaw, ayRaw, azRaw; // raw accelerometer values float ax, ay, az;
// read raw accelerometer measurements from device
CurieIMU.readAccelerometer(axRaw, ayRaw, azRaw);
// convert the raw accelerometer data to G's
ax = convertRawAcceleration(axRaw);
ay = convertRawAcceleration(ayRaw);
az = convertRawAcceleration(azRaw);
pos = 90+ax*90;
constrain (pos,0,180);
myservo.write(pos);
}
float convertRawAcceleration(int aRaw) {
// since we are using 2G range
// -2g maps to a raw value of -32768
// +2g maps to a raw value of 32767
float a = (aRaw * 2.0) / 32768.0;
return a; }
CODE ANALYSIS
#include <Servo.h>
To drive a servo, you must have the library “Servo.h” included. This library comes preinstalled with the Arduino IDE, so you don't have to import it manually.
Servo myservo;
Defines “myservo” as a servo typed object to use functions in library “Servo.h”.
myservo.attach(9);
Defines which pin the servo is attached to (D9 in our case).
pos = 90+ax*90;
Maps the value of “ax” (from -1 to 1) to the value of “pos” (from 0 to 180).
constrain (pos,0,180);
Puts a constrain on “pos“, making sure it doesn't exceed the limit.
write(pos);
Sets servo to move to an angle. You may put any integer number ranges from 0-180. This number corresponds to the angular position between 0-180 degrees respectively.