2024-03-02

使用 ESP32-S3 模仿 O.MG Cable

以 ATmega32u4 讀 SD卡 指令模擬 USB HID 操作鍵盤及滑鼠自動操作很方便
雖然不需要每次更新 ATmega32u4 的韌體,但仍然需要預先將指令儲存在 SD卡 中
因此在下想製作可以互動操作

預覽

O.MG Cable 是一種由 Hak5公司 製作的 USB線
外觀上與一般 USB線 相似,但內部就是一塊 具備WiFi功能的微控制器
因此可以建立網頁伺服器,透過 HTTP請求 將操作內容發送到微控制器再模擬 USB HID 發送對應指令
但 O.MG Cable 非常貴,因此在下尋找其他替代品

ESP32-S3 0.42in-OLED

ESP32-S3 0.42in-OLED 是一款整合 ESP32-S30.42寸OLED 的開發板,總共引出 11支引腳

使用 ESP32-S3 原生的 I2C 的 SCLSDA 連接到 0.42寸OLED熒幕
除了 0.42寸OLED熒幕 ,還有一粒 WS2812B RGB LED ,兩者都不佔用引出的引腳
另外 ESP32-S3 亦具備 WiFi 及 BLE HID 及 USB HID 功能
因此在下嘗試使用 ESP32-S3 來模仿 O.MG Cable

外觀

ESP32-S3 0.42in-OLED 的正面

這塊 0.42寸OLED熒幕 使用 SSD1306晶片
並且使用 I2C 協定直接連接到 ESP32-S3晶片 的 GP40(SCL) 及 GP41(SDA) ,不需要佔用引出的引腳

0.42寸OLED熒幕 擁有 闊72像素 高40像素 共 2880像素

除了 OLED 外,亦提供使用 WS2812B RGB LED
與 OLED 相同, RGB LED 控制引腳直接連接到 ESP32-S3晶片 的 GP39 ,同樣不需要佔用引出的引腳

背面焊接 ESP32-S3晶片,具備 WiFi 及 BLE HID 及 USB HID 功能

BOOT按鈕,亦是 GP0 ,按下表示接地

RST按鈕,按下接地並重設裝置

顯示開關狀態的 藍色LED,連接電源後亮著

與之前試用的 ESP32-C3 Super Mini 相同,ESP32-S3 0.42-OLED 同樣使用 晶片天線

ESP32-S3 0.42-OLED 除了能使用 BAT(VIN)USB 連接電源
亦提供 JST XH 插頭,可以連接 4支引腳,由左至右順序為:

  1. GND
  2. 3V3(VIN)
  3. SDA
  4. SCL
引腳
USB方向(正面)
左排引腳 右排引腳
15 VIN
GP18 1 14 5V
GP17 2 13 GND
GP9 3 12 3V3
GP8 4 11 GP35
GP7 5 10 GP36
GP6 6 9 GP37
GP5 7 8 GP16
編號 引腳 方向 功能
1 GP18 輸出輸入 第18數碼引腳
2 GP17 輸出輸入 第17數碼引腳
3 GP9 輸出輸入 第9數碼引腳
4 GP8 輸出輸入 第8數碼引腳
5 GP7 輸出輸入 第7數碼引腳
6 GP6 輸出輸入 第6數碼引腳
7 GP5 輸出輸入 第5數碼引腳,UART TX引腳
8 GP16 輸出輸入 第16數碼引腳,UART RX引腳
9 GP37 輸出輸入 第37數碼引腳,SPI MISO引腳
10 GP36 輸出輸入 第36數碼引腳,SPI SCK引腳
11 GP35 輸出輸入 第35數碼引腳,SPI MOSI引腳
12 3V3 3.3V 電源輸出
13 GND 接地
14 5V 5V 電源輸出
15 VIN 電源輸入
RGBLED GP39 輸出 第39數碼引腳,WS2812B RGB LED引腳
OLEDSCL GP40 輸出 第40數碼引腳,OLED I2C SCL引腳
OLEDSDA GP41 輸出 第41數碼引腳,OLED I2C SDA引腳
RGB LED 測試

安裝 neopixel函式庫,簡化控制 WS2812B RGB LED 的流程

#include <Adafruit_NeoPixel.h>
#define RGB_PIN 39
#define RGB_COUNT 1
#define EMPTY 0x00
#define LEVEL 0x10
const uint32_t PROGMEM COLORS[] = {
	EMPTY << 16 | EMPTY << 8 | EMPTY,
	LEVEL << 16 | EMPTY << 8 | EMPTY,
	EMPTY << 16 | LEVEL << 8 | EMPTY,
	EMPTY << 16 | EMPTY << 8 | LEVEL,
	LEVEL << 16 | LEVEL << 8 | EMPTY,
	EMPTY << 16 | LEVEL << 8 | LEVEL,
	LEVEL << 16 | EMPTY << 8 | LEVEL,
	LEVEL << 16 | LEVEL << 8 | LEVEL,
};
Adafruit_NeoPixel rgb(RGB_COUNT, RGB_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
	rgb.begin();
}
void loop() {
	for (byte i = 0; i < sizeof(COLORS) / sizeof(const uint32_t PROGMEM); i++) {
		rgb.setPixelColor(0, COLORS[i]);
		rgb.show();
		delay(1000);
	}
}

使用測試 WS2812B RGB LED 的函式庫便可以控制,只是設定 引腳為39 及 數量為1

OLED 測試

安裝 u8g2函式庫,簡化控制 OLED 的流程

#include <U8g2lib.h>
#define I2C_SCL 40
#define I2C_SDA 41
U8G2_SSD1306_72X40_ER_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE, I2C_SCL, I2C_SDA);
void setup() {
	u8g2.begin();
	u8g2.clear();
	u8g2.setFontPosTop();
	u8g2.setFont(u8g2_font_6x10_tr);
	u8g2.setDrawColor(1);
	u8g2.drawStr(0, 0, "hello, world");
	u8g2.drawStr(0, 8, "Raspberry Pi");
	u8g2.drawStr(0, 16, "Arduino Nano");
	u8g2.drawStr(0, 24, "ESP32S3-OLED");
	u8g2.drawStr(0, 32, "HKGoldenMr.A");
	u8g2.sendBuffer();
}
void loop() {
	delay(1);
}

控制 OLED 顯示資料
接駁電源 至 顯示畫面 所需時間大約為 0.5秒

USB HID 測試
#include <USB.h>
#include <USBHIDKeyboard.h>
USBHIDKeyboard Keyboard;
void setup() {
	USB.begin();
	Keyboard.begin();
	delay(1000);
	Keyboard.print("hello, world");
}
void loop() {
}

ESP32-S3 不是使用 Keyboard.hMouse.h 而是原生的 USB HID 函式庫
因此不需要安裝額外函式庫即可使用 USB HID

函式庫名稱 功能
USBHIDKeyboard.h 鍵盤控制
USBHIDMouse.h 滑鼠控制
USBHIDConsumerControl.h 與使用者感受相關的控制
USBHIDSystemControl.h 系統控制
USBHIDGamepad.h 遊戲控制器控制

但當 ESP32-S3 設置為 USB HID 後, Arduino IDE 會無法找到 ESP32-S3 的連接埠
但 ESP32-S3 連接到 電腦後,卻能執行鍵盤輸入效果
即是 ESP32-S3 運作正常,卻未能讓 Arduino IDE 偵測

USB裝置列表 能顯示 ESP32-S3 , 但在 /dev 中卻找不到 抽象控制模型(Abstract Control Model (ACM))
然而卻找到新的 原始人機界面裝置 (Human Interface Device Raw (HIDRAW))
(中斷 ESP32-S3 的連接後, /dev/hidraw0 消失)

在下估計是由於 ESP32-S3 被設定為 USB HID 後,電腦會將 ESP32-S3 當作 USB HID 而不是開發板
因此如果需要更新韌體時,便需要先按著 ESP32-S3 的 BOOT按鈕 ,並重新啟動 ESP32-S3 載入到 BOOT模式
才可讓電腦將 ESP32-S3 辨識為 ACM ,才能更新韌體

由於 ESP32-S3 支援 OTA更新韌體 ,若果要避免因為使用 USB HID 而無法更新韌體
可以在程式碼中加入 WiFi.hArduinoOTA.h 函式庫及其功能,便可以透過 OTA 更新 ESP32-S3 的韌體

ESP32 WiFi USB HID

配合 u8g2 ,將連接資訊在 OLED 中顯示,方便連接到 ESP32-S3 的網頁伺服器

使用 WiFi USB HID 有兩將方法連接
最簡單是連接到 ESP32-S3 存取點 (Access Point(AP))
最大好處是不受其他網絡存取限制,但連接距離受 ESP32-S3 的訊號範圍限制
亦可以使用 WiFiManager 互動方式連接到其實無線網絡,不需要指定網絡及避免洩漏密碼
如果閣下是該網絡的擁有者,甚至可以將 通訊埠轉發 (Port Forwarding) ,允許其他網絡連接
但如果閣下並非該網絡的擁有者,則會受到限制

使用 HTTP請求 來控制 電腦

除了基本的鍵盤及滑鼠操作,還可以控制 音量 、 亮度
甚至 關機 、 重新開機 、 休眠 都能夠控制

總結

這個專案與之前使用 ATmega32u4 相同,都是使用低成本工具模仿昂貴工具
WiFi USB HID 能夠無線連接及即時互動操作,的確比 SD卡 更方便
而且 ESP32-S3 的運作速度比 ATmega32u4 更快,可以更快速輸入及執行指令
另外 ROM容量 及 RAM容量 亦比 ATmega32u4 多,能編寫更多功能以執行更多操作

操作上,雖然類似 VNC ,但 WiFi USB HID 最大的好處就是能使用存取點連接
有些網絡由於安全考慮而限制內聯網絡的存取權限,或封鎖連接埠,而令裝置無法使用網絡
而由於 WiFi USB HID 是硬件連接,除了不需要在系統安裝軟件,還可以遙距操作
不過使用存取點的連接距離則無法經互聯網連接,只能有限度地遙距操作

配合網頁伺服器的操作,還能夠使用類似 Curl 的 HTTP請求 工具
快速執行大量腳本操作,非常適合即時、重覆性高的任務

但使用要注意, ESP32 的工作溫度比較高,直接接觸 ESP32 的晶片有機會被灼傷

不過仍然無法流暢使用,例如在下經常使用中文輸入法輸入中文字
當輸入法為並非英文時,會無法執行輸入文字的功能

HID 除了支援鍵盤、滑鼠、遊戲控制器等常見的 USB裝置 外,還包括:

  • 電話(Telephony)
  • 電視(Television)
  • 媒體(Media)
  • 電源(Power)
  • 電池(Battery)

由於類別非常多,在下不列具所有設備,簡單而言 HID 足夠函蓋所有已知的輸入設備
而且還有保留 16位元 功能分頁(Usage Page),而且每個分頁提供 16位元 功能編號(Usage ID)
即是 HID 能夠支援 60000多種設備,而每種設備支援 60000多個功能
例如在下測試的 亮度控制 及 音量控制 並非只能控制電腦的設定值
而是只要該裝置都使用對應的 HID 標準設計,便可以使用相同的方法控制
在下測試自己的 電話 及 電視都 能用相同的方法控制 亮度 及 音量
即是只要能夠了解裝置使用 HID 分頁的類別,便可以自行製作控制該裝置的控制器
並透過支援 USB協定 的微控制器,將控制指令傳送到目標裝置

參考資料

沒有留言 :

張貼留言