
Choć na chwilę obecną to w zasadzie inteligentne oświetlenie + zestawy różnej maści czujników, acz pełznie we właściwą stronę.
1. Wstęp i motywacja
Jakiś czas temu stworzyłem dwa projekty. Pierwszy - stacja meteo -> https://www.elektroda.pl/rtvforum/topic3165735.html, który w ciągu miesiąca albo dwóch będzie miał już chyba 11 inkarnację elektroniki (do tej pory poza zbieraniem danych ze stacji, posłużył także do dodania funkcji sieciowych do SmartUPS SC620). Drugi -> https://www.elektroda.pl/rtvforum/topic3255866.html - sterownik do kuchennych LEDów, czy w ogóle LEDów mający port RS485. Port do tej pory nie był wykorzystywany, ale w zasadzie co stoi na przeszkodzie aby usunąć czujnik oświetlenia zewnętrznego i karmić sterownik danymi oświetlenia ze stacji meteo na balkonie?

2. Stare problemy i nowe moduły
Sterownik w zasadzie działa poprawnie, jedyny mankament projektowy jaki się ujawnił to wzbudzający się losowo (a tak na prawdę wraz z uruchomieniem agregatu lodówki) czujniki PIR, ot ktoś pomyślał sobie, że jak nie da przy zmieniaczu poziomów (?) (level shifter), od strony czujnika PIR rezystorów ustalających stan/podciągających do zasilania to nic się nie stanie... stało się, PIR działający w oparciu o przerwania był straszliwie podatny na wszystkie zakłócenia, ale to nic czego nie dało by się rozwiązać zmianami w sofcie.
Gdzieś po drodze zachciało mi się bawić STM32F030, a że jakoś nie pałam miłością do zestawów prototypowych/startowych to zrobiłem sobie coś, co jest oparte o w/w a ma jakieś konkretne zastosowanie - zbiera dane. Moduły nie są jakoś szczególnie ciekawe, ani skomplikowane, projekt PCB (jak zawsze) wykonany "z palca", nie ma schematu. Każdy ma wyprowadzone 4 porty analogowe, TIM3 (PWM), I2C, SPI, 1-Wire, kilka luźnych GPIO i właśnie port RS485 oparty o ST3485. A, że ja najwyraźniej nie mogę żyć bez przeprojektowania czegoś, a w szafie leżą Si4455 (które kiedyś dostałem od kolegi, bo mieli wolne), powstał projekt bardzo zbliżonych funkcjonalnie modułów z usuniętym wyprowadzeniem SPI i luźnymi GPIO, ale za to z komunikacją radiową @868MHz i EEPROMem, ale to myślę jest temat na osobny temat, jak już powstaną i zadziałają.


Moduły składają się z 2 części, właściwej i dodatkowej, zawierającej dwa gniazda RJ45, dwa ledy, mostek prostowniczy i złączki.


Idea była taka, aby właściwa część była na ile to możliwe kompaktowa, co by się dało ją upchnąć w małej przestrzeni (nie wiem czemu wyszła większa niż puszka elektryczna). A w razie dostępności większej ilości przestrzeni można skorzystać z pełnej wersji dla łatwiejszej zabawy nimi. Elektrycznie moduły nie używają pary numer 1, zostanie do wykorzystania w przyszłości. Para numer dwa obsługuje komunikację po wspomnianym wcześniej RS485, para 3 i 4 przesyła zasilanie o dowolnej polaryzacji i napięciu 12V. Schemat połączeń jest kompatybilny z dość popularnym pasywnym PoE, dzięki czemu do zasilania wszystkiego (poza modułem LEDów) nadaje się "wstrzykiwacz", który został zaprojektowany dla stacji meteo:


A który przy okazji umożliwił zasilanie jednym zasilaczem laptopowym dużej części drobnicy elektronicznej, jaka się po domu pałęta (switch, access point, ładowarki telefonów, czujniki różne). Oszczędność na gniazdkach, poza tym wygodniej.
3. Topologia sieci
Ale to wszystko musi jakoś ze sobą rozmawiać. Magistrala RS485 jest rozpięta na konkretne pomieszczenie. Każde, które używa tego schematu czujników ma swoją własną magistralę, także jak jakieś urządzenie widzi inne bezpośrednio to wie, że jest w jego pomieszczeniu, mniej konfiguracji. Wspomniana wyżej 11 inkarnacja elektroniki stacji ma także inne zastosowania, bo poza tym że obsługuje czujniki i wymienia dane z serwerem to ma też transciver RS485, co pozwala jej na zachowywanie się jak bramka dla danego pomieszczenia. Urządzenia wpięte do RS485 na ogół bawią się we własnym sosie, w większości wypadków nie muszą wiedzieć co się dzieje na zewnątrz pomieszczenia. Dla wszystkich innych wypadków albo bramka przyśle im jakieś zdarzenie albo same mogą ją odpytać o jakiś czujnik poza ich bezpośrednim polem widzenia.

Bramka, duże to, ale w sumie mam na szczęście opcje ukrywania ich chociażby za lodówką.
4. Protokół
Protokół, czyli coś dla czego głównie stworzyłem wpis, ot może ktoś zauważy coś co udało mi się w nim przegapić.

Większość protokołów rozmawiających po RS485 ma naturę master-slave. Moim zdaniem w tego typu zastosowaniach to mało wygodne. Jeśli zniknie z jakiegoś powodu master, wszystko przestanie działać. A tak mogę sobie odpiąć z magistrali bramkę, czy dowolny inny element, a reszta na ile to możliwe dalej funkcjonować.
Każdy moduł ma swój 32bit adres, przypadkiem pokrywa się to z wielkością crc32. (STM ma sprzętowy moduł, można sobie tak wygenerować unikalne adresy z UID mikrokontrolera).
Urządzenia komunikują się za pomocą pakietów, pakiety są skonstruowane podobnie do ramek ethernetu w połączeniu z elementami UDP.
Każda ramka poprzedzona jest preambułą (4 znaki) 0x55 i pole oznaczającym start ramki. Potem idzie nagłówek:
Code: C
to/from - wiadomo. Adresy 00000000 i FFFFFFFF są zarezerwowane, drugi oznacza "broadcast". Długość ramki ograniczona jest w protokole do 64k, ale praktycznie wartością ograniczającą jest wielkość bufora do którego trzeba upchnąć odbierane dane, a ta jest różna w zależności od sprzętu i trybu. Przykładowo aplikacja główna ma RX: 128, TX: 512 a bootloader: RX:786 TX:128. Bramka z racji na spory zapas pamięci mogłaby spokojnie wymieniać pełne ramki ethernetu razem z siecią RS.
protoType - protokół jaki został opakowany w ramkę. Zastosowanie mają obecnie dwa, jeden identyczny z tym, jakiego używa stacja meteo, a drugi to TFTP (o czym za chwilę). Dało by się nawet zrobic routing IP, na ile to ma sens.
flags - na przyszłość
seq - jeśli to pole ma wartość zero, pakiet nie wymaga potwierdzenia. Zaraz po wysłaniu jest kasowany z kolejki, nie ma tutaj znaczenia czy gdzieś dotarł czy nie, ot nie jest to aż tak ważna informacja. Jeśli jest ustawione, nadawca czeka ~20ms na potwierdzenie dostarczenia, jeśli go nie otrzyma ponawia kilkukrotnie transmisje. Jeśli je dostanie kasuje ramkę z bufora, jeśli nie - zgłasza "timeout". Broadcasty z zasady nie są potwierdzane.
len - raczej wiadome.
Następnie idą dane i 32bit suma kontrolna, crc32.
Po co taka przestrzeń adresowa - bo adresy są stałe, niekonfigurowalne i unikalne. Wystarczy wpiąć, wysłać broadcast, który zainteresuje wszystkich i mamy listę tego co jest wpięte. Całość działa z prędkością nieco poniżej 1Mbps.
Każdy moduł ma uruchomiony timer pracujący z częstotliwością 100Hz, raczej nie ma opcji aby zegary były w nich zsynchronizowane, więc mamy jako taką losowość czasu podjęcia transmisji zapewnioną na tym etapie. Ponadto transmisja nie zostanie rozpoczęta jeśli właśnie trwa odbiór jakiejś ramki i nie został zakończony, a także jeśli sprzęt wykryje bit startu na linii (plus dla F030 za taką informację*). F103 nie ma takiego sprytnego USARTa, więc sprawdzenie stanu linii przed wysyłką odbywa się przez sprawdzenie stanu pinu TX (porty pracują w half-dupleksie) jeśli jest wysoki - można coś nadać, jeśli nie - transmisja czeka 10ms na kolejny slot. Metoda wykrywania zajętości linii w wypadku F103 nie jest idealna, a z braku lepszej alternatywy (flagi BUSY), ale na ogół działa. Testy pokazały, że przynajmniej ST3485 dobrze tolerują kolizje, żaden się przy ich celowym, cyklicznym wywoływaniu nie spalił, także myślę że przy w/w metodach ich unikania wszystko powinno działać sprawnie przez długi czas.
* z drugiej strony, jak wspomniałem w F103 można sobie sprawdzić stan GPIO podłączonego do USARTu, co nie jest idealne bo możemy trafić akurat między bity, ale w F030 IDR takiego GPIO zawsze pokazuje zero.
Po co ten TFTP - każdy moduł ma złącze SWD, raczej wiadomo po co. Ale poza złączem ma także 7kB bootloader obsługujący programowanie protokołem TFTP. Akurat tym, bo stacja meteo ma taki. Także jeśli w danej sieci istnieje bramka ethernetowa, to istnieje możliwość aktualizacji firmware o ile znany jest adres modułu i bramki**:

** - A adres modułu w sieci RS485 jest częścią niektórych UIDów czujników.
Operacja trwa kilka sekund. Minus jest taki, że jak się załaduje niewłaściwy firmware to trzeba się pofatygować z programatorem do modułu, bo bootloader sam z siebie się nie włącza. Dla kompatybilności (i wygody) bramka od strony sieci eth zachowuje się jak typowy moduł swojej klasy, tj po uruchomieniu wykrywa co ma podłączone po stronie RS'a i o ile tamtejsze moduły mają na sobie jakieś czujniki, to dodaje je do listy swoich czujników, każdy czujnik ma 64bit unikalny ID, akurat taki długi bo 1-Wire/DS18B20 mają tego typu adresy.

Całość działa w tej konfiguracji od paru dni i współczynnik kolizji/zgubionych pakietów/błędów CRC nie przekracza 0.5%. Przy czym czujniki odpytywane sa o nowe dane co 5s (przez bramkę eth i sterownik led), a moduł podłączony do PIR (HC-SR501) wysyła zdarzenia jak tylko się pojawią, czyli natychmiast po wykryciu ruchu. Wszystkie zdarzenia przekazywane są przez bramkę do serwera, na którym siedzi sobie software logujący co bardziej interesujące rzeczy. I tak oto LEDy w kuchni (a później w przedpokoju) mogą korzystać z danych z czujnika wystawionego za oknem, a jakby się uprzeć, to czujki ruchu sterujące oświetleniem można spiąć w system alarmowy.
A do tego prawie działająca (bo poza odpytaniem czujników to za wiele nie potrafi) aplikacja androidowa:





Cool? Ranking DIY