Bluetooth使用方法
Seeed Studio XIAO ESP32C3はBluetooth 5(LE)接続をサポートしています。このwikiでは、このボードでのBluetoothの基本的な使用方法を紹介します。
ハードウェアセットアップ
- ステップ1. 付属のWiFi/Bluetoothアンテナをボード上のIPEXコネクタに接続します

- ステップ2. USB Type-CケーブルでXIAO ESP32C3をコンピュータに接続します

Bluetoothデバイスのスキャン
この例では、XIAO ESP32C3を使用して周囲の利用可能なBluetoothデバイスをスキャンします。
- ステップ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);
}
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. コードをアップロードし、シリアルモニターを開いてBluetoothデバイスのスキャンを開始します

XIAO ESP32C3 をBluetoothサーバーとして使用
この例では、XIAO ESP32C3 をBluetoothサーバーとして使用します。ここでは、スマートフォンを使用してXIAO ESP32C3 ボードを検索し、文字列を送信してシリアルモニターに表示します
- ステップ1. 以下のコードをコピーしてArduino IDEに貼り付けます
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
// See the following for generating UUIDs:
// 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() {
// put your main code here, to run repeatedly:
delay(2000);
}
ESP32開発ボードをバージョン3.0.0以上にアップグレードしている場合は、互換性を保つためにコードの一部を変更する必要があります。
std::string value = pCharacteristic->getValue();
をString value = pCharacteristic->getValue();
に変更してください
-
ステップ 2. コードをアップロードしてシリアルモニターを開く
-
ステップ 3. スマートフォンにLightBlueアプリをダウンロードしてインストールする
-
ステップ 4. スマートフォンのBluetoothを有効にし、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; // In milliseconds
NimBLEScan* pBLEScan;
class ScanCallbacks : public NimBLEScanCallbacks {
void onResult(const NimBLEAdvertisedDevice* advertisedDevice) override {
if (advertisedDevice->haveName()) {
Serial.print("Device name: ");
Serial.println(advertisedDevice->getName().c_str());
Serial.println("");
}
if (advertisedDevice->haveServiceUUID()) {
NimBLEUUID devUUID = advertisedDevice->getServiceUUID();
Serial.print("Found 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("Found an iBeacon!");
NimBLEBeacon oBeacon = NimBLEBeacon();
oBeacon.setData(reinterpret_cast<const uint8_t*>(strManufacturerData.data()), strManufacturerData.length());
Serial.printf("iBeacon Frame\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("Found another manufacturers beacon!");
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("Found an EddystoneTLM beacon!");
NimBLEEddystoneTLM foundEddyTLM = NimBLEEddystoneTLM();
foundEddyTLM.setData(reinterpret_cast<const uint8_t*>(serviceData.data()), serviceData.length());
Serial.printf("Reported battery voltage: %dmV\n", foundEddyTLM.getVolt());
Serial.printf("Reported temperature from TLM class: %.2fC\n", (double)foundEddyTLM.getTemp());
int temp = (int)serviceData[5] + (int)(serviceData[4] << 8);
float calcTemp = temp / 256.0f;
Serial.printf("Reported temperature from data: %.2fC\n", calcTemp);
Serial.printf("Reported advertise count: %d\n", foundEddyTLM.getCount());
Serial.printf("Reported time since last reboot: %ds\n", foundEddyTLM.getTime());
Serial.println("\n");
Serial.print(foundEddyTLM.toString().c_str());
Serial.println("\n");
}
}
}
} scanCallbacks;
void setup() {
Serial.begin(115200);
Serial.println("Scanning...");
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("Devices found: ");
Serial.println(foundDevices.getCount());
Serial.println("Scan done!");
pBLEScan->clearResults(); // delete results scan buffer to release memory
delay(2000);
}
結果

技術サポート & 製品ディスカッション
私たちの製品をお選びいただき、ありがとうございます!私たちは、お客様の製品体験が可能な限りスムーズになるよう、さまざまなサポートを提供しています。異なる好みやニーズに対応するため、複数のコミュニケーションチャンネルを用意しています。