Last active
November 18, 2020 09:22
-
-
Save xymox12/241e1e686d8a95e526af9f611c2f217d to your computer and use it in GitHub Desktop.
This file contains hidden or 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
/* | |
Based on Neil Kolban example for IDF: | |
https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleWrite.cpp | |
Ported to Arduino ESP32 by Evandro Copercini | |
*/ | |
// Modificado por Juan Antonio Villalpando. | |
// http://kio4.com/arduino/160i_Wemos_ESP32_BLE.htm | |
// https://community.appinventor.mit.edu/t/ble-esp32-bluetooth-send-receive-arduino-ide/1980/3 | |
// https://github.com/michaelruck/ESP32_phone_camera_remote_shutter | |
// A Frankenstein's monstor from the above that works for me :P | |
// Camera Shutter BLE HID code for Android. | |
// Apart from the HID device, an extra service + characteristic is also created to react to | |
// commands from a MIT Inventor 2 application (TODO) | |
#include <BLEDevice.h> | |
#include <BLEUtils.h> | |
#include <BLEServer.h> | |
#include <BLE2902.h> | |
#include <BLEHIDDevice.h> | |
#include <HIDTypes.h> | |
#include <HIDKeyboardTypes.h> | |
// Bluetooth labels | |
#define __MANUFACTURER "CAHSS DIT" | |
#define __BT_NAME "Cam-Butts" | |
// UUIDs | |
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" | |
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" | |
// BLE HID Descriptor Report ID | |
#define MEDIA_KEYS_ID 0x01 | |
// Hex value of the key pressed | |
#define KEY_PRESSED 0xe9 // Volume up key | |
BLEHIDDevice *hid; | |
BLECharacteristic *inputVolume; | |
BLECharacteristic *outputVolume; | |
// Boolean to check in loop if BLE successfully connected | |
bool connected = false; | |
// Application callback | |
class MyCallbacks: public BLECharacteristicCallbacks { | |
String valor; | |
void onWrite(BLECharacteristic *pCharacteristic) { | |
std::string value = pCharacteristic->getValue(); | |
if (value.length() > 0) { | |
valor = ""; | |
for (int i = 0; i < value.length(); i++){ | |
// Serial.print(value[i]); // Presenta value. | |
valor = valor + value[i]; | |
} | |
Serial.println("*********"); | |
Serial.print("valor = "); | |
Serial.println(valor); // Presenta valor. | |
} | |
} | |
}; | |
// Server Callback | |
class ServerCallbacks : public BLEServerCallbacks { | |
void onConnect(BLEServer* pServer) { | |
connected = true; | |
BLE2902* desc = (BLE2902*)inputVolume->getDescriptorByUUID(BLEUUID((uint16_t)0x2902)); | |
desc->setNotifications(true); | |
} | |
void onDisconnect(BLEServer* pServer) { | |
connected = false; | |
BLE2902* desc = (BLE2902*)inputVolume->getDescriptorByUUID(BLEUUID((uint16_t)0x2902)); | |
desc->setNotifications(false); | |
} | |
}; | |
// BLE HID Callback | |
class MyOutputCallbacks: public BLECharacteristicCallbacks { | |
void onWrite(BLECharacteristic* me) { | |
uint8_t* value = (uint8_t*)(me->getValue().c_str()); | |
ESP_LOGI(LOG_TAG, "special keys: %d", *value); | |
} | |
}; | |
// Task can make use of second core on esp32 | |
void taskServer(void*) { | |
BLEDevice::init(__BT_NAME); | |
BLEServer *pServer = BLEDevice::createServer(); | |
pServer->setCallbacks(new ServerCallbacks()); | |
// Service 1 = pService == Android App interface | |
BLEService *pService = pServer->createService(SERVICE_UUID); | |
// Characteristic 1 | |
BLECharacteristic *pCharacteristic = pService->createCharacteristic( | |
CHARACTERISTIC_UUID, | |
BLECharacteristic::PROPERTY_READ | | |
BLECharacteristic::PROPERTY_WRITE | | |
BLECharacteristic::PROPERTY_NOTIFY | | |
BLECharacteristic::PROPERTY_INDICATE | |
); | |
pCharacteristic->addDescriptor(new BLE2902()); | |
pCharacteristic->setCallbacks(new MyCallbacks()); | |
pCharacteristic->setValue("Hello World"); | |
pService->start(); | |
// Service 2 = HID == Camera Clicker | |
hid = new BLEHIDDevice(pServer); | |
inputVolume = hid->inputReport(1); // <-- input REPORTID from report map | |
outputVolume = hid->outputReport(MEDIA_KEYS_ID); // <-- output REPORTID from report map | |
std::string name = __MANUFACTURER; | |
hid->manufacturer()->setValue(name); | |
hid->pnp(0x02, 0xe502, 0xa111, 0x0210); | |
hid->hidInfo(0x00, 0x02); | |
// HID Descriptor report (consider https://github.com/drdnar/Arduino-HID-Remote instead?) | |
const uint8_t report[] = { | |
USAGE_PAGE(1), 0x0C, // USAGE_PAGE (Consumer) | |
USAGE(1), 0x01, // USAGE (Consumer Control) | |
COLLECTION(1), 0x01, // COLLECTION (Application) | |
USAGE_MINIMUM(1), 0x00, // USAGE_MINIMUM (Unassigned) | |
USAGE_MAXIMUM(2), 0x3c, 0x02, // USAGE_MAXIMUM (AC Format | |
REPORT_ID(1), MEDIA_KEYS_ID, // REPORT_ID (3) | |
USAGE_PAGE(1), 0x0C, // USAGE_PAGE (Consumer) | |
LOGICAL_MINIMUM(1), 0x00, // LOGICAL_MINIMUM (0) | |
LOGICAL_MAXIMUM(2), 0x3c, 0x02, // LOGICAL_MAXIMUM (1) | |
REPORT_SIZE(1), 0x10, // REPORT_SIZE (1) | |
REPORT_COUNT(1), 0x10, // REPORT_COUNT (16) | |
HIDINPUT(1), 0x00, // INPUT (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) | |
END_COLLECTION(0) // END_COLLECTION | |
}; | |
hid->reportMap((uint8_t*)report, sizeof(report)); | |
hid->startServices(); | |
BLESecurity *qSecurity = new BLESecurity(); | |
qSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND); | |
// Advertise Server | |
BLEAdvertising *pAdvertising = pServer->getAdvertising(); | |
pAdvertising->setAppearance(HID_KEYBOARD); | |
pAdvertising->addServiceUUID(hid->hidService()->getUUID()); | |
pAdvertising->start(); | |
// Set battery level - just not 0 :P | |
hid->setBatteryLevel(70); | |
delay(portMAX_DELAY); | |
} | |
void setup() { | |
Serial.begin(115200); | |
// Create a task to make use of esp32 cores | |
xTaskCreate(taskServer, "server", 20000, NULL, 5, NULL); | |
} | |
void loop() { | |
static bool volDirUp = true; | |
delay(4000); | |
if (connected) { | |
Serial.println("Cheese..."); | |
// Key press | |
uint8_t vol_up_key_press = KEY_PRESSED; | |
inputVolume->setValue((uint8_t*)&vol_up_key_press,sizeof(vol_up_key_press)); | |
inputVolume->notify(); | |
//Key release | |
uint8_t vol_up_key_release = 0x0; | |
inputVolume->setValue((uint8_t*)&vol_up_key_release,sizeof(vol_up_key_release)); | |
inputVolume->notify(); | |
delay(1000); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment