ESP32 i podwójne zliczanie impulsów

Początki są trudne. Postanowiłem podłączyć licznik SMD72Bi do homeassistanta. Licznik jest dwukierunkowy, ale zaznaczam na początku jest wykorzystywany jako podlicznik do PC i liczy tylko pobór. Ma wyjście impulsowe 1000im/kWh zamykające obwód w momencie mignięcia diody. Podłączyłem to wyjście bezpośrednio do GND i D4 (GPIO4) na płytce ESP32.
Kompletnie się na tym nie znam i działa na tym co znajdę w internecie część rozumiejąc, a część robiąc kopiuj/wklej. ESP32 jest już widoczne w homeassitant i z tym nie ma problemu, encje odczytuje itp.
Problem1.
Zliczam impulsy w ten sposób:

sensor:
  - platform: pulse_counter
    pin: GPIO4
    unit_of_measurement: "kWh"
    name: "Licznik energii"
    id: licznik_energii
    filters:
      - multiply: 0.001

i w logach urządzenia widzę to tak:

13:03:14	[D]	[pulse_counter:186]	
'Licznik energii': Retrieved counter: 88.00 pulses/min

Dokładnie 2 razy za dużo impulsów, przypuszczam że bezpośrednie podłączenie zlicza mi załączenie i wyłączenie impulsu, ale prawdziwym probleme (to chyba da się obejść zmieniając multiply na 0,0005) że w homeassistacie w ogóle pokazuje dziwne rzeczy:

Tak ze 100x mniej podliczył energii niż by wynikało ze zliczanych impulsów.

Problem 2.
Jak pobrać bieżącą moc z licznika. Wymyśliłem sobie żeby zliczyać czas pomiędzy impulsami (1Wh) i liczyć P=W/t, ale jak pobrać ten czas z ESP32, a może w ogóle nie tędy droga i trzeba to zrobić inaczej, choć taki sposób by mi pasował bo byłby najaktualniejszy - minimalny pobór na PC to 7W czyli ~500s pomiędzy impulsami, a maksymalny to może być około 4kW czyli ~0,9s.

Ile takie ESP32 zniesie wgrań konfiguracji?

Na początek naucz się jak zamieszczać kod na forum:

Z tego co można wyczytać w dokumentacji ESPHome, to lepiej jest użyć komponentu

Zamiast pulse_counter. Zobacz jaki mam kod dla zliczania impulsów na wodomierzu.

U mnie działa to dobrze z ustawieniami dla internal_filter: 100ms oraz opcjonalnym timeout: 1min (wskazówka wodomierza może zatrzymać się pod czujnikiem i impuls może trwać godzinami).

sensor:
  - platform: pulse_meter
    name: "Przepływ wody"
    pin:
      number: GPIO5
#      inverted: true 
      mode:
        input: true
        pullup: true
    internal_filter_mode: PULSE
    unit_of_measurement: "l/min."
    accuracy_decimals: 0
    icon: "mdi:gauge"
    internal_filter: 100ms
    timeout: 1min
    total:
      id: water_usage_total
      name: "Woda zużycie total"
      icon: "mdi:water"
      unit_of_measurement: "m³"
      accuracy_decimals: 3
      device_class: water
      state_class: total_increasing
      filters:
        - multiply: 0.001

Jeśli bezpośrednio, to musisz wiedzieć czy tak możesz. Na dodatek nie użyłeś dla GPIO wewnętrznego pullup: true i input: true.

A podstawa to ustalenie jak prawidłowo można się podłączyć pod te wyjście impulsowe tego licznika, co jest elementem wykonawczym na tym wyjściu.

Tym bardziej powinieneś korzystać z oficjalnej dokumentacji, a nie przypadkowych zlepkach informacji, z przypadkowych źródeł wklejając kod bez zrozumienia. Zamiast tracić bliżej nieokreślony czas na próby, mając nadzieję, że się uda, lepiej poświęcić go na zrozumienie jak to działa.

2 polubienia

Potestowałem przez tydzień, sprawdzałem pobieranie impulsów za pomocą pulse_meter, pulse_counter, binary_sensor, próbowałem to jakoś dopasować i uzyskałem taki efekt


za pomocą:

sensor:
  # Licznik impulsów na minutę
  - platform: pulse_counter
    pin:
      number: GPIO4
      mode: INPUT_PULLUP
    name: "Impulsy na minutę"
    id: impulsy_na_minute
    unit_of_measurement: "imp/min"
    update_interval: 30s
    internal_filter: 13us 
  
  - platform: template
    name: "Moc1 (W)"
    id: moc_sensor1
    unit_of_measurement: "W"
    accuracy_decimals: 1
    lambda: |-
      return id(impulsy_na_minute).state * 30;
    update_interval: 30s    

  # Obliczanie energii w kWh
  - platform: total_daily_energy
    name: "Zużycie energii (kWh)"
    power_id: moc_sensor1
    unit_of_measurement: "kWh"
    accuracy_decimals: 3
    filters:
      - multiply: 0.001  # Konwersja z Wh na kWh
    state_class: total_increasing

Jak widać po mnożniku ESP32 zlicza mi impulsy podwójnie, ale stabilnie to co liczy ESP zgadza się z tym co pokazuje licznik. Wejście beznapięciowe NO podłaczyłem rezystorem 10k z 3,3V do gpio i włączyłem mode: INPUT_PULLUP (sprawdzałem z miernikiem) i pomimo że to teoretycznie to samo to takie podwójne połączenie mi działa.

Jak najlepiej takie beznapięciowe NO podłączyć do gpio i oprogramować żeby nie liczyło podwójnie?

Czy można bezproblemowo wykorzystać inne wolne gpio na tym ESP32 do podłączenia termometrów np. na DS18B20

To nie jest teoretycznie to samo. Masz teraz zdublowany pullup - jeden którym jest fizyczny rezystor, a drugi którym jest źródło prądowe wewnątrz MCU, ich prąd jakoś-tam się sumuje. W dużym uproszczeniu to jest sytuacja taka jakbyś podłączył 2 rezystory równolegle do zasilania.
Jeśli wartość rezystora 10k jest za duża, to wystarczy dobrać odpowiednio mniejszą (kierując się datasheetem, rozsądkiem i najlepiej realnymi pomiarami, zwykle nie powinna być mniejsza niż 1k więc warto wypróbować np. 2k2, 3k3, 4k7 i 6k8 tylko idąc od końca).

1 polubienie

Dzięki, popróbuję. Mierzyłem i przy wyłączonym pullup nie było napięcia na gpio a przy włączonym się pojawiało, ale nie działo idealnie dużo impulsów było gubionych. Wyłączę pullup i dam mniejsza rezystancję.

Tak się przyglądam - po czym kol. wnioskuje, że liczy podwójnie?

Po tym że w instrukcji licznika jest podane 1000 impulsów/kWh. Również obserwacja diody na to wskazuje, tak samo jak liczydło z licznika i ilość zliczonych impulsów na wyjściu NO. Licznik to SDM72Bi. Na razie działa dobrze z tym kodem co załączyłem, wartości zliczane ESP32 w homeassistant zgadzają się z tym co podaje licznik na swoim wyświetlaczu i widać już wyraźnie że to co podaje PC w swojej apce (i w homeassistant) to jest liczone dobrze, ale tylko dla spręzarki, grzałki CWU i grzałki CO, notomiast nie zlicza zużycia energii elektroniki (7W) i podgrzewania tacy ociekowej i grzałki oleju (200W) przy ujemnych temperaturach.

1 polubienie

Zrób właściwą konwersję jednostek i poruszaj się w spójnych jednostkach .

Mierzysz co 30sek, więc w jednostkach/minutę energii powinno być 2* więcej.
W tym miejscu energię odczytaną z licznika masz w jednostkach kWh aby było spójnie (wyrażone w minutach) gdzieś powinieneś wyrównać [kWh/60] = [kWmin]
np. w tej lambdzie.

Najlepiej (skoro używasz interwału 30s) przelicz to na kWsek.
Jeśli przekształcisz to na papierze to otrzymasz właściwy współczynnik dla lambdy mocy.

`return id(impulsy_na_minute).state * współczynnik;`

Przestań kombinować z rezystorami i GPIO, bo problem leży w matematyce.
Już kiedyś to było napisane: zmierzoną energię przeliczamy na moc , żeby następnie wyliczyć energię. :exploding_head:

Na próbę zmień interwał obliczeń na 60sek i sprawdź poprawność, ponieważ 60sek a 30 to dokładnie *2