Project tutorial
Bluetooth Low Energy: Gesture Control

Bluetooth Low Energy: Gesture Control © CC BY-SA

Example of the use of Bluetooth LE using the Arduino MKR WiFi 1010 and Arduino Nano 33 BLE Sense boards with the ArduinoBLE library.

  • 1,350 views
  • 1 comment
  • 4 respects

Components and supplies

About this project

Example of the use of Bluetooth Low Energy technology using the Arduino MKR WiFi 1010 and Arduino Nano 33 BLE Sense boards with the ArduinoBLE library.

This example is based on the “Central → LedControl” and “Peripherical → LED” sketches of the ArduinoBLE library.

The Bluetooth on the Arduino Nano 33 BLE Sense is managed by a NINA B306 module (Bluetooth v.5.0)

NINA B306 Data Sheet

The Bluetooth on the Arduino MKR WiFi 1010 is managed by the NINA-W102 module (Bluetooth v.4.2)

NINA-W10 Data Sheet

The following links explain the basics of Bluetooth Low Energy technology that will help us understand how it works:

https://www.arduino.cc/en/Reference/ArduinoBLE

https://learn.adafruit.com/introduction-to-bluetooth-low-energy/introduction

CIRCUIT

Components:

  • Central device: Arduino Nano 33 BLE Sense.
  • Peripheral device: Arduino MKR WiFi 1010 + Arduino MKR RGB Shield.

Target:

The central device will connect to the peripheral device searching for the characteristic of the specified service.

Once the connection is established if the Arduino Nano 33 BLE Sense gesture sensor (ADPS-9960) detects any of the following movements: UP, DOWN, LEFT and RIGHT the central device will write the corresponding value (associated with these movements) in the characteristic of the peripheral device by displaying the corresponding text with a color on the MKR RGB LED Matrix.

SKETCHES

A) Arduino Nano 33 BLE Sense central device sketch:

#include <ArduinoBLE.h>
#include <Arduino_APDS9960.h>
const char* deviceServiceUuid = "19b10000-e8f2-537e-4f6c-d104768a1214";
const char* deviceServiceCharacteristicUuid = "19b10001-e8f2-537e-4f6c-d104768a1214";
int gesture = -1;
int oldGestureValue = -1;
void setup() {
Serial.begin(9600);
while (!Serial);
if (!APDS.begin()) {
Serial.println("Error initializing APDS9960 sensor!");
}
APDS.setGestureSensitivity(80); // [1..100]
// begin ble initialization
if (!BLE.begin()) {
Serial.println("starting BLE failed!");
while (1);
}
Serial.println("BLE Central - gesture control");
}
void loop() {
connectToPeripheral();
}
void connectToPeripheral(){
BLEDevice peripheral;
do
{
// start scanning for peripherals
BLE.scanForUuid(deviceServiceUuid);
peripheral = BLE.available();
} while (!peripheral);
if (peripheral) {
// discovered a peripheral, print out address, local name, and advertised service
Serial.print("Found ");
Serial.print(peripheral.address());
Serial.print(" '");
Serial.print(peripheral.localName());
Serial.print("' ");
Serial.print(peripheral.advertisedServiceUuid());
Serial.println();
// stop scanning
BLE.stopScan();
controlPeripheral(peripheral);
}
}
void controlPeripheral(BLEDevice peripheral) {
// connect to the peripheral
Serial.println("Connecting ...");
if (peripheral.connect()) {
Serial.println("Connected");
} else {
Serial.println("Failed to connect!");
return;
}
// discover peripheral attributes
Serial.println("Discovering attributes ...");
if (peripheral.discoverAttributes()) {
Serial.println("Attributes discovered");
} else {
Serial.println("Attribute discovery failed!");
peripheral.disconnect();
return;
}
BLECharacteristic gestureCharacteristic = peripheral.characteristic(deviceServiceCharacteristicUuid);
if (!gestureCharacteristic) {
Serial.println("Peripheral does not have gesture characteristic!");
peripheral.disconnect();
return;
} else if (!gestureCharacteristic.canWrite()) {
Serial.println("Peripheral does not have a writable gesture characteristic!");
peripheral.disconnect();
return;
}
while (peripheral.connected()) {
gesture = gestureDetectection();
if (oldGestureValue != gesture) {
// gesture value changed
oldGestureValue = gesture;
Serial.print("writing value: ");
Serial.println(gesture);
gestureCharacteristic.writeValue((byte)gesture);
Serial.println("done!");
}
}
Serial.println("Peripheral disconnected!");
}
int gestureDetectection(){
if (APDS.gestureAvailable()) {
// a gesture was detected
gesture = APDS.readGesture();
switch (gesture) {
case GESTURE_UP:
Serial.println("Detected UP gesture");
break;
case GESTURE_DOWN:
Serial.println("Detected DOWN gesture");
break;
case GESTURE_LEFT:
Serial.println("Detected LEFT gesture");
break;
case GESTURE_RIGHT:
Serial.println("Detected RIGHT gesture");
break;
default:
Serial.println("NO gesture detected!");
break;
}
}
return gesture;
}

B) Arduino MKR WiFi 1010 peripheral device sketch:

#include <ArduinoBLE.h>
#include <Arduino_MKRRGB.h>
enum {
GESTURE_NONE = -1,
GESTURE_UP = 0,
GESTURE_DOWN = 1,
GESTURE_LEFT = 2,
GESTURE_RIGHT = 3
};
const char* deviceServiceUuid = "19b10000-e8f2-537e-4f6c-d104768a1214";
const char* deviceServiceCharacteristicUuid = "19b10001-e8f2-537e-4f6c-d104768a1214";
int gesture = -1;
// BLE gesture Service
BLEService gestureService(deviceServiceUuid);
// BLE gesture Switch Characteristic
BLEByteCharacteristic gestureCharacteristic(deviceServiceCharacteristicUuid, BLERead | BLEWrite);
void setup() {
//Serial.begin(9600);
//while (!Serial);
// initialize the display
MATRIX.begin();
// set the brightness, supported values are 0 - 255
MATRIX.brightness(120);
// configure the text scroll speed
MATRIX.textScrollSpeed(50);
MATRIX.clear();
MATRIX.endDraw();
// begin ble initialization
if (!BLE.begin()) {
//Serial.println("starting BLE failed!");
while (1);
}
// set advertised local name and service UUID:
BLE.setLocalName("Gesture peripheral");
BLE.setAdvertisedService(gestureService);
// add the characteristic to the service
gestureService.addCharacteristic(gestureCharacteristic);
// add service
BLE.addService(gestureService);
// set the initial value for the characeristic:
gestureCharacteristic.writeValue(-1);
// start advertising
BLE.advertise();
//Serial.println("BLE gesture Peripheral");
}
void loop() {
// listen for BLE peripherals to connect:
BLEDevice central = BLE.central();
// if a central is connected to peripheral:
if (central) {
//Serial.print("Connected to central: ");
// print the central's MAC address:
//Serial.println(central.address());
// while the central is still connected to peripheral:
while (central.connected()) {
// if the remote device wrote to the characteristic,
if (gestureCharacteristic.written()) {
gesture = gestureCharacteristic.value();
writeGesture(gesture);
}
}
// when the central disconnects, print it out:
//Serial.print(F("Disconnected from central: "));
//Serial.println(central.address());
}
}
void writeGesture(int gesture)
{
int R = 0;
int G = 0;
int B = 0;
String text = "";
switch (gesture) {
case GESTURE_UP:
text =" UP";
R=0;
G=255;
B=0;
break;
case GESTURE_DOWN:
text ="DOWN";
R=255;
G=0;
B=0;
break;
case GESTURE_LEFT:
text ="LEFT";
R=0;
G=0;
B=255;
break;
case GESTURE_RIGHT:
text ="RIGHT";
R=207;
G=9;
B=227;
break;
default:
text ="";
R=0;
G=0;
B=0;
break;
}
MATRIX.clear();
MATRIX.endDraw();
MATRIX.beginText(0, 0, R, G, B); // X, Y, then R, G, B
MATRIX.print(text);
MATRIX.endText(SCROLL_LEFT);
}

Code

Arduino Nano 33 BLE Sense central device sketchArduino
#include <ArduinoBLE.h>
#include <Arduino_APDS9960.h>

const char* deviceServiceUuid = "19b10000-e8f2-537e-4f6c-d104768a1214";
const char* deviceServiceCharacteristicUuid = "19b10001-e8f2-537e-4f6c-d104768a1214";
  
int gesture = -1; 
int oldGestureValue = -1;   

void setup() {
  
  Serial.begin(9600);
  while (!Serial);

  if (!APDS.begin()) {
    Serial.println("Error initializing APDS9960 sensor!");
  }

   APDS.setGestureSensitivity(80); // [1..100]
  
  // begin ble initialization
  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");
    while (1);
  }

  Serial.println("BLE Central - gesture control");

}

void loop() {
  
     connectToPeripheral();
}


void connectToPeripheral(){

  BLEDevice peripheral;

  do
  {
     // start scanning for peripherals
    BLE.scanForUuid(deviceServiceUuid);
    peripheral = BLE.available();
    
  } while (!peripheral);

  
  if (peripheral) {
    // discovered a peripheral, print out address, local name, and advertised service
    Serial.print("Found  ");
    Serial.print(peripheral.address());
    Serial.print(" '");
    Serial.print(peripheral.localName());
    Serial.print("' ");
    Serial.print(peripheral.advertisedServiceUuid());
    Serial.println();
  
    // stop scanning
    BLE.stopScan();
  
    controlPeripheral(peripheral);
   
  }
  
}

void controlPeripheral(BLEDevice peripheral) {

  
  // connect to the peripheral
  Serial.println("Connecting ...");

  if (peripheral.connect()) {
    Serial.println("Connected");
  } else {
    Serial.println("Failed to connect!");
    return;
  }

  // discover peripheral attributes
  Serial.println("Discovering attributes ...");
  if (peripheral.discoverAttributes()) {
    Serial.println("Attributes discovered");
  } else {
    Serial.println("Attribute discovery failed!");
    peripheral.disconnect();
    return;
  }

  BLECharacteristic gestureCharacteristic = peripheral.characteristic(deviceServiceCharacteristicUuid);
    
  if (!gestureCharacteristic) {
    Serial.println("Peripheral does not have gesture characteristic!");
    peripheral.disconnect();
    return;
  } else if (!gestureCharacteristic.canWrite()) {
    Serial.println("Peripheral does not have a writable gesture characteristic!");
    peripheral.disconnect();
    return;
  }

  
  while (peripheral.connected()) {

    gesture = gestureDetectection();

    if (oldGestureValue != gesture) {
      
      // gesture value changed
      oldGestureValue = gesture;
          
      Serial.print("writing value: ");
      Serial.println(gesture);
      gestureCharacteristic.writeValue((byte)gesture);
      Serial.println("done!");

    }
  
  }

  Serial.println("Peripheral disconnected!");

}
  
int gestureDetectection(){

  if (APDS.gestureAvailable()) {
    
    // a gesture was detected
    gesture = APDS.readGesture();

    switch (gesture) {
      case GESTURE_UP:
        Serial.println("Detected UP gesture");
        break;
      case GESTURE_DOWN:
        Serial.println("Detected DOWN gesture");
        break;
      case GESTURE_LEFT:
        Serial.println("Detected LEFT gesture");
        break;
      case GESTURE_RIGHT:
        Serial.println("Detected RIGHT gesture");
        break;
      default:
        Serial.println("NO gesture detected!");
        break;
      }
    
    }

    return gesture;
    
}
Arduino MKR WiFi 1010 peripheral device sketchArduino
#include <ArduinoBLE.h>
#include <Arduino_MKRRGB.h>

enum {
  GESTURE_NONE = -1,
  GESTURE_UP = 0,
  GESTURE_DOWN = 1,
  GESTURE_LEFT = 2,
  GESTURE_RIGHT = 3
};

const char* deviceServiceUuid = "19b10000-e8f2-537e-4f6c-d104768a1214";
const char* deviceServiceCharacteristicUuid = "19b10001-e8f2-537e-4f6c-d104768a1214";

int gesture = -1;

// BLE gesture Service
BLEService gestureService(deviceServiceUuid); 

// BLE gesture Switch Characteristic 
BLEByteCharacteristic gestureCharacteristic(deviceServiceCharacteristicUuid, BLERead | BLEWrite);


void setup() {
  
  //Serial.begin(9600);
  //while (!Serial);

  // initialize the display
  MATRIX.begin();
  // set the brightness, supported values are 0 - 255
  MATRIX.brightness(120);
  // configure the text scroll speed
  MATRIX.textScrollSpeed(50);
  MATRIX.clear();
  MATRIX.endDraw();

  
  // begin ble initialization
  if (!BLE.begin()) {
    //Serial.println("starting BLE failed!");
    while (1);
  }

  // set advertised local name and service UUID:
  BLE.setLocalName("Gesture peripheral");
  BLE.setAdvertisedService(gestureService);

  // add the characteristic to the service
  gestureService.addCharacteristic(gestureCharacteristic);

  // add service
  BLE.addService(gestureService);

  // set the initial value for the characeristic:
  gestureCharacteristic.writeValue(-1);

  // start advertising
  BLE.advertise();

  //Serial.println("BLE gesture Peripheral");
}

void loop() {
  
  // listen for BLE peripherals to connect:
  BLEDevice central = BLE.central();

  // if a central is connected to peripheral:
  if (central) {
    
    //Serial.print("Connected to central: ");
    // print the central's MAC address:
    //Serial.println(central.address());

    // while the central is still connected to peripheral:
    while (central.connected()) {
      
      // if the remote device wrote to the characteristic,
      if (gestureCharacteristic.written()) {
         gesture = gestureCharacteristic.value();
         writeGesture(gesture);
       }
      
    }

    // when the central disconnects, print it out:
    //Serial.print(F("Disconnected from central: "));
    //Serial.println(central.address());
  }
}

void writeGesture(int gesture)
{

  int R = 0;
  int G = 0;
  int B = 0;
  String text = "";
  
   switch (gesture) {
    
      case GESTURE_UP:
        text =" UP";
        R=0;
        G=255;
        B=0;
        break;
      case GESTURE_DOWN:
        text ="DOWN";
        R=255;
        G=0;
        B=0;
        break;
      case GESTURE_LEFT:
        text ="LEFT";
        R=0;
        G=0;
        B=255;
        break;
      case GESTURE_RIGHT:
        text ="RIGHT";
        R=207;
        G=9;
        B=227;
        break;
      default:
        text ="";
        R=0;
        G=0;
        B=0;
        break;
        
    }
    
    MATRIX.clear();
    MATRIX.endDraw();
    MATRIX.beginText(0, 0, R, G, B); // X, Y, then R, G, B
    MATRIX.print(text);
    MATRIX.endText(SCROLL_LEFT);
      
}

Comments

Similar projects you might like

Home Automation With Arduino 101 Using Bluetooth Low Energy

Project tutorial by naveen manwani

  • 2,317 views
  • 0 comments
  • 6 respects

Gesture Control Robot

Project tutorial by Raunak Oberai

  • 14,021 views
  • 17 comments
  • 35 respects

Playing NFS By Hand Gesture Control

Project tutorial by Najad

  • 5,894 views
  • 3 comments
  • 26 respects

Gesture Controlled Trainable Arduino Robot Arm via Bluetooth

Project tutorial by KureBas Robotics

  • 23,852 views
  • 54 comments
  • 155 respects

How to Make a Gesture Control Robot at Home

Project tutorial by Shubham Shinganapure

  • 8,765 views
  • 13 comments
  • 59 respects

Control the Speed of Brushless DC Motor Using Bluetooth

Project tutorial by mohitmehlawat

  • 8,034 views
  • 3 comments
  • 17 respects
Add projectSign up / Login