LDPS · HUB CONTROL PANEL

實體控制面板 — 設計一頁通PROPOSAL · rev A · 2026-07-28

4×4 WS2812 pads · transport / 群組鍵 · 2× encoder + 8-LED level bar · MCU 與 Dongle 共用(ESP32-S3)。權威文件:docs/reference/hardware/07-hub-control-panel.html

1 · 面板版面整機 ≈ 285 × 186 mm,面板區在觸控屏右側

SYS FLEET LINK MODE ← status ×4(3mm through-hole,595 #4 驅動) PWR PLAYER MAIN G1 G2 G3 G4 ALL PADS 4×4 · 17 mm · 內建 WS2812 · 4 頁 SELECT C1 C2 C3 C4 PAGE TRANSPORT · 作用於選中 PLAYER · 12 mm -100 PLAY PAUSE +100 DARK REJOIN BRIGHT bar ×8(琥珀) BRIGHT VOL bar ×8(藍) VOL MUSIC 按鍵合計 37(入 matrix) = 35 實體鍵 + 2 encoder push WS2812 chain × 35: 功能鍵 19 → pads 16 普通 LED × 20: bar 8×2 + status 4 (595 靜態驅動,§5)
版面依 mockup:左 PLAYER 直欄、中 4×4 pads(17 mm)、右 SELECT/PAGE 欄、下 transport 列、 底部 bar+encoder ×2。所有語意(哪鍵做什麼、pads 第幾頁)由 Hub 決定 — 面板是 dumb terminal。

2 · 系統架構MCU 與 Dongle 共用,面板 PCB 是被動板

OPi 3B Control-Hub (Python) kiosk UI · engine USB-CDC(或 UART0) {TYPE}:{PAYLOAD}\n ESP32-S3(共用 MCU) Dongle firmware 1.3.x RF 路徑不動 · 面板為新模組 SX1262 433 MHz LoRa 播放幀 → Edge Nodes ESP-NOW 2.4 GHz 管理 → Edge Nodes panel bus(17 訊號 + 電源,2×13 IDC) PANEL PCB=被動板 37鍵 diode matrix + 74HCT595 ×4 + WS2812 chain ×35 + EC11 ×2 Prototype:DevKitC-1 + SX1262 模組直接插在面板 PCB(取代散裝 dongle)· Production:MCU 在 Hub 底板
Dongle 1.2.6 只用 9 支 GPIO、單一 Arduino loop,RMT / PCNT / LEDC 全空著 — 面板正好全用硬體外設, 不碰 RF 任何路徑。功能演進只改 Hub Python(面板 firmware 不用重刷)。

3 · 整體連線圖每顆按鍵 / LED 走哪條 signal · 怎麼串 · 各芯片 IO 分配

面板 PCB(實體版面) ESP32-S3 與 Dongle 共用 GPIO 9 SR_DATA GPIO 10 SR_SCLK GPIO 11 LATCH_M GPIO 8 LATCH_L GPIO 18 OE_L GPIO 12 COL0 GPIO 13 COL1 GPIO 14 COL2 GPIO 21 COL3 GPIO 47 COL4 GPIO 48 WS_DATA GPIO 1 ENC1_A GPIO 2 ENC1_B GPIO 41 ENC2_A GPIO 42 ENC2_B GPIO 4-7·15-17 = SX1262(RF,不動) GPIO 19/20 = USB → OPi GPIO 38/39/40 = spare 面板全部訊號經 J1 ribbon 到面板 U1 74HCT595 row driver DATA SCLK LATCH_M(掃描用) U2 74HCT595 BRIGHT bar DATA(與 U1 並聯) SCLK LATCH_L + OE_L(調光) U3 74HCT595 VOL bar DATA ← 上一顆 Q7′ SCLK LATCH_L + OE_L(調光) U4 74HCT595 status LED DATA ← 上一顆 Q7′ SCLK LATCH_L + OE_L(調光) Q7′串出 Q7′串出 U5 電平轉換 3.3 V → 5 V(WS2812) ENC1 BRIGHT A/B ENC2 VOL A/B 轉軸 A/B 直入 ESP(PCNT) 按壓腳 → 走 MATRIX(R2C4 / R3C4) R0 R1 R2 R3 R4 R5 R6 R7 ROW0–7 → 全部按鍵(見鍵上 R 標籤) COL0–4 回讀 → ESP SYS U4·Q0 FLEET U4·Q1 LINK U4·Q2 MODE U4·Q3 MAIN R4 C0 #0 G1 R4 C1 #1 G2 R4 C2 #2 G3 R4 C3 #3 G4 R4 C4 #4 ALL R5 C0 #5 PAD1 R0 C0 #22 PAD2 R0 C1 #21 PAD3 R0 C2 #20 PAD4 R0 C3 #19 PAD5 R1 C0 #23 PAD6 R1 C1 #24 PAD7 R1 C2 #25 PAD8 R1 C3 #26 PAD9 R2 C0 #30 PAD10 R2 C1 #29 PAD11 R2 C2 #28 PAD12 R2 C3 #27 PAD13 R3 C0 #31 PAD14 R3 C1 #32 PAD15 R3 C2 #33 PAD16 R3 C3 #34 R0 C4 #18 R1 C4 #17 C1 R6 C0 #16 C2 R6 C1 #15 C3 R6 C2 #14 C4 R6 C3 #13 DARK R5 C2 #6 -100 R7 C0 #7 PLAY R7 C1 #8 PAUSE R7 C2 #9 +100 R7 C3 #10 REJOIN R5 C1 #11 MUSIC R5 C3 #12 PLAYER PADS 4×4 · 17 mm · 內建 WS2812 SELECT PAGE TRANSPORT → 進 chain 第一顆 #0 BRIGHT bar · 8 段光條模組(琥珀) Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 ← U2 Q0–Q7(段1–段8) VOL bar · 8 段光條模組(藍) Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 ← U3 Q0–Q7(段1–段8) ENC1 BRIGHT 按壓 = R2·C4 ENC2 VOL 按壓 = R3·C4 圖例 — 每顆鍵上:左下 R/C = 走哪條 ROW/COL(matrix)· 右上 #n = WS2812 串聯順序 R0 ← U1·Q0 R1 ← U1·Q1 R2 ← U1·Q2 R3 ← U1·Q3 R4 ← U1·Q4 R5 ← U1·Q5 R6 ← U1·Q6 R7 ← U1·Q7 C0 → GPIO12 C1 → GPIO13 C2 → GPIO14 C3 → GPIO21 C4 → GPIO47 WS2812 串聯路徑(#0 → #34,逐顆 DOUT→DIN)· 起點 = U5 電平轉換輸出 MATRIX:U1 逐條拉低 ROW → 讀 5 條 COL;每鍵串一顆 diode(可多鍵同按)。掃描與燈共用 DATA/SCLK,用 LATCH_M / LATCH_L 分開鎖存,互不干擾。 LED 595(U2→U3→U4)串成一條:DATA 進 U2、Q7′ 逐顆串下去;三顆 OE 併聯接 OE_L 做 bar/status 整體調光。 WS2812:只有 35 顆按鍵在 chain 上(功能鍵 19 + pads 16)。bar 與 status 是普通 LED,由 595 靜態驅動,不在 chain。 串聯順序按實體相鄰排(省走線);工程師若因 layout 需要調整順序,回報最終順序即可(改 firmware map,硬體不變)。 限流電阻、pull-up、去耦電容、diode 型號、ribbon 腳位排序等細節依慣例處理,本圖只定 path / connection。

3.1 · 哪顆芯片管哪些東西

U1 74HCT595 全部 37 個按鍵的掃描 唯一一顆接到按鍵的 595 — 輸出 8 條 ROW,掃描用 U2 74HCT595 BRIGHT bar 的 8 段 只接這 8 顆 LED,不接任何按鍵 U3 74HCT595 VOL bar 的 8 段 只接這 8 顆 LED,不接任何按鍵 U4 74HCT595 status 4 顆 LED SYS / FLEET / LINK / MODE(+4 路 spare) GPIO 48(不經 595) 35 顆按鍵的燈(WS2812) 一條 data 線逐顆串下去 — 與 595 完全無關 四顆 595 只有 U1 接按鍵;按鍵自己的燈完全不經 595 所以:按一顆鍵 = 走 U1(掃描)· 那顆鍵亮燈 = 走 WS2812 串 · 兩件事在硬體上完全分開。

3.2 · 按鍵 matrix — COL / ROW 都是共用線,U1 負責掃描

按鍵 matrix — 8 條 ROW × 5 條 COL 的實際接法 每個格子 = 一個按鍵。ROW 和 COL 都是共用線(common)。 U1 74HCT595 掃描器 ROW0 ← U1 Q0 ROW1 ← U1 Q1 ROW2 ← U1 Q2 ROW3 ← U1 Q3 ROW4 ← U1 Q4 ROW5 ← U1 Q5 ROW6 ← U1 Q6 ROW7 ← U1 Q7 COL0 ↓ 進 ESP COL1 ↓ 進 ESP COL2 ↓ 進 ESP COL3 ↓ 進 ESP COL4 ↓ 進 ESP PAD1 PAD2 PAD3 PAD4 PAD5 PAD6 PAD7 PAD8 PAD9 PAD10 PAD11 PAD12 ENC1 按壓 PAD13 PAD14 PAD15 PAD16 ENC2 按壓 MAIN G1 G2 G3 G4 ALL REJOIN DARK MUSIC spare C1 C2 C3 C4 spare -100 PLAY PAUSE +100 spare U1 就是「enable scanning」:一次只放行一條 ROW 第 1 步 ROW0 拉低,其餘 7 條保持高 讀 COL0–4 → 得知 PAD1 PAD2 PAD3 PAD4 ▲ 這 5 個誰被按 第 2 步 ROW1 拉低 讀 COL0–4 → 得知 PAD5…▼ 這 5 個誰被按 ROW2 → ROW7 依序 8 條輪完 = 掃描一輪,每秒 1000 輪(1 kHz) 每個按鍵:一腳接 COL(共用線)· 另一腳經一顆 diode 接 ROW;diode 方向朝 ROW,防止多鍵同按時互相導通誤判。 橙色兩格 = 兩顆 encoder 的按壓開關 — 接法與普通按鍵完全一樣(見 3.3)。灰色虛線 3 格 = 預留位,加鍵不用改線路。

3.3 · Encoder 怎麼接

Encoder(EC11)接法 — 旋轉與按壓是兩套獨立線路 一顆 EC11 共 5 支腳:旋轉 3 支 + 按壓 2 支 ENC1(BRIGHT) EC11 旋鈕 A ENC1_A → GPIO 1 C GND(公共腳) B ENC1_B → GPIO 2 旋轉:A / B 兩條直接進 ESP 的硬體計數器(PCNT) 不經 595、不經 matrix、不用中斷 — ESP 自己數格數與方向 SW1 SW2 COL4 → ESP GPIO 47 diode ROW2 ← U1 Q2 按壓:兩支腳就是一個普通開關 接進 matrix 的 R2·C4 位置,跟其他 37 個鍵一模一樣 ENC2(VOL)完全相同 A → GPIO 41 ・ B → GPIO 42 ・ C → GND 按壓兩腳 → COL4 + 經 diode 接 ROW3(R3·C4) 兩顆 encoder 的按壓共用 COL4,靠不同 ROW 分辨 A / B 兩條為什麼能判斷方向:波形相差 90° A B A 先變 = 順轉 B 先變 = 逆轉 ESP 內建 PCNT 硬體計數器自己數, 韌體只是定時去讀「目前累計到多少」, 不佔 CPU、不用中斷。

按鍵 — 8×5 diode matrix

  • 37 鍵(35 實體鍵 + 2 顆 encoder 按壓),8 ROW × 5 COL,尚有 3 個 spare 鍵位
  • ROW 由 U1 74HCT595 驅動(只吃 3 支 GPIO),COL ×5 直接回讀進 ESP
  • 每鍵串一顆 diode → 任意組合同按都不會誤判(pads 演出中多鍵齊發)

Bar / Status — 595 靜態驅動

  • 兩條 bar 各一顆 8 段光條模組(DIP-16),一顆 595 對一條 bar
  • 靜態點亮:無掃描、無 refresh、無閃爍,只在數值變化時寫一次
  • U2→U3→U4 串成一條,與 U1 共用 DATA/SCLK,用第二條 LATCH 分開;OE 併聯做整體調光

WS2812 — 單 pin 一條 chain

  • 只有 35 顆按鍵在 chain 上(功能鍵 19 → pads 16),逐顆 DOUT→DIN
  • 經一顆電平轉換(3.3 V → 5 V)進第一顆;順序按實體相鄰排
  • 兩段之間留一個 header,分段可獨立更換/檢修

Encoder ×2

  • 轉軸 A/B 直接進 ESP,用硬體計數器(PCNT)— 零中斷、零 CPU
  • 按壓腳併入 matrix(R2·C4 / R3·C4),不另占 GPIO
  • 轉動 → Hub → bar 更新往返 ≈ 20–40 ms;kiosk 顯示與面板 bar 永遠同步

4 · ESP32-S3 Pin Map新增 15 支 · spare 3 支 · 不碰 strapping/PSRAM/radio

GPIO用途備註
4 / 5 / 6 / 7SX1262 SCK / MISO / MOSI / NSS既有,不動(跨板統一 pinout)
15 / 16 / 17SX1262 BUSY / DIO1 / RST既有,不動
19 / 20 · 43 / 44USB D−/D+(對 OPi CDC)· UART0 debug既有,不動
9 / 10 / 11595 bus DATA / SCLK / LATCH_M(row driver #1)新增 · matrix
8 / 18LATCH_L / OE_L(LEDC PWM)→ LED 595 #2–#4新增 · bar/status
12 / 13 / 14 / 21 / 47COL0–COL4(input,外部 10k pull-up)新增
48WS2812 DATA(RMT + DMA)新增 · 與底板 status-LED 建議腳一致
1 / 2 · 41 / 42ENC1 A/B(PCNT0)· ENC2 A/B(PCNT1)新增
38 / 39 / 40spare留給未來(matrix 內另有 3 spare 鍵位)
0 / 3 / 45 / 46 · 26–37strapping · Flash/PSRAM 禁區面板不觸碰

面板 ↔ MCU 的 path / connection 見 §9 連線圖;ribbon 腳位排序由工程師定。

5 · OPi ↔ 面板協議單一固定長度二進位幀 · 全狀態同步 · 週期 + 觸發

下行 · Hub → 面板(全部燈的完整狀態) 一種幀、定長、二進位 — 不再有多種訊息 0-1 MAGIC A5 5A 2 TYPE 0x01 3 SEQ 幀序號 4 BRIGHT 全域亮度 5 BAR1 0–8 格 6 BAR2 0–8 格 7 STATUS 4 燈 × 2bit 8 FLAGS 面板暗等 9–148 LED[35] × { R, G, B, MODE } 每顆按鍵一組 · MODE:0 恆亮 1 閃 2 呼吸 3 單閃(面板本地渲染) 149 CRC-8 整幀校驗 = 定長 150 bytes 上行 · 面板 → Hub(全部輸入的完整狀態) 同樣一種幀 — 送「絕對值」不送「事件」,漏幀可自癒 0-1 MAGIC A5 5A 2 TYPE 0x81 3 SEQ 幀序號 4–8 KEYS 40 bit bitmap 8 ROW × 5 COL:1 = 按下(絕對狀態,不是事件) 9–10 ENC1 累計計數 uint16 絕對值,會回捲 11–12 ENC2 累計計數 uint16 絕對值 13 FW VER 面板版本 14 FLAGS 首幀等 15 CRC-8 整幀校驗 = 定長 16 bytes 收發節奏 — 固定慢速心跳 + 變化即時補發 時間 週期幀 週期幀 250 ms 250 ms 週期幀 250 ms 週期幀 250 ms 週期幀 250 ms 按下 → 立即補一幀 轉 encoder → 立即補一幀 ✕ 這幀壞掉/漏收 ↑ 下一個週期幀自動補正 — 因為每幀都是完整狀態(冪等) 為什麼送絕對值不送事件:漏一個「按下事件」= 那次操作永久消失;漏一幀「全狀態」= 下一幀就補回。Encoder 同理送累計計數,Hub 自己相減出格數。 Hub 或面板任一方重啟都不用握手:雙方各自持續送全狀態幀,幾百 ms 內自動收斂一致。 定長二進位:收方按 MAGIC 對齊、讀固定長度、驗 CRC-8;不合就整幀丟棄等下一幀 — 不會半句解析錯而誤動作。 頻寬:下行 150 B、上行 16 B,250 ms 一次 = 佔 UART 約 5%。實際走 USB-CDC,完全不是瓶頸。 與既有 RF 訊息共存:現有 dongle 訊息全是 ASCII,面板幀以 0xA5 開頭(非 ASCII)→ 收方一眼分辨,不衝突。

設計原則

  • 只有一種幀(每個方向各一):不用多種訊息 — 少一種訊息就少一種「漏收 / 解不到 = 沒執行」的失敗模式
  • 每幀都是完整狀態,不是變化量:所以幀是冪等的,重複收、漏收、亂序都不會累積錯誤
  • 固定慢速心跳(250 ms)+ 按下 / 轉動時立即補一幀:反應即時,同時保證最慢 250 ms 內一定回到正確狀態
  • 二進位定長:對齊 MAGIC → 讀固定長度 → 驗 CRC-8;壞幀整個丟棄等下一幀,不會半句解析錯而誤動作

關鍵細節

  • Encoder 送累計計數不送增量:漏一幀若送增量 = 亮度永久偏掉;送絕對累計值,Hub 相減即可,下一幀自動補回
  • 按鍵送 bitmap 不送事件:Hub 比對前後幀自行判斷按下 / 放開 / 長按 / 雙擊
  • 免握手:任一方重啟後,雙方持續送全狀態幀,數百 ms 內自動收斂 — 不需要查詢 / 重繪流程
  • 連線監測免費:超過 ~2 s 沒收到對方的週期幀 = 對方掉線,雙方都能立即知道並顯示
面板仍是 dumb terminal。面板只上報「哪些鍵被按著、encoder 轉到多少」,只執行「每顆燈什麼顏色」—— 所有語意(哪個鍵代表什麼、pads 第幾頁、亮度換算)都在 Hub Python,並走 kiosk 同一條 action 路徑, 不另開平行入口。功能演進只改 Hub,不用重刷面板韌體。

6 · BOM 摘要(面板 PCB)

類別零件用量
Pads17×17 mm 方形自復位鍵,內建 WS2812(透光鍵帽)16
功能鍵12×12 mm 同款19
EncoderEC11 帶 push2
Bar / status LED8 段 LED 光條模組 DIP-16(20.3×10.2 mm)×2(BRIGHT 琥珀 + VOL 藍)+ 限流 330–470 Ω ×16(依色);status 3 mm LED(綠2/藍1/琥珀1)+ 470 Ω ×4;引腳留長頂到面板開窗2+4
掃描 / bar 驅動74HCT595(#1 row + #2–#4 LED)4
Diode / shifter1N4148WS ×40(每鍵)· 74AHCT1G125 ×1(與 Node 同 BOM)41
被動 / 保護1000 µF + 100 nF ×N + 10 kΩ ×7 + 33 Ω + RC 去彈跳 · polyfuse 3 A~21
連接2×13 IDC(production)/ DevKitC-1 排母 + SX1262 模組位 + SMA(prototype)

內建 WS2812 按鍵(Taobao「發光按鍵 WS2812 自復位」)鎖 SKU 前先買樣: 鍵帽透光均勻度 / DIN-DOUT 四腳可串聯 / 行程手感盲操作。17 mm 與 12 mm 最好同一家。

LDPS Hub Control Panel · 設計一頁通 · 2026-07-28 rev A · 權威文件 LDPS-Hardware/docs/reference/hardware/07-hub-control-panel.html · 狀態 PROPOSAL(待 Xavier review)