
Witajcie moi drodzy.
Pokażę tu wnętrze inteligentnego gniazda Tuya LSPA9 które oferuje pomiar zużytej energii elektrycznej oraz sterowanie przez WiFi, a następnie omówię jego wewnętrzny protokół komunikacji z układem scalonym mierzącym energię elektryczną. Następnie pokażę jak zaimplementowałem jego wsparcie w moim firmware w języku C i omówię krok po kroku łączenie tego gniazda z Home Assistant przy użyciu mojego OpenBeken, jako że korzysta ono z modułu CB2S czyli BK7231N. Na koniec również opiszę jak dokonać w nim kalibracji takiego gniazda, która jest niezbędna do otrzymywania sensownych wyników.
Powiązane tematy
Recenzja gniazda mierzącego energię produkcji BlitzWolf z pełnym omówieniem oryginalnej aplikacji producenta (bez zabaw z C i zmianą firmware):
https://www.elektroda.pl/rtvforum/topic3687040.html
Temat ogólnie o moim firmware dla BK7231:
https://www.elektroda.pl/rtvforum/topic3866123.html
Temat o Home Assistant:
https://www.elektroda.pl/rtvforum/topic3777098.html
Tematy o wgrywaniu OpenBK na inne produkty:
https://www.elektroda.pl/rtvforum/topic3875654.html
https://www.elektroda.pl/rtvforum/topic3880540.html
https://www.elektroda.pl/rtvforum/topic3874289.html
Repozytorium mojego wsadu:
https://github.com/openshwprojects/OpenBK7231T_App
Zakup gniazda LSPA9 EU
Gniazdo znalazłem pod hasłem LSPA9 EU Smart Plug WiFi Smart Outlet Socket Voice Control Works for Alexa, za całość zapłaciłem około 17$ (14$ produkt + VAT, przesyłka):


Gniazdo działa normalnie z aplikacją Tuya, ale ją testowałem już w innych tematach w tym dziale:

Tym razem nie było wysyłki z Czech a transport trwał naprawdę bardzo długo. Chyba ponad miesiąc. Na szczęście obyło się bez dopłat.
Paczka nadana niby z Wiązowna (FASTPRO), ale wiadomo, że to był tylko mały ułamek jej drogi.

Na opakowaniu jest tylko naklejona naklejka z modelem produktu (LSPA9), gdyby nie ona, to nie byłoby wiadomo jakie to gniazdo:





W zestawie jest gniazdo i instrukcja:




Wnętrze LSPA9 EU
Jakiekolwiek testy z aplikacją producenta pominąłem. To już omawiałem w innych tematach.
Do środka jest ciężko się dostać, nieco popsułem przy tym obudowę.
Trzeba podważyć od górnej krawędzi:


Wyłania się moduł CB2S:


CB2S - czyli moduł WiFi zrealizowany w oparciu o BK7231N. Wspierany przez OpenB7231N.


Oprócz tego widać układ pomiaru energii - BL0942, stabilizator LDO 3.3V AMS1117-3.3 (bo układ zasilacza dostarcza 12V by móc sterować przekaźnikiem, a moduł WiFi wymaga 3.3V), tranzystory J3Y (do załączania przekaźnika):

Z kolei sam zasilacz (beztransformatorowy!) zrealizowany jest na BP2525. Nie pierwszy raz spotykam ten układ w urządzeniu smart.

Ten wielki rezystor to zapewne rezystor bezpiecznikowy. Oprócz tego ochrona wejścia jest słaba, żadnego warystora tu nie widzę...
Przekaźnik jest od spodu:


Krótka analiza płytki za pomocą multilmetru już nam mówi, co tu się dzieje.
Jest to standardowe gniazdo smart, przy czym BL0942 podłączony jest poprzez UART do CB2S. BL0942 oferuje też tryb SPI, ale nie jest on tu używany. A szkoda, bo ten sam port UART z CB2S jest używany przy aktualizacji firmware - czy będzie z tym problem?


Wgrywanie własnego wsadu - OpenBK7231N - część 1
Analogicznie jak w poprzednich tematach z serii:
Qiachip Smart Switch - BK7231N/CB2S - wnętrze, programowanie
'Żarówka' LED WiFi RGBCW Tuya - wnętrze, programowanie, BK7231N
Ogrodowy podwójny przekaźnik Tuya CCWFIO232PK - BK7231T - programowanie
Lutowanie kabelków do RX/TX oraz CEN:


Lutowanie kabelków przed LDO (tak, by na wejściu AMS1117 podać 5V z USB):

Ale na tym etapie przerwałem, gdyż najpierw chciałem podejrzeć swoim konwerterem UART komunikację CB2S z BL0942.
Komunikacja z BL0942
Z noty katalogowej BL0942 wynika, że używany jest baud 4200.
Zobaczmy jakie pakiety przy tym baud udało mi się przechwycić.
Wysyłane przez CB2S:

Wysyłane przez BL0942:

Czyli host wysyła dwa bajty, zawsze takie same (nawet bez CRC?), w formie zapytania o pomiary a BL0942 odpowiada wynikami pomiarów.
Nagłówek 0x55 kojarzy mi się z TuyaMCU, ale to nie jest protokół TuyaMCU.
Można by tu zgadywać jego zawartość, ale mamy przecież notę katalogową.

Adnotacja {0,1,0,1,1,0,A2,A1} świadczy o tym, że układ wspiera podłączenie kilku sztuk (czterech, na tyle adresów pozwalają dwa bity adresowe) na jedną magistralę UART. Działa to tak, że wszystkie cztery układy nasłuchują wywołania, a odpowiada na nie tylko ten, którego adres jest w tym wywolaniu zawarty.
W naszym gnieździe jest jednak pojedynczy układ, więc nie ma problemu.
Wyniki pomiarów w pakiecie są rozbite na osobne bajty. Każdy z nich jest liczba trzybajtową. Mierzone są m.in. wartości RMS, częstotliwośc, moc.
Jest też jednobajtowa suma kontrolna (checksum), służąca wykrywaniu ewentualnych błędów transmisji. Suma kontrolna liczona jest z pozostałych bajtów pakietu, jej wartośc przy nadaniu umieszczana jest na końcu pakietu. Jeśli przy odebraniu policzymy wartośc sumy kontrolnej i będzie ona inna niż ta, którą umieścił na końcu pakietu nadawca, to wiemy, że zawartośc takiego pakietu uległa zmianie (zakłóceniu) i należy go odrzucic.
W celu weryfikacji wzoru na sumę kontrolną napisałem program:
Code: c
Uruchamianie tego na Windowsie pozwoliło mi szybko zweryfikować czy obliczenia są wykonywane poprawnie.
Reszty implementacji dokonałem w swoim OpenBK:
https://github.com/openshwprojects/OpenBK7231T_App/
Mam już przygotowany system UART wraz z odbiorczym buforem kołowym, który omawiałem tutaj.
Nadanie zapytania o pomiar jest proste:
Code: c
Odbiór zrealizowałem podobnie tak jak w przypadku TuyaMCU. Regularnie sprawdzam, czy w buforze kołowym jest ilość bajtów nie mniejsza, niż długość oczekiwanego pakietu. Dodatkowo wiem, że nagłówek pakietu to zawsze 0x55, więc jak jest pierwszy inny bajt, to go pomijam.
Code: c
Następnie wiem, że odebrany został już cały pakiet, więc sprawdzam jego sumę kontrolną.
Code: c
Jeśli suma kontrolna jest błędna, to pomijam pakiet -UART_ConsumeBytes(BL0942_PACKET_LEN).
Teraz pora wydobyć z niego pomiary. Musimy połączyć osobne bajty w czterobajtową liczę całkowitą (są tu trzy bajty, ale na tej platformie integer ma 4 bajty). UWAGA: uzyskana liczba będzie musiała zostać jeszcze przetworzona, o tym później.
Code: c
Operator << to przesunięcie bitowe, a | to suma logiczna.
Uzyskana liczba będzie typu 3569180. Daleko jej do 230V.
Trzeb będzie ją podzielić przez stałą, która różni się nieco między konkretnymi sztukami gniazd i służy do kalibracji.
Skąd wziąć wartość stałej?
Mierzymy rzetelnym multimetrem napięcie i dzielimy na nie uzyskane raw_unscaled_voltage.
Mimo to, mogę z góry podać, że wartości stałych będą mniej więcej takie:
Code: c
Obliczenie finalnych pomiarów:
Code: c
Gotowe.
Uzupełnienie i implementacja
Kalibracja w OpenBK wykonywana jest poprzez system komend. Zmierzone wartości podajemy komendami a system sam liczy i wyświetla BL0942_PREF, BL0942_UREF, BL0942_IREF.
Code: c
Analogicznie dla prądu i mocy.
Wgrywanie własnego wsadu - OpenBK7231N - część 2
Przy pierwszym wgrywaniu wsadu na to gniazdo odlutowałem BL0942, gdyż bałem się konfliktu na UART:

Oryginalny wsad Tuya od razu wykrył brak BL:

Cały "programator":


Wgrywanie:

Na tym etapie restartowałem moduł krótkim zwarciem CEN do masy (naprawdę krótkim, nie udaje się to za pierwszym razem).


Potem przylutowałem BL0942 i z ciekawości sprawdziłem, czy też uda się wgrać wsad - bez problemów. Najwyraźniej różnica baud rate oraz unikalny sposób wywołania BL0942 sprawił, że ten nie nadawał nic w trakcie programowania.
Ale i tak warto było odlutować BL, chociażby by prześledzić ścieżki.
Dalszych aktualizacji softu dokonywałem przez OTA (over the air, przez Wifi).
Role pinów (czyli gdzie jest podłączony przekaźnik, a gdzie przycisk):

Kalibracja BL0942 w OpenBeken
Tą operację powinien wykonać każdy użytkownik OpenBeken na urządzeniach z pomiarem energii!
Operacja jest analogiczna do kalibracji takiego gniazdka w Tasmocie, nawet komendy są podobne.
Bez tej operacji pomiary będą się różnić od rzeczywistych, być może nawet w dużym stopniu.
Zakładam, że mamy już wgrane OpenBeken na nasze urządzenie.
Uruchamiamy sterownik BL0942, komenda:
startDriver BL0942
Najwygodniej jest wpisać ją poprzez nakładkę wizualną-panel javascript, tutaj:

Od tego momentu powinny nam pokazywać się na głównej stronie pomiary z BL0942.
Pomiary wyłączonym przekaźnikiem, bez kalibracji:

To napięcie jest zawyżone.
Pomiary z żarówką 60W, bez kalibracji:

Trzeba dokonać kalibracji - bierzemy jakiś rzetelny miernik i spisujemy ile rzeczywiście pobiera mocy i prądu żarówka, spisujemy też napięcie:


Podłączamy z powrotem tę samą żarówkę do gniazda z OpenBeken (to niezwykle ważne i gniazdo musi być włączone w ten czas!).
Teraz, w linii komend, wpisujemy komendy VoltageSet [poprawneNapięcieV], CurrentSet [poprawnyPrądA] i PowerSet [poprawnaMocW], jednocześnie zapisując odpowiedzi systemu:

Odpowiedź od systemu:

Zapisujemy sobie w notatniku, że VREF = 15987.125000
Analogicznie wykonujemy dla pozostałych komend.
PREF = -683.023987
IREF = 272302.687500
Odświeżamy stronę:

Weryfikacja z obciążeniem rezystancyjnym:

Obciążenie rezystancyjne to po prostu rezystor, którego opór znam. W tym przypadku współczynnik mocy wynosi 1 i można policzyć z napięcia oczekiwany prąd i moc jaka się wydzieli.
Teraz pora zapisać konfigurację i współczynniki kalibracji.
startDriver BL0942
VREF 15987.125000
PREF -683.023987
IREF 272302.687500
To są komendy w pełni konfigurujące nasze BL0942.
Nie chcemy jednak wpisywać ich ręcznie z każdym rozruchem urządzenia.
W tym celu zapisujemy u nas na komputerze jako autoexec.bat, a potem przeciągamy w panelu App OpenBK tutaj:

W ten sposób zapisujemy to jako plik w pamięci OpenBK, w systemie plików LittleFS.
Można też sprawdzić, czy plik potem jest poprawnie listowany i wyświetlany.
Od tego momentu konfiguracja już siedzi w pamięci. Będzie pamiętana po uruchomieniu ponownie urządzenia.
UWAGA: Jakiekolwiek OTA czyści system plików - to dlatego, że system plików korzysta z tej samej sekcji flash co OTA. Dlatego polecam trzymać kopie naszych konfiguracji w postaci zwykłych plików na naszym komputerze.
Alternatywa dla LittleFS
Dla krótkich komend (do 512 znaków) system oferuje też alternatywę dla LittleFS. Można je ustawić jako "short startup command", wtedy trzymane są one razem z konfiguracją pinów w pamięći flash. Do użycia kilku komend należy tam użyć dyrektywy Backlog z komendami oddzielonymi średnikami.
Startup command ustawiamy tutaj:

Komenda ta wykonuje się automatycznie na starcie urządzenia (za wyjątkiem trybu "safe mode", uruchamianego poprzez kilkukrotne włączenie i wyłączenie urządzenia bądź na skutek dokonania kilku niepełnych rozruchów pod rząd (pełny rozruch zaliczany jest gdy urządzenie się włączy i popracuje 30 sekund) - "safe mode" służy do ewentualnego odratowania urządzenia które zawiesza się na skutek złej konfiguracji.
Parowanie z Home Assistant
Teraz jeszcze trzeba jakoś przekazać wyniki pomiarów do HA poprzez MQTT.
Najpierw podajemy namiary na HA w ustawieniach, w Config->MQTT, tak jak w przypadku innych urządzeń.
Potem z Config->Generate Home Assistant Config pobieramy nazwę wewnętrzną urządzenia, przykładowo obk0696FB33.
Sama konfiguracja dla configuration.yaml będzie nieco inna.
Poniżej umieszczam przykład:
sensor:
- platform: mqtt
name: "BL0942 Voltage"
state_topic: "obk0696FB33/voltage/get"
unit_of_measurement: "V"
- platform: mqtt
name: "BL0942 Current"
state_topic: "obk0696FB33/current/get"
unit_of_measurement: "A"
- platform: mqtt
name: "BL0942 Power"
state_topic: "obk0696FB33/power/get"
unit_of_measurement: "W"
Kod powyżej konfiguruje tylko odczyt pomiarów. Osobno musimy dodać sterowanie przekaźnikiem z tego urządzenia - do bloku "switch", ale to tak jak zawsze, pokazywałem to w poprzednich tematach z serii o OpenBeken.
Po zmianie konfiguracji restartujemy HA. Od tego momentu nasz Home Assistant będzie już zbierać dane na wykresach:

To jest zużycie energii przez laptopa w trybie normalnym pracy.

Czy "Oszczędzanie energii" coś zmieni?

Nie oszczędza to dużo mocy. A w trybie "Wysoka wydajność"?

Po jakimś czasie:

Napięcie:

O dziwo mój Brymen BM857s to potwierdza. Spadło o te kilka V napięcie. Czyli pomiar jest precyzyjny.
Dodatkowe testy i ponowna kalibracja
Jeśli nie jesteśmy zadowoleni z dokładności pomiarów, to możemy dokonać kalibracji w nieco bardziej rzetelny sposób. Przykładowo można skorzystać z obciążenia o charakterze w pełni rezystancyjnym. Wtedy współczynnik mocy wynosi 1 i obliczenia się uproszczają, można prosto policzyć ze zmierzonej rezystancji i napięcia oczekiwaną moc, itd. Mam do tego przygotowany rezystor:



Podsumowanie
Tym razem było nieco trudniej, bo musiałem zaimplementować komunikację z BL0942, by te gniazdo w pełni obsłużyć, ale szczęście informacje o protokole oraz nota katalogowa użytego układu były dostępne w sieci, więc wszystko poszło bez większych trudności. Ręczna kalibracja BL0942 jest tu niezbędna, ale po jej wykonaniu gniazdo mierzy poprawnie a wyniki są też wyświetlane na naszym panelu Home Assistant, którzy tworzy z nich wykresy pokazujące zużycie energii w czasie.
Jeśli chodzi o dokładność pomiarów, to dla mnie jest zadowalająca. Nawet wahania napięcia o te 4V się zgadzają. Moce mierzone są nawet do 0.5W (sprawdziłem poprzez wpięcie smart "żarówki" która tyle pobiera w standby i potwierdziłem też drugim miernikiem).
Samo wgrywanie wsadu jest proste - BL0942 nie zakłóca nam linii UART przy programowaniu, wystarczy więc przylutować przewody. A być może wkrótce i tuya-cloudcutter będzie to gniazdo wspierać, więc potrzeba lutowania zniknie i będziemy wgrywać wsad zdalnie...
Cool? Ranking DIY