sobota, 7 kwietnia 2018

ESP8266 i dekodowanie stałych kodów 433 MHz

Miałem zamiar ponarzekać na oprogramowanie SONOFF RF Bridge ale już mi przeszło. Nie ma na co! Do świetnego sprzętu dostajemy oprogramowanie realizujące podstawowe funkcje routera. Mała liczba pamiętanych kodów? Ograniczona liczba współpracujących urządzeń? No to co. Dla większości użytkowników Bridge będzie i tak znakomitym rozwiązaniem. Szybko i skutecznie połączy bezprzewodowe urządzenia hasające do tych por samopas. A jak komu mało -  kupi następny SONOFF za 40 zł lub nawet dwa. I ciągle będzie to nieprawdopodobnie tanio. Fani Domoticza, RodeNet czy BLYNKa zawsze będą narzekać na fabryczny firmware. Ale dla nich producent  przygotował urządzenie tak by nadawało się do dalszych modyfikacji. SONOFF dla DIY - po polsku SLZ (Sobie Lepiej Zrobię) to przykład wręcz modelowy. Miast więc narzekać wystarczy wydusić z SONOFFa wszystko co potrzeba. Ale najpierw trzeba umieć zobaczyć to co niewidzialne.
Można wymyślić cały szereg funkcji Routera 433. Można ale i tak najważniejszymi pozostaną - bezbłędny odbiór kodów i sprawne ich nadawanie. Reszta to nieistotne dodatki. Jak widać po SONOFFie nie jest to wcale banalna sprawa. Temat dekodowania stałych kodów bezprzewodowych urządzeń pracujących w paśmie 433 MHz jest wałkowany w środowisku ARDUINO od wielu lat. Ale tak naprawdę istnieje tylko jedna poważna biblioteka obsługująca kompleksowo te funkcje.

RCswitch autorstwa  Suat Özgür (sui77) jest nie do pobicia. I jako jedyna działa poprawnie na  ESP8266 i ESP32. Co więcej - jest wciąż rozwijana. Jest więc oczywistą oczywistością, że stanowi ona kręgosłup mojego routera.

Protokołów stałych kodów jest dużo. Jak mówi spiskowa teoria - to celowa polityka producentów  sprzętu. Poza "klasycznymi" typami kodów związanymi obsługującymi je scalakami jak:

SC5262 / SC5272 /HX2262 / HX2272 / PT2262 / PT2272 / EV1527 / RT1527 / FP1527 / HS1527

istnieje cały szereg nienazwanych kodów zaimplementowanych w różne bezprzewodowe gadżety. Wszystkie one w jakimś stopniu bazują na kodzie Manchester. I we wszystkich są zakodowane zera i jedynki a w niektórych nawet cztery stany. Ponadto zawsze występują w nich sygnały synchronizacji pozwalające określić początek i długość transmisji. Rodzaj sygnału określany jest długością trwania następujących po sobie stanów niskich i wysokich.Klasyczny wykres transmitowanego kodu wygląda mniej więcej tak


Jak w tym się połapać?
Nie ma potrzeby jeśli biblioteka rozpoznaje kod. Gorzej gdy kod nie mieści się w standardzie - pozostaje próbować zmodyfikować bibliotekę a wtedy reguły dekodowania transmisji mogą się przydać. SUI77 dostarcza sporej dawki wiedzy na temat kodów i umożliwia dodawanie własnych kodów do swojej biblioteki Tym sposobem pojawiają się kolejne klony bibliotek obejmujące coraz szersze spektrum urządzeń i protokołów np
Martin-Laclaustra
vamanea
flav1972
ESP-easy
RCSwitch_64
Nie zająłbym się głębiej tematem kodów gdyby nie bezprzewodowe dzwonki. Na potrzeby jednego z projektów potrzebowałem ładnej dźwiękowej sygnalizacji. Ładnej w znaczeniu dźwięku i obudowy. Padło więc na bezprzewodowe dzwonki idealnie spełniające oba warunki, że o cenie nie wspomnę. Niestety dopiero trzeci zakupiony dzwonek dał się zdekodować biblioteką RCswitch.
Dwa pozostałe bezużytecznie zalegały szufladę aż do teraz. Chęć ich włączenia do urządzeń obsługiwanych przez Router wymusił bliskie spotkanie trzeciego stopnia z teorią kodów 433. No to popatrzmy bliżej o co w tym wszystkim chodzi.

Dzwonek nr 1


Urządzenie firmy ...... jest rozpoznawane przez bibliotekę RCswitch dając takie oto wyniki pomiarów

Decimal: 4797521 (23Bit) Binary: 10010010011010001010001 Tri-State: not applicable PulseLength: 578 microseconds Protocol: 1

RAW data - dane do wykresu kodu: 17937,1522,463,533,1450,531,1453,1510,475,523,1459,524,1461,1506,477,522,1461,520,1463,1505,479,1505,478,518,1466,1503,479,519,1464,519,1464,518,1466,1502,482,516,1467,1503,482,516,1467,516,1468,515,1468,1501,484,

Na wykresie (zrobionym na tej stronie) początek kodu pierwszego dzwonka ma taki przebieg



Co można odczytać z surowych danych?
- długość impulsu synchronizacji ok 18000 us (pierwszy czas)
- dł. podstawowa impulsu danych coś ok 500 us (tu duża różnica z daną podawaną przez program w pozycji PulseLength = 578)
- dł drugiego impulsu danych ok 1500
- stosunek czasów 1 i 0 to 3:1 (lub 1:3 bo nie wiem co jest zerem a co jedynką)
- stosunek impulsu synchronizacji do impulsu podstawowego ok 36

Tablice protokołów kodów zawarte są w  bibliotece RCSwitch.cpp w linii 76-82. Wcześniej w komentarzach SUI77 zawarł podstawowy opis struktury typowego kodu i jego odwzorowanie do tablicy protokołów 

Zdekodowanie protokołu nr 1 w dzwonku wydaje się prawidłowe
Tablica protokołów definiuje ten kod tak 

{ 350, { 1, 31 }, { 1, 3 }, { 3, 1 }, false }, // protocol 1

co oznacza
  • długość impulsu podstawowego 350 us
  • 1 impuls HIGH i 31 impulsów  LOW synchronizacji (31 x 500  = 15500 us)
  • stosunek długości  impulsów dla 1 i 0 to 1:3 i 3:1 (lub odwrotnie)
  • kod nie ma odwróconej logiki (false) - o tym parametrze później
Poza długością impulsu - dzwonek  570 a w protokole 350 - pozostałe dane kodu są w zasadzie zgodne.  

Niestety wysyłanie kodu o  parametrach odczytanych przez bibliotekę (nr kodu 4797521 / 23bity , 578 impuls, 1 protokół) nie uruchamiało dzwonka! Dopiero wpisanie długości impulsu odczytanego z danych RAW (ok 500 us) pobudziło dzwonek Tadaaaammm! Do czegoś ta analiza kodów jednak się przydaje.

Co dziwniejsze zamiana na protokół nr 2 powodowała również uruchomienie dzwonka. A  protokół nr 2 wygląda na absolutnie różny od kodu dzwonka:

{ 650, { 1, 10 }, { 1, 2 }, { 2, 1 }, false }, // protocol 2

Wszystko ma różne za to czas impulsu jest bliższy wartości rzeczywistej dzwonka. Widać ten parametr miał istotne znaczenie w tym przypadku. 

Dzwonek nr 2


Urządzenie firmy ...... jest NIE jest rozpoznawane przez bibliotekę RCswitch SUI77.
Spróbujmy użyć klonów biblioteki podstawowej np autorstwa Martin-Laclaustra mającej rozszerzony zakres rozpoznawanych urządzeń.

Biblioteka ta jak raz pięknie czyta  kod mojego dzwonka

Decimal: 99392 (17Bit) Binary: 11000010001000000 Tri-State: not applicable PulseLength: 367 microseconds Protocol: 0
RAW data: 6596,358,1112,356,1112,355,383,1079,396,1071,396,1072,397,1070,1124,346,398,1069,395,1073,394,1073,1123,347,392,1073,396,1072,395,1072,396,1072,396,1071,397,


Wielkości wynikające z RAW data:
- długość impulsu synchronizacji ok 6600 (pierwszy czas)  
- dł. podstawowa impulsu danych coś ok 366 us - zgadza się z PulseLength = 367 
- dł drugiego impulsu danych ok 1070
- stosunek czasów 1 i 0 to 3:1 (lub 1:3 bo nie wiem co jest zerem a co jedynką)
- stosunek impulsu synchronizacji do impulsu podstawowego ok 18

a więc opis w tabeli powinien być podobny do tego

{ 366, { 1, 18 }, { 1, 3 }, { 3, 1 }, false }, // protocol 0

ale protokołu o numerze 0 w kodzie Martin-Laclaustra. po prostu nie ma. Nie ważne - ważne że kod jest rozpoznawany.

Jeszcze próba wysłania kodu o parametrach  (nr kodu 99392 / 17bity , 366 impuls, 0 protokół) i oczywiście kicha. Jak nie ma takiego protokołu to to nie ma. Protokół o numerze 0 nie istnieje - to tylko informacja dla użytkownika, że taki protokół można dołączyć do tabeli kodów na  dowolnie wybranej pozycji.
Wpisuję więc  powyższy wiersz tabeli na pozycji protokołu 1. Nadawanie ... i też kicha. Coś z nadawanym kodem jest nie tak.
Ale dla takich upierdliwców jak ja Martin przygotował Analizator Protokołu  . I wynik działania analizatora pokazuje gdzie był błąd
====
Received 99392 / 17bit Protocol: 1
data bits of pulse train duration: 24943
proposed protocol: { 367, { 18, 1 }, { 1, 3 }, { 3, 1 }, true }
====
first level down
6602 356 
1111 358 1110 357 381 1083 387 1079 389 1078 391 1077 1123 346 390 1075 
394 1073 395 1072 1128 341 397 1069 399 1069 398 1070 400 1068 398 1069 
400 1068 
====
Jest to kod z odwróconą logiką i wiersz tabeli musi wyglądać tak

{ 366, { 18, 1 }, { 1, 3 }, { 3, 1 }, true },

Czym różni się logika pozytywna od negatywnej kodu widać na poniższych wykresach - program reaguje na inne zbocze zmiany stanu.



No to jeszcze raz nowy protokół do tabeli kodów i kolejna próba wysłania informacji do dzwonka. Ciszaaa. Powtórna analiza protokołu - coś strasznie dużo powtórzeń kodu zarejestrował Analizator Protokołu  Liczę - 30 razy kod jest powtarzany. Noo nieźle. Wpisuję nową wartość do mySwitch.setRepeatTransmit(30); - standardowo jest tam wartość 4 - i kolejna proba. Dzonek werszcie się odzywa choć tylko co 2-3 raz. Dla pewności dobijam liczbę powtórzeń do 50 razy. Nareszcie dzwonek reaguje prawidłowo.  50 powtórzeń by prawidłowo zadziałało urządzenie - no tak ale nie jest to przecież typowy element domowej automatyki. Ważne że jednak zmusiłem go do pracy.

Dzwonek nr 3

To już nie dziś. Dziś należy mi się solidny odpoczynek.

A tu kilka przydatnych linków w temacie

https://github.com/sui77/rc-switch/wiki/KnowHow_LineCoding // podstawy o kodach stałych
http://tinkerman.cat/decoding-433mhz-rf-data-from-wireless-switches/ // trochę opisu o dekodowaniu
http://test.sui.li/oszi/ - // monitor online
https://github.com/Martin-Laclaustra/rc-switch // ulepszona biblioteka RCswitch
https://github.com/sui77/rc-switch/issues  // komentarze do podstawowej biblioteki RCswitch autorstwa sui77
https://github.com/sui77/rc-switch //podstawowa biblioteka RCswitch

I jak zawsze pozostaje mi tylko czekać na ewentualny ciąg dalszy....

119

Brak komentarzy:

Publikowanie komentarza