你是否曾注意到,在瘋狂的科技世界裡,總有一個古怪的小專案試圖解決一個極其小眾的問題,而它唯一的競爭對手可能是左手螺絲起子或會自動隱藏的鬧鐘?
我在日常工作流程中使用兩台不同的電腦,並共用同一組鍵盤/滑鼠。嘗試過 Amazon 上幾款 USB 切換盒後,我發現它們都有類似的問題——切換需要一段時間、按鈕操作相當笨拙,而且隨著時間過去也沒有任何改善。
我真正想要的,是能用鍵盤快速切換輸出,並且能藉由滑鼠游標在螢幕間移動來達到相同效果。這個專案讓你同時享有兩種方式,即使你的電腦執行不同的作業系統也沒問題!
特色
- 完全自由且開源
- 切換時無明顯延遲
- 只需將滑鼠游標拖曳至另一台電腦即可切換
- 無需安裝任何軟體
- 零件平價易購(低於 15 歐元)
- 3D 列印卡扣式機殼
- 輸出端之間具完整電氣隔離
- 支援 Linux、macOS 與 Windows
現在已提供使用者手冊
運作原理
本裝置作為鍵盤/滑鼠與電腦之間的中介,同時建立並維持與兩台電腦的連線。接著依據你的選擇,決定將滑鼠與按鍵輸入轉發至哪一台電腦。鍵盤會跟隨滑鼠,反之亦然,只要將滑鼠拖曳到另一台桌面,即可切換兩者。
滑鼠
為了讓滑鼠游標能神奇地跨越桌面,滑鼠 HID 報告描述子改為使用絕對座標,接著將仍以相對位移傳來的滑鼠報告在內部累加,持續精準追蹤位置。
當你試圖將游標移出螢幕邊緣朝向另一台螢幕時,裝置會保留 Y 座標,並將最大 X 值替換為最小 X 值,隨即切換輸出端。這能確保游標以相同高度無縫出現在另一台螢幕,提升切換的順暢感。
從 Mac 拖曳滑鼠至 Linux 會自動切換輸出。
實際切換發生在其中一隻箭頭停止移動、另一隻箭頭開始移動的那一刻。
鍵盤
裝置以 USB Host 角色定期查詢鍵盤,尋找 HID 報告中預先設定的熱鍵(例如我常用的 Ctrl + Caps Lock)。一旦偵測到,即將後續所有字元轉發至另一個輸出端。
為了讓你隨時清楚目前使用哪個輸出端,可重複利用鍵盤 LED 提供視覺回饋。
它也會記住每台電腦的 LED 狀態,讓你能接續上次的設定。
如何建置
為避免建置時出現版本不相容與路徑問題,以及省去下載大型 SDK 的麻煩,本專案已內建最小化的 Pico SDK 與 TinyUSB。
在 Debian/Ubuntu 系統上,請先安裝以下套件:
apt update
apt install \
build-essential \
cmake \
gcc-arm-none-eabi \
libnewlib-arm-none-eabi \
python3
接著執行以下指令即可建置:
cmake -S . -B build
cmake --build build
此外,若要重新建置網頁 UI,請查看 webconfig/ 目錄並執行 ./render.py(需安裝 jinja2)。
另一種方式是透過 Docker 執行「docker compose」或「docker-compose」:
docker-compose -f misc/docker.yml run --rm build_container
此方式可確保建置結果可重製。
若要重新建立磁碟映像,請查看 disk/ 目錄並執行 ./create.sh,必要時可依系統調整。你需要 dosfstools(提供 mkdosfs)。
使用預先建置的映像檔
或者,你也可以使用預先建置的映像檔。從 0.6 版開始僅提供單一通用映像檔。你需要 .uf2 檔案,只需將其複製到裝置即可,方式如下:
韌體升級
選項 1(韌體 0.6 及以上)— 同時按下 左 Ctrl + 右 Shift + c + o 進入「設定模式」。鍵盤插入的那端裝置會重新啟動並顯示為名為「DESKHOP」的 USB 磁碟。將 .uf2 檔案複製至該磁碟即可。映像檔驗證完成後,裝置會燒錄並重新啟動,隨即升級另一塊板子。升級期間 LED 會閃爍。完成後會寫入快閃記憶體並重新啟動,結束程序。
注意 — 這不是一般 USB 磁碟,無法用來複製檔案。
選項 2 — 使用 ROM 開機載入程式 — 按住板載按鈕後連接每個 Pico,並將 uf2 複製到出現的快閃磁碟。0.6 版以後的映像檔支援按住按鈕而無需斷電,但「按住按鈕再插電」始終有效。
選項 3 — CDC 快閃指令(僅限偵錯建置)— 若韌體編譯時啟用 DH_DEBUG_CDC_FLASH=ON,可透過 CDC 序列埠指令觸發開機載入程式模式:
echo -n 'flash' > /dev/tty.usbmodem11104
這會立即將裝置重設至開機載入程式模式,顯示為「RPI-RP2」磁碟。此功能僅供開發流程使用。
其他功能
滑鼠減速
你是否曾想精準調整 YouTube 影片滑桿,卻因滑鼠移動太跳而必須像五歲小孩玩「Operation」遊戲一樣小心翼翼?
按下 右 CTRL + 右 ALT 可切換滑鼠減速模式。滑鼠游標會明顯變慢,讓你完成精細工作;再次快速按下相同按鍵即可恢復正常速度。
切換鎖定
若想鎖定在單一螢幕,使用 RIGHT CTRL + K。
這能避免你不小心切換到其他螢幕。再次按下相同組合即可解除。
同時鎖定兩台螢幕
使用 RIGHT CTRL + L 可同時鎖定兩台電腦。
要使用此功能,請先在設定中為每個輸出端指定作業系統(因為快捷鍵不同)。
遊戲模式
若你在玩遊戲,遊戲可能無法與絕對滑鼠模式相容。為此,新增了遊戲模式,可透過 LEFT CTRL + RIGHT SHIFT + G 切換。進入遊戲模式後,滑鼠會鎖定在目前螢幕,並以標準相對座標模式運作。這也能解決各種虛擬機器、尚未支援的作業系統等問題。
螢幕保護程式
本功能據稱可防止電腦進入待機,但說真的——它只是好玩。預設關閉,會讓滑鼠游標像乒乓球一樣在螢幕上彈跳。啟用後,當滑鼠在使用者設定的時間內無動作時啟動;一旦你對該螢幕送出任何輸入,即自動關閉。
潛在用途範例:我有一個有問題的 USB 擴充座,無法從待機恢復影像,因此不讓它進入睡眠是個實用的 workaround。
硬體
電路以兩塊 Raspberry Pi Pico 為基礎,選擇它的原因是價格低廉(每片 4.10 歐元)、可手焊,且大多數供應商都有現貨。
兩塊 Pico 透過 UART 連接,並以 Analog Devices ADuM1201 雙通道數位隔離器(約 3 歐元)或更便宜、更快且腳位相容的 TI ISO7721DR(約 1.5 歐元)隔開;後者為首選。
雖然它們原本不支援雙 USB,但透過一個令人驚嘆的專案——利用 RP2040 的可程式化 IO 奇技實作 USB——現在可以同時作為 USB 主機與裝置。
PCB[已更新]
為讓 DIY 組裝盡可能簡單,走線保留在單面,零件數量也降到最低。
USB D+/D- 差動線應等長,但刻意做成略微不對稱,以補償 Pico PCB 本身對應 GPIO 走線的長度差異,使整體長度匹配。
目標差動阻抗(Zd)為 90 歐姆(實際約 107 歐姆,已足夠接近)。
板厚設計為 1.6 mm,以符合卡扣式機構需求。
PCB 有兩個版本(對使用者而言差異不大)。原始版(v1.0)較易焊接與組裝;v1.1 版則新增以下升級:
-
新增 ESD 保護(TPD4E1U06DBVR)
-
新增鍵盤/滑鼠連接器的 VBUS 電容
-
絲印方向標記
-
為已預焊接頭的相容板提供定位孔
-
USB 27 歐姆電阻
此版本因需焊接小型瞬態電壓抑制 IC 與 0805 電阻,手焊難度略高,但仍可完成。理論上可省略 TVS(不建議),裝置仍可運作。
即將推出——使用裸 RP2040、無需 Pico、體積更小、更方便的版本。
機殼
由於我對 3D 建模不太擅長,機殼簡單樸實但能完成任務。它易於列印,耗材約 33 克,需數小時。
水平方向的 PCB 移動由穿過孔洞的定位柱限制,垂直方向則由側邊的卡扣凸耳固定——無需螺絲。機殼已重新設計,加入 Logo 與兩個額外卡扣凸耳,提供更好的密封性。
兩塊板子的 Micro USB 連接器從機殼側邊偏移,因此孔洞需稍大,以便插頭插入。
上蓋採用卡扣式設計,附螺絲起子槽方便開啟。頂部標記為凹陷式,可用蠟筆填色增加對比(或直接保留原狀)。
零件清單
點擊此處查看原始 PCB v1.0 零件清單| 元件 | 數量 | 單價 / 歐元 | 總價 / 歐元 |
|---|---|---|---|
| Raspberry Pi Pico | 2 | 4.10 | 8.20 |
| ADuM1201BRZ | 1 | 2.59 | 2.59 |
| 1206 SMD 100nF 電容 | 2 | 0.09 | 0.18 |
| USB-A PCB 連接器 | 2 | 0.20 | 0.40 |
| 2.54 1x03 接頭 | 2 | 0.08 | 0.16 |
| 總計 | 11.53 |
可使用 TI ISO7721DR 取代 ADuM——腳位相容、價格更低、規格更佳。
PCB v1.1
| 元件 | 零件 | 數量 | 單價 / 歐元 | 總價 / 歐元 |
|---|---|---|---|---|
| U1, U2 | Raspberry Pi Pico | 2 | 4.10 | 8.20 |
| J1, J4 | USB-A PCB 連接器 | 2 | 0.20 | 0.40 |
| U4 | TI ISO7721DR | 1 | 1.40 | 1.40 |
| (或 ADuM1201BRZ) | ||||
| C1, C2 | 0805 SMD 100nF 電容 | 2 | 0.09 | 0.18 |
| R1, R2, R3, R4 | 0805 SMD 27ohm 電阻 | 4 | 0.03 | 0.12 |
| U3, U5 | TPD4E1U06DBVR | 2 | 0.31 | 0.62 |
| C3, C4 | 4.7uF SMD 0805 電容 | 2 | 0.07 | 0.14 |
| J2, J3 | 2.54 1x03 接頭 | 2 | 0.08 | 0.16 |
| 總計 | 11.22 |
USB-A 連接器可選 Molex MX-67643-0910 或尺寸相容的平價替代品。
額外步驟:
- 製作 PCB(已提供 Gerber,選擇 1.6 mm 板厚)
- 3D 列印機殼(已提供 STL 檔案,耗材約 33 克)
組裝指南
如果你有電子組裝經驗,可能不需要這份指南。但若你沒有經驗,這段影片或許能幫助你完成流程。請注意,焊接後應清除 PCB 上的助焊劑,以防腐蝕。
標準清除方式是使用異丙醇與舊牙刷。但猜怎麼著?我不會把我的舊牙刷放到網路上,所以你得自己想辦法 :)
[注意] 本影片組裝指南涵蓋 PCB v1.0。修訂版 v1.1 非常相似,流程基本相同。
使用指南
鍵盤快捷鍵 —(韌體 0.68 版及以上)
設定:
左 Shift左 Ctrl + 右 Shift + C + O— 進入設定模式右 Shift + F12 + D— 清除快閃記憶體設定右 Shift + F12 + Y— 儲存螢幕切換偏移量
使用:
右 CTRL + 右 ALT— 切換滑鼠減速模式右 CTRL + K— 鎖定/解鎖滑鼠桌面切換右 CTRL + L— 同時鎖定兩端輸出(請先在設定中指定輸出作業系統)左 Shift左 CTRL + 右 Shift + G— 切換遊戲模式(鎖定在目前螢幕,作為標準滑鼠)左 CTRL + 右 Shift + S— 啟用螢幕保護程式左 CTRL + 右 Shift + X— 停用螢幕保護程式左 CTRL + Caps Lock— 切換輸出端
注意:部分鍵盤無法同時正確傳送兩個 Shift,因此快捷鍵已更改為適用於所有人。造成困擾敬請見諒。
游標高度校正
此步驟非必要,但若你的螢幕未完全對齊或尺寸不同,會很有用。目標是讓滑鼠游標以完全相同的高度出現。
將滑鼠停在較大螢幕、與較小/較低螢幕相同高度的位置(圖示),然後按下 右 Shift + F12 + Y。LED(與 Caps Lock)應閃爍確認。
若較小螢幕下緣高於較大螢幕下緣,請重複相同步驟於底部邊界。此設定會儲存至快閃記憶體,並從此保留校正值。
單一輸出端多螢幕
Windows 與 Mac 在多螢幕搭配絕對定位時會出現問題,因此需要 workaround(仍在實驗階段)。目前有一個更好的 workaround 正在開發中,但目前你必須為每個輸出端設定作業系統與螢幕數量。
主要螢幕需置中,次要螢幕置於邊緣。若要設定實際選項,請開啟裝置的網頁設定頁面。
網頁設定模式
從韌體 0.6 版開始,引入了改進的設定模式。請依照以下步驟設定裝置:
-
按下左 Ctrl + 右 Shift + C + O — 裝置會重新啟動並進入設定模式(鍵盤插入的那一端)。設定期間 LED 會持續閃爍。
-
新的 USB 磁碟「DESKHOP」會出現,內含單一檔案 config.htm
-
使用 Chromium / Chrome 開啟該檔案。目前不支援 Firefox,因為它未實作 WebHID。
-
點擊「連接」並允許 DeskHop 裝置配對。
-
依需求設定選項,然後點擊「儲存」寫入裝置。
-
點擊選單中的「離開」以安全離開設定模式。
問題:Chromium 在 Linux 上無法運作。
解答:你可能需要調整 /dev 權限,或建立對應的 udev rules 檔案,並確認你的使用者屬於正確的群組,例如:
/etc/udev/rules.d/99-deskhop.rules
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="c000", GROUP="plugdev", MODE="0660"
問題:為什麼不直接像 Via 一樣做一個漂亮的線上網頁,而是採用這個奇怪的 USB 磁碟方式?
解答:從隨機線上位置載入 JavaScript 與你的輸入裝置互動存在潛在安全風險。設定網頁僅限本地,且絕不從外部載入任何內容。
請注意,設定網頁並非刻意混淆而「奇怪」——它是因儲存空間極為有限而自我解壓縮。完整原始碼 100% 開源且為本儲存庫的一部分,歡迎自行重建。
功能驗證
當你連接新的 USB 週邊裝置時,板子會閃爍 LED 兩次,並指示另一塊板子做相同動作。這樣你可以測試每塊板子的 USB 與對外通訊是否正常。
請先在一側插入鍵盤,再換另一側進行測試。若一切正常,兩種情況下 LED 都會快速來回閃爍。
安全性與安全性
部分功能刻意省略,儘管它們能讓裝置更容易使用或設定。以下是這些決定的快速說明:
- 系統之間沒有複製貼上或任何資訊共享。這能防止資訊外洩。
- 未經使用者明確同意,不允許 WebHID 裝置管理。輸出端電腦無法主動連線,唯一例外是標準鍵盤 LED 開/關訊息,且嚴格限制為 1 位元組資料。
- 無法從輸出端觸發韌體升級。僅能透過特殊鍵盤快捷鍵,由使用者明確且刻意操作。
- 已插入的鍵盤/滑鼠自訂端點不會被暴露,也不會將資訊轉發至這些裝置。它們的潛在漏洞能有效與電腦隔離。
- 不允許保留輸入歷史。
- 裝置不會主動發送按鍵輸入。唯一送出的內容是你自行輸入/觸發的內容。
- 輸出端以實體分離,並以至少 2kV 的最小隔離電壓進行電氣隔離。
- 裝置之間交換的所有封包皆為固定長度,設定的選項僅限於短清單。大多數選項為唯讀。跨裝置韌體升級可停用。
- 沒有藍牙、Wi-Fi、網路或網際網路存取等功能。
- 在任何情況下都不視任何已連接的電腦為可信任對象。
- 設定模式在一段時間無操作後會自動停用。
- 全部程式碼皆為開源,無任何二進位 blob,並有詳細註解說明其用途。我鼓勵你永遠不要信任任何人,並透過手動稽核確認你執行的內容。
這仍無法保證任何事情,但我相信這是一套合理的基礎規則,能讓你保持安全與保護。
常見問題
-
我只有兩塊 Pico,可以不用 PCB 與隔離器嗎?
當然可以。建議使用隔離器,但沒有它應該也能運作。
-
如果我的螢幕解析度不同,會發生什麼事?
滑鼠移動在抽象座標空間中進行,電腦會自行計算與實體螢幕的對應關係,因此應該能正常運作。
-
我可以在哪裡購買?
我沒有販售任何東西,這只是個人的非商業興趣專案。
更新 1:你似乎可以從 Elecrow 以單件數量訂購(PCB、已組裝 PCB 或完整裝置)。 據使用者回報,板子送達時是空白的,你必須自行燒寫韌體。
更新 2:我從未向 Elecrow 要求任何東西,但幾天前他們主動提供小額預算贊助本專案,用於未來的板子原型製作。由於我的目標是開發支援更多輸出的更好板子,我相信原型服務對專案會有幫助。
-
透過滑鼠切換作用中螢幕時,鍵盤是否會跟隨(反之亦然)?
是的,設計目標就是讓它像單一台電腦一樣運作。
-
這是否支援鍵盤/滑鼠組合接收器,例如 Logitech Unifying receiver?
應該支援。最近的韌體更新後,對組合接收器的支援已大幅改善。
-
這是否支援無線滑鼠與鍵盤使用各自的無線接收器(滑鼠一個、鍵盤另一個)?
應該支援——我已測試過 Anker 無線滑鼠搭配獨立接收器,運作正常。
-
我在建置或編譯時遇到問題
請查看 疑難排解 Wiki,可能有解答。
軟體替代方案
如果你在特定情境下可以使用軟體方案,以下是幾個替代方案。
- Barrier — 免費、開源
- Input Leap — 免費、開源
- Synergy — 商業軟體
- Mouse Without Borders — 免費,僅限 Windows
- Universal Control — 免費,Apple 產品
限制
- Windows 10 在 KB5003637 更新中破壞了 HID 絕對座標行為,因此在 Windows 上無法使用超過 1 個螢幕(滑鼠會停留在主螢幕)。目前有一個實驗性 workaround,更好的方案正在開發中。
- 程式碼需要清理與重構。
- 尚未在廣泛的裝置上測試,我不知道它在你的硬體上是否能正常運作。有合理的機會可能無法立即開箱即用。
- 進階鍵盤(帶有旋鈕、額外按鈕或滑桿)可能會遇到這些額外硬體無法運作的問題。
- 擁有 300 個按鈕的超現代滑鼠可能會看到部分按鈕無法如預期運作。
- 注意:兩台電腦都必須連接並為 USB 供電,本裝置才能運作(每塊板子由它所插入的電腦供電)。如今許多桌上型電腦與筆記型電腦即使關機仍會提供電源。若你需要在單塊板子完全斷電的情況下運作,應該可以使用 USB 集線器將鍵盤與滑鼠都插入單一埠。
- macOS 在多於一個螢幕時會出現問題,最新韌體提供了一個實驗性 workaround 來修正此問題。
進度
那麼,這麼多熱情是怎麼回事?我不敢相信——請允許我向大家致謝!我從未預期一個簡單的個人專案會引起這種關注,因此初始功能相當基本(就像我的烹飪技巧),主要涵蓋我自己的使用情境。敬請期待未來的韌體更新,它們將帶來更廣泛的裝置相容性、更多功能與更少的錯誤。由於這是興趣專案,我感謝你對時間限制的理解,並承諾盡我所能做到最好。
計劃中的功能:
- 改善 Windows 與 macOS 多螢幕的 workaround
- 透明/遊戲模式
- 支援超過 2 個輸出端
- 設定 UI 改善
- ……以及更多!
正在開發精簡版,僅需單塊 Pico W 板即可提供基本功能,大幅降低成本,讓你即使沒有額外硬體或 PCB 也能嘗試。
滑鼠輪詢現在應可達 1000 Hz(圖表中的低點是我手臂因不斷移動而感到疼痛 :-)):
贊助/捐款
我做這個專案不是為了獲利或其他任何原因,只是想透過為大家創造更好的工作環境來幫助人們。 如果你想進一步支持本專案,請考慮向無國界醫生等慈善機構捐款。
請允許我向所有曾經或考慮幫助過的人致謝!
免責聲明
我誠懇地請求任何嘗試建置本專案的人理解並承認,我對任何傷害、損害或其他後果概不負責。你的安全很重要,我鼓勵你謹慎進行本專案,在整個過程中採取必要的預防措施,並為自己的健康承擔個人責任。請不要觸電、燒傷、感到壓力或生氣。祝你玩得開心!
快樂切換!












0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.