#include #include #include #include #include #include #include #include // TODO -- BLE server name #define bleServerName "" bool deviceConnected = false; // TODO -- Generate a unique UUID for your Bluetooth service // See the following for generating UUIDs: // https://www.uuidgenerator.net/ #define SERVICE_UUID "91bad492-b950-4226-aa2b-4ede9fa42f59" #define CHARACTERISTIC_UUID "ca73b3ba-39f6-4ab3-91ae-186dc9577d99" // BEGIN CHARACTERISTICS // FOR THE FOLLOWING LINES CHANGE ONLY THE UUID of the characteristic // Define a caracteristic with the properties: Read, Write (with response), Notify // Use the above link for generating UUIDs BLECharacteristic characteristic( CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_NOTIFY ); // Define a descriptor characteristic // IMPORTANT -- The characteristic should have the descriptor UUID 0x2902 or 0x2901 BLEDescriptor *characteristicDescriptor = new BLEDescriptor(BLEUUID((uint16_t)0x2902)); // Setup callbacks onConnect and onDisconnect (no change necessary) class MyServerCallbacks: public BLEServerCallbacks { void onConnect(BLEServer* pServer) { deviceConnected = true; Serial.println("Device connected"); }; void onDisconnect(BLEServer* pServer) { deviceConnected = false; Serial.println("Device disconnected"); } }; // End setup callbacks onConnect and onDisconnect (no change necessary) // Setup callbacks for charactristics // IMPORTANT -- all caracteristics can use the same callbacks class // or you can define a different class for each characteristic containing the onWrite method // The onWrite callback method is called when data is received by the ESP32 // This is where you will write you logic, according to the app specs class CharacteristicsCallbacks: public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *characteristic) { // Get characteristic value sent from the app, according to the specs std::string data = characteristic->getValue(); Serial.println(data.c_str()); // <-- This is the message sent from the app, according to the specs // Possible steps: // 1. Deserialize data using the ArduinoJson library // 2. Get the action from the JSON object // 3. Check action and perform the corresponding operations // IMPORTANT -- if it is an API project, connect to WiFi when the appropriate action is requested and // make sure to set the http request timeout to 10s or more // IMPORTANT -- If using the ArduinoJson library, use a DynamicJsonDocument with the size of 15000 // 5. Define the response structure, according to the app specifications // (Use JsonArray or JsonObject, depending on the response type) // IMPORTANT -- The cacapcity of the response array/object must not exceed 512B, especially for BLE // 6. Populate the response object according to the app specs // 7. Encode the response object as a JSON string // 8. Write value to the characteristic and notify the app // TODO -- Write your code } }; void setup() { // Start serial communication Serial.begin(115200); // BEGIN DON'T CHANGE // Create the BLE Device BLEDevice::init(bleServerName); // Create the BLE Server BLEServer *pServer = BLEDevice::createServer(); // Set server callbacks pServer->setCallbacks(new MyServerCallbacks()); // Create the BLE Service BLEService *bleService = pServer->createService(SERVICE_UUID); // Create BLE characteristics and descriptors bleService->addCharacteristic(&characteristic); characteristic.addDescriptor(characteristicDescriptor); // Set chacrateristic callbacks characteristic.setCallbacks(new CharacteristicsCallbacks()); // Start the service bleService->start(); // Start advertising BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); pAdvertising->addServiceUUID(SERVICE_UUID); pServer->getAdvertising()->start(); Serial.println("Waiting a client connection to notify..."); // END DON'T CHANGE } void loop() { // possible code to be executed for the actions which run periodically // (possibly conditioned by an interrupt flag) }