iT邦幫忙

2023 iThome 鐵人賽

DAY 17
0

Day 17 Web Serial API

成功組成跟韌體溝通的 protocol 資料後,接下來就是要透過任何 Serial 傳送給 ChameleonUltra 並且等候回應。筆者在開發這個專案時,主要會用 Web Serial API 進行開發,所以先來介紹這個 API 該如何使用。

瀏覽器支援度

目前 Web Serial API 支援所有 PC 的作業系統 (ChromeOS, Linux, macOS, and Windows),只要是 Chrome 89 以上的版本就有支援。

安全性限制

僅限 HTTPS 使用

因為藍牙會有可能曝露個人資料以及定位,所以 Web BLE API 只能在 HTTPS 網站上使用。

在本地開發過程中也會有這個限制,筆者會在接下來的文章提到要如何解決這個限制。

只能在特定的使用者互動的事件中使用

我們在這個專案中會使用 navigator.bluetooth.requestDevice 的 API,但由於安全性考量,Chrome 限制這個 API 只能在特定的使用者互動的事件中使用,例如 pointerupclicktouchend …等。

如何連線到 Chameleon Ultra

首先,我們需要先檢查瀏覽器是否支援 Web Serial API:

function isWebSerialSupported() {
  return "serial" in navigator
}

如果有支援的話,下一步就是尋找 Chameleon Ultra,在這個步驟會需要裝置 ID:

const filters = [
  { usbVendorId: 0x6868, usbProductId: 0x8686 }, // Chameleon Tiny
]
// 這行程式碼會跳出選擇裝置的視窗
const port = await navigator.serial.requestPort({ filters })
console.log(port.getInfo())

成功取得 port 以後,就可以開始進行連線:

await port.open({ baudRate: 115200 }) // Chameleon Ultra 的 baudRate 為 115200

如何讀取資料

以下是 Read from and write to a serial port | Chrome Developers 所提供的範例程式碼:

const reader = port.readable.getReader()

// Listen to data coming from the serial device.
while (true) {
  const { value, done } = await reader.read()
  if (done) { // Allow the serial port to be closed later.
    reader.releaseLock()
    break
  }
  console.log(value) // value is a Uint8Array.
}

但在這個專案中,會需要頻繁檢查資料是否完整傳送,所以筆者選擇寫一個自訂的 WritableStream,然後使用 pipeTo 將資料寫入 WritableStream,以下是範例程式碼:

class WritableSink {
  constructor() {
    this.bufs = []
  }

  write(chunk) {
    this.bufs.push(Buffer.from(chunk)) // convert Uint8Array to Buffer
  }
}
const writable = new WritableStream(new WritableSink())
port.readable.pipeTo(writable) // no await prevent blocking

如何寫入資料

我們會透過筆者自己寫的 Buffer 來組成 ChameleonUltra 的 Protocol,由於這個 Buffer 繼承自 Uint8Array,所以可以直接當成 Uint8Array 來使用,然後透過 port.writable.write 來寫入資料:

const buf = Buffer.from('11ef03e80000000b0a48656c6c6f20576f726c64e4', 'hex') // 來自 Day 6 的範例
const writer = port.writable.getWriter()
await writer.write(buf)
writer.releaseLock()

參考連結


上一篇
Day 16 Buffer 的進階使用技巧 (Part 2)
下一篇
Day 18 Web BLE API
系列文
用 Web Serial/Bluetooth 來控制 ChameleonUltra 硬體30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言