蓝牙使用
Seeed Studio XIAO ESP32C3 支持蓝牙 5 (LE) 连接。本教程将介绍在此开发板上使用蓝牙的基础知识。
硬件设置
- 步骤 1. 将随附的 WiFi/ 蓝牙天线 连接到开发板上的 IPEX 连接器

- 步骤 2. 通过 USB Type-C 数据线将 XIAO ESP32C3 连接到您的计算机

扫描蓝牙设备
在这个示例中,我们将使用 XIAO ESP32C3 扫描周围可用的蓝牙设备。
- 步骤 1. 将下面的代码复制并粘贴到 Arduino IDE 中
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
int scanTime = 5; //In seconds
BLEScan* pBLEScan;
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
}
};
void setup() {
Serial.begin(115200);
Serial.println("Scanning...");
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
pBLEScan->setInterval(100);
pBLEScan->setWindow(99); // less or equal setInterval value
}
void loop() {
// put your main code here, to run repeatedly:
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
Serial.print("Devices found: ");
Serial.println(foundDevices.getCount());
Serial.println("Scan done!");
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
delay(2000);
}
tip
如果您已经将ESP32开发板升级到3.0.0版本以上,您需要更改一些代码以使其兼容。
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
更改为BLEScanResults* foundDevices = pBLEScan->start(scanTime, false);
Serial.println(foundDevices.getCount());
更改为Serial.println(foundDevices->getCount());
步骤 2. 上传代码并打开串口监视器开始扫描蓝牙设备

XIAO ESP32C3 作为蓝牙服务器
在这个示例中,我们将使用XIAO ESP32C3作为蓝牙服务器。在这里我们将使用智能手机搜索XIAO ESP32C3开发板,并发送字符串在串口监视器上显示
- 步骤 1. 复制并粘贴以下代码到Arduino IDE中
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
// 生成UUID请参考以下链接:
// https://www.uuidgenerator.net/
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string value = pCharacteristic->getValue();
if (value.length() > 0) {
Serial.println("*********");
Serial.print("New value: ");
for (int i = 0; i < value.length(); i++)
Serial.print(value[i]);
Serial.println();
Serial.println("*********");
}
}
};
void setup() {
Serial.begin(115200);
BLEDevice::init("MyESP32");
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
pCharacteristic->setValue("Hello World");
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
}
void loop() {
// 在这里放置您的主要代码,以便重复运行:
delay(2000);
}
tip
如果您已经将ESP32开发板升级到3.0.0版本以上,您需要更改一些代码以使其兼容。
std::string value = pCharacteristic->getValue();
更改为String value = pCharacteristic->getValue();
-
步骤 2. 上传代码并打开串口监视器
-
步骤 3. 在您的智能手机上下载并安装LightBlue应用
-
步骤 4. 打开手机蓝牙,将手机靠近XIAO ESP32C3,扫描设备并连接MyESP32设备

- 步骤 5. 打开LightBlue应用并点击Bonded选项卡

- 步骤 6. 点击MyESP32旁边的CONNECT

- 步骤 7. 点击最底部显示Readable, Writable的部分

- 步骤 8. 在Data format下拉菜单中,选择UTF-8 String

- 步骤 9. 在WRITTEN VALUES下输入"Hello"并点击WRITE

您将在Arduino IDE的串口监视器上看到文本字符串"Hello"的输出

NimBLE-Arduino
介绍
与基于bluedroid的库相比,该库显著减少了ESP32 BLE应用程序的资源使用并提高了性能。目标是在合理范围内尽可能保持与原始库的兼容性,但使用NimBLE堆栈。此外,该库将得到更积极的开发和维护,以提供比原始库更好的功能和稳定性。
更多信息请访问作者的Github链接。
步骤 1.添加库

步骤 2.示例
代码
#include <Arduino.h>
#include <NimBLEDevice.h>
#include <NimBLEAdvertisedDevice.h>
#include "NimBLEEddystoneTLM.h"
#include "NimBLEBeacon.h"
#define ENDIAN_CHANGE_U16(x) ((((x) & 0xFF00) >> 8) + (((x) & 0xFF) << 8))
int scanTime = 5 * 1000; // 以毫秒为单位
NimBLEScan* pBLEScan;
class ScanCallbacks : public NimBLEScanCallbacks {
void onResult(const NimBLEAdvertisedDevice* advertisedDevice) override {
if (advertisedDevice->haveName()) {
Serial.print("设备名称: ");
Serial.println(advertisedDevice->getName().c_str());
Serial.println("");
}
if (advertisedDevice->haveServiceUUID()) {
NimBLEUUID devUUID = advertisedDevice->getServiceUUID();
Serial.print("发现 ServiceUUID: ");
Serial.println(devUUID.toString().c_str());
Serial.println("");
} else if (advertisedDevice->haveManufacturerData() == true) {
std::string strManufacturerData = advertisedDevice->getManufacturerData();
if (strManufacturerData.length() == 25 && strManufacturerData[0] == 0x4C && strManufacturerData[1] == 0x00) {
Serial.println("发现一个 iBeacon!");
NimBLEBeacon oBeacon = NimBLEBeacon();
oBeacon.setData(reinterpret_cast<const uint8_t*>(strManufacturerData.data()), strManufacturerData.length());
Serial.printf("iBeacon 帧\n");
Serial.printf("ID: %04X Major: %d Minor: %d UUID: %s Power: %d\n",
oBeacon.getManufacturerId(),
ENDIAN_CHANGE_U16(oBeacon.getMajor()),
ENDIAN_CHANGE_U16(oBeacon.getMinor()),
oBeacon.getProximityUUID().toString().c_str(),
oBeacon.getSignalPower());
} else {
Serial.println("发现其他制造商的信标!");
Serial.printf("strManufacturerData: %d ", strManufacturerData.length());
for (int i = 0; i < strManufacturerData.length(); i++) {
Serial.printf("[%X]", strManufacturerData[i]);
}
Serial.printf("\n");
}
return;
}
NimBLEUUID eddyUUID = (uint16_t)0xfeaa;
if (advertisedDevice->getServiceUUID().equals(eddyUUID)) {
std::string serviceData = advertisedDevice->getServiceData(eddyUUID);
if (serviceData[0] == 0x20) {
Serial.println("发现一个 EddystoneTLM 信标!");
NimBLEEddystoneTLM foundEddyTLM = NimBLEEddystoneTLM();
foundEddyTLM.setData(reinterpret_cast<const uint8_t*>(serviceData.data()), serviceData.length());
Serial.printf("报告的电池电压: %dmV\n", foundEddyTLM.getVolt());
Serial.printf("TLM 类报告的温度: %.2fC\n", (double)foundEddyTLM.getTemp());
int temp = (int)serviceData[5] + (int)(serviceData[4] << 8);
float calcTemp = temp / 256.0f;
Serial.printf("数据报告的温度: %.2fC\n", calcTemp);
Serial.printf("报告的广播计数: %d\n", foundEddyTLM.getCount());
Serial.printf("报告的上次重启后时间: %ds\n", foundEddyTLM.getTime());
Serial.println("\n");
Serial.print(foundEddyTLM.toString().c_str());
Serial.println("\n");
}
}
}
} scanCallbacks;
void setup() {
Serial.begin(115200);
Serial.println("扫描中...");
NimBLEDevice::init("Beacon-scanner");
pBLEScan = BLEDevice::getScan();
pBLEScan->setScanCallbacks(&scanCallbacks);
pBLEScan->setActiveScan(true);
pBLEScan->setInterval(100);
pBLEScan->setWindow(100);
}
void loop() {
NimBLEScanResults foundDevices = pBLEScan->getResults(scanTime, false);
Serial.print("发现的设备: ");
Serial.println(foundDevices.getCount());
Serial.println("扫描完成!");
pBLEScan->clearResults(); // 删除扫描结果缓冲区以释放内存
delay(2000);
}
结果

技术支持与产品讨论
感谢您选择我们的产品!我们在这里为您提供不同的支持,以确保您使用我们产品的体验尽可能顺畅。我们提供多种沟通渠道,以满足不同的偏好和需求。