Problem z klawiaturą macierzową membranową ESPHome

Witam, od pewnego czasu próbuję podłączyć klawiaturę macierzową 4x5, podłączyłem wszystkie 9 pinów do ESP, skonfigurowałem w kodzie i chciałem aby była możliwość zmiany scen oraz parametrów w sterowniku i wyświetlanie tego na LCD. Mam wrażenie, że esp nie reaguje wcale na klawiaturę.
Próbowałem to wykonać jako binary_sensor i brak jakiegokolwiek działania, oraz jako matrix_keypad z implementacją wierszy i kolumn, ale to nic nie pomaga
Macie jakieś pomysły jak to ogarnąć?

Pokaż YAMLa i schemat.

Tu są przedstawione moje nieudane próby załączenia przekaźnika podpisanego jako Zawor8.
Wiem, że on się załącza i jest zaimplementowany poprawnie w ESPHome, bo sterowałem nim z logiki czujników.

matrix_keypad:
  id: mykeypad
  rows:
    - pin: GPIO13
    - pin: GPIO12
    - pin: GPIO14
    - pin: GPIO27
    - pin: GPIO26
  columns:
    - pin: GPIO25
    - pin: GPIO32
    - pin: GPIO35
    - pin: GPIO34
  keys: "AB#*123C456D789EF0GH"
  has_diodes: false

key_collector:
  - id: pincode_reader
    source_id: mykeypad
    min_length: 4
    max_length: 4
    end_keys: "#"
    end_key_required: true
    back_keys: "*"
    clear_keys: "C"
    allowed_keys: "AB#*123C456D789EF0GH"
    timeout: 5s
    on_progress:
      - logger.log:
          format: "input progress: '%s', started by '%c'"
          args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ]
    on_result:
      - logger.log:
          format: "input result: '%s', started by '%c', ended by '%c'"
          args: [ 'x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)" ]
    on_timeout:
      - logger.log:
          format: "input timeout: '%s', started by '%c'"
          args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ]

binary_sensor:
  - platform: matrix_keypad
    keypad_id: mykeypad
    id: keyF1
    row: 0
    col: 0
    on_press:
      then:
        - switch.turn_on: Zawor8
    on_release:
      then:
      - switch.turn_off: Zawor8   
  - platform: matrix_keypad
    id: keyF2
    row: 0
    col: 1
    on_press:
      then:
        - switch.turn_on: Zawor8
    on_release:
      then:
      - switch.turn_off: Zawor8      
  - platform: matrix_keypad
    keypad_id: mykeypad
    id: keyHASZ
    row: 0
    col: 2
    on_press:
      then:
        - switch.turn_on: Zawor6
    on_release:
      then:
      - switch.turn_off: Zawor8      
  - platform: matrix_keypad
    id: keySTAR
    row: 0
    col: 3
    on_press:
      then:
        - switch.turn_on: Zawor6
    on_release:
      then:
      - switch.turn_off: Zawor8      
  - platform: matrix_keypad
    keypad_id: mykeypad
    id: key1
    row: 1
    col: 0
    on_press:
      then:
        - switch.turn_on: Zawor6
    on_release:
      then:
      - switch.turn_off: Zawor8      
  - platform: matrix_keypad
    id: key2
    row: 1
    col: 1
    on_press:
      then:
        - switch.turn_on: Zawor8
    on_release:
      then:
      - switch.turn_off: Zawor8      
  - platform: matrix_keypad
    keypad_id: mykeypad
    id: key3
    row: 1
    col: 2
    on_press:
      then:
        - switch.turn_on: Zawor8
    on_release:
      then:
      - switch.turn_off: Zawor8      
  - platform: matrix_keypad
    id: keyUP
    row: 1
    col: 3
    on_press:
      then:
        - switch.turn_on: Zawor8
    on_release:
      then:
      - switch.turn_off: Zawor8        
  - platform: matrix_keypad
    keypad_id: mykeypad
    id: key4
    row: 2
    col: 0
    on_press:
      then:
        - switch.turn_on: Zawor8
    on_release:
      then:
      - switch.turn_off: Zawor8      
  - platform: matrix_keypad
    id: key5
    row: 2
    col: 1
    on_press:
      then:
        - switch.turn_on: Zawor8
    on_release:
      then:
      - switch.turn_off: Zawor8      
  - platform: matrix_keypad
    keypad_id: mykeypad
    id: key6
    row: 2
    col: 2
    on_press:
      then:
        - switch.turn_on: Zawor8
    on_release:
      then:
      - switch.turn_off: Zawor8      
  - platform: matrix_keypad
    id: keyDOWN
    row: 2
    col: 3
    on_press:
      then:
        - switch.turn_on: Zawor8
    on_release:
      then:
      - switch.turn_off: Zawor8      
  - platform: matrix_keypad
    keypad_id: mykeypad
    id: key7
    row: 3
    col: 0
    on_press:
      then:
        - switch.turn_on: Zawor8
    on_release:
      then:
      - switch.turn_off: Zawor8  
  - platform: matrix_keypad
    id: key8
    row: 3
    col: 1
    on_press:
      then:
        - switch.turn_on: Zawor8
    on_release:
      then:
      - switch.turn_off: Zawor8  
  - platform: matrix_keypad
    keypad_id: mykeypad
    id: key9
    row: 3
    col: 2
    on_press:
      then:
        - switch.turn_on: Zawor8
    on_release:
      then:
      - switch.turn_off: Zawor8  
  - platform: matrix_keypad
    id: keyESC
    row: 3
    col: 3 
    on_press:
      then:
        - switch.turn_on: Zawor8
    on_release:
      then:
      - switch.turn_off: Zawor8  
  - platform: matrix_keypad
    keypad_id: mykeypad
    id: keyLEFT
    row: 4
    col: 0
    on_press:
      then:
        - switch.turn_on: Zawor8
    on_release:
      then:
      - switch.turn_off: Zawor8  
  - platform: matrix_keypad
    id: key0
    row: 4
    col: 1
    on_press:
      then:
        - switch.turn_on: Zawor8
    on_release:
      then:
      - switch.turn_off: Zawor8  
  - platform: matrix_keypad
    keypad_id: mykeypad
    id: keyRIGHT
    row: 4
    col: 2
    on_press:
      then:
        - switch.turn_on: Zawor8
    on_release:
      then:
      - switch.turn_off: Zawor8  
  - platform: matrix_keypad
    id: keyENT
    row: 4
    col: 3 Tekst sformatowany

Podłączenie klawiatury jest bezpośrednio do ESP32 do pinów w takiej kolejności:
rzędy:
- pin: GPIO13
- pin: GPIO12
- pin: GPIO14
- pin: GPIO27
- pin: GPIO26
kolumny:
- pin: GPIO25
- pin: GPIO32
- pin: GPIO35
- pin: GPIO34

z dokumentacji

columns (Required, list): A list of pins where the vertical matrix lines are connected, in order from left to right. These pins need to be input capable with pullups enabled. If there is no internal pullup, then an external one is required.

więc na GPIO34 i GPIO35 musisz podpiąć własne rezystory pullup, bo akurat te GPIO nimi nie dysponują, więc rezystory to konieczność (dlatego prosiłem o schemat).

W sumie rozsądnie byłoby użyć jako kolumny GPIO: 34, 35, 36 i 39, czyli wszystkie wejścia bez wbudowanych pullupów, bo wtedy będziesz w stanie zapewnić identyczne warunki pracy dokładając im własne pullupy; ale tak w sumie to napisałem o tym w ten sposób, abyś mógł łatwo przeorganizować piny wykorzystane jako selektor rzędów

rows (Required, list): A list of pins where the horrizontal matrix lines are connected, in order from top to bottom. These pins need to be output capable.

może jestem przesądny (te piny nie są na “czarnej liście”), ale bym sobie darował wykorzystanie GPIO: 12, 14 i 15 (tylko dlatego, że ich funkcje potencjalnie mogą z czymkolwiek kolidować, choć w tym zastosowaniu nie powinny)


Kolejna kwestia - jak definiujesz komponent matrix_keypad: to późniejsze jego wykorzystanie w binary_sensor: może wykorzystywać wcześniejszą definicję

ta klawiatura jak rozumiem wygląda tak:
AB#*
123C
456D
789E
F0GH
więc zamiast

  - platform: matrix_keypad
    keypad_id: mykeypad
    id: keyF1
    row: 0
    col: 0

powinno działać

  - platform: matrix_keypad
    id: keyF1
    key: A

Jakkolwiek z tego co napisałeś to chyba ta klawiatura

zweryfikowałeś oczywiście które piny do czego służą, bo jak na Botland to zaskoczył mnie brak dokumentacji (ale podejrzewam, że 4 piny od lewej to kolumny, potem rzędy).


Pokaż tą logikę czujników, bo tu chyba wychodzi kolejna kwestia - identyfikatory encji moim zdaniem powinny być z małej litery, więc raczej nie Zawor8 tylko zawor8.


PS W ciemno założyłem, że chodzi o MCU ESP32 (solo lub dual core - te na prockach Xtensa LX6, a nie np. ESP32-Cx lub ESP32-Sx).

Cytat

Okej, ma to sens dla mnie, przepiąłem piny oraz dołożyłem rezystory podciągające

Jak czytałem to niby obie opcje są poprawne i powinny działać, ale zmieniłem teraz licząc, że pomoże.

Tak, to jest dokładnie ta klawiatura i sprawdziłem, które piny są od czego przy okazji aktu desperacji czy nie jest wadliwa.

Zmieniłem te litery z dużej na małe, chciałem pokazać tą logikę jednak usunąłem ją przypadkiem jak próbowałem zrobić czujniki wilgotności gleby przez multiplekser więc w tej chwili przekaźniki nazwane jako zawor nie są sterowane żadną automatyką tylko są dodane tak:

  - platform: gpio
    name: "Relay6"
    inverted: yes
    pin: GPIO5
    id: zawor6
  - platform: gpio
    name: "Relay8"
    inverted: yes
    pin: GPIO19
    id: zawor8   

Edit:

Od razu podeślę cały kod dla ułatwienia sprawy z moim “cyrkiem”.
Głównym celem tego jest zrobienie automatycznego sterowania nawadniania dla 12 sekcji ogrodu wraz z wyświetlaczem i klawiaturą do zmiany parametrów jednak jeszcze daleka droga do tego.

esphome:
  name: esp32-1-home
  friendly_name: ESP32_1_HOME

esp32:
  board: esp32dev
  framework:
    type: arduino
# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "qFDuCbddD5eOd807ihxk8GWteZ6OZNpQ+0qKdxG5Yoo="

ota:
  password: "83f0956c20b45ea8853328c72196c1c0"

wifi:
  networks:
    ssid: "multimedia_Glowny"
    password: "k0l0_z4m4CHOWE"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "multimedia_Glowny"
    password: "k0l0_z4m4CHOWE"

cd74hc4067:
  - id: cd74hc4067_1
    pin_s0: GPIO15
    pin_s1: GPIO4
    pin_s2: GPIO16
    pin_s3: GPIO17

#D2 syg
#D15 D4 D16 D17

text_sensor:
  - platform: template
    name: Keypad
    id: keypad               

matrix_keypad:
  id: mykeypad
  rows:
    - pin: GPIO13
    - pin: GPIO12
    - pin: GPIO14
    - pin: GPIO27
    - pin: GPIO26
  columns:
    - pin: GPIO36
    - pin: GPIO39
    - pin: GPIO35
    - pin: GPIO34
  keys: "AB#*123C456D789EF0GH"
  has_diodes: false

binary_sensor:
  - platform: matrix_keypad
    id: keyF1
    key: A
    on_press:
      then:
        - switch.turn_on: zawor8
    on_release:
      then:
      - switch.turn_off: zawor8   
  - platform: matrix_keypad
    id: keyF2
    key: B
    on_press:
      then:
        - switch.turn_on: zawor8
    on_release:
      then:
      - switch.turn_off: zawor8      
  - platform: matrix_keypad
    id: keyHASZ
    key: P
    on_press:
      then:
        - switch.turn_on: zawor6
    on_release:
      then:
      - switch.turn_off: zawor8      
  - platform: matrix_keypad
    id: keySTAR
    key: O
    on_press:
      then:
        - switch.turn_on: zawor6
    on_release:
      then:
      - switch.turn_off: zawor8      
  - platform: matrix_keypad
    id: key1
    key: 1
    on_press:
      then:
        - switch.turn_on: zawor6
    on_release:
      then:
      - switch.turn_off: zawor8      
  - platform: matrix_keypad
    id: key2
    key: 2
    on_press:
      then:
        - switch.turn_on: zawor8
    on_release:
      then:
      - switch.turn_off: zawor8      
  - platform: matrix_keypad
    id: key3
    key: 3
    on_press:
      then:
        - switch.turn_on: zawor8
    on_release:
      then:
      - switch.turn_off: zawor8      
  - platform: matrix_keypad
    id: keyUP
    key: C
    on_press:
      then:
        - switch.turn_on: zawor8
    on_release:
      then:
      - switch.turn_off: zawor8        
  - platform: matrix_keypad
    id: key4
    key: 4
    on_press:
      then:
        - switch.turn_on: zawor8
    on_release:
      then:
      - switch.turn_off: zawor8      
  - platform: matrix_keypad
    id: key5
    key: 5
    on_press:
      then:
        - switch.turn_on: zawor8
    on_release:
      then:
      - switch.turn_off: zawor8      
  - platform: matrix_keypad
    id: key6
    key: 6
    on_press:
      then:
        - switch.turn_on: zawor8
    on_release:
      then:
      - switch.turn_off: zawor8      
  - platform: matrix_keypad
    id: keyDOWN
    key: D
    on_press:
      then:
        - switch.turn_on: zawor8
    on_release:
      then:
      - switch.turn_off: zawor8      
  - platform: matrix_keypad
    id: key7
    key: 7
    on_press:
      then:
        - switch.turn_on: zawor8
    on_release:
      then:
      - switch.turn_off: zawor8  
  - platform: matrix_keypad
    id: key8
    key: 8
    on_press:
      then:
        - switch.turn_on: zawor8
    on_release:
      then:
      - switch.turn_off: zawor8  
  - platform: matrix_keypad
    id: key9
    key: 9
    on_press:
      then:
        - switch.turn_on: zawor8
    on_release:
      then:
      - switch.turn_off: zawor8  
  - platform: matrix_keypad
    id: keyESC
    key: E
    on_press:
      then:
        - switch.turn_on: zawor8
    on_release:
      then:
      - switch.turn_off: zawor8  
  - platform: matrix_keypad
    id: keyLEFT
    key: F
    on_press:
      then:
        - switch.turn_on: zawor8
    on_release:
      then:
      - switch.turn_off: zawor8  
  - platform: matrix_keypad
    id: key0
    key: 0
    on_press:
      then:
        - switch.turn_on: zawor8
    on_release:
      then:
      - switch.turn_off: zawor8  
  - platform: matrix_keypad
    id: keyRIGHT
    key: G
    on_press:
      then:
        - switch.turn_on: zawor8
    on_release:
      then:
      - switch.turn_off: zawor8  
  - platform: matrix_keypad
    id: keyENT
    key: H
switch:
  - platform: gpio
    pin:
      number: GPIO18
      inverted: true
    name: "Relay7"
    internal: false
    id: zawor7

  - platform: template
    id: blinds_up
    name: "Blinds Up"
    lambda: return id(bu_switch);
    turn_on_action:
      - lambda: |-
          id(bu_switch) = true;

    turn_off_action:
      - lambda: |-
          id(bu_switch) = false;

#  - platform: ADC
#    name: "Relay2"
#    inverted: yes
#    pin: A0
#    id: zawor2
#  - platform: gpio
#    name: "Relay3"
#    inverted: yes
#    pin: GPIO4
#    id: zawor3
#  - platform: gpio
#    name: "Relay4"
#    inverted: yes
#    pin: GPIO16
#    id: zawor4
#  - platform: gpio
#    name: "Relay5"
#    inverted: yes
#    pin: GPIO17
#    id: zawor5
  - platform: gpio
    name: "Relay6"
    inverted: yes
    pin: GPIO5
    id: zawor6
  - platform: gpio
    name: "Relay8"
    inverted: yes
    pin: GPIO19
    id: zawor8   

sensor:

  - platform: adc
    pin: GPIO33
    id: adc_sensor
    update_interval: 20ms

  - platform: cd74hc4067
    name: "Soil Moisture 1"
    id: SMV1
    number: 0
    sensor: adc_sensor
    update_interval: 20s 

  - platform: cd74hc4067
    name: "Soil Moisture 2"
    id: SMV2
    number: 1
    sensor: adc_sensor
    update_interval: 20s

  - platform: cd74hc4067
    name: "Soil Moisture 3"
    id: SMV3
    number: 2
    sensor: adc_sensor
    update_interval: 20s 

  - platform: cd74hc4067
    name: "Soil Moisture 4"
    id: SMV4
    number: 3
    sensor: adc_sensor
    update_interval: 20s
    unit_of_measurement: "%"

  - platform: cd74hc4067
    name: "Soil Moisture 5"
    id: SMV5
    number: 4
    sensor: adc_sensor
    update_interval: 20s
    unit_of_measurement: "%"

  - platform: cd74hc4067
    name: "Soil Moisture 6"
    id: SMV6
    number: 5
    sensor: adc_sensor
    update_interval: 20s
    unit_of_measurement: "%"

  - platform: cd74hc4067
    name: "Soil Moisture 7"
    id: SMV7
    number: 6
    sensor: adc_sensor
    update_interval: 20s
    unit_of_measurement: "%"

  - platform: cd74hc4067
    name: "Soil Moisture 8"
    id: SMV8
    number: 7
    sensor: adc_sensor
    update_interval: 20s
    unit_of_measurement: "%"    

  - platform: cd74hc4067
    name: "Soil Moisture 9"
    id: SMV9
    number: 8
    sensor: adc_sensor
    update_interval: 20s
    unit_of_measurement: "%"

  - platform: cd74hc4067
    name: "Soil Moisture 10"
    id: SMV10
    number: 9
    sensor: adc_sensor
    update_interval: 20s
    unit_of_measurement: "%"
    filters:
    - median:
        window_size: 10
        send_every: 6
        send_first_at: 1
    - calibrate_linear:
        - 1.08 -> 0
        - 0.08 -> 100
    - lambda: if (x < 0.08) return 100;
        else if (x > 1.08) return 0;
        else return (x);
    accuracy_decimals: 3

  - platform: cd74hc4067
    name: "Soil Moisture 11"
    id: SMV11
    number: 10
    sensor: adc_sensor
    update_interval: 20s
    unit_of_measurement: "%"
    filters:
    - median:
        window_size: 10
        send_every: 6
        send_first_at: 1
    - calibrate_linear:
        - 1.08 -> 0
        - 0.08 -> 100
    - lambda: if (x < 0.08) return 100;
        else if (x > 1.08) return 0;
        else return (x);
    accuracy_decimals: 3

  - platform: cd74hc4067
    name: "Soil Moisture 12"
    id: SMV12
    number: 11
    sensor: adc_sensor
    update_interval: 20s
    unit_of_measurement: "%"
    filters:
    - median:
        window_size: 10
        send_every: 6
        send_first_at: 1
    - calibrate_linear:
        - 1.08 -> 0
        - 0.08 -> 100
    - lambda: if (x < 0.08) return 100;
        else if (x > 1.08) return 0;
        else return (x);
    accuracy_decimals: 3

  - platform: cd74hc4067
    name: "Soil Moisture 1123123123"
    id: SMV13
    number: 12
    sensor: adc_sensor
    update_interval: 20s
    unit_of_measurement: "%"
    filters:
    - median:
        window_size: 10
        send_every: 6
        send_first_at: 1
    - calibrate_linear:
        - 1.08 -> 0
        - 0.08 -> 100
    - lambda: if (x < 0.08) return 100;
        else if (x > 1.08) return 0;
        else return (x);
    accuracy_decimals: 3

  - platform: cd74hc4067
    name: "Soil Moisture 2123123131"
    id: SMV14
    number: 13
    sensor: adc_sensor
    update_interval: 20s
    unit_of_measurement: "%"
    filters:
    - median:
        window_size: 10
        send_every: 6
        send_first_at: 1
    - calibrate_linear:
        - 1.08 -> 0
        - 0.08 -> 100
    - lambda: if (x < 0.08) return 100;
        else if (x > 1.08) return 0;
        else return (x);
    accuracy_decimals: 3

  - platform: cd74hc4067
    name: "Soil Moisture 112313"
    id: SMV15
    number: 14
    sensor: adc_sensor
    update_interval: 20s
    filters:
    - median:
        window_size: 10
        send_every: 6
        send_first_at: 1
    - calibrate_linear:
        - 1.08 -> 0
        - 0.08 -> 100
    - lambda: if (x < 0.08) return 100;
        else if (x > 1.08) return 0;
        else return (x);
    accuracy_decimals: 3

  - platform: dht
    pin: GPIO23
    temperature:
      name: "DHT11 Temperature"
      id: Temp
    humidity:
      name: "DHT11 Humidity"
      id: Hum
    update_interval: 1s

 

  


globals:
  - id: my_global_int
    type: int
    restore_value: no
    initial_value: '1'
  - id: my_global_int2 
    type: int
    restore_value: no
    initial_value: '0'  
  - id: scena0
    type: int
    restore_value: no
    initial_value: '0'
  - id: scena1
    type: int
    restore_value: no
    initial_value: '0'

  - id: bu_switch
    type: boolean
    restore_value: true
    initial_value: "false"  

i2c:
  sda: GPIO21
  scl: GPIO22
display:
  - platform: lcd_pcf8574
    dimensions: 20x4
    address: 0x27
    id: LCD16X2_1
    update_interval: 500ms
    lambda: |-
      it.printf(18,3, "%i", id(my_global_int));
      if (id(my_global_int)<10) {
        it.printf(6, 1, "Sterownik");
        it.printf(2, 2, "Do Nawadniania v1");
        it.printf(2, 3, "Pawel Muszynski");        
        id(my_global_int) += 1;
      }
      if (id(my_global_int)>=10) {
        if (id(my_global_int)<=20){
          it.printf(2, 0, "Wilgotnosc gleby");         
          it.printf(0, 2, "Sekcja 1= %.1f%% 0.f%", id(SMV1).state, id(zawor6).state);
          it.printf(0, 3, "Sekcja 2= %.1f%% 0.f%", id(SMV2).state, id(zawor6).state);
        }
        if (id(my_global_int)>20){
          it.printf(2, 0, "Wilgotnosc gleby");         
          it.printf(0, 2, "Sekcja 3= %.1f%%", id(SMV3).state);
          it.printf(0, 3, "Sekcja 4= %.1f%%", id(SMV4).state);
        }
        if (id(my_global_int)>30){
          it.printf(2, 0, "Wilgotnosc gleby");         
          it.printf(0, 2, "Sekcja 5= %.1f%%", id(SMV5).state);
          it.printf(0, 3, "Sekcja 6= %.1f%%", id(SMV6).state);
        }
        if (id(my_global_int)>40){
          it.printf(2, 0, "Wilgotnosc gleby");         
          it.printf(0, 2, "Sekcja 7= %.1f%%", id(SMV7).state);
          it.printf(0, 3, "Sekcja 8= %.1f%%", id(SMV8).state);
        }
        if (id(my_global_int)>50){
          it.printf(2, 0, "Wilgotnosc gleby");         
          it.printf(0, 2, "Sekcja 9= %.1f%%", id(SMV9).state);
          it.printf(0, 3, "Sekcja 10=%.1f%%", id(SMV10).state);
        }
        if (id(my_global_int)>60){
          it.printf(2, 0, "Wilgotnosc gleby");         
          it.printf(0, 2, "Sekcja 11=%.1f%%", id(SMV11).state);
          it.printf(0, 3, "Sekcja 12=%.1f%%", id(SMV12).state);
        }
          id(my_global_int) += 1;
        } 
        if (id(my_global_int)>70) {
          id(scena1) +=1;
          id(my_global_int)=10;
          if (id(scena1)>=7){
            id(scena1)=0;
          }
        
      }
      if (id(my_global_int2)<10) {
        id(my_global_int2) += 1;
      }
      if (id(my_global_int2)>=10) {
        id(my_global_int2) = 0;
      }
time:
- platform: homeassistant
  id: my_time

Stare wersje YAMLa masz w starych pełnych backupach HA, więc można je stamtąd wygrzebać.

Co do zapisu identyfikatorów z dużej litery - byłem w błędzie, małe litery to po prostu tylko tzw. dobra praktyka, ale czasem znalezienie czegoś konkretnego w całej dokumentacji jest trudne

Jak dotąd nie używałem klawiatury matrycowej w ESPHome, więc nie podpowiem z praktyki co tu może być nie w porządku, nie wiem jak się zachowuje ta integracja, na dobry początek zapalaj LEDy lub wręcz pisz do loga zamiast kłapać przekaźnikami - szczerze mówiąc nie wiem jak się tu zachowuje integracja takiej klawiatury biorąc pod uwagę multipleksowanie klawiszy, a dokumentacja tej integracji jest naprawdę kiepska.

Multiplekser jest tylko do czujników, a klawiatura jest bezpośrednio.
Będę próbował dalej działać z tą klawiaturą.

Klawiatura macierzowa jest obsługiwana przez multiplekser zbudowany bezpośrednio z GPIO tego ESP - taka jest zasada jej działania…

Tu masz zajebisty artykulik, który świetnie tłumaczy parę zagadnień

Natomiast dokumentacja ESPHome jest w tym fragmencie centralnie do d…
bo są np. takie opcje jak has_pulldowns bez opisu jak to użyć w powiązaniu ze sprzętem.

Normalna konfiguracja zakłada multipleksowanie rzędów stanem niskim - wtedy wciśnięcie klawisza powoduje ściągnięcie do masy któregoś z GPIO wejściowych (kolumny).

Więc na logikę w przypadku klawiatury z pulldownami zamiast pullupów na kolumnach, multipleksowanie wyjść też musi być odwrócone (rzędy będą przemiatane wystawieniem stanu wysokiego) - wtedy wciśnięcie klawisza będzie stanem wysokim.
Skoro korzystasz akurat z tych wejść, które sugerowałem możesz rezystory pociągnąć do masy zamiast Vcc i ustawić tą opcję dla eksperymentu. (być może dla klawiatury membranowej gdzie zapewne rezystancja styków jest sporo większa od bliskiej zera łatwiej będzie wykryć stan wysoki niż niski, jaką masz wartość pullupów, czy w tej konfiguracji pulldownów?)

Ja po prostu błędów nie widzę w tej twojej konfiguracji, a reszty kodu poza klawiaturą to nawet nie analizowałem, bo i po co, przecież on nie jest do niczego potrzebny, więc możesz go tymczasowo wywalić - duży projekt zawsze wymaga uruchamiania po kawałku.

Zajrzyj do kodu - każde wykryte naciśnięcie klawisza i jego puszczenie powinno się znaleźć w logu (więc w celach uruchamiania nie musisz podpinać żadnych elementów wykonawczych)


Tak poza konkurencją to można użyć też jakiś dedykowany układ multipleksera, tak swoją drogą - kolejna czarna dziura w dokumentacji to TM1637 (który może służyć też jako dedykowany multiplekser klawiatury macierzowej z tym, że takiej nieco biedniejszej - 2 kolumny), gdzie są np. schematy połączenia kaskadowego bez odniesienia do konfiguracji.
(planowałem kiedyś eksperyment, ale nie dorobiłem się takiej ilości tych wyświetlaczy)

Wiedziałem, że jest obsługa jakichś bardziej dedykowanych układów dla klawiatur, tylko niestety znowu trafiłem na lukę w dokumentacji (ten rozdział nie jest podlinkowany w rozsądnych miejscach a w wyszukiwarce najwyraźniej użyłem niewłaściwe słowa kluczowe…), więc tu masz takie rozwiązanie typu “Ostatnia deska ratunku” - specjalizowany multiplekser dla klawiatury maksymalnie 64-klawiszowej (8x8)

powinien być sklasyfikowany też do “mechanical”.


Tak na zakończenie to generalnie polecam w takich przypadkach jak “niedziałający komponent mimo teoretycznej poprawności konfiguracji” pokopanie po issues, również tych dawno zamkniętych - może tam są informacje, które z powodu barku mocy przerobowej osób rozwijających ten projekt nie trafiły do oficjalnej dokumentacji (są w niej spore braki i wymaga uzupełnień przez przytomnych użytkowników, którzy wiedzą co robią).

Dokumentacja kitu na bazie SX1509 (link w dokumentacji ESPHome się przedawnił)

dokumentacja Sparkfun jednak jest na swoim miejscu

https://learn.sparkfun.com/tutorials/sx1509-io-expander-breakout-hookup-guide/

Próbuję dalej no cóż, zależy tylko żeby cokolwiek działało.
A wiesz może jak zrobić, aby ESP komunikowało się tylko po USB UART bez wifi ? chciałem zwiększyć sobie ilość pinów pomiarowych bo trochę mało mam a zabawa w multipleksery mi nie wychodzi a mało czasu mam już.

Poważnie o to pytasz w kontekście ESPHome?

Przejrzałem tego całościowego YAMLa i trochę mam wrażenie, że podszedłeś albo na zasadzie “mam w szufladzie to z tego ulepię”, albo nie pokopałeś po dokumentacji bardziej całościowo by nabrać świadomości jak najłatwiej osiągnąć cel i pod to kupić podzespoły, ale za rok też będzie wiosna - nie musisz odpalać tego nawadniania w tym roku.

Czy to może jakiś szkolny projekt by wykorzystać multipleksery, bo to tak trochę pachnie ;D


No OK może podrzucę jakiś hint:

CD74HC4067 ma 16 wlotów analog i potrzebuje 4 pinów DO i 1 AI (bo sam nic nie mierzy tylko multipleksuje)

ADS1115 ma 4 wloty analog i potrzebuje 2 pinów DIO (magistrala I2C) ale rozwiązanie się skaluje - możesz użyć ich więcej
2 sztuki ADS1115 mają 8 wlotów analog i potrzebują nadal 2 pinów DIO
4 sztuki ADS1115 mają 16 wlotów analog i potrzebują nadal 2 pinów DIO
idąc w hardkor z wlotami
8 sztuk ADS1115 ma 32 wloty analog i potrzebują 4 pinów DIO (2 magistrale I2C)

na multipleksowanie tej klawiaturki bezpośrednio w ESP potrzebujesz 9 pinów (5x DO + 4x DI),
używając specjalizowanego ekspandera-multipleksera na I2C
SX1509 zużywasz jego 9 wejść z 16, a potrzebujesz 2 pinów DIO
uwaga to może być ta sama magistrala I2C, którą używasz dla ADS1115 czyli zero pinów jeśli lecisz wraz z jednym lub kilkoma ADS1115
w dodatku masz jeszcze dostępne 7 wolnych DIO w ekspanderze

hint2
do zastosowań wymagających dużej liczby IO jest dedykowany ESP32-S2 (jednordzeniowy LX7, status NRND, ale to chyba nikomu nie przeszkadza w DIY) albo nowszy ESP32-S3 (jednordzeniowy RISC)
zresztą co ja się produkuję fajna tabelka taki bryk ze specyfikacji
https://espeasy.readthedocs.io/en/latest/ESPEasy/ESPchips.html

tylko w kwestiach praktycznych S2 można bez trudu znaleźć w postaci płytki prototypowej, w formacie PCB zgodnym RPi pico, która ma od groma wyprowadzeń, S3 nie widziałem w tym formacie, ale najtańsze wypusty są wzorowane na referencyjnej płytce deweloperskiej Espressifa esp32-s3

w sumie jeśli się nie boisz wyzwań to… ESPHome działa też na RPi pico z tym, że jest to faza eksperymentalna (platformio tu stanęło okoniem…)

hint3
prototypując coś tak skomplikowanego jako DIY musisz się liczyć z porażką, łatwo przegapić jakiś szczególik

Uznajmy, że to projekt szkolny jednak do wykonania nawadniania 12 sekcji. Jakby się dało czytać 12 sekcji i wysterować 12 przekaźników z wyświetlaczem i klawiaturą bez stosowania multipleksera to znaczy, że bardzo zabłądziłem w tym projekcie. Jest to moje pierwsze zetknięcie się z mikrokontrolerami dlatego też niektóre rzeczy nie wydają mi się oczywiste i zadaje głupie pytania

No to nie wiem czy ESPHome jest w ogóle dopuszczalnym rozwiązaniem…
W końcu to nie jest prawdziwe programistyczne IDE tylko projekt - rozszerzenie Home Assistant’a w osprzęt DIY… to że na jego bazie można budować proste urządzenia mniej lub bardziej autonomiczne to jakby tylko możliwość powstała przy okazji.
Podejrzewam, że powinieneś stosować rozwiązania, których się uczysz.
Czy w ogóle masz dowolność wyboru komponentów?

Spójrz na to co sugerowałem wyżej - 3x ADS1115 daje dokładnie 12 asymetrycznych wejść analogowych, dedykowany multiplekser klawiatury zadziała razem z nimi dając dodatkowe DI lub DO do wykorzystania.

Upieram się przy rozwiązaniach I2C bo chcesz tam upchnąć jeszcze 12 przekaźników i wyświetlacz, więc projektowanie powinieneś zacząć od przeczytania co da się wycisnąć z danego MCU przekaźników pewnie nie obskoczysz inaczej niż bezpośrednio z DO (co nie znaczy, że nie można inaczej, ale wtedy musiałbyś mieć jeszcze pomocniczy MCU), więc byłoby fajnie ogarnąć chociaż wyświetlacz bez zużywania dodatkowych pinów w ogromnej ilości - tu pomoże ekspander wyjść PCF8574 - wepniesz go w pojedynczą szynę I2C na której już masz 3 sztuki ADS1115 i jeden SX1509

a ewentualne wodotryski sobie dołożysz na wolnych GPIO jeśli jakieś zostaną (stawiam na to, że tak).

I w pewnym sensie cel dydaktyczny stosowania multiplekserów i tak zostanie osiągnięty, tylko musisz się wgryźć bardziej w dokumentację użytych peryferiów by udowodnić, że stosujesz ich od groma.


Aha i jeszcze wracając do dydaktyki :stuck_out_tongue: związanej z obsługą klawiatury, tak naprawdę do przetestowania działania komponentu klawiatury w ESPHome nie potrzebujesz wcale klawiatury, potrzebne są tylko rezystory, którymi podciągniesz sobie linie wejść do Vcc czy GND oraz kawałek drutu którym będziesz zwierać odpowiednie DO z DI udając klawiaturę - to szczególnie istotne, gdy usiłujesz odpalić projekt na breadboardzie, gdzie trudno uzyskać pewne połączenia.

Prócz tego należy testować każdy komponent osobno, bo przy takim skomplikowaniu projektu nawet nie próbowałem weryfikować czy komponenty nie kolidują ze sobą.

Kolejna kwestia na którą zwróciłem uwagę to w ogóle badanie wilgotności gleby na bezczelnego, czyli mierząc jakąś rezystancję (tego w ogóle chyba nie masz zaimplementowanego sprzętowo). Robiłeś już jakieś eksperymenty, że to w ogóle jest możliwe w ten sposób? (podejrzewam, że krótkofalowo tak, ale elektrody testowe zgniją prędzej lub później, bo rozłoży je elektroliza, więc takie rozwiązanie raczej nie ma walorów użytkowych…)

Następna

    - calibrate_linear:
        - 1.08 -> 0
        - 0.08 -> 100

zamieniłbym na

    - calibrate_linear:
        - 0.08 -> 100
        - 1.08 -> 0

W ogóle to mierzyłeś napięcie na tym wejściu AI bez multipleksera?

PS nie widzę kliknięć w linki do tych dokumentacji, które linkowałem już wcześniej, więc nabieram przekonania, że wcale nie zamierzasz realizować tego projektu, a mój czas był stracony…

Uruchamiaj po prostu każdy komponent oddzielnie, bo usiłując odpalić wszystko naraz to raczej się nie uda.
Każdy komponent uruchamiaj w najbardziej podstawowej konfiguracji dopiero potem dodając opcje dodające “wodotryski”.

Spokojnie sprawdzam linki tylko nie zawsze na tym komputerze, a na drugim nie jestem zalogowany.

Odnośnie tego to tak, za pierwszym razem podłączałem czujniki pojemnościowe z Ali bezpośrednio pod wejścia ESP i dostawałem zakres pomiarowy w zakresie około 2,9-0,8V i działały dość precyzyjnie. Potem zająłem się działaniem multipleksera cd74hc4067, aby wykorzystać jego do odczytu parametrów. W pierwszej chwili skalibrowałem go tak jak powyżej ale coś mi nie pasowało. Ostatecznie wziąłem się za czytanie i okazało się że jak amator nie uwzględniłem zakresu tłumienia, które rozwiązało cały problem. Mój błąd w pełni.

Główny problem jaki mi pozostał to dalsza zabawa z klawiaturą, dziś nie miałem czasu za nią się zabrać więc jutro doczytam to co wysyłałeś powyżej jeszcze raz o klawiaturze i dam odpowiedź zwrotną czy się udało czy nie.

Z wodotrysków, które chciałbym dołożyć zostały mi same pierdoły wymagane do wyświetlania stanów przekaźników na wyświetlaczu. No i dodatkowo dopisać automatykę do sprawnych już odczytów wilgotności gleby.
image
do pomiarów wilgotności gleby użyłem tych czujników ze zdjęć i teraz już działa w miarę poprawnie

1 Like