進階通訊
本頁涵蓋進階 USB 通訊方法、串列埠和網路通訊端。有關基本讀取和寫入,請參閱寫入和讀取。
USB 傳輸類型
Section titled “USB 傳輸類型”了解 USB 傳輸類型之間的差異,將幫助您選擇正確的方法並排除意外錯誤。
| 類型 | 方法 | 典型大小 | 使用情況 |
|---|---|---|---|
| 中斷 | device.write() / device.read() | 3–64 位元組 | RGB 資料、小型命令、鍵盤/滑鼠輸入 |
| 批量 | device.write() / device.read() | 64–1025 位元組 | LCD 影像、韌體更新、大型設定區塊 |
| 控制 | device.send_report() / device.get_report() / device.control_transfer() | 32–192 位元組 | 認證握手、HID 功能報告、裝置設定 |
相同的 device.write() 和 device.read() 函式用於中斷和批量傳輸——USB 驅動程式根據端點和封包大小確定傳輸類型。
HID 報告方法
Section titled “HID 報告方法”device.input_report()
Section titled “device.input_report()”發送 HID GET_INPUT_REPORT 控制傳輸。類似於 device.get_report(),但專門請求輸入報告而非功能報告。當 get_report() 返回錯誤資料(因為裝置將輸入和功能報告類型分開)時使用此方法。
| 參數 | 類型 | 說明 | 範例 |
|---|---|---|---|
| DataArray | 1D 陣列 | 報告請求資料 | [0x01] |
| Length | Int | 預期的報告大小(位元組) | 64 |
| 返回值 | 類型 | 說明 |
|---|---|---|
| DataArray | 1D 陣列 | 從裝置接收到的位元組 |
var inputData = device.input_report([0x01], 64);原始 USB 方法
Section titled “原始 USB 方法”device.bulk_transfer()
Section titled “device.bulk_transfer()”對特定 USB 端點執行直接的批量或中斷傳輸。與使用 device.set_endpoint() 所選端點的 device.write() 和 device.read() 不同,此方法允許您通過地址來定向任何端點。
- 以
0x80或更高值結尾的端點地址為 IN(裝置 → 主機,讀取)。 - 低於
0x80的端點地址為 OUT(主機 → 裝置,寫入)。
| 參數 | 類型 | 說明 | 範例 |
|---|---|---|---|
| Endpoint | Hex | USB 端點地址 | 0x81 |
| DataArray | 1D 陣列 | 要發送的資料(OUT),或空陣列(IN) | [0x01, 0x02] |
| Length | Int | 傳輸大小(位元組) | 64 |
| Timeout | Int | 放棄前的毫秒數 | 100 |
| 返回值 | 類型 | 說明 |
|---|---|---|
| DataArray | 1D 陣列 | 接收到的位元組(IN 傳輸),或空陣列 |
// 寫入到端點 0x01device.bulk_transfer(0x01, [0x00, 0x01, 0x02], 3, 100);
// 從端點 0x81 讀取var response = device.bulk_transfer(0x81, [], 64, 100);
// 大型批量寫入(例如 LCD 影像資料)device.bulk_transfer(0x02, imageData, 1024, 500);device.control_transfer()
Section titled “device.control_transfer()”低階 USB 控制傳輸。用於認證握手、廠商特定協定,以及 HID 方法不足的情況。這是控制傳輸,而非批量傳輸。
| 參數 | 類型 | 說明 | 範例 |
|---|---|---|---|
| RequestType | Hex | USB 請求類型位元組(方向、類型、接收者) | 0xA1 |
| Request | Hex | 請求代碼(裝置特定) | 0x01 |
| Value | Hex | 值欄位 | 0x0100 |
| Index | Int | 介面或端點索引 | 0x00 |
| DataArray | 1D 陣列 | 要發送的資料(主機到裝置),或空陣列 | [] |
| Length | Int | 預期的響應長度(裝置到主機) | 192 |
| Timeout | Int | 放棄前的毫秒數 | 1000 |
| 返回值 | 類型 | 說明 |
|---|---|---|
| DataArray | 1D 陣列 | 接收到的位元組(裝置到主機傳輸) |
常用 RequestType 值:
| 值 | 方向 | 類型 | 接收者 | 使用情況 |
|---|---|---|---|---|
0x21 | 主機 → 裝置 | Class | Interface | HID SET_REPORT |
0xA1 | 裝置 → 主機 | Class | Interface | HID GET_REPORT |
0x80 | 裝置 → 主機 | Standard | Device | 描述符讀取 |
0x00 | 主機 → 裝置 | Standard | Device | 標準命令 |
// 讀取認證令牌(裝置 → 主機,class,interface)var token = device.control_transfer( 0xA1, // 裝置到主機,class,interface 0x01, // GET_REPORT 0x0100, // 報告類型(Feature)+ 報告 ID 0x00, // 介面 0 [], // 無輸出資料 192, // 預期接收 192 位元組 1000 // 1 秒超時);
// 發送功能報告(主機 → 裝置)device.control_transfer(0x21, 0x09, 0x0300, 0, [0x03, 0x08, 0x32], 0, 500);對於串列/COM 埠裝置,匯入串列模組並將外掛程式的 Type() 設定為 "serial"。
import { serial } from "@SignalRGB/serial";
export function Type() { return "serial"; }serial.connect({ baudRate: 115200, // 預設:115200 parity: "None", // "None", "Even", "Odd", "Space", "Mark" dataBits: 8, // 5, 6, 7, 或 8 stopBits: "One" // "One", "OneAndHalf", "Two"});| 方法 | 說明 | 返回值 |
|---|---|---|
serial.connect(options?) | 開啟串列埠 | bool |
serial.disconnect() | 關閉串列埠 | void |
serial.isConnected() | 檢查連線狀態 | bool |
serial.write(data) | 發送資料 | 已寫入位元組數 |
serial.read(maxBytes?, timeoutMs?) | 讀取可用位元組(預設:全部,超時 1000ms) | 位元組陣列 |
serial.readAll() | 立即讀取所有可用位元組 | 位元組陣列 |
serial.availablePorts() | 列出可用 COM 埠 | 陣列 |
serial.getPortName() | 當前埠名稱 | string |
serial.getBaudRate() | 當前鮑率 | number |
serial.getDeviceInfo() | 含 VID、PID 等的埠資訊 | object |
import { serial } from "@SignalRGB/serial";
export function Type() { return "serial"; }
export function Initialize() { if (!serial.connect()) { device.log("Failed to connect to serial port"); return; } device.log(`Connected on ${serial.getPortName()} at ${serial.getBaudRate()} baud`);}
export function Render() { serial.write([0xFF, ...RGBData]);}
export function Shutdown() { serial.disconnect();}網路通訊(TCP / UDP)
Section titled “網路通訊(TCP / UDP)”對於網路連接的裝置,匯入 TCP 或 UDP 模組並將 Type() 設定為 "network"。兩個模組都使用事件型回呼模型。
import { tcp } from "@SignalRGB/tcp";import { udp } from "@SignalRGB/udp";
export function Type() { return "network"; }import { tcp } from "@SignalRGB/tcp";
let socket;
export function Initialize() { socket = tcp.createSocket();
socket.on("connected", () => { device.log("Connected"); socket.send([0x01, 0x02, 0x03]); });
socket.on("message", (data) => { device.log(`Received: ${data}`); });
socket.on("error", (err) => { device.log(`Error: ${err}`); });
socket.connect("192.168.1.100", 8080);}
export function Render() { if (socket.state === socket.ConnectedState) { socket.send(RGBData); }}
export function Shutdown() { socket.close();}TCP 方法:
| 方法 | 說明 |
|---|---|
tcp.createSocket() | 建立新的 TCP 通訊端 |
socket.connect(address, port) | 連接到主機 |
socket.send(data) | 發送字串或位元組陣列 |
socket.bind(port) | 綁定到本地埠 |
socket.close() | 關閉通訊端 |
socket.on(event, callback) | 註冊事件處理器 |
TCP 事件: "connected"、"disconnected"、"message"、"error"
import { udp } from "@SignalRGB/udp";
let socket;
export function Initialize() { socket = udp.createSocket();
socket.on("message", (data) => { device.log(`Received: ${data}`); });
socket.connect("192.168.1.100", 21324);}
export function Render() { socket.send(RGBData);}
export function Shutdown() { socket.close();}UDP 方法:
| 方法 | 說明 |
|---|---|
udp.createSocket() | 建立新的 UDP 通訊端 |
socket.connect(address, port) | 設定預設發送目標 |
socket.send(data) | 發送到已連接的地址 |
socket.write(data, address, port) | 發送到特定地址,無需先呼叫 connect() |
socket.bind(port) | 綁定到本地埠以接收資料 |
socket.close() | 關閉通訊端 |
socket.on(event, callback) | 註冊事件處理器 |
UDP 事件: "connected"、"disconnected"、"message"、"error"
DTLS(加密 UDP)
Section titled “DTLS(加密 UDP)”對於需要加密通訊的裝置(例如 Philips Hue),使用 dtls 功能。它使用預共用金鑰(PSK)提供 DTLS 加密 UDP。
export function Initialize() { device.addFeature("dtls");
dtls.onConnectionEstablished(() => { device.log("DTLS connected"); }); dtls.onConnectionClosed(() => { device.log("DTLS closed"); }); dtls.onConnectionError(() => { device.log("DTLS error"); });
dtls.createConnection("192.168.1.50", 2100, authIdentity, authKey);}
export function Render() { if (dtls.hasEncryptedConnection()) { dtls.send(RGBData); }}
export function Shutdown() { dtls.CloseConnection();}DTLS 方法:
| 方法 | 說明 |
|---|---|
dtls.createConnection(host, port, identity, key) | 使用 PSK 開啟加密連線 |
dtls.send(data, endianness?) | 發送加密資料(0 = 小端序,1 = 大端序) |
dtls.hasEncryptedConnection() | 連線已建立時返回 true |
dtls.CloseConnection() | 關閉連線 |
dtls.onConnectionEstablished(cb) | 連線成功時的回呼 |
dtls.onConnectionClosed(cb) | 連線關閉時的回呼 |
dtls.onConnectionError(cb) | 發生錯誤時的回呼 |