Avilmaru
Published © CC BY-SA

Bluetooth Low Energy: Gesture Control

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

IntermediateFull instructions provided4,917
Bluetooth Low Energy: Gesture Control

Things used in this project

Story

Read more

Code

Arduino Nano 33 BLE Sense central device sketch

Arduino
#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 sketch

Arduino
#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);
      
}

Credits

Avilmaru
6 projects • 17 followers

Comments