[分享] 16鍵鍵盤 (ESPHome)

鍵盤主體為 4x4 矩陣鍵盤 與 ESP32-C3 開發板,使用 HA + ESPhome 系統,wifi 通訊,USB 供電

一次能按單個按鍵,每個按鍵可有多種按鍵事件(single / double / hold / …),但快速連點可能偵測失敗

電路接線


開發板 GPIO8 有連接 LED 使用,因此圖中鍵盤第四腳跨接至上方 GPIO4
開發板 GPIO9 有連接 Boot Button,預計不會使用,因此也拿來連接鍵盤使用

desktop-keypad.yaml

substitutions:
  device_name: "desktop-keypad"
  friendly_name: 桌面開關16鍵

packages:
  device_web: !include templates/device_web.yaml

esp32:
  board: esp32-c3-devkitm-1

matrix_keypad:
  id: mykeypad
  rows:
    - pin: GPIO21
    - pin: GPIO20
    - pin: GPIO10
    - pin: GPIO9
  columns:
    - pin: GPIO4
    - pin: GPIO7
    - pin: GPIO6
    - pin: GPIO5

binary_sensor:
  - <<: !include { file: common/matrix_keypad_button.yaml, vars: { num: 1, row: 0, col: 0 } }
  - <<: !include { file: common/matrix_keypad_button.yaml, vars: { num: 2, row: 0, col: 1 } }
  - <<: !include { file: common/matrix_keypad_button.yaml, vars: { num: 3, row: 0, col: 2 } }
  - <<: !include { file: common/matrix_keypad_button.yaml, vars: { num: 4, row: 0, col: 3 } }
  - <<: !include { file: common/matrix_keypad_button.yaml, vars: { num: 5, row: 1, col: 0 } }
  - <<: !include { file: common/matrix_keypad_button.yaml, vars: { num: 6, row: 1, col: 1 } }
  - <<: !include { file: common/matrix_keypad_button.yaml, vars: { num: 7, row: 1, col: 2 } }
  - <<: !include { file: common/matrix_keypad_button.yaml, vars: { num: 8, row: 1, col: 3 } }
  - <<: !include { file: common/matrix_keypad_button.yaml, vars: { num: 9, row: 2, col: 0 } }
  - <<: !include { file: common/matrix_keypad_button.yaml, vars: { num: 10, row: 2, col: 1 } }
  - <<: !include { file: common/matrix_keypad_button.yaml, vars: { num: 11, row: 2, col: 2 } }
  - <<: !include { file: common/matrix_keypad_button.yaml, vars: { num: 12, row: 2, col: 3 } }
  - <<: !include { file: common/matrix_keypad_button.yaml, vars: { num: 13, row: 3, col: 0 } }
  - <<: !include { file: common/matrix_keypad_button.yaml, vars: { num: 14, row: 3, col: 1 } }
  - <<: !include { file: common/matrix_keypad_button.yaml, vars: { num: 15, row: 3, col: 2 } }
  - <<: !include { file: common/matrix_keypad_button.yaml, vars: { num: 16, row: 3, col: 3 } }

event:
  - platform: template
    name: Action
    id: action
    device_class: button
    event_types:
      - ""
      - "button_1_single"
      - "button_1_double"
      - "button_1_hold"
      - "button_2_single"
      - "button_2_double"
      - "button_2_hold"
      - "button_3_single"
      - "button_3_double"
      - "button_3_hold"
      - "button_4_single"
      - "button_4_double"
      - "button_4_hold"
      - "button_5_single"
      - "button_5_double"
      - "button_5_hold"
      - "button_6_single"
      - "button_6_double"
      - "button_6_hold"
      - "button_7_single"
      - "button_7_double"
      - "button_7_hold"
      - "button_8_single"
      - "button_8_double"
      - "button_8_hold"
      - "button_9_single"
      - "button_9_double"
      - "button_9_hold"
      - "button_10_single"
      - "button_10_double"
      - "button_10_hold"
      - "button_11_single"
      - "button_11_double"
      - "button_11_hold"
      - "button_12_single"
      - "button_12_double"
      - "button_12_hold"
      - "button_13_single"
      - "button_13_double"
      - "button_13_hold"
      - "button_14_single"
      - "button_14_double"
      - "button_14_hold"
      - "button_15_single"
      - "button_15_double"
      - "button_15_hold"
      - "button_16_single"
      - "button_16_double"
      - "button_16_hold"

    on_event:
      then:
        - lambda: |-
            id(action_text).publish_state(event_type);

text_sensor:
  - platform: template
    name: "Action"
    id: action_text

matrix_keypad_button.yaml

- platform: matrix_keypad
  keypad_id: mykeypad
  name: "Button ${num}"
  row: ${row}
  col: ${col}
  internal: true

  on_multi_click:
    - timing:
        - ON for at most 1s
        - OFF for at most 1s
        - ON for at most 1s
        - OFF for at least 0.2s
      then:
        - event.trigger:
            id: action
            event_type: "button_${num}_double"
        - event.trigger:
            id: action
            event_type: ""

    - timing:
        - ON for at most 1s
        - OFF for at least 0.5s
      then:
        - event.trigger:
            id: action
            event_type: "button_${num}_single"
        - event.trigger:
            id: action
            event_type: ""

    - timing:
        - ON for at least 1s
      then:
        - event.trigger:
            id: action
            event_type: "button_${num}_hold"
        - event.trigger:
            id: action
            event_type: ""

device_web.yaml 為 esphome, wifi, ota, api, web_server … 等基本配置(略)

補充說明:

  1. event_type: “” 的作用是事件發生後立即重置事件,目的是為了簡化 unavailable 狀態的自動化流程
  2. event.desktop_keypad_action 在 HA Automation 可以用 event_types 選單來選擇事件,免除手動輸入事件名稱
  3. event 狀態內容是時間戳,在 Logbook 會查詢不到俱體按鍵事件,於擴增 sensor.desktop_keypad_action 後可查詢按鍵紀錄,且 sensor 實體在 node-red 更容易使用

HA - automations.yaml

- id: 'desktop-keypad'
  alias: 桌面開關16鍵
  description: ''
  triggers:
  - trigger: state
    entity_id:
    - event.desktop_keypad_action
  conditions: []
  actions:
  - choose:
    - conditions:
      - condition: state
        entity_id: event.desktop_keypad_action
        attribute: event_type
        state: button_1_single
      sequence:
      - action: script.set_an_alarm_to_take_out_the_trash
  mode: parallel
  max: 10

其它矩陣鍵盤案例

參考資訊