/********* Pleasedontcode.com **********
Pleasedontcode thanks you for automatic code generation! Enjoy your code!
- Terms and Conditions:
You have a non-exclusive, revocable, worldwide, royalty-free license
for personal and commercial use. Attribution is optional; modifications
are allowed, but you're responsible for code maintenance. We're not
liable for any loss or damage. For full terms,
please visit pleasedontcode.com/termsandconditions.
- Project: "BLE Client"
- Source Code NOT compiled for: ESP32 DevKit V1
- Source Code created on: 2025-02-11 18:03:14
********* Pleasedontcode.com **********/
/****** SYSTEM REQUIREMENTS *****/
/****** SYSTEM REQUIREMENT 1 *****/
/* **ESP32 BLE Client (Stable & Crash-Free)** - */
/* Scans for `PERIPH`, connects when found, auto- */
/* reconnects if lost. - Separate tasks for BLE */
/* connection & Modbus RTU handling. - FreeRTOS, */
/* mutexes, watchdogs, and memory tracking to prevent */
/* crased */
/****** END SYSTEM REQUIREMENTS *****/
/* START CODE */
/****** DEFINITION OF LIBRARIES *****/
#include //https://github.com/arduino-libraries/ArduinoBLE
#include //https://github.com/adafruit/DHT-sensor-library
#include // Added for BLE functionality
/****** FUNCTION PROTOTYPES *****/
void setup(void);
void loop(void);
/***** DEFINITION OF DIGITAL INPUT PINS *****/
const uint8_t myDHT22_DHT22_DOUT_PIN_D4 = 4;
// Define UUIDs for BLE service and characteristics
static BLEUUID serviceUUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
static BLEUUID charUUID("6e400003-b5a3-f393-e0a9-E50E24DCCA9E");
static BLEUUID rxUUID("6e400002-b5a3-f393-e0A9-E50E24DCCA9E");
// Global variables
static bool connected = false;
static BLEClient* pClient = nullptr;
static BLERemoteService* pRemoteService = nullptr;
static BLERemoteCharacteristic* pRemoteCharacteristic = nullptr;
static BLERemoteCharacteristic* pRemoteRxCharacteristic = nullptr;
static BLEAdvertisedDevice* myDevice = nullptr;
static BLEScan* pBLEScan = nullptr;
// BLE Client callback
class MyClientCallback : public BLEClientCallbacks {
void onConnect(BLEClient* pclient) {
Serial.println("Connected to peripheral.");
}
void onDisconnect(BLEClient* pclient) {
connected = false;
Serial.println("Disconnected from peripheral.");
}
};
// Task: Scan for BLE devices and connect
void scanAndConnectTask(void* pvParameters) {
esp_task_wdt_add(NULL); // Enable watchdog for this task
while (1) {
Serial.println("Scanning for BLE devices...");
pBLEScan->start(5, false);
vTaskDelay(1000 / portTICK_PERIOD_MS);
BLEScanResults foundDevices = *pBLEScan->getResults(); // FIXED POINTER ERROR
for (int i = 0; i < foundDevices.getCount(); i++) {
BLEAdvertisedDevice advertisedDevice = foundDevices.getDevice(i);
Serial.println("Found Device: " + advertisedDevice.toString());
if (advertisedDevice.haveName() && advertisedDevice.getName() == "PERIPH") {
pBLEScan->stop();
myDevice = new BLEAdvertisedDevice(advertisedDevice);
Serial.println("Target device found. Connecting...");
if (connectToServer()) {
Serial.println("Connected successfully.");
} else {
Serial.println("Connection failed. Retrying...");
}
myDevice = nullptr;
}
}
printMemoryUsage("scanAndConnectTask");
vTaskDelay(5000 / portTICK_PERIOD_MS);
esp_task_wdt_reset(); // Reset watchdog to prevent task hang
}
}
// Function: Connect to BLE server
bool connectToServer() {
if (pClient != nullptr && pClient->isConnected()) {
return true;
}
pClient = BLEDevice::createClient();
pClient->setClientCallbacks(new MyClientCallback());
if (!pClient->connect(myDevice)) {
Serial.println("Failed to connect to peripheral.");
delete pClient;
pClient = nullptr;
return false;
}
pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService == nullptr) {
Serial.println("Failed to find service UUID.");
pClient->disconnect();
return false;
}
pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
pRemoteRxCharacteristic = pRemoteService->getCharacteristic(rxUUID);
if (pRemoteCharacteristic == nullptr || pRemoteRxCharacteristic == nullptr) {
Serial.println("Failed to find characteristics.");
pClient->disconnect();
return false;
}
connected = true;
return true;
}
// Task: Send and receive data
void sendReceiveTask(void* pvParameters) {
esp_task_wdt_add(NULL); // Enable watchdog for this task
while (1) {
if (connected) {
sendReadRequestToSlave(0x43, 5);
readDataFromPeripheral();
}
printMemoryUsage("sendReceiveTask");
vTaskDelay(5000 / portTICK_PERIOD_MS);
esp_task_wdt_reset(); // Reset watchdog to prevent task hang
}
}
// Function: Send read request to slave device
void sendReadRequestToSlave(uint16_t startingAddress, uint16_t length) {
Serial.println("Sending read request...");
if (!connected || pRemoteRxCharacteristic == nullptr) {
Serial.println("Not connected or RX characteristic unavailable.");
return;
}
uint8_t requestData[8] = {
0x20, 0x03,
(startingAddress >> 8) & 0xFF, startingAddress & 0xFF,
(length >> 8) & 0xFF, length & 0xFF,
0x72, 0xAC
};
pRemoteRxCharacteristic->writeValue(requestData, sizeof(requestData));
}
// Function: Read data from peripheral
void readDataFromPeripheral() {
if (!connected || pRemoteCharacteristic == nullptr) {
Serial.println("Not connected or TX characteristic unavailable.");
return;
}
String value = pRemoteCharacteristic->readValue();
Serial.print("Received Data: ");
Serial.println(value);
Serial.print("Data (HEX): ");
for (size_t i = 0; i < value.length(); i++) {
Serial.print((uint8_t)value[i], HEX);
Serial.print(" ");
}
Serial.println();
}
// Function: Print memory usage
void printMemoryUsage(const char* taskName) {
Serial.print("[MEMORY] Task: ");
Serial.print(taskName);
Serial.print(" | Free Heap: ");
Serial.print(esp_get_free_heap_size());
Serial.print(" bytes | Min Heap: ");
Serial.print(esp_get_minimum_free_heap_size());
Serial.println(" bytes");
}
void setup(void)
{
Serial.begin(57600); // Initialize Serial for debugging
Serial.println("Starting BLE Client...");
BLEDevice::init("CENTRAL");
// Set TX power
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, ESP_PWR_LVL_P9); // This line may not be compatible with ArduinoBLE library
// Initialize BLE scan
pBLEScan = BLEDevice::getScan();
pBLEScan->setInterval(2000);
pBLEScan->setWindow(1000);
pBLEScan->setActiveScan(true);
// Create tasks on specific cores
xTaskCreatePinnedToCore(scanAndConnectTask, "Scan Task", 10240, NULL, 1, NULL, 0);
xTaskCreatePinnedToCore(sendReceiveTask, "Data Task", 10240, NULL, 2, NULL, 1);
pinMode(myDHT22_DHT22_DOUT_PIN_D4, INPUT_PULLUP); // Initialize DHT sensor pin
}
void loop(void)
{
// put your main code here, to run repeatedly:
delay(500); // Delay to prevent overwhelming the loop
}
/* END CODE */