9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

IoTLTAdvent Calendar 2018

Day 10

Nefry BTからブラウザにWeb Bluetoothでデータを表示する方法

Last updated at Posted at 2018-12-10

IoTLT Advent Calendar 2018の10日目担当の蔵下です。普段はIoTな会社でWeb系の開発を行っています。

のびすけさんの記事「Nefry BT(ESP32)からBLEでNode.jsにデータを送ってみよう」で、Nefry BTもいい感じにBLE使えるやん!:clap: ということで、 Nefry BT ↔ ブラウザ でデータを表示する方法をまとめてみました。

web.gif

▲クリスマスっぽさを少しだけ:christmas_tree:

Nefry BT(BLEデバイス)とブラウザの通信はWeb Bluetoothでできる

Nefry BTとブラウザでのデータ通信は Web Bluetooth で実現できます。普段の仕事でもゴニョゴニョ使っているので、詳細は他記事でまとめていますので良かったら見てみてください。

Web Bluetoothは、現在(2018/12/10)Windows、Mac、AndroidのChromeで使えます(詳細はこちら)。そうです、 スマホでも使えます! IoTなデモ作る幅も広がると思うので、ぜひ触ってみてください。

ソースコード

今回のデモはのびすけさんの記事「Nefry BT(ESP32)からBLEでNode.jsにデータを送ってみよう」をベースに一部変更を加えながら進めました(ありがとうございます!)。Nefry BTは初期のR1を使っています。

スケッチ(Nefry BT側のコード)

sketch.ino
#include <Nefry.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
uint8_t value = 0;

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

#define SERVICE_UUID        "d5875408-fa51-4763-a75d-7d33cecebc31"
#define CHARACTERISTIC_UUID "a4f01d8c-a037-43b6-9050-1876a8c23584"

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

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

void setup() {
  Serial.begin(115200);

  // Create the BLE Device
  BLEDevice::init("NefryBT");

  // Create the BLE Server
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  // Create the BLE Service
  BLEService *pService = pServer->createService(SERVICE_UUID);

  // Create a BLE Characteristic
  pCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID,
                      BLECharacteristic::PROPERTY_READ   |
                      BLECharacteristic::PROPERTY_WRITE  |
                      BLECharacteristic::PROPERTY_NOTIFY |
                      BLECharacteristic::PROPERTY_INDICATE
                    );

  // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
  // Create a BLE Descriptor
  pCharacteristic->addDescriptor(new BLE2902());

  // Start the service
  pService->start();

  // Start advertising
  pServer->getAdvertising()->start();
  Serial.println("Waiting a client connection to notify...");
}

void loop() {

  if (deviceConnected) {
    Serial.printf("*** NOTIFY: %d ***\n", value);
    char buffer[32];
    sprintf(buffer, "{\"val\":%d}", value);
    Serial.printf(buffer);
    pCharacteristic->setValue(buffer);
    pCharacteristic->notify();
    //pCharacteristic->indicate();
    value++;
  }
  delay(2000);
}

JavaScript(ブラウザ側のコード)

main.js
const SERVICE_UUID = 'd5875408-fa51-4763-a75d-7d33cecebc31'
const CHARACTERISTIC_UUID = 'a4f01d8c-a037-43b6-9050-1876a8c23584'

const btn = document.getElementById('btn')
const text = document.getElementById('text')

// Web Bluetoothはユーザーアクションをトリガーに処理を始める必要がある
btn.addEventListener('click', (event) => {
  connect()
})

const connect = () => {
  // Scan
  navigator.bluetooth.requestDevice({
    // 'Nefry'というデバイス名でフィルタリング
    acceptAllDevices: false,
    filters: [
      {namePrefix: 'Nefry'}
    ],
    optionalServices: [
      // 使用したいServiceを登録しておく
      SERVICE_UUID
    ]
  })
    // 接続
    .then(device => device.gatt.connect())
    // Service取得
    .then(server => server.getPrimaryService(SERVICE_UUID))
    // Characteristic取得
    .then(service => service.getCharacteristic(CHARACTERISTIC_UUID))
    // Notificationsを開始
    .then(characteristic => setNotifications(characteristic))
    // Errorはこちら
    .catch(error => console.log(error))
}

// Notification設定
const setNotifications = (characteristic) => {

  // Add Event
  characteristic.addEventListener('characteristicvaluechanged', (event) => {
    const value = event.target.value

    // データをパース
    const decoder = new TextDecoder('utf-8')
    const str = decoder.decode(value)
    const json = JSON.parse(str)
    // Nefry BTからのデータを表示
    if (text) text.innerHTML = json.val
  })

  // Notifications開始
  characteristic.startNotifications()
}

HTML(ブラウザ側のコード)

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Web Bluetooth API</title>
  <script src="main.js" defer></script>
  <!-- CSSは省略 -->
</head>
<body>
<button id="btn">Connect</button>
<div id="text"></div>
</body>
</html>

まとめ

特に面白みのないネタになってしまいました(笑)。ですが、みなさんの面白いIoT作品の新たな選択肢になればいいなと思いまとめてみました。最近IoTLT参加できていなかったので、来年からまたちょこちょこ参加したいと思います! 良いお年を~

9
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?