Designing BLE-Enabled Smart Home Devices with ESP32

Bluetooth Low Energy (BLE) is a cornerstone of modern smart home ecosystems, offering low power consumptionZigbee Green Power: Ultra-Low-Power Energy Harvesting SolutionsZigbee Green Power: Ultra-Low-Power Energy Harvesting SolutionsDiscover how ZGP enables battery-free IoT devices through energy harvesting with ESP32 integrations, supporting smart home and industrial applications. and seamless integration with mobile devices. The ESP32’s dual-core architecture and integrated BLE stack make it an ideal choice for DIY smart switches, locks, or sensors. This guide will walk you through the process of designing, implementing, and optimizing a BLE-enabled smart home device, such as a smart light, using the ESP32. You’ll also learn how to integrate it with a mobile app and set up automation rules.

Table of Contents🔗

Understanding the Project Scope🔗

Smart home devices are everywhere, from lights to locks, thermostats, and more. The ESP32, with its built-in BLE capability, is an excellent choice for building such devices due to its low power consumptionZigbee Green Power: Ultra-Low-Power Energy Harvesting SolutionsZigbee Green Power: Ultra-Low-Power Energy Harvesting SolutionsDiscover how ZGP enables battery-free IoT devices through energy harvesting with ESP32 integrations, supporting smart home and industrial applications., dual-core processing, and robust wireless connectivity. In this project, we’ll focus on creating a BLE-enabled smart light that can be controlled via a mobile app and integrated with automation rules.

Hardware Components {#hardware-components}🔗

Here’s what you’ll need:

WiringUsing Quectel BC66/BG96 Modules with ESP32 for NB-IoT ConnectivityUsing Quectel BC66/BG96 Modules with ESP32 for NB-IoT ConnectivityExplore our detailed tutorial on integrating Quectel BC66/BG96 with ESP32 for low-power, reliable NB-IoT connectivity. Learn hardware setup and AT commands. Diagram:

graph LR ESP32 -->|GPIO 23| Relay[Relay IN] ESP32 -->|I2C (SDA/SCL)| PN532[NFC Module] Relay --> AC_Light[AC Light Bulb]

Setting Up the BLE Server {#setting-up-the-ble-server}🔗

The ESP32Setting Up ESP32 as a Wi-Fi Access PointSetting Up ESP32 as a Wi-Fi Access PointMaster ESP32 AP configuration with our step-by-step guide. Set up a secure, local IoT network using practical code examples and optimization tips. will act as a BLE server, exposing a Light Control Service with characteristics for on/off and brightness.

Arduino Code:

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHAR_ON_OFF_UUID    "beb5483e-36e1-4688-b7f5-ea07361b26a8"
#define CHAR_BRIGHTNESS_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a9"
BLEServer* pServer;
BLEService* pService;
BLECharacteristic* pCharOnOff;
BLECharacteristic* pCharBrightness;
void setup() {
  BLEDevice::init("SmartLight-ESP32");
  pServer = BLEDevice::createServer();
  pService = pServer->createService(SERVICE_UUID);
  // On/Off Characteristic (Writeable)
  pCharOnOff = pService->createCharacteristic(
    CHAR_ON_OFF_UUID,
    BLECharacteristic::PROPERTY_WRITE
  );
  // Brightness Characteristic (Notify)
  pCharBrightness = pService->createCharacteristic(
    CHAR_BRIGHTNESS_UUID,
    BLECharacteristic::PROPERTY_NOTIFY | BLECharacteristic::PROPERTY_READ
  );
  pService->start();
  BLEAdvertising* pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->start();
}

Defining Custom GATT Services and Characteristics {#defining-custom-gatt-services-and-characteristics}🔗

A smart light needs a custom GATTNative Protocols: Wi-Fi (2.4 GHz), Bluetooth Classic, and BLENative Protocols: Wi-Fi (2.4 GHz), Bluetooth Classic, and BLEExplore ESP32 connectivity with Wi-Fi, Bluetooth Classic, and BLE. Learn implementation tips and best practices for IoT projects. service to control its state (ON/OFF) and brightness. Here’s an example:

1. Define a Custom Service:

NimBLEService* pLightService = pServer->createService("1234"); // Custom UUID
NimBLECharacteristic* pLightState = pLightService->createCharacteristic(
  "5678", // Custom UUID
  NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::NOTIFY
);
pLightState->setValue("OFF");

2. Handle Write Requests:

Update the light state when the mobile app sends a command:

pLightState->setCallbacks(new LightCallbacks());
class LightCallbacks : public NimBLECharacteristicCallbacks {
  void onWrite(NimBLECharacteristic* pCharacteristic) {
    std::string value = pCharacteristic->getValue();
    if (value == "ON") {
      digitalWrite(LED_PIN, HIGH); // Turn on the light
    } else {
      digitalWrite(LED_PIN, LOW); // Turn off the light
    }
  }
};

Building a Mobile App for Control {#building-a-mobile-app-for-control}🔗

Use a mobile app (e.g., nRF Connect or a custom Swift/Kotlin app) to interact with the ESP32Setting Up ESP32 as a Wi-Fi Access PointSetting Up ESP32 as a Wi-Fi Access PointMaster ESP32 AP configuration with our step-by-step guide. Set up a secure, local IoT network using practical code examples and optimization tips.:

1. Scan for Devices: Filter by the service UUID 4fafc201-1fb5-459e-8fcc-c5c9c331914b.

2. Write to On/Off Characteristic: Send 0x01 to turn on the light, 0x00 to turn it off.

3. Read Brightness: Subscribe to notifications for real-time updates.

Example Write Request (Android):

val characteristic = service.getCharacteristic(CHAR_ON_OFF_UUID)
characteristic.value = byteArrayOf(0x01)
bluetoothGatt.writeCharacteristic(characteristic)

Controlling GPIOs via BLE Commands {#controlling-gpios-via-ble-commands}🔗

Map BLENative Protocols: Wi-Fi (2.4 GHz), Bluetooth Classic, and BLENative Protocols: Wi-Fi (2.4 GHz), Bluetooth Classic, and BLEExplore ESP32 connectivity with Wi-Fi, Bluetooth Classic, and BLE. Learn implementation tips and best practices for IoT projects. commands to GPIO actions. For example, toggle GPIO 23 when the On/Off characteristic is written:

class MyCallbacks: public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pCharacteristic) {
    std::string value = pCharacteristic->getValue();
    if (value == "0x01") {
      digitalWrite(23, HIGH);  // Relay ON
    } else {
      digitalWrite(23, LOW);   // Relay OFF
    }
  }
};
// Assign callback to the On/Off characteristic
pCharOnOff->setCallbacks(new MyCallbacks());

Adding Security Layers {#adding-security-layers}🔗

1. BLENative Protocols: Wi-Fi (2.4 GHz), Bluetooth Classic, and BLENative Protocols: Wi-Fi (2.4 GHz), Bluetooth Classic, and BLEExplore ESP32 connectivity with Wi-Fi, Bluetooth Classic, and BLE. Learn implementation tips and best practices for IoT projects. Pairing:

BLESecurity *pSecurity = new BLESecurity();
pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_BOND);

2. NFCNFC Security: Implementing Encryption and Tamper DetectionNFC Security: Implementing Encryption and Tamper DetectionLearn how to secure your ESP32 NFC projects with AES encryption, HMAC validation, and tamper detection techniques for robust wireless security. Authentication: Use the PN532 modulePeer-to-Peer NFC Communication Between ESP32 DevicesPeer-to-Peer NFC Communication Between ESP32 DevicesDiscover how to set up NFC P2P communication on ESP32 devices. Our tutorial covers hardware, software integration, and practical security measures. to validate user NFC tags before enabling BLE control.

NFCNFC Security: Implementing Encryption and Tamper DetectionNFC Security: Implementing Encryption and Tamper DetectionLearn how to secure your ESP32 NFC projects with AES encryption, HMAC validation, and tamper detection techniques for robust wireless security. Validation Snippet:

import NDEF
from pn532 import PN532
nfc = PN532()
nfc.begin()
if nfc.read_passive_target():
  record = NDEF.TextRecord("AUTH_USER_123")
  if nfc.ndef_read() == record:
    enable_ble_control()  # Unlock BLE commands

Implementing Automation Rules {#implementing-automation-rules}🔗

Automation rules can be implemented on the ESP32Setting Up ESP32 as a Wi-Fi Access PointSetting Up ESP32 as a Wi-Fi Access PointMaster ESP32 AP configuration with our step-by-step guide. Set up a secure, local IoT network using practical code examples and optimization tips. or in the cloud. For example:

  • Time-Based Automation: Turn the light ON at sunset and OFF at sunrise.
  • Motion Detection: Use a PIR sensor to trigger the light when motion is detected.

Example code for time-based automation:

void checkTimeBasedAutomation() {
  int currentHour = getCurrentHour(); // Implement this function
  if (currentHour >= 18 || currentHour <= 6) {
    digitalWrite(LED_PIN, HIGH); // Turn on the light
  } else {
    digitalWrite(LED_PIN, LOW); // Turn off the light
  }
}

Power Optimization for 24/7 Operation {#power-optimization-for-247-operation}🔗

esp_ble_gap_set_prefer_conn_params(esp_bd_addr_t bd_addr, 24, 48, 0, 600);
esp_deep_sleep_start();  // Wake via timer or external interrupt
ParameterValueImpact
Connection Interval45 msBalance latency/power
TX Power-12 dBmReduce range for lower RSSI
Advertising Delay1000 msAfter initial pairing

Testing and Debugging {#testing-and-debugging}🔗

Real-World Applications {#real-world-applications}🔗

1. Smart Lock: Add a servo motor controlled via BLENative Protocols: Wi-Fi (2.4 GHz), Bluetooth Classic, and BLENative Protocols: Wi-Fi (2.4 GHz), Bluetooth Classic, and BLEExplore ESP32 connectivity with Wi-Fi, Bluetooth Classic, and BLE. Learn implementation tips and best practices for IoT projects., with NFC as a backup.

2. Energy Monitoring: Integrate a current sensor (e.g., ACS712) and report data via BLENative Protocols: Wi-Fi (2.4 GHz), Bluetooth Classic, and BLENative Protocols: Wi-Fi (2.4 GHz), Bluetooth Classic, and BLEExplore ESP32 connectivity with Wi-Fi, Bluetooth Classic, and BLE. Learn implementation tips and best practices for IoT projects. notifications.

3. Voice Control: Bridge BLE with Amazon Alexa using ESP32’s Wi-Fi and AWS IoTConnecting ESP32 to Cloud Services via Wi-FiConnecting ESP32 to Cloud Services via Wi-FiDiscover how to connect your ESP32 to AWS, Azure, and Google Cloud using secure Wi-Fi. This guide covers setup, error handling, and low power strategies..

Hybrid Example (BLE + Wi-FiArquitetura ESP32: SoC dual-core, subsistemas RF integradosArquitetura ESP32: SoC dual-core, subsistemas RF integradosDiscover the ESP32’s dual-core prowess and integrated RF subsystems for efficient, innovative IoT applications—from smart homes to industrial sensors.):

// Sync BLE state with cloud via MQTT
if (ble_state_changed) {
  wifi_client.publish("home/lights/room1", payload);
}
graph TB BLE_App -->|On/Off Command| ESP32 ESP32 -->|MQTT| AWS_Cloud[AWS IoT Core] AWS_Cloud -->|Voice Command| Alexa

Use ESP32’sCombining Wi-Fi with Deep Sleep for Low-Power ApplicationsCombining Wi-Fi with Deep Sleep for Low-Power ApplicationsLearn how to integrate Wi-Fi and deep sleep on ESP32 to maximize battery life in IoT devices. This guide offers practical tips and step-by-step instructions. dual-core to isolate BLE and Wi-FiArquitetura ESP32: SoC dual-core, subsistemas RF integradosArquitetura ESP32: SoC dual-core, subsistemas RF integradosDiscover the ESP32’s dual-core prowess and integrated RF subsystems for efficient, innovative IoT applications—from smart homes to industrial sensors. tasks:

By following this guide, you’ll have a fully functional Bluetooth-controlled smart home device powered by the ESP32Setting Up ESP32 as a Wi-Fi Access PointSetting Up ESP32 as a Wi-Fi Access PointMaster ESP32 AP configuration with our step-by-step guide. Set up a secure, local IoT network using practical code examples and optimization tips.. Whether you’re building a smart light, lock, or any other IoT device, the principles remain the same. Happy building! 🚀

Author: Marcelo V. Souza - Engenheiro de Sistemas e Entusiasta em IoT e Desenvolvimento de Software, com foco em inovação tecnológica.

References🔗

Share article

Related Articles