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 · 面板版面面板 PCB 145 × 175 mm(200 × 200 為上限)· 1:1 比例,背景格線 10 mm

200 × 200 mm 上限(虛線) SYS FLEET LINK MODE status LED ×4(Ø3 直插) MAIN G1 G2 G3 G4 ALL PAD1 PAD2 PAD3 PAD4 PAD5 PAD6 PAD7 PAD8 PAD9 PAD10 PAD11 PAD12 PAD13 PAD14 PAD15 PAD16 ▲ ▼ C1 C2 C3 C4 REJOIN -100 PLAY PAUSE +100 DARK ♪ PLAYER PADS 4×4 · 17 mm SELECT PAGE TRANSPORT MUSIC BRIGHT VOL 145 mm 175 mm 17 5 pitch 22 12 93 實際 145 × 175 mm — 200 × 200 是上限不是目標 寬:11 + PLAYER 12 + 8 + PADS 83(4×17 + 3×5)+ 8 + SELECT/PAGE 12 + 11 = 145 mm 高:10 + status 10 + 4 + 主區 93 + 6 + TRANSPORT 12 + 8 + bar/encoder 20 + 12 = 175 mm SELECT(▲▼)與 PAGE(C1–C4)同一直欄;level bar 與 encoder 同一橫行。 REJOIN 在 PLAYER 欄正下方(群組相關);DARK 與 MUSIC 上下相疊(輸出狀態)。 背景格線 10 mm,元件 1:1 可直接量。固定孔與外殼公差由機構決定。
版面依 mockup:左 PLAYER 直欄、中 4×4 pads(17 mm)、右 SELECT / PAGE 欄、下 transport 列、 底部 bar + encoder ×2。所有語意(哪鍵做什麼、pads 第幾頁)由 Hub 決定 — 面板是 dumb terminal。
觸控屏不在這片板上:面板 PCB 與屏各自獨立。

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 · 145 × 175 mm(1:1 版面見 §1) 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 FLEET LINK MODE status LED ×4 ← U4 Q0–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 REJOIN R5 C1 #6 -100 R7 C0 #7 PLAY R7 C1 #8 PAUSE R7 C2 #9 +100 R7 C3 #10 DARK R5 C2 #11 ♪ R5 C3 #12 PLAYER PADS 4×4 · 17 mm · 內建 WS2812 SELECT PAGE TRANSPORT ← U2 Q0–Q7 BRIGHT ← U3 Q0–Q7 VOL MUSIC 圖例 — 每顆鍵上:左下 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。 REJOIN 在 PLAYER 欄正下方(群組相關)· DARK 與 MUSIC 上下相疊(輸出狀態)· PLAY / PAUSE 維持兩顆分開(動作冪等,盲操作不會誤觸)。 限流電阻、pull-up、去耦電容、diode 型號、ribbon 腳位排序等細節依慣例處理,本圖只定 path / connection。
整機外殼(機構拍板用):面板 145 × 175 mm 與 7" 觸控屏(模組約 165 × 125 mm)左右並排, 正面約 325 × 195 mm,與原 mockup 標的 285 × 186 同級。面板仍有壓縮空間 — pad 間隙 5 → 4、邊距 11 → 8 可再收到約 138 × 168。

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 的按壓開關 — 接法與普通按鍵完全一樣(見 4.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 驅動74HCT595D(SOIC-16 貼片;卷帶為 SN74HCT595DR)· #1 row + #2–#4 LED。必須 HCT 不可用 HC — HC 門檻 ≈3.5 V 吃不到 ESP32 的 3.3 V 訊號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)