Last active
November 11, 2019 22:04
-
-
Save Palantir555/27315593fbc5bdbed21bfb9cbceb7e85 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This sketch is the BLE GATT server for a halloween costume. | |
* For more information on the project, check this post: | |
* https://jcjc-dev.com/2019/11/11/esp32-arduino-bluetooth-halloween-costume/ | |
* | |
* Create a BLE server that, once we receive a connection, will poll a button and | |
* an accelerometer. If the button is pressed or the device is moved abruptly, | |
* the device will send a notification to the BLE clients. | |
* | |
* The service advertises itself as $BLE_STORM_SERVICE_UUID | |
* And has a characteristic of $BLE_PROP_CHARACTERISTIC_UUID | |
* | |
* The design of creating the BLE server is: | |
* 1. Create a BLE Server | |
* 2. Create a BLE Service | |
* 3. Create a BLE Characteristic on the Service | |
* 4. Create a BLE Descriptor on the characteristic | |
* 5. Start the service. | |
* 6. Start advertising. | |
* | |
* A connect hander associated with the server starts a background task that | |
* performs notification every couple of seconds. | |
* | |
* Author: Juan Carlos Jimenez Caballero | |
* | |
* License: Fully Open Source. Use at your own peril | |
* This firmware uses code found in Aruino's ESP32 BLE GATT example, and some | |
* snippets from other unlicensed open source projects | |
*/ | |
#include <BLE2902.h> | |
#include <BLEDevice.h> | |
#include <BLEServer.h> | |
#include <BLEUtils.h> | |
/* Modify these UUIDs for your project. Generate your own using uuidgenerator.net | |
* or any other UUID generator */ | |
#define BLE_STORM_SERVICE_UUID "ca626879-77c5-4f6d-922c-e8fa1a6cb83c" | |
#define BLE_PROP_CHARACTERISTIC_UUID "08ea4673-8b2b-4394-8390-d6e6e96b4974" | |
#define GPIO_BUTTON_PIN 14 /* wire-connected button */ | |
#define ACCEL_SCL_PIN 22 | |
#define ACCEL_SDA_PIN 21 | |
#define USE_ACCEL_INPUT 1 | |
#if USE_ACCEL_INPUT | |
#define ACCL_THRESHOLD 50 | |
#include <Adafruit_ADXL345_U.h> | |
#include <Adafruit_Sensor.h> | |
#include <Wire.h> | |
/* Assign a unique ID to this sensor at the same time */ | |
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345); | |
#endif | |
BLEServer* pServer = NULL; | |
BLECharacteristic* pCharacteristic = NULL; | |
bool deviceConnected = false; | |
bool oldDeviceConnected = false; | |
bool button_read = LOW; | |
bool last_button_read = LOW; | |
class MyServerCallbacks : public BLEServerCallbacks | |
{ | |
void onConnect(BLEServer* pServer) | |
{ | |
deviceConnected = true; | |
}; | |
void onDisconnect(BLEServer* pServer) | |
{ | |
deviceConnected = false; | |
} | |
}; | |
void notify_uint32(uint32_t value) | |
{ | |
uint32_t bt_characteristic_value = value; | |
pCharacteristic->setValue((uint8_t*)&bt_characteristic_value, | |
sizeof(uint32_t)); | |
pCharacteristic->notify(); | |
} | |
void setup() | |
{ | |
Serial.begin(115200); | |
/* GPIO Init */ | |
pinMode(GPIO_BUTTON_PIN, INPUT_PULLUP); | |
#if USE_ACCEL_INPUT | |
/* The I2C data pins must be INPUT_PULLUP for accel.begin() to succeed */ | |
pinMode(ACCEL_SDA_PIN, INPUT_PULLUP); | |
pinMode(ACCEL_SCL_PIN, INPUT_PULLUP); | |
/* Initialise the sensor */ | |
while(!accel.begin()) { | |
/* Unable to detect the ADXL345. check your connections */ | |
Serial.println("ERROR! Unable to detect ADXL345. Check your wiring!"); | |
delay(1000); | |
} | |
/* Set the range to whatever is appropriate for your project */ | |
accel.setRange(ADXL345_RANGE_16_G); /* _8_G, _4_G, _2_G */ | |
#endif | |
/* Create the BLE Device */ | |
BLEDevice::init("ESP32"); | |
/* Create the BLE Server */ | |
pServer = BLEDevice::createServer(); | |
pServer->setCallbacks(new MyServerCallbacks()); | |
/* Create the BLE Service */ | |
BLEService* pService = pServer->createService(BLE_STORM_SERVICE_UUID); | |
/* Create a BLE Characteristic */ | |
pCharacteristic = pService->createCharacteristic( | |
BLE_PROP_CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | | |
BLECharacteristic::PROPERTY_WRITE | | |
BLECharacteristic::PROPERTY_NOTIFY | | |
BLECharacteristic::PROPERTY_INDICATE); | |
/* Create a BLE Descriptor */ | |
pCharacteristic->addDescriptor(new BLE2902()); | |
/* Start the service */ | |
pService->start(); | |
/* Start advertising */ | |
BLEAdvertising* pAdvertising = BLEDevice::getAdvertising(); | |
pAdvertising->addServiceUUID(BLE_STORM_SERVICE_UUID); | |
pAdvertising->setScanResponse(false); | |
pAdvertising->setMinPreferred(0x0); /* set bt_characteristic_value to 0x00 | |
* to not advertise this parameter */ | |
BLEDevice::startAdvertising(); | |
Serial.println("Waiting for a client connection to notify..."); | |
} | |
void loop() | |
{ | |
if(deviceConnected) { | |
uint32_t virtual_switch = 0; | |
button_read = digitalRead(GPIO_BUTTON_PIN); | |
if((button_read == LOW) && (last_button_read == HIGH)) { | |
/* button pressed */ | |
(virtual_switch == 1) ? (virtual_switch = 0) : (virtual_switch = 1); | |
notify_uint32(virtual_switch); | |
delay(300); /* Debounce */ | |
} | |
last_button_read = button_read; | |
#if USE_ACCEL_INPUT | |
/* Get a new sensor event (acceleration is measured in m/s^2) */ | |
sensors_event_t event; | |
accel.getEvent(&event); | |
if((event.acceleration.x > ACCL_THRESHOLD) || | |
(event.acceleration.x < -1 * ACCL_THRESHOLD) || | |
(event.acceleration.y > ACCL_THRESHOLD) || | |
(event.acceleration.y < -1 * ACCL_THRESHOLD) || | |
(event.acceleration.z > ACCL_THRESHOLD) || | |
(event.acceleration.z < -1 * ACCL_THRESHOLD)) { | |
/* These debug messages are useful to calibrate ACCL_THRESHOLD */ | |
/* | |
Serial.print("x: "); Serial.print(event.acceleration.x); | |
Serial.print(" | y: "); Serial.print(event.acceleration.y); | |
Serial.print(" | z: "); Serial.println(event.acceleration.z); | |
*/ | |
notify_uint32(1); | |
delay(400); | |
} | |
#endif | |
} | |
/* disconnecting */ | |
if(!deviceConnected && oldDeviceConnected) { | |
delay(500); /* give the BT stack the chance to get things ready */ | |
pServer->startAdvertising(); /* restart advertising */ | |
Serial.println("start advertising"); | |
oldDeviceConnected = deviceConnected; | |
} | |
/* connecting */ | |
if(deviceConnected && !oldDeviceConnected) { | |
/* do stuff here on connecting */ | |
oldDeviceConnected = deviceConnected; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment