Skip to main content

Bluetooth使用方法

Seeed Studio XIAO ESP32C3はBluetooth 5(LE)接続をサポートしています。このwikiでは、このボードでのBluetoothの基本的な使用方法を紹介します。

ハードウェアセットアップ

  • ステップ1. 付属のWiFi/Bluetoothアンテナをボード上のIPEXコネクタに接続します
pir
  • ステップ2. USB Type-CケーブルでXIAO ESP32C3をコンピュータに接続します
pir

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);
}
tip

ESP32開発ボードをバージョン3.0.0以上にアップグレードした場合、互換性を保つためにいくつかのコードを変更する必要があります。

  1. BLEScanResults foundDevices = pBLEScan->start(scanTime, false);BLEScanResults* foundDevices = pBLEScan->start(scanTime, false); に変更
  2. Serial.println(foundDevices.getCount());Serial.println(foundDevices->getCount()); に変更

ステップ2. コードをアップロードし、シリアルモニターを開いてBluetoothデバイスのスキャンを開始します

pir

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);
}
tip

ESP32開発ボードをバージョン3.0.0以上にアップグレードしている場合は、互換性を保つためにコードの一部を変更する必要があります。

  1. std::string value = pCharacteristic->getValue();String value = pCharacteristic->getValue(); に変更してください
  • ステップ 2. コードをアップロードしてシリアルモニターを開く

  • ステップ 3. スマートフォンにLightBlueアプリをダウンロードしてインストールする

  • ステップ 4. スマートフォンのBluetoothを有効にし、XIAO ESP32C3に近づけて、デバイスをスキャンしてMyESP32デバイスに接続する

pir
  • ステップ 5. LightBlueアプリを開き、Bondedタブをクリックする
pir
  • ステップ 6. MyESP32の横にあるCONNECTをクリックする
pir
  • ステップ 7. 最下部にあるReadable, Writableと表示されているセクションをクリックする
pir
  • ステップ 8. Data formatドロップダウンメニューでUTF-8 Stringを選択する
pir
  • ステップ 9. WRITTEN VALUESの下に「Hello」と入力し、WRITEをクリックする
pir

Arduino IDEのシリアルモニターに文字列「Hello」が出力されるのが確認できます

pir

NimBLE-Arduino

概要

このライブラリは、bluedroidベースのライブラリと比較して、ESP32 BLEアプリケーションのリソース使用量を大幅に削減し、パフォーマンスを向上させます。目標は、元のライブラリとの互換性を合理的な範囲で維持しつつ、NimBLEスタックを使用することです。さらに、このライブラリは元のライブラリよりも積極的に開発・保守され、改善された機能と安定性を提供します。

詳細については、作者のGithubリンクをご覧ください。

ステップ 1.ライブラリの追加

pir

ステップ 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);
}

結果

pir

技術サポート & 製品ディスカッション

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

Loading Comments...