Wio Terminal 蓝牙 Web API

本文主要介绍如何使用 Web Bluetooth API 和 Wio Terminal 的蓝牙功能交互。Web Bluetooth API 提供了在网络浏览器上与蓝牙设备交互的能力,类似于 Physical Web,帮助人们直接从网络走到设备并与之交互。

Web Bluetooth 示例

以下示例演示了如何设置 Wio Terminal 并使用一个简单的 HTML 站点将 Web Bluetooth API 与 Wio Terminal 的蓝牙进行交互。

Arduino 设置

请参照 Wio Terminal 网卡固件更新Wio Terminal 蓝牙教程 更新 RTL8720 固件并安装依赖库。

将下面示例代码复制到 Arduino IDE,编译并上传到 Wio Terminal:

#include <rpcBLEDevice.h>
#include <BLEServer.h>
#include <BLE2902.h>

bool _BLEClientConnected = false;
uint8_t level = 10;

#define BatteryService BLEUUID((uint16_t)0x180F) 
BLECharacteristic BatteryLevelCharacteristic(BLEUUID((uint16_t)0x2A19), BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_NOTIFY);

class MyServerCallbacks : public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      _BLEClientConnected = true;
    };

    void onDisconnect(BLEServer* pServer) {
      _BLEClientConnected = false;
    }
};

/* ######## CALL back to receive data from Phone ######## */
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"

class MyCallbacks: public BLECharacteristicCallbacks {

    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();
      Serial.println(rxValue[0]);

      if (rxValue.length() > 0) {
        Serial.println("*********");
        Serial.print("Received Value: ");

        for (int i = 0; i < rxValue.length(); i++) {
          Serial.print(rxValue[i]);
        }
        Serial.println();
        Serial.println("*********");
      }

    }
};

/* ############################################################### */
void initBLE() {
  BLEDevice::init("BLE Battery");
  // Create the BLE Server
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  // Create the BLE Service
  BLEService *pBattery = pServer->createService(BatteryService);

  pBattery->addCharacteristic(&BatteryLevelCharacteristic);
  BatteryLevelCharacteristic.addDescriptor(new BLE2902());


  /* ######## define callback ######## */
  BLECharacteristic *pWriteCharacteristic = pBattery->createCharacteristic(
                                         CHARACTERISTIC_UUID_RX,
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  pWriteCharacteristic->setAccessPermissions(GATT_PERM_READ | GATT_PERM_WRITE);

  pWriteCharacteristic->setCallbacks(new MyCallbacks());
  /* ############################################################### */

  pServer->getAdvertising()->addServiceUUID(BatteryService);

  pBattery->start();
  // Start advertising
  pServer->getAdvertising()->start();
}

void setup() {
  Serial.begin(115200);
//   while(!Serial);
  Serial.println("--- Wio Terminal BLE Battery Level Indicator ---");
  initBLE();
}

void loop() {

  BatteryLevelCharacteristic.setValue(&level, 1);
  BatteryLevelCharacteristic.notify();
  delay(3000);

  level++;
  Serial.print("Battery Level: ");
  Serial.println(int(level));

  if (int(level)==100)
    level=0;
}

上面的代码将 Wio Terminal 配置为蓝牙可发现名称 BLE Battery 并作为蓝牙服务器,建立一个 Battery BLE Service。这很重要,后面需要与 Web Bluetooth API 的 HTML 站点匹配。

Web Bluetooth API HTML 网页

现在 Wio Terminal 已全部设置完毕,我们需要使用 Web Bluetooth API 编写一个 HTML 站点,以便它们可以交互。检查以下内容以供参考:

  • 下载 webbluetooth.html 文件;
  • 使用最新的 Google Chrome 或 Microsoft Edge 浏览器(它们支持 Web Bluetooth APIs)打开 webbluetooth.html
  • F12 打开 Console 控制台;
  • 点击网页上的 Connect with BLE device 按钮,你应该会看到 BLE Battery(Wio Terminal)出现在连接窗口中。 点击 Connect
  • 点击 Start 按钮开始接收来自 Wio Terminal 的电池电量数据。

Web Bluetooth API 网页控制台:

Arduino 串口监视器:

看,现在 Wio Terminal 正在与使用 Web Bluetooth API 的站点交互!这个功能使得 BLE 更加有趣,你可以通过 Web 浏览器传输信息!

可视化传感器数据

下面这个示例介绍如何使用 Web Bluetooth API 在网页上以可视化的方式显示 Wio Terminal 的加速度传感器数据。

img

Arduino 设置

请参照 Wio Terminal 网卡固件更新Wio Terminal 蓝牙教程 更新 RTL8720 固件并安装依赖库。

下载 WebBluetooth-Accelerator.ino,或直接将下面示例代码复制到 Arduino IDE。

#include <rpcBLEDevice.h>
#include <BLEServer.h>
#include <LIS3DHTR.h>

#define accelerometerService "19b10000-e8f2-537e-4f6c-d104768a1214"
#define firstCharacteristic  "19b10010-e8f2-537e-4f6c-d104768a1214"
#define DESCRIPTOR_UUID      "19b10010"

LIS3DHTR<TwoWire> lis;

bool deviceConnected = false;
bool oldDeviceConnected = false;

BLEServer *pServer = NULL;
BLECharacteristic * pCharacteristic;

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      Serial.println("MyServerCallbacks onConnect ");
      deviceConnected = true;
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();

      if (rxValue.length() > 0) {
        Serial.println("*********");
        Serial.print("Received Value: ");
        for (int i = 0; i < rxValue.length(); i++)
          Serial.print(rxValue[i]);

        Serial.println();
        Serial.println("*********");
      }
    }
};

void setup() {
  Serial.begin(115200);
//  while(!Serial){};

  lis.begin(Wire1);
  if (!lis) {
    Serial.println("Accelerater Error!");
    while(1);
  }
  lis.setOutputDataRate(LIS3DHTR_DATARATE_25HZ); //Data output rate
  lis.setFullScaleRange(LIS3DHTR_RANGE_2G); //Scale range set to 2g
  Serial.println("Accelerater Initialised!");

  Serial.println("Starting BLE work!");

  BLEDevice::init("Accelerometer");
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  BLEService *pService = pServer->createService(accelerometerService);
  pCharacteristic = pService->createCharacteristic(
                                         firstCharacteristic,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );
  pCharacteristic->setAccessPermissions(GATT_PERM_READ | GATT_PERM_WRITE);
  BLEDescriptor *pDescriptor = pCharacteristic->createDescriptor(
                                         DESCRIPTOR_UUID,
                                          ATTRIB_FLAG_VOID | ATTRIB_FLAG_ASCII_Z,
                                         GATT_PERM_READ | GATT_PERM_WRITE,
                                         2
                                         );
  pCharacteristic->setCallbacks(new MyCallbacks());
  pService->start();

  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(accelerometerService);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();
  Serial.println("Characteristic defined! Now you can read it in your phone!");
}

void loop() { 
  if (deviceConnected) {
    updateAcceleration();
  }
      // disconnecting
    if (!deviceConnected && oldDeviceConnected) {
        delay(500); // give the bluetooth stack the chance to get things ready
        pServer->startAdvertising(); // restart advertising
        Serial.println("start advertising");
        oldDeviceConnected = deviceConnected;
    }
    // connecting
    if (deviceConnected && !oldDeviceConnected) {
    // do stuff here on connecting
        oldDeviceConnected = deviceConnected;
    }
}

void updateAcceleration() {
  float x_values, y_values, z_values;
  x_values = lis.getAccelerationX();
  y_values = lis.getAccelerationY();
  z_values = lis.getAccelerationZ();

  String accelerometerData = String(x_values)+"|"+String(y_values)+"|"+String(z_values);
  Serial.println(accelerometerData);
  pCharacteristic->setValue(accelerometerData.c_str());
  pCharacteristic->notify();
  delay(20);
}

Web Bluetooth API HTML 网页

  • 使用最新的 Google Chrome 或 Microsoft Edge 浏览器打开 Web Bluetooth Accelerometer Plotter For Wio Terminal 网页。对应的 HTML 代码在这里
  • 连接名为 “Accelerator” 的设备(Wio Terminal),然后你就可以看到网页上动态显示加速度传感器的数据。

img

学会这个技能,你就可以使用 Wio Terminal 编写 Web 蓝牙交互网站啦!

资源链接

2 Comments

  1. I’m not that much of a online reader to be honest but your
    blogs really nice, keep it up! I’ll go ahead and bookmark your website to come back later on. All the best

Leave a Reply