Last active
March 7, 2023 15:00
-
-
Save squirelo/c3e4d44e267cb19c572f060d3d58377e to your computer and use it in GitHub Desktop.
This code creates a GATT server and a GATT client on separate FreeRTOS tasks, and runs them on different cores of the ESP32. The GATT server exposes a characteristic that can be read and written by the GATT client. The GATT client scans for the server, connects to it, and writes a new value to the characteristic every second. Note that you'll ne…
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
#include <BLEDevice.h> | |
#include <BLEUtils.h> | |
#include <BLEServer.h> | |
#include <BLE2902.h> | |
// Define UUIDs for our service and characteristics | |
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" | |
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" | |
// Define the GATT server and client objects | |
BLEServer *pServer; | |
BLEClient *pClient; | |
// Define the characteristic value | |
uint8_t charValue = 0; | |
// Define the RTOS task handles | |
TaskHandle_t serverTaskHandle = NULL; | |
TaskHandle_t clientTaskHandle = NULL; | |
// Define the MyClientCallbacks class | |
class MyClientCallbacks : public BLEClientCallbacks { | |
public: | |
void onConnect(BLEClient* pClient) { | |
Serial.println("Connected to server"); | |
} | |
void onDisconnect(BLEClient* pClient) { | |
Serial.println("Disconnected from server"); | |
} | |
}; | |
// GATT server task function | |
void serverTask(void *parameter) { | |
// Create the BLE server | |
BLEDevice::init("ESP32 Server ChatGPT FTW"); | |
pServer = BLEDevice::createServer(); | |
BLEService *pService = pServer->createService(SERVICE_UUID); | |
BLECharacteristic *pCharacteristic = pService->createCharacteristic( | |
CHARACTERISTIC_UUID, | |
BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | |
); | |
pCharacteristic->setValue(&charValue, 1); | |
pCharacteristic->setCallbacks(new BLECharacteristicCallbacks()); | |
pService->start(); | |
// Start advertising | |
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); | |
pAdvertising->addServiceUUID(SERVICE_UUID); | |
pAdvertising->start(); | |
// Run the server loop | |
while (1) { | |
// Update the value of the characteristic | |
pCharacteristic->setValue(&charValue, 1); | |
pCharacteristic->notify(); | |
delay(10); | |
} | |
} | |
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks { | |
public: | |
void onResult(BLEAdvertisedDevice advertisedDevice) { | |
Serial.printf("Found device %s\n", advertisedDevice.toString().c_str()); | |
} | |
}; | |
// GATT client task function | |
void clientTask(void *parameter) { | |
// Create the BLE client | |
BLEDevice::init("ESP32 Client"); | |
pClient = BLEDevice::createClient(); | |
pClient->setClientCallbacks(new MyClientCallbacks()); | |
// Scan for the server | |
BLEScan *pScan = BLEDevice::getScan(); | |
pScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); | |
pScan->setActiveScan(true); | |
pScan->start(5); | |
// Connect to the server | |
BLEAddress serverAddress("AA:BB:CC:DD:EE:FF"); | |
BLERemoteCharacteristic *pRemoteCharacteristic; | |
while (1) { | |
if (!pClient->isConnected()) { | |
BLEScanResults scanResults = pScan->getResults(); | |
for (int i = 0; i < scanResults.getCount(); i++) { | |
BLEAdvertisedDevice device = scanResults.getDevice(i); | |
if (device.getAddress() == serverAddress) { | |
Serial.println("Connecting to server..."); | |
pClient->connect(serverAddress); | |
BLERemoteService *pRemoteService = pClient->getService(SERVICE_UUID); | |
if (pRemoteService != nullptr) { | |
pRemoteCharacteristic = pRemoteService->getCharacteristic(CHARACTERISTIC_UUID); | |
} | |
break; | |
} | |
} | |
} | |
// Write a value to the characteristic | |
charValue++; | |
pRemoteCharacteristic->writeValue(&charValue, 1); | |
delay(1000); | |
} | |
} | |
void setup() { | |
// Create and start the server task | |
xTaskCreatePinnedToCore( | |
serverTask, | |
"Server Task", | |
10000, | |
NULL, | |
1, | |
&serverTaskHandle, | |
1 | |
); | |
// Create and start the client task | |
xTaskCreatePinnedToCore( | |
clientTask, | |
"Client Task", | |
10000, | |
NULL, | |
2, | |
&clientTaskHandle, | |
0 | |
); | |
} | |
void loop() { | |
// Empty loop | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment