Pular para o conteúdo principal

Uso de Bluetooth

O Seeed Studio XIAO ESP32C3 suporta conectividade Bluetooth 5 (LE). Este wiki apresentará os conceitos básicos do uso de Bluetooth nesta placa.

Configuração do hardware

  • Passo 1. Conecte a antena WiFi/Bluetooth incluída ao conector IPEX na placa
pir
  • Passo 2. Conecte o XIAO ESP32C3 ao seu computador via cabo USB Type-C
pir

Escanear dispositivos Bluetooth

Neste exemplo, vamos usar o XIAO ESP32C3 para escanear dispositivos Bluetooth disponíveis ao redor dele.

  • Passo 1. Copie e cole o código abaixo no 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);
}
dica

Se você já atualizou sua placa de desenvolvimento ESP32 para a versão 3.0.0 ou superior, é necessário alterar alguns trechos do código para compatibilidade.

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

Passo 2. Faça o upload do código e abra o Monitor Serial para começar a escanear dispositivos Bluetooth

pir

XIAO ESP32C3 como servidor Bluetooth

Neste exemplo, vamos usar o XIAO ESP32C3 como servidor Bluetooth. Aqui, vamos procurar a placa XIAO ESP32C3 usando um smartphone e enviar strings para exibição no monitor serial

  • Passo 1. Copie e cole o código abaixo no 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);
}
dica

Se você já atualizou sua placa de desenvolvimento ESP32 para a versão 3.0.0 ou superior, é necessário alterar alguns trechos do código para compatibilidade.

  1. std::string value = pCharacteristic->getValue(); altere para String value = pCharacteristic->getValue();
  • Passo 2. Faça o upload do código e abra o Monitor Serial

  • Passo 3. Baixe e instale o aplicativo LightBlue no seu smartphone

  • Passo 4. Ative o Bluetooth no seu celular, aproxime o celular do XIAO ESP32C3, escaneie os dispositivos e conecte-se ao dispositivo MyESP32

pir
  • Passo 5. Abra o aplicativo LightBlue e clique na aba Bonded
pir
  • Passo 6. Clique em CONNECT ao lado de MyESP32
pir
  • Passo 7. Clique na seção na parte inferior que diz Readable, Writable
pir
  • Passo 8. No menu suspenso Data format, selecione UTF-8 String
pir
  • Passo 9. Digite "Hello" em WRITTEN VALUES e clique em WRITE
pir

Você verá a string de texto "Hello" exibida no monitor serial do Arduino IDE

pir

NimBLE-Arduino

Introdução

Esta biblioteca reduz significativamente o uso de recursos e melhora o desempenho para aplicações BLE no ESP32 em comparação com a biblioteca baseada em bluedroid. O objetivo é manter, na medida do razoável, a compatibilidade com a biblioteca original, mas utilizando a pilha NimBLE. Além disso, esta biblioteca será desenvolvida e mantida de forma mais ativa para fornecer capacidades e estabilidade aprimoradas em relação à original.

Para mais informações, acesse o Github do autor neste link.

Passo 1. Adicionar Biblioteca

pir

Passo 2. Exemplo

Código

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

Resultado

pir

Suporte Técnico e Discussão do Produto

Obrigado por escolher nossos produtos! Estamos aqui para fornecer diferentes tipos de suporte para garantir que sua experiência com nossos produtos seja a mais tranquila possível. Oferecemos vários canais de comunicação para atender a diferentes preferências e necessidades.

Loading Comments...