LoginSignup
18
11

More than 5 years have passed since last update.

Web Bluetooth(Read/Write/Notifications)の使い方まとめ

Posted at

公私共に年末に向けてバタバタしながらもaptpod Advent Calendar 2018の9日目。

2018年もブラウザの進化が止まらない1年でしたね。その中でもWebBluetoothがWindows 10のChromeでも使えるようになったのはインパクトでかかったです。仕事でも実際に導入していろいろいじくり倒しました(その時の記事「Web Bluetoothを実戦投入すると意外と使えたメモ」)。

今回はWeb BluetoothでBLEデバイスとデータ通信する際のRead/Write/Notificationsをシンプルなコードで紹介します。

ソースコード

データ通信する前の下準備

BLEデバイスとデータ通信する前に、ブラウザからBLEデバイスをスキャンし接続する必要があります。スキャン時は、デバイス名・サービスUUIDでフィルタリングすることができます。

// Service UUID
const SERVICE_UUID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'

// Characteristic UUID
const CHARACTERISTIC_UUID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'

// Scan
navigator.bluetooth.requestDevice({
  // 全てのBLEデバイスをスキャン対象とする場合はtrue
  // フィルタリングしたい場合はfalse
  acceptAllDevices: false,
  // デバイス名, デバイス名のプレフィックス, ServiceのUUID
  filters: [
    {name: 'デバイス名'},
    {namePrefix: 'デバイス名のプレフィックス'},
    {services: [SERVICE_UUID]}
  }],
  // 接続するService
  optionalServices: [SERVICE_UUID]
})
  .then(device => {
    // 接続
    return device.gatt.connect()
  }))
  .then(server => {
    // Service取得
    return server.getPrimaryService(SERVICE_UUID)
  })
  .then(service => {
    // Characteristic取得
    return service.getCharacteristic(CHARACTERISTIC_UUID)
  })
  .then(characteristic => {
    // characteristicに対してRead/Write/Notificationsの処理を記述
  })
  .catch(error => console.error(error))

Read

characteristic.readValue()
  .then(response => {
    // データがStringの場合
    const decoder = new TextDecoder('utf-8')
    const str = decoder.decode(response)
    console.log(str)

    // データがnumberの場合
    const num = getUintN(response)
    console.log(num)
  })
  .catch(error => console.error(error))

// 数値変換
const getUintN = (dataView) => {
  switch(dataView.byteLength) {
    case 0:
      return 0
    case 1:
      return dataView.getUint8(0)
    case 2:
      return dataView.getUint16(0)
    case 4:
      return dataView.getUint32(0)
    case 8: {
      const top = dataView.getUint32(0) * Math.pow(2, 32)
      const bottom = dataView.getUint32(4)
      return top + bottom
    }
    default:
      return 0
  }
}

Write

const num = 1
characteristic.writeValue(new Uint8Array([num]));

Notifications

// Add Event
characteristic.addEventListener('characteristicvaluechanged', handler)

characteristic.startNotifications()
  .catch(error => {
    // Remove Event
    characteristic.removeEventListener('characteristicvaluechanged', handler)
    console.error(error)
  })

const handler = (event) => {
  const value = event.target.value

  // データがStringの場合
  const decoder = new TextDecoder('utf-8')
  const str = decoder.decode(value)
  console.log(str)

  // データがnumberの場合
  const num = getUintN(value)
  console.log(num)
}

手元にBLEデバイスがないけど試してみたい場合は

iOSアプリ「LightBlue® Explorer」で仮想のBLEデバイスを作成して試してみてください。無料で使えるので気軽に雰囲気がつかめると思います。

まとめ

普段の開発でWeb Bluetoothに触れる機会は少ないと思います。ですが、ブラウザの進化とともにJSでできることがこれからも広がっていくでしょう。ブラウザが限定されてしまうこともありますが、 次のWebで何ができるのか 積極的にキャッチアップしていければと思います。

18
11
0

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
18
11