Project tutorial
Arduino101 Bluetooth Intertial Measurement Unit (IMU)

Arduino101 Bluetooth Intertial Measurement Unit (IMU) © GPL3+

Use the Arduino101 Bluetooth wireless interface to read the Intertial Measurement Unit (IMU) with your phone or tablet using Blynk !

  • 1,745 views
  • 0 comments
  • 6 respects

Components and supplies

Apps and online services

About this project

The Arduino101 features the Intel Curie Processor with a Bluetooth Low Energy Radio, Inertial Measurement Unit and sensors, in an Arduino Uno format.Today we'll be learning about the Bluetooth Low Energy Radio and a simple method to get access to sensors and peripherals on your phone or tablet using the Blynk GUI Library to make our user interface.

Important

The following project was tested using a few specific versions of libraries and applications - as the most recent versions have some bugs in them.If you experience problems, first make sure you are using these tested versions:

  • Arduino IDE Version 1.8.1
  • Intel Curie Board File Version 1.0.7
  • Blynk Version 0.4.6

Bluetooth Low Energy support in Blynk is still in BETA test status, so this is pretty new code that is being actively developed. Bluetooth security is also low. Be warned, there may be bugs and dragons here, as you are on the bleeding edge now...

Installation

On your laptop or computer, please install :

  • Install the Arduino IDE Version 1.8.1 from https://www.arduino.cc/en/Main/OldSoftwareReleases#previous
  • Install the Intel Curie Board File Version 1.0.7 from https://www.arduino.cc/en/guide/arduino101#toc2
  • Install Blynk Version 0.4.6 from http://www.blynk.cc/getting-started/
  • Install the SimpleTimer Library from https://github.com/jfturcot/SimpleTimer Install the Arduino_101_BLE_Relays.ino sketch from below.
  • Install the TimeLib library from : https://github.com/PaulStoffregen/Time/blob/master/TimeLib.h

On your smartphone or tablet, please install :

  • Android Store from https://play.google.com/store/apps/details?id=cc.blynk&hl=en
  • Apple/iTunes Store from https://itunes.apple.com/us/app/blynk-iot-for-arduino-rpi-particle-esp8266/id808760481?mt=8

Start the Blynk Application on Android or iPhone

  • After installing the Blynk application, start it up
  • While Blynk is free, they do charge for using many "widgets" (it's how they stay in business...) for complicated GUI displays, this basic example should fit within a "free" account. You can add "Energy" in the store, usually start with a small amount (< $20), that will last for a number of different Blynk projects.
  • Blynk can "clone" a user interface project using a QRcode image - shine your camera at the image below :

Now your smartphone screen should look like :

The four (4) Buttons at the top of the screen can be used to control two (2) Relay boards, for up to four ($) relays total. The Six Values represent the six degrees of freedom.

Email the Blynk Authorization Code to Yourself

Press the "Setup" icon (the Nut Icon on the top right), and you'll get the setup menu like this :

Press the "Email All" button, and it Blynk will email you a unique authorization code for your device. You will need to enter that Auth Code String into your Arduino sketch (program) and then download it to your hardware in order to pair your device with your smartphone.

Plug in your Arduino101

The first time you plug in your Arduino101 board, it may take several minutes to identify and load drivers. Don't worry if you get an error the first time, the USB serial port can get disabled during Arduino101 reset, and can sometimes fail before the drivers get loaded. Note which serial port get assigned (i.e. COM7, etc.)

Program your Arduino101 Bootloader

  • Start the Arduino IDE
  • Under "Tools->Board Manager" select the Arduino/Genuino101 board
  • Under "Tools->Board Manager" select the correct serial port (i.e. COM7)
  • Under "Tools->Board Manager" select Programmer: Arduino/Genuino101 Firmware Update
  • Under "Tools->Board Manager" select "Burn Bootloader"

This will insure that your boards file and bootloader version match. If you have problems uploading, try burning the bootloader again.

Program your Arduino101

  • Cut the Blynk Auth Code from your Email and paste it into the Arduino Sketch in place of the "XXXX''s"
  • From the Arduino IDE select "Sketch->Upload", and your project will compile and get loaded into flash memory.
  • The default Device name under Bluetooth is "hack01", you can change this in the sketch if you wish to uniquely identify your board.

Install your Adapter board and Relays

If not already installed, unplug the Arduino101 and add the boards as shown :

Now your smartphone screen should look like :

The first thing we need to do is to connect to the Arduino101 Bluetooth - so press the little "Bluetooth" icon on the display -

Now press the "Connect BLE device" button :

Select your device from the list, in the workshop they should have different names for each team's device. "hack02" is shown here...The internal gears will spin a bit, and then you should get a connected message:

Use the <- back arrow to return to the Arduino101setup screen

Now make sure to press the "play" arrow in the upper right hand corner of the screen to change from "setup" mode to "live" mode. If you press the buttons in "setup" mode (which has the dotted background screen), you can change the button settings. In "live" mode, the four buttons operate the four (4) relays, turning them on and off.

How does it work?

In a Blynk enabled sketch, you can either call out physical device pins to manipulate, or use virtual device pins. I prefer virtual device pins for flexibility in porting a project to different boards and/or devices. Virtual pins also allow for arbitrary data types to be passed back and forth across a connection - making it easy to use Wi-Fi, or Bluetooth radios with little or no code changes.Virtual PinsVirtual pins are named V0 thru Vxx and use a simple access method

BLYNK_WRITE(V1) { 
 int pinData = param.asInt(); 
 digitalWrite(relay1_pin, pinData); 
} 

V1 controls Relay1, V2 controls Relay2, V3, controls Relay3, etc.Under the Widget settings for buttons, slider, etc is a pin select menu, just pick an unused virtual pin number to add a new function, either read or write or both.

V5 through V10 are used for AX, AY, AZ, GX, GY, and GZ respectively.

The widget above will display a value sent from the device on VIrtual Pin V5 with a range of 0-1023 and update frequency of 1 second. Our widget will use data "push" instead of 1 Sec polling.

Simple widgets, like the button, have less parameters to set. Use "Delete" to remove unwanted widget and to restore your "Energy Points" for making other projects.

Don't Flood the Server...

Free accounts are limited to the amount of data they can upload to the server, typically 10 pins per second, which is plenty for most applications. The easiest way to do that is to use a SimpleTimer set to interrupt once per second and update the pins. Another trick I use is to only send data change updates, not the raw data; and if your input data is noisy, then filter it first. See this ESP32/Blynk project for a more advanced example using timers data change flags and filters.

Okay, I got it, what's next?

Now we can read the Inertial Measurement Unit and transmit the sensor data back to the smartphone. So what will you use it for?

Code

Arduino_101_BLE_IMUC/C++
An Arduino101 sketch to send IMU data over a bluetooth connection
/*************************************************************
  Download latest Blynk library here:
    https://github.com/blynkkk/blynk-library/releases/latest

  Blynk is a platform with iOS and Android apps to control
  Arduino, Raspberry Pi and the likes over the Internet.
  You can easily build graphic interfaces for all your
  projects by simply dragging and dropping widgets.

    Downloads, docs, tutorials: http://www.blynk.cc
    Sketch generator:           http://examples.blynk.cc
    Blynk community:            http://community.blynk.cc
    Social networks:            http://www.fb.com/blynkapp
                                http://twitter.com/blynk_app

  Blynk library is licensed under MIT license
  This example code is in public domain.

 *************************************************************
  Note: This requires CurieBLE library
    from http://librarymanager/all#CurieBLE

  Warning: Bluetooth support is in beta!
 *************************************************************/

// comment the next line to disable Serial Output
//#define SERIAL_DEBUG 

#ifdef SERIAL_DEBUG
#define BLYNK_PRINT Serial
#endif

#include <BlynkSimpleCurieBLE.h>
#include <CurieBLE.h>
#include <CurieIMU.h>
#include <SimpleTimer.h>
#include <TimeLib.h>

int ax, ay, az;           // accelerometer values
int gx, gy, gz;           // gyrometer values
int calibrateOffsets = 1; // determine whether calibration takes place or not

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

BLEPeripheral  blePeripheral;

// A timer instance to avoid flooding the Blynk Server
SimpleTimer timer;

int relay1_pin = 6;
int relay2_pin = 10;
int relay3_pin = 5;
int relay4_pin = 9;
int led_pin    = 13;
int blinkState = 0;

BLYNK_WRITE(V1) {
  int pinData = param.asInt();
  digitalWrite(relay1_pin, pinData);
}

BLYNK_WRITE(V2) {
  int pinData = param.asInt();
  digitalWrite(relay2_pin, pinData);
}

BLYNK_WRITE(V3) {
  int pinData = param.asInt();
  digitalWrite(relay3_pin, pinData);
}

BLYNK_WRITE(V4) {
  int pinData = param.asInt();
  digitalWrite(relay4_pin, pinData);
}

/* we could also do it this way with "Pull"
BLYNK_READ(V5) {
  Blynk.virtualWrite(5, millis() / 1000);
}
*/

void timerService()
{
  // update the IMU data  
  // read raw accel/gyro measurements from device
  CurieIMU.readMotionSensor(ax, ay, az, gx, gy, gz);
  // We'll use "PUSH" at 1 sec intervals
  Blynk.virtualWrite(5,ax);  // V5
  Blynk.virtualWrite(6,ay);  // V6
  Blynk.virtualWrite(7,az);  // V7
  Blynk.virtualWrite(8,gx);  // V8
  Blynk.virtualWrite(9,gy);  // V9
  Blynk.virtualWrite(10,gz); // V10  

  #ifdef SERIAL_DEBUG
  // display tab-separated accel/gyro x/y/z values
  Serial.print("a/g:\t");
  Serial.print(ax);
  Serial.print("\t");
  Serial.print(ay);
  Serial.print("\t");
  Serial.print(az);
  Serial.print("\t");
  Serial.print(gx);
  Serial.print("\t");
  Serial.print(gy);
  Serial.print("\t");
  Serial.println(gz);
  #endif
  
// blink LED to indicate activity
  blinkState = !blinkState;
  digitalWrite(led_pin, blinkState);
}

void setup()
{
  #ifdef SERIAL_DEBUG
  // Debug console
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB
  }
  #endif
  
  // initialize the output (GPIO) pins
  pinMode(led_pin, OUTPUT);
  pinMode(relay1_pin, OUTPUT);
  pinMode(relay2_pin, OUTPUT);
  pinMode(relay3_pin, OUTPUT);
  pinMode(relay4_pin, OUTPUT);
  digitalWrite(led_pin, 0);    // V0
  digitalWrite(relay1_pin, 0); // V1
  digitalWrite(relay2_pin, 0); // V2
  digitalWrite(relay3_pin, 0); // V3
  digitalWrite(relay4_pin, 0); // V4

  // Other Time library functions can be used, like:
  //   timeStatus(), setSyncInterval(interval)...
  // Read more: http://www.pjrc.com/teensy/td_libs_Time.html
  // Update timerService every 1.0 second
  // we do this to avoid flooding the connection 
  // (i.e. the Blynk server) with too much data
  timer.setInterval(1000L, timerService);
  
  // start the Accel/Gyro/IMU
  CurieIMU.begin();
  delay(2000);

  #ifdef SERIAL_DEBUG
  Serial.print("Starting Gyroscope calibration and enabling offset compensation...");
  #endif
  
  CurieIMU.autoCalibrateGyroOffset();
  
  #ifdef SERIAL_DEBUG
  Serial.println(" Done with Gyroscope calibration");
  Serial.print("Starting Acceleration calibration and enabling offset compensation...");
  #endif
  
  CurieIMU.autoCalibrateAccelerometerOffset(X_AXIS, 0);
  CurieIMU.autoCalibrateAccelerometerOffset(Y_AXIS, 0);
  CurieIMU.autoCalibrateAccelerometerOffset(Z_AXIS, 1);
  
  #ifdef SERIAL_DEBUG
  Serial.println(" Done with Acceleration calibration");
  #endif
  
  // Set the accelerometer range to 250 degrees/second
  CurieIMU.setGyroRange(250);
  // Set the accelerometer range to 2G
  CurieIMU.setAccelerometerRange(2);
  
  blePeripheral.setLocalName("hack01");
  blePeripheral.setDeviceName("hack01");
  blePeripheral.setAppearance(384);

  Blynk.begin(blePeripheral, auth);

  blePeripheral.begin();
  #ifdef SERIAL_DEBUG
  Serial.println("Waiting for BTLE connection...");
  #endif
}

void loop()
{
  // nice and simple...
  Blynk.run();
  blePeripheral.poll();
  timer.run();
}

Schematics

Arduino_101_BLE_Relayer Presentation
Presentor's Slides

Comments

Similar projects you might like

Arduino101 Bluetooth Interfacing

Project tutorial by Tom Moxon

  • 2,483 views
  • 0 comments
  • 13 respects

Hackster Live April 2017 Workshop - Optional - Easy Add-on

Project tutorial by Katie Kristoff

  • 883 views
  • 3 comments
  • 7 respects

BLE Robot Using Blynk & Arduino

Project tutorial by Tom Moxon

  • 2,336 views
  • 0 comments
  • 13 respects

Smart Garbage Monitoring System Using Arduino 101

Project tutorial by Technovation

  • 21,419 views
  • 7 comments
  • 32 respects

Arduino101 / tinyTILE BLE: Match-Making Sunglasses

Project tutorial by Kitty Yeung

  • 11,335 views
  • 2 comments
  • 35 respects
Add projectSign up / Login