為了要在 JS 上面很精確的組成 ChameleonUltra 的 Protocol,你會有兩個方向可以選擇:
Uint8Array
及 DataView
來處理Buffer
來處理但這兩個都有各自的優缺點,接下來筆者會大概介紹一下這兩個的差異。
Uint8Array
及 DataView
Uint8Array
及 DataView
都是 Ecma 所定義的物件,在各大主流瀏覽器跟 Node.js 上的支援都沒太大問題,可以用來處理二進位的資料。
但 Uint8Array
只能用來處理 Uint8
的資料,如果需要處理別的資料形態或是 Big/Little Endian 的問題,就需要使用 DataView
來處理。但 DataView 本身又不能儲存資料,所以每次都需要宣告一個 Uint8Array
來儲存資料,然後再透過 DataView
來處理,真的是頗麻煩而且會變成取變數名稱的地獄。
Buffer
在 Node.js 有一個內建的 Buffer
可以用來處理二進位的資料,裡面也有直接針對各種資料格式及 Big/Little Endian 所設計的函式,但可惜的就是只有在 Node.js 上面能夠使用。
為了要讓這個的 Side Project 能夠跨平台 (瀏覽器跟 Node.js) 使用,然後也要盡量避免其他人需要重新看文件學才能順利使用,所以我就嘗試找了幾個可以在打包後在瀏覽器上面使用的 Buffer
套件,但後來發現對 TypeScript 的支援或多或少都有一點點小問題,所以後來我就決定自己使用 Uint8Array
及 DataView
來模擬一個 Buffer
出來使用,整個都是使用 TypeScript 進行開發,並且在打包後可以在瀏覽器上面使用。並且同時幫它加上一些自定義的函式,方便用來組成 ChameleonUltra 的 Protocol 資料。
筆者所實作的 Buffer 網址: https://github.com/taichunmin/chameleon-ultra.js/blob/master/src/buffer.ts
接著,來示範一下該如何使用這個 Buffer 來組成 ChameleonUltra 的 Protocol 資料。
const data = Buffer.from('Hello World') // 假設需要傳送的資料是 Hello World
function calcLrc(buf) {
return 0x100 - _.sum(buf) & 0xFF
}
const buf = Buffer.allocUnsafe(data.length + 10) // 建立一個足夠大的 Buffer 來組成 protocol 資料
buf.writeUInt16BE(0x11EF, 0) // 寫入 SOF 及 LRC1
buf.writeUInt16BE(1000, 2) // 寫入 CMD
buf.writeUInt16BE(0x0000, 4) // 寫入 STATUS
buf.writeUInt16BE(data.length, 6) // 寫入 LEN
buf[8] = calcLrc(buf.subarray(2, 8)) // 寫入 LRC2
data.copy(buf, 9) // 寫入 DATA
buf[buf.length - 1] = calcLrc(data) // 寫入 LRC3
console.log(buf.toString('hex'))
// Output: 11ef03e80000000b0a48656c6c6f20576f726c64e4