Skip to content

Instantly share code, notes, and snippets.

@squirelo
Last active March 7, 2023 15:00
Show Gist options
  • Save squirelo/c3e4d44e267cb19c572f060d3d58377e to your computer and use it in GitHub Desktop.
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…
#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