Sterowanie poprzez r485 miedzy urzadzeniami

Witam

Macie jakies doswiadczenie w sterowaniu wzajemnym miedzy urzadzeniami poprzez rs485? Wejscia jednego z nich steruja i odpytuja o stan reszte urzadzen lub kazde moze sterowac kazdym? Mam spiete po lan, moge poprzez post zmienic stan dowolnego switcha w sieci, odpytac juz nie wiem jak. Moze jest jakos sposob na sterowanie?

Dlaczego tak? W kazdym urzadzeniu mam 16 wejsc i wyjsc, mam urzadzen 4, nie chce fizycznie zmieniac kabli na wejsciach, co leca do wlacznikow. Najlepiej bylo by nadawac im funkcjonalnosc softowo, ale tak na razie moge zrobic w ramach 1 urzadzenia.

Pozdrawiam

Pisząc o RS-485 jaki masz na myśli konkretny protokół?

Nie, mam na mysli link pomiedzy urzadzeniami (mam na plycie 485 i moge je spiac ze soba), niestety wifi nie ma.

Czy to bedzie modbus czu cos innego, nie ma znaczenia, oby status encji byl mozliwy do odczytu i zapisu.

Ponieważ rs485 jest magistralą półdupleksową, musi być jedno urządzenie (master), które będzie pilnować aby na magistrali nie było konfliktów. Można zrobić taki most (master) pomiędzy rs485 a np. modbus master.

To jest tylko hardware - aby coś więcej powiedzieć trzeba wiedzieć jakiego protokołu używa.
Co znowu determinuje metodę.

…lub podejście typu czysty żywioł. Urządzenia nie mają narzuconego odgórnie Mastera. Każdy węzeł jest równouprawniony (Multi-Master).

  • Jak to działa: Urządzenie, które chce nadać swój stan, najpierw “słucha” magistrali. Jeśli linia jest wolna, natychmiast zaczyna nadawać (kto pierwszy, ten lepszy).

  • Problem kolizji: Jeśli dwa urządzenia zaczną nadawać w dokładnie tym samym ułamku sekundy, dochodzi do kolizji (dane się mieszają).

  • Rozwiązanie (Okna czasowe po kolizji): Gdy urządzenia wykryją kolizję, przerywają nadawanie. Następnie każde z nich losuje lub ma przypisane własne okno czasowe (opóźnienie), po którym spróbuje ponownie. Urządzenie z krótszym czasem opóźnienia wygrywa i zajmuje linię jako pierwsze.

2. Magistrala CAN (Controller Area Network) – “Wygrywa ważniejszy bez kolizji”

Jeśli zależy Ci na metodzie, gdzie urządzenia nadają jednocześnie, ale jedno z nich “wygrywa” bez uszkodzenia danych i bez tracenia czasu na ponowne próby, idealnym rozwiązaniem jest CAN-bus.

  • Jak to działa: Każda wiadomość ma swoje ID (priorytet). Urządzenia zaczynają nadawać w tym samym momencie (wspólne okno startowe).

  • Arbitraż bitowy: Podczas nadawania każdego bitu urządzenia jednocześnie słuchają magistrali. Stan niski (0) jest dominujący i nadpisuje stan wysoki (1). Jeśli urządzenie wysyłało “1”, ale zobaczyło na linii “0”, oznacza to, że ktoś inny wysyła ważniejszą wiadomość. Urządzenie natychmiast milknie (przegrywa), a zwycięzca kontynuuje nadawanie bez żadnych zakłóceń.

  • Uwaga: CAN wymaga dedykowanych kontrolerów (wbudowanych np. w ESP32, STM32) oraz transceiverów (np. MCP2551) zamiast MAX485.

3. TDMA (Time Division Multiple Access) – “Sztywne okna czasowe”

To metoda, w której czas na magistrali jest podzielony na idealnie równe, cykliczne okna czasowe przypisane na stałe do każdego urządzenia.

  • Jak to działa: Urządzenie 1 ma swoje 5 milisekund na nadanie stanu, potem Urządzenie 2 ma swoje 5 ms, potem Urządzenie 3 itd.

  • Zaleta: Całkowity brak kolizji i przewidywalność (determinizm).

  • Wada: Wymaga idealnej synchronizacji zegarów między mikrokontrolerami. Jeśli urządzenie nie ma nic do powiedzenia, jego okno czasowe marnuje się (magistrala milczy).


Jak to najprościej zrobić na RS-485 (Hybryda: Pseudo-TDMA + Polling)

Jeśli chcesz zachować prosty sprzęt RS-485 (MAX485), ale uniknąć fizycznych kolizji, najłatwiej zaimplementować programowe szczeliny czasowe uzależnione od ID urządzenia.

Algorytm bez Mastera (Peer-to-Peer):

  1. Wprowadzasz globalny marker czasu (np. po ciszy na linii trwającej 50 ms wszystkie urządzenia resetują swój licznik).

  2. Urządzenie o ID:1 ma okno na nadawanie od 0 do 10 ms.

  3. Urządzenie o ID:2 ma okno na nadawanie od 11 do 20 ms.

  4. Urządzenie o ID:3 ma okno od 21 do 30 ms.

Jeśli ID:1 nie ma nic do wysłania, czas mija i w 11. milisekundzie ID:2 może bezpiecznie zająć linię.

”Do wyboru, do koloru” :grin:

2 polubienia

Jak widać, protokół ma tu zasadnicze znaczenie.

Jak ze beda to wlaczniki, prawdopodobienstwo wcisniecia jednoczesnie jest znikoma.

Moge jeden z modulow zrobic master, mysle ze to nie problem, bardziej interesuje mnie jak to dziala od strony esphome.

Moga wszystkie sprawdzac zajetosc linii i jesli wolna to proba nadawania.

Okna czasowe raczej odpadaja, ciezko bedzie zsynchronizowac.

Szukalem jakiegos przykladu sterowania miedzy urzadzeniami, ciezko cos sensownego znalesc. Do kazdego id (switcha) dodaje sie cos czy tylko ze zdalnego urzadzenia wysyla sie adres + id i komende (np set czy toggle)..nie za bardzo bawilem sie 485. Przy uart okresla sie ilosc bitow i losc znakow (lub czeka na /n /r i czyta z bufora, tutaj to dziala tak samo? Wiem ze esphome dziala wyzej niz czytanie z rejestrow uart (chyba ze pisze sie scrypt ze wstawka c i tyle) i wysylam to co chce i analizuje to co oczekune sam, nie mam pomyslu jak to ugrysc.

Przydal by sie jakis przyklad takiej komunikacji, rapottowania stanu lub zmiany stanu zdalnego urzadzenia.

To jest właśnie protokół - czy to jest rs485, czy rs232, czy też uart TTL nie ma nic do rzeczy.
W zasadzie działania jest to cały czas uart. Różnica w rs485 jest taka, że nie można wysyłać i odbierać jednocześnie. W każdym przypadku do konwertera, z procesora połączone są sygnały TxD, RxD.
Jeśli chcesz to zrobić w ESPHome to wysiadam.

To po co pchasz się w uart i nie użyjesz automatyzacji HA lub MQTT ?

Podparłem się AI i otrzymałem takie cóś:
Tak, w ESPHome można używać komend URL (zapytań HTTP), ale działają one niezależnie od protokołu MQTT. Możesz to skonfigurować na dwa sposoby:

  1. Wysyłanie komend URL przez ESPHome (np. ESPHome klika w link URL, aby sterować innym urządzeniem).

  2. Odbieranie komend URL przez ESPHome (np. inne urządzenie wysyła link URL do ESPHome, aby włączyć przekaźnik).

Oto jak to zrobić w praktyce:


1. Wysyłanie komend URL z ESPHome (Klient HTTP)

Jeśli chcesz, aby naciśnięcie przycisku podłączonego do ESPHome wywołało zewnętrzny adres URL (np. webhook w zewnętrznym systemie), używasz komponentu http_request.

# Aktywacja obsługi zapytań HTTP
http_request:
  user_agent: esphome/device
  timeout: 5s

binary_sensor:
  - platform: gpio
    pin: GPIO0
    name: "Fizyczny Przycisk"
    on_press:
      then:
        # Wywołanie adresu URL po kliknięciu przycisku
        - http_request.get: "http://1192.168.1"


2. Odbieranie komend URL przez ESPHome (Serwer Web)

Jeśli chcesz sterować ESPHome, wpisując odpowiedni adres URL w przeglądarce lub wysyłając zapytanie z innego programu, musisz uruchomić na ESPHome lokalny serwer tekstowy za pomocą komponentu web_server_v2.

# Uruchomienie serwera WWW na porcie 80
web_server:
  port: 80
  version: 2

Po wgraniu tej konfiguracji ESPHome udostępnia adresy URL w formacie REST API, którymi możesz sterować urządzeniem:

Przykłady komend URL (sterowanie komponentem o id: rele):

  • Włączenie (POST): http://<IP_URZADZENIA>/switch/rele/turn_on

  • Wyłączenie (POST): http://<IP_URZADZENIA>/switch/rele/turn_off

  • Przełączenie stanu (POST): http://<IP_URZADZENIA>/switch/rele/toggle

  • Status urządzenia w formacie JSON (GET): http://<IP_URZADZENIA>/local

Uwaga: Komendy sterujące (turn_on/turn_off) wymagają wysłania zapytania metodą POST. Zwykłe wklejenie tego linku do przeglądarki (która używa metody GET) nie zadziała bez dodatkowych wtyczek lub użycia programu typu cURL / Postman.


Podsumowanie: Łączenie z MQTT

Możesz bez problemu używać MQTT oraz komend URL jednocześnie na jednym urządzeniu. ESPHome może raportować stan czujników przez MQTT, a jednocześnie reagować na komendy HTTP URL lub samemu je wysyłać.

W jaki sposób chcesz wykorzystać komendy URL? Jeśli napiszesz, czy ESPHome ma wysyłać zapytania (np. do zewnętrznego API), czy odbierać sygnały sterujące, przygotuję dla Ciebie gotowy kod YAML.

2 polubienia

Glowne zolozenie, podlaczam wlaczniki jak leci i potem zmieniam ich przeznaczenie na poszczegolne wyjscie. Mozna przez lan, ale wolalbym po rs, padnie siec i bedzie problem, rs bardziej stabilnie i nie potrzebuje dodatkowych urzadzen.

Automatyzacje robie na kincony a16, mam lan i ha, ale wole to zrobic bez ha i lanu.

Ogorlie teraz tez dziala, ale staram sie zrobic czesc swiatel niezaleznych calkowicie.

Ai tez mi podal jakis przyklad kodu z maszynka parsingu, tak jak myslalem, bufor i analoza stringa, cmd:adres: przelacznik: stan

Musze na spokojnie sprawdzic czy to zadziala

Zawsze będzie jakieś krytyczne urządzenie węzłowe, które może paść. Najbliżej Twoich oczekiwań jest KNX. W ogóle to zaczynasz od końca - na początek to rozwiąż problem kolizji na magistrali a później co i jak przesłać w telegramie. Z reguły takie telegramy zaczyna sìe od wysłania preambuły np. kilku unikatowych bajtów 0x55. Odebranie ich przez inne nasłuchujące urządzenia są sygnałem o zajętości magistrali.. itd.

1 polubienie

Tak zamierzam zrobic, sytuacja, kiedy ktos wlaczy wlacznik idealnie w tym samym czasie jest bliska zero, nawet gdyby, jak nie zadziala wcisnie drugi raz.

Master w tym wypadku jest zbedny, jedynie nasluchiwac czy leci cos w bus.

Mozna na koncu wyslac jakis kod wzolnienia, np 0x54 by urzadzenia ktore oczekuja na nadawanie dostaly info ze konoec nadawania.

Czyli ktos gada, leci 0x55 reszta czeka na zwolnienie 0x54. Proste i chyba skuteczne, urzadzenie oczekujace wysle po chwili po otrzymaniu ramki zwolnienia.

Sa tylko 4 urzadzenia wiec tloku nie ma.

Tasmota implementuje KNX od dawna.

Do tego może wykonywać automatyzacje poprzez reguły i skrypty.

W ESPHome nie ma wsparcie natywnego, jest komponent niestandardowy:

Jeśli bliżej Ci do własnego kodowania w C++ to w ESPHome możesz zautomatyzować wiele:

Urządzenia od Shelly mają wsparcie dla KNX, bodajże od gen.3

Proste ale nie skuteczne .. a co gdy z jakiegoś powodu nie odpowie 0x54 - magistrala się zatrzyma?
”Tanim mięsem” tego nie opędzisz powinieneś zrobić coś na wzór profibus i tu (bo pisaniny jest zbyt dużo):slight_smile: AI, które możesz męczyć dalej sam.

Tak, jak najbardziej. Implementacja protokołu wzorowanego na Profibus (szczególnie Profibus-DP i FMS) na układach ESP32 dla własnych urządzeń DIY jest w pełni możliwa i wręcz bardzo efektywna. ESP32 posiada ogromną zaletę sprzętową: jego kontroler UART ma wbudowany sprzętowy tryb obsługi RS-485 (UART_MODE_RS485_HALF_DUPLEX), który potrafi automatycznie sterować pinem DE/RE z mikrosekundową precyzją, eliminując błędy czasowe przełączania kierunku transmisji. [1, 2]

Kluczem do uproszczonego, “profibusowego” systemu DIY jest odtworzenie jego serca, czyli mechanizmu Token Passing (Przekazywanie Żetonu) połączonego z odpytywaniem podrzędnych urządzeń (Master-Slave).


Jak działa autorski “Mini-Profibus” (Logika systemu)

W Twojej sieci DIY nie ma jednego sztywnego Mastera. Zamiast tego tworzysz sieć typu Multi-Master / Multi-Slave.

  1. Urządzenia o wyższych mocach obliczeniowych (np. ESP32 z wyświetlaczem, główny serwer) są typu Master.

  2. Proste urządzenia (czujniki, wykonawcze) są typu Slave.

Krok 1: Krążenie Żetonu (Logical Token Ring) między Masterami

Tylko ten Master, który aktualnie posiada cyfrowy “żeton” (Token), ma prawo nadawać na magistrali RS-485.

[ MASTER 1 ] --(ma żeton)--> Odpytuje swoje Slavy -> Przekazuje żeton do M2
      ^                                                     |
      |_____________________________________________________V
[ MASTER 3 ] <----------------------------------------- [ MASTER 2 ]

  • Master 1 wykonuje swoją pracę (np. przez 20 ms).

  • Po zakończeniu wysyła specjalną, krótką ramkę: [DO_KOGO: MASTER_2][RAMKA: TOKEN].

  • Master 1 przechodzi w tryb nasłuchiwania. Master 2 odbiera żeton, staje się “właścicielem” linii i teraz on rządzi magistralą.

Krok 2: Odpytywanie urządzeń Slave przez aktualnego Mastera

Gdy dany Master posiada żeton, realizuje klasyczny cykl Profibus-DP:

  • Wysyła do podległego mu Slave_ID_5 ramkę z nowymi nastawami i jednocześnie żąda informacji zwrotnej.

  • Slave natychmiast odpowiada swoim stanem.


Co zyskujesz dzięki takiemu podejściu?

  • Całkowity brak kolizji: Ponieważ w danym ułamku sekundy tylko jedno urządzenie na całej magistrali ma prawo zacząć nadawać (właściciel żetonu), fizyczne kolizje i nakładanie się sygnałów są zredukowane do zera.

  • Elastyczność i determinizm: Każde urządzenie ma gwarancję, że w każdym cyklu sieci otrzyma swój czas na przesłanie stanu.


Implementacja na ESP32 (Konkrety programowe)

Aby zrobić to dobrze, wykorzystaj natywne funkcje ESP-IDF (dostępne też w środowisku Arduino dla ESP32). Kluczem jest konfiguracja sterownika UART:

#include "driver/uart.h"

#define UART_NUM       UART_NUM_2
#define TX_PIN         (17)
#define RX_PIN         (16)
#define RTS_PIN        (18) // Podłączony do DE/RE w MAX485

void setup_rs485() {
    uart_config_t uart_config = {
        .baud_rate = 500000, // Profibus kocha wysokie prędkości! ESP32 bez problemu wyciągnie 500kbps lub 1Mbps
        .data_bits = UART_DATA_8_BITS,
        .parity    = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
    };
    
    // Konfiguracja portu
    uart_param_config(UART_NUM, &uart_config);
    uart_set_pin(UART_NUM, TX_PIN, RX_PIN, RTS_PIN, UART_PIN_NO_CHANGE);
    
    // KLUCZOWY MOMENT: Sprzętowa obsługa RS-485 przez ESP32
    uart_driver_install(UART_NUM, 1024, 1024, 0, NULL, 0);
    uart_set_mode(UART_NUM, UART_MODE_RS485_HALF_DUPLEX);
}

Dzięki UART_MODE_RS485_HALF_DUPLEX funkcja uart_write_bytes() sama podniesie pin RTS (DE/RE) w stan wysoki przed wysłaniem pierwszego bitu i opuści go w stan niski dokładnie ułamek mikrosekundy po wysłaniu bitu stopu ostatniego bajtu. [1]


Struktura minimalistycznej ramki DIY Profibus

Aby sieć działała szybko i bezbłędnie, Twoja ramka danych powinna zawierać sumę kontrolną (np. prosty CRC8 lub CRC16), zapobiegającą akceptacji uszkodzonych danych:

Nagłówek (Start) Adres Odbiorcy Adres Nadawcy Typ Ramki Długość Danych Dane (Payload) Suma CRC
0xAA 0x02 (M2) 0x01 (M1) 0x05 (Token) 0x00 brak 0xXX
0xAA 0x10 (Slave) 0x01 (M1) 0x01 (Data) 0x02 [Stan1][Stan2] 0xXX

Sytuacje awaryjne (Co musisz przewidzieć w kodzie DIY?)

Tworząc własny protokół z krążącym żetonem, musisz obsłużyć dwie sytuacje krytyczne:

  1. Zgubienie żetonu: Jeśli Master 1 przekaże żeton do Mastera 2, ale w tym momencie nastąpi zakłócenie na linii i ramka ulegnie uszkodzeniu, Master 2 nie dowie się, że ma żeton. Magistrala ucichnie. Rozwiązanie: Każdy Master musi mieć timer (np. timeout 50 ms). Jeśli przez ten czas na linii panuje absolutna cisza, Master o najniższym ID (np. ID: 1) ma prawo wygenerować nowy żeton i przejąć kontrolę.

  2. Wyłączenie jednego z Masterów: Jeśli Master 2 zostanie fizycznie odłączony z zasilania, Master 1 będzie próbował oddać mu żeton i nikt nie odpowie. Rozwiązanie: Jeśli po 3 próbach przekazania żetonu pod dany adres brak jest jakiejkolwiek aktywności, Master modyfikuje swoją listę i próbuje przekazać żeton do kolejnego Mastera w ringu (np. Master 3).

Taka implementacja na ESP32 da Ci potężną, stabilną, odporną na kolizje sieć przemysłową w skali mikro, pracującą z prędkościami rzędu kilkuset kilobitów na sekundę.

Jeśli chcesz, mogę pomóc Ci rozpisać strukturę automatów stanów (State Machine) w C++, która steruje przełączaniem trybów z Nasłuchiwania na Posiadanie Żetonu. Czy w Twoim projekcie urządzenia Master będą na stałe przypisane do sieci, czy planujesz możliwość ich odłączania w locie?

Jak jakies urzadzenie nie odpowie, moge wprowadzic timer, ze jesli po 0x55 po pewnym czasie nie pojawi sie 0x54, pierwszy modul ktoremu minie czas ma wyslac 0x55 i 0x54..tak ze kazde urzadzenie moze zresetowac linie.

Juz mam jakis wstepny kod do esphome, zobacze czy zadziala i jak.

Najbardziej mnie interesuje zmiana stanu w remote module..odczyt juz nie koniecznie, moze ack tez zrobie.

dla zainteresowanych:

Zaczynamy znacznikiem 0x55 i konczymy 0x54. Urzadzenia nasluchuja czy poszlo 0x54 i do tego, jesli przez 1sek nic sie nie dzieje a poszlo 0x55,wysylane jest 0x54 przez pierwsze urzadzenie.

Stestowalem i wyglada ze dziala.

1 polubienie

Zmieniłbym tylko 0x54 na 0xAA - jak rozpiszesz 0x55 i 0xAA na bity to domyślisz się dlaczego. :slight_smile:

1 polubienie

Racja..zawsze moze dojsc do przeklamania..:wink: poprawie