Bắt đầu với ESP32 Wifi bluetooth

23/02/2026
bat-dau-voi-esp32-wifi-bluetooth

ESP32 là chíp ra đời từ 2016 nhưng đang được ưa chuộng hơn arduino, vì nó có t`ính năng kết nối Wifi và cả bluetooth. Cấu hình hoạt động mạnh hơn arduino. Xu thế đây sẽ là chíp thay thế cho arduino hiện tại. Vì vậy, bạn nên update nó ngay.

ESP32 rất phù hợp tạo web điều khiển, tuy nhiên nếu dùng blue rất hạn chế do phải làm app mới chạy được. Bài này viết để test blue cho esp32. Theo đánh giá của tôi, blue không hiệu quả lắm. Nếu có app sẽ tốt hơn. Ví dụ ohstem cũng dùng app. Nếu điều khiển bằng kí tự đơn giản để test thì dùng nrf connec for mobile là dùng được.

Dùng Blue, mỗi app có mã này khác nhau, nếu họ chia sẻ thì dùng được, không chia sẻ thì không kết nối được.

#define SERVICE_UUID           "00001523-1212-efde-1523-785feabcd123"
#define LED_CHARACTERISTIC     "00001525-1212-efde-1523-785feabcd123"

Đây cũng là yếu tố độc đáo để khác biệt

Bước 1: Cài Arduino IDE

Nếu chưa có:

Tải tại:
https://www.arduino.cc/en/software

Cài đặt bình thường.

Bước 2: Thêm board ESP32

Mở Arduino IDE

Chọn:

File → Preferences

Tìm dòng:

Additional Boards Manager URLs

Dán link này:

https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

Nhấn OK


Bước 3: Cài thư viện ESP32

Chọn:

Tools → Board → Boards Manager

Gõ:

ESP32

Cài:

esp32 by Espressif Systems

Khuyên dùng version ổn định: (Nếu đang dùng 3.x.x → gỡ ra cài lại 2.0.17)

Nhấn Install

Đợi 2–5 phút


Bước 4: Chọn đúng board

Vào:

Tools → Board

Chọn:

ESP32 Dev Module

(đây là loại phổ biến nhất)

Cấu hình đầy đủ cho ESP-32D

Tools chọn như sau:

mục giá trị  
Board ESP32 Dev Module  
Port COM của ESP32  
CPU Frequency 240MHz  
Flash Frequency 80MHz  
Flash Mode DIO chú ý thay đổi
Partition Scheme Default  
Upload Speed 115200 chú ý thay đổi


Bước 5: Chọn cổng COM

Cắm ESP32 vào máy tính

Chọn:

Tools → Port → COM…

Ví dụ:

COM3
COM4


Bước 6: Test thử

Upload code này:

-------------------------------------------

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
void setup() {
  Serial.begin(115200);
  delay(2000);
  Serial.println("START");
  BLEDevice::init("ESP32_BLE_TEST");
  BLEServer *pServer = BLEDevice::createServer();
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->start();
  Serial.println("BLE OK - Advertising");
}
void loop() {}

------------------------------------------

Mở Serial Monitor

Nếu hiện:

START
BLE OK - Advertising

→ Thành công


Bước 7: Nếu upload lỗi

Nhấn giữ nút:

BOOT

trên ESP32 khi upload

Thông báo:  Brownout detector was triggered

👉 Đây là lỗi sụt áp nguồn trên ESP32-WROOM-32D, không phải lỗi code.

ESP32 cần nguồn rất ổn định, đặc biệt khi bật BLE hoặc WiFi. Dùng thêm nguồn cho bộ chia USB hoặc cấp nguồn 3.3V/5V vào ESP32


Cấu hình chuẩn khuyên dùng

Tools:

mục giá trị
Board ESP32 Dev Module        
Upload Speed 921600 (11520000)
Flash Frequency         80MHz
Port COMx

Sau khi cài xong, ESP32 có thể làm:

✔ Bluetooth iPhone
✔ WiFi Webserver
✔ Điều khiển relay
✔ Robot
✔ IoT

*******************************************************************

Tất cả các chip ESP32 chính hãng của Espressif Systems đều hỗ trợ BLE.

Chú ý: Không thể kết nối Bluetooth trong cài đặt của Iphone

KHÔNG tìm được ESP32 BLE trong mục Cài đặt → Bluetooth của iPhone

Đây là điểm rất nhiều người nhầm.


Vì sao iPhone không hiển thị ESP32 ở đó?

Trong iPhone:

Settings → Bluetooth

chỉ hiển thị thiết bị dùng Bluetooth Classic, ví dụ:

  • tai nghe

  • loa

  • ô tô

  • bàn phím


ESP32 bạn đang dùng là:

👉 BLE (Bluetooth Low Energy)

iPhone không hiển thị BLE custom trong phần này


Muốn thấy ESP32 → phải dùng app chuyên dụng

Cài một trong các app này:

  • LightBlue ← dễ dùng nhất

  • nRF Connect


Sau khi mở LightBlue

Chọn:

SCAN

Bạn sẽ thấy:

ESP32_BLE_TEST

hoặc

ESP32-D


Tóm tắt dễ hiểu

Nơi tìm Có thấy ESP32 BLE không
Settings → Bluetooth ❌ Không
LightBlue app ✅ Có
nRF Connect app ✅ Có

Ví dụ thực tế

ESP32 giống:

  • thiết bị IoT

  • cảm biến

  • thiết bị thông minh

→ iPhone chỉ cho app truy cập, không cho ghép đôi trong Settings


Kết luận

👉 Không tìm trong Cài đặt Bluetooth
👉 Phải dùng app LightBlue/Blue Scanner/nRF Toolbox


1. Các loại ESP32 phổ biến và BLE

Loại BLE       Bluetooth Classic   
ESP32 (ESP32-WROOM-32)        
ESP32-S2
ESP32-S3
ESP32-C3
ESP32-C6

📌 Quan trọng:

  • ESP32 thường → BLE + Classic

  • ESP32-S3, C3 → chỉ BLE

  • ESP32-S2 → không có Bluetooth


2. Cách nhận biết nhanh bằng mắt

Nhìn trên module

Nếu ghi:

ESP32-WROOM-32
ESP32-WROOM-32D
ESP32-WROOM-32U

➡ chắc chắn có BLE


Nếu ghi:

ESP32-S3-WROOM → có BLE

ESP32-C3-WROOM → có BLE

ESP32-S2-WROOM → không có BLE

 

So sánh Android vs iPhone

  Android       iPhone             
Bluetooth Classic
BLE
Serial Bluetooth
Điều khiển ESP32          ✅ (BLE)

Kết luận

✔ ESP32 điều khiển bằng iPhone được
✔ Phải dùng BLE
✔ Không dùng HC-05, HC-06

---------------------------------------------------------------------------

Cách đúng: dùng BLE trên ESP32

Sơ đồ tổng thể

ESP32 (BLE Server) ⇄ iPhone (BLE Client) ⇄ App điều khiển


Cách đơn giản nhất (không cần viết app)

Bạn dùng app trên iPhone:

  • LightBlue (MIỄN PHÍ – tốt nhất)

  • nRF Connect (chuyên nghiệp)


Ví dụ code ESP32 điều khiển LED từ iPhone

Khi gửi:

  • gửi "1" → bật LED

  • gửi "0" → tắt LED

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

#define LED 2

BLECharacteristic *pCharacteristic;
bool deviceConnected = false;

#define SERVICE_UUID        "12345678-1234-1234-1234-123456789abc"
#define CHARACTERISTIC_UUID "abcd1234-5678-1234-5678-123456789abc"

class MyCallbacks: public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pCharacteristic) {
    String value = pCharacteristic->getValue();

    if (value.length() > 0) {
      if (value == "1") digitalWrite(LED, HIGH);
      if (value == "0") digitalWrite(LED, LOW);
    }
  }
};

void setup() {

  pinMode(LED, OUTPUT);

  BLEDevice::init("ESP32_BLE");

  BLEServer *pServer = BLEDevice::createServer();

  BLEService *pService = pServer->createService(SERVICE_UUID);

  pCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID,
                      BLECharacteristic::PROPERTY_WRITE
                    );

  pCharacteristic->setCallbacks(new MyCallbacks());

  pService->start();

  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->start();

}

void loop() {
}

 

Cách dùng trên iPhone

Bước 1

Cài app LightBlue

Bước 2

Mở app → scan

sẽ thấy:

ESP32_BLE

Bước 3

Chọn Characteristic

gửi:   => 1  => LED bật

gửi: =>  0 =>  LED tắt

-----------------------------------------------------------

Cách test chắc chắn nhất (test bằng code)

Upload code này:

#include "BLEDevice.h"
void setup() {
Serial.begin(115200);
BLEDevice::init("ESP32_BLE_TEST");
Serial.println("BLE OK");
}
void loop() {}

Nếu chạy OK → có BLE

------------------------------------------------------

App phổ biến (không cần code)

App Dùng để điều khiển ESP32 BLE? Ghi chú
Blynk ❗ BLE chưa hỗ trợ tốt nếu dùng Wi-Fi tốt hơn
Bluetooth Serial Controller ✔ Có nút điều khiển gửi ký tự qua BLE
BLE Scanner ✔ Scan + gửi ký tự giao diện đơn đơn

📌 App chuyên robot trên App Store thường dùng Bluetooth Classic → không phù hợp với ESP32 BLE.

-------------------------------------------------------------------------------

Trên iPhone dùng nRF Connect

Bước 1

Nạp code:

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

#define LED 2

BLEServer *pServer = NULL;
BLECharacteristic *pCharacteristic = NULL;

bool deviceConnected = false;

#define SERVICE_UUID        "12345678-1234-1234-1234-123456789abc"
#define CHARACTERISTIC_UUID "abcd1234-5678-1234-5678-123456789abc"


// xử lý connect / disconnect

class MyServerCallbacks: public BLEServerCallbacks {

  void onConnect(BLEServer* pServer) {

    deviceConnected = true;
    Serial.println("Device Connected");

  };

  void onDisconnect(BLEServer* pServer) {

    deviceConnected = false;
    Serial.println("Device Disconnected");

    // QUAN TRỌNG: bật lại advertising
    BLEDevice::startAdvertising();

    Serial.println("Advertising again");

  }

};
// xử lý nhận dữ liệu

class MyCallbacks: public BLECharacteristicCallbacks {

  void onWrite(BLECharacteristic *pCharacteristic) {

    std::string value = pCharacteristic->getValue();

    if (value == "1") {

      digitalWrite(LED, HIGH);
      Serial.println("LED ON");

    }

    if (value == "0") {

      digitalWrite(LED, LOW);
      Serial.println("LED OFF");

    }

  }

};


void setup() {

  Serial.begin(115200);

  pinMode(LED, OUTPUT);

  BLEDevice::init("ESP32_LED");

  pServer = BLEDevice::createServer();

  pServer->setCallbacks(new MyServerCallbacks());

  BLEService *pService =
  pServer->createService(SERVICE_UUID);


  pCharacteristic =
  pService->createCharacteristic(
    CHARACTERISTIC_UUID,
    BLECharacteristic::PROPERTY_WRITE
  );

  pCharacteristic->setCallbacks(new MyCallbacks());

  pService->start();


  BLEAdvertising *pAdvertising =
  BLEDevice::getAdvertising();

  pAdvertising->start();

  Serial.println("Ready");

}


void loop() {

}

Bước 2:

Mở nRF Connect

SCAN

Chọn tên blue .......... chọn Connect, nếu ko kết nối được thì bấm EN trên esp32, rồi kết nối lại.

Bước 3: Mở blue đó lên, có giao diện như dưới

Bấm vào biểu tượng "dấu phẩy" chọn UTF-8 như hình dưới

Bấm ra ngoài để đóng lại, Bấm nút mũi tên chỉ lên bên phải, chọn UTF-8, gõ 1 hoặc 0 để điều khiển, lúc này: Serial Monitor sẽ hiện: 

LED ON
LED OFF

 

************************************************************

nRF Blinky làm được gì

App có sẵn:

  • Nút bật tắt LED

  • Hiển thị trạng thái Button

Rất phù hợp test nhanh.


Code ESP32 chuẩn cho nRF Blinky

Copy code này nạp ESP32:

 

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

#define LED_PIN 2

BLECharacteristic *ledCharacteristic;

#define SERVICE_UUID "00001523-1212-efde-1523-785feabcd123"
#define LED_CHARACTERISTIC "00001525-1212-efde-1523-785feabcd123"

class LEDCallbacks: public BLECharacteristicCallbacks {

void onWrite(BLECharacteristic *pCharacteristic) {

std::string value = pCharacteristic->getValue();

if (value.length() > 0) {

if (value[0] == 0x01) {

digitalWrite(LED_PIN, HIGH);

Serial.println("LED ON");

}
else {

digitalWrite(LED_PIN, LOW);

Serial.println("LED OFF");

}

}

}

};

void setup() {

Serial.begin(115200);

pinMode(LED_PIN, OUTPUT);

BLEDevice::init("ESP32_BLINKY");

BLEServer *server = BLEDevice::createServer();

BLEService *service = server->createService(SERVICE_UUID);

ledCharacteristic = service->createCharacteristic(

LED_CHARACTERISTIC,

BLECharacteristic::PROPERTY_WRITE

);

ledCharacteristic->setCallbacks(new LEDCallbacks());

service->start();

server->getAdvertising()->start();

Serial.println("Ready");

}

void loop() {}


Cách dùng

Bước 1

Mở:

nRF Blinky

Bước 2

Connect:

ESP32_BLINKY

Bước 3

Bấm:

ON → LED sáng
OFF → LED tắt


Ưu điểm nRF Blinky

✔ đơn giản nhất
✔ có nút sẵn
✔ không cần cấu hình
✔ chạy tốt trên iPhone