Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Arduino --> częstotliwość przesyłu danych po Modbus TCP/IP

madiz08 20 Jan 2019 12:46 2112 13
  • #1
    madiz08
    Level 14  
    Witam
    Ostatnio eksperymentuję sporo z wymianą danych pomiędzy mikrokontrolerem i PLC S7-1200. Wczoraj zmontowałem układ odczytujący pozycję enkodera absolutnego (od 0 do 1023 pozycji):
    Arduino --> częstotliwość przesyłu danych po Modbus TCP/IP
    Za pomocą płytki ethernet shield chciałbym przesyłać dane PLC. Jeżeli chodzi o sam przesył to nie mam z tym problemu, ale o ile wcześniej prędkość cyklicznego wysyłania nie miała dla mnie znaczenia to teraz ma i to duże. Enkoder przy szybszych obrotach (1obr/s) przesyła do PLC nie co jedną pozycję, lecz co 40 a nawet 50 pozycji, czyli nici z dokładnego pozycjonowania.


    Czy w kodzie można zwiększyć częstotliwość wysyłania danych?
    Mój kod:
    Code: c
    Log in, to see the code


    Dodano po 4 [minuty]:

    Chodzi mi o to czy wogóle jest możliwość zwiększenia częstotliwości wysyłania danych do PLC, czy też może ten przesył wykonuje się na tyle szybko na ile protokół Modbus TCP/IP pozwala i niestety do częstego przesyłu danych się nie nadaje.

    Dodano po 3 [minuty]:

    Arduino --> częstotliwość przesyłu danych po Modbus TCP/IP
    W TIA odbiór danych ustawiony mam na odbiór tylko jednej danej

    Dodano po 1 [minuty]:

    A być może do takich celów powinienem użyć innej biblioteki lub zmodyfikować obecną?
    Do you have a problem with Arduino? Ask question. Visit our forum Arduino.
  • Helpful post
    #2
    Freddie Chopin
    MCUs specialist
    Modbus slave (Twoje urządzenie) niczego nie wysyła sam z siebie - wszystkie zależy od tego jak często odpytuje go Modbus master (Twój PLC). Generalnie przy użyciu Modbusa ciężko wyciągnąć więcej niż ~10 zapytań na sekundę, choć po ETH powinno być lepiej niż na RS-485, z tym że na wolnym Arduino zalety szybszego ETH mogą być nieosiągalne.
  • #3
    madiz08
    Level 14  
    Aj, szkoda, liczyłem że będzie możliwe uzyskanie minimum 20 zapytań na sekundę
    Arduino --> częstotliwość przesyłu danych po Modbus TCP/IP
    Zobaczyłem, że w PLC jest taki parametr jak powyżej. Zaraz porobię kilka testów do ilu mogę zejść, bez wywalenia błędu w słowie statusu
  • Helpful post
    #4
    Freddie Chopin
    MCUs specialist
    Bardziej szukałbym parametru typu okres odpytywania (polling period czy coś w ten deseń) - to co pokazałeś tylko timeout po którym brak odpowiedzi uznawany jest za błąd, więc jeśli Twoje urządzenie odpowiada za każdym razem, to raczej nie powinien on mieć żadnego wpływu. Jeśli masz możliwość, to można też przy pomocy wiresharka zobaczyć ile mija czasu pomiędzy wysłaniem zapytania a odesłaniem odpowiedzi - ten czas to jest absolutne minimum jakie jesteś w stanie uzyskać. Zmniejszyć go można tylko poprzez jakieś poprawki w kodzie samej biblioteki Modbusa, choć nie wiadomo czy jest tam jakieś pole manewru (Arduino jest dosyć wolne, no i nie ma sprzętowego ETH).

    Moja opinia o ~10 zapytaniach na sekundę odnosi się głównie do ModbusRTU, czyli takiego pracującego na jakimś interfejsie szeregowym. Na ModbusTCP w sumie nigdy nie sprawdzałem czy tam też jest takie ograniczenie i z czego dokładnie wynika. Tak czy siak Modbus jest sam w sobie dosyć powolny i ciężko przy jego pomocy uzyskać jakieś super prędkości...
  • #5
    madiz08
    Level 14  
    Rozumiem, postaram się poszukać parametru odpowiadającego za częstotliwość odpytywania. Dobry pomysł z wierSharkiem, dawno tego nie używałem ale zainstaluję i nawet z czystej ciekawości sprawdzę
    Biblioteka mojego modbusa to:

    MODBUS.h
    Code: c
    Log in, to see the code


    MODBUS.Cpp
    Code: c
    Log in, to see the code


    Jestem kiepski z języka C, ale wydaje mi się, że ustalany jest jedynie czas na nawiązanie połączenia, a przed zapisem czy odczytem użyte jest zapytanie czy Modbus jest wolny. No nic w pierwszej kolejności spróbuję znaleźć parametr częstotliwości odpytywania w PLC

    Dodano po 2 [godziny] 41 [minuty]:

    Niestety nie znalazłem informacji o częstotliwości wysyłania zapytań. Na Youtubie znalazłem filmiki gdzie cyklicznie wysyłano impuls na wejście REQ (request). Na PLC zrobiem przerwanie cykliczne co 50ms impuls na to wejście i niestety słabiutko. Poniżej tabela, której wiersze są uzupełniane jeżeli pozycja enkodera się zmieni:

    Arduino --> częstotliwość przesyłu danych po Modbus TCP/IP
    Co prawda kręciłem wałem enkodera dosyć szybko, ale i tak widać (na pomareńczowo), że rozrzut odczytu jest ogromny.
    Sprawdziłem jak radzi sobie Arduino z wyświetlaniem zmian pozycji enkodera ustawiając Serial na 115200:
    Arduino --> częstotliwość przesyłu danych po Modbus TCP/IP
    Także bez porównania. Poza wierSharkiem (który najpierw muszę zainstalować) sprawdziłem pingowanie w CMD
    Arduino --> częstotliwość przesyłu danych po Modbus TCP/IP
    Czy na podstawie tego czasu odpowiedzi można stwierdzić, że znacznie szybsza transmisja jest jest możliwa do osiągnięcia?
  • Helpful post
    #6
    Freddie Chopin
    MCUs specialist
    madiz08 wrote:
    Czy na podstawie tego czasu odpowiedzi można stwierdzić, że znacznie szybsza transmisja jest jest możliwa do osiągnięcia?

    Raczej nie, ping pracuje na baaaaaardzo niskiej warstwie protokołu, a Ty chcesz przecież używać jednej z wyższych (TCP), do tego z protokołem aplikacji (Modbus) i to jeszcze w formie pytanie-odpowiedź.

    Generalnie możesz spróbować zamiast programu na PLC użyć dowolnego mastera Modbusa na PC, np. jest programik QModMaster albo bardzo wygodny (i niestety tylko na Windowsa) Modbus Tester. Tym sposobem dużo łatwiej będzie Ci określić jak szybko odpowiada urządzenie, bo w programach tych jest zwykle coś na styl "monitora/loggera", który pokazuje poszczególne zapytania i odpowiedzi w formie binarnej wraz z timestampem.
  • Helpful post
    #7
    Sareph
    Level 23  
    Freddie Chopin wrote:
    ping pracuje na baaaaaardzo niskiej warstwie protokołu, a Ty chcesz przecież używać jednej z wyższych (TCP)
    Taka ciekawostka, niby ICMP jest w warstwie 3 (czyli tej samej co IP) a TCP w 4, ale tak na prawdę oba protokoły "sa opakowane" bezpośrednio w pakiety IP, więc ICMP to jakoś niżej od TCP to nie jest.
  • #8
    michalko12
    MCUs specialist
    Freddie Chopin wrote:
    oja opinia o ~10 zapytaniach na sekundę odnosi się głównie do ModbusRTU, czyli takiego pracującego na jakimś interfejsie szeregowym

    Nie wiem czemu tak sądzisz. Wszystko zależy od prędkości transmisji i długości rameki. >100 spokojnie można uzyskać @57600bps przy transmisji kilku rejestrów.
  • #9
    Freddie Chopin
    MCUs specialist
    michalko12 wrote:
    >100 spokojnie można uzyskać @57600bps przy transmisji kilku rejestrów.

    Odważnie (; Wychodzi "aż" 57 bajtów na pytanie i odpowiedź, oczywiście przy założeniu, że pomiędzy pytaniem a odpowiedzią oraz między odpowiedzią a następnym pytaniem nie ma absolutnie żadnej przerwy, co oczywiście nie jest możliwe, bo RTU opiera się właśnie na przerwach. Na same przerwy przypada 3.5 znaku na starcie i 3.5 znaku na końcu, do tego zarówno w pytaniu jak i odpowiedzi muszą być 4 bajty obowiązkowe. Wychodzi więc, że przy tych - dosyć nierealnych - założeniach o natychmiastowej odpowiedzi na pytanie, zostaje te 35 bajtów na dane. Niby spoko, ale które urządzenie odpowiada natychmiast po otrzymaniu zapytania, skoro w zasadzie najpierw musi zanalizować ramkę, sprawdzić CRC, odkodować o co chodzi, potem te dane o które było pytanie wyczarować skądś, złożyć w ramkę, policzyć dla niej CRC, ... Każda milisekunda zwłoki (zarówno między pytaniem a odpowiedzią jak i odpowiedzią a następnym pytaniem) ogranicza ilość dostępnych danych o ~5 bajtów. Teraz dołóżmy do tego jeszcze fakt, że takie cuda można sobie robić na sprzętowych sterownikach które działają w czasie rzeczywistym. PLC z GUI (jak u autora) czy normalny PC na ogarnięcie że coś się na porcie szeregowym pojawiło (albo na rozpoczęcie wysyłania ramki) potrzebuje naprawdę sporo czasu.
  • Helpful post
    #10
    michalko12
    MCUs specialist
    Freddie Chopin wrote:
    Teraz dołóżmy do tego jeszcze fakt, że takie cuda można sobie robić na sprzętowych sterownikach które działają w czasie rzeczywistym.


    Np. ModbusRTU Funkcja 3 - Read Holding Registers @57600:
    Zapytanie: 8B + 3,5 znaku = 2ms
    ======Czas na generacje odpowiedzi...=======
    Odpowiedź - 5B + 2xN + 3,5 znaku = 4,8ms dla 10 rejestrów
    Odpowiedź - 5B + 2xN + 3,5 znaku = 45ms dla 125 rejestrów(max)
    Sam MODBUS jest w stanie przeciągnąć ponad 100 transakcji na sekundę. Dla ramek o maksymalnej długości to jest w okolicach 20 ramek na sekundę. A czy masterem jest PLC, Windows czy coś innego to inna kwestia. Wygenerowanie pełnej ramki odpowiedzi w czasie <1ms też nie jest nierealne i zależy od tego jak jest napisany soft slave'a.
  • #11
    kk.2000
    Level 26  
    Odniosę się do REALNYCH prędkości Modbus TCP przy połączeniu sieciowym 100MB. Shield W5100.

    Odpytując 1 rejestr Arduino osiągam średnio 400 odpowiedzi /s, co daje 2,5ms czasu w obydwie strony (nie pomijam komunikacji zwrotnej).

    Odpytując 10 rejestrów uzyskuję 300 odp./s, czyli ok. 3,3ms.

    Odpytanie 100 rejestrów daje 100 odp./s, czyli zjada 10ms czasu.

    (testy na PLC Beckhoff<=>Arduino, identyczne czasy PC<=>Arduino)
    __________

    Moje Arduino przeliczało temperatury z Dallasów. Kilka do kilkudziesięciu czujników odpytywanych po 1-wire.

    Madis (kolega z postu nr 1) nie ma zoptymalizowanego programu w Arduino, dlatego ma tak duże czasy odpowiedzi. Arduino (UNO identycznie jak Leonardo) radzi sobie bardzo dobrze z Modbus TCP, ale z tasku należy usunąć wszystko co zbędne.

    Np. sam Print do portu COM zajmuje 18ms.
  • #12
    Slawek K.
    Level 34  
    Mam Modbusa RTU po rs485, po stronie slave atmega328, po stronie master 2560, ramka 16 rejestrów uint16_t, przy predkosci 115200 udało mi się osiągnąć 20 odpowiedzi na sekundę, powyżej już są timeouty.

    Pozdr
  • #13
    bart-projects
    Level 22  
    Co byś nie robił to po odebraniu zapytania Modbus Slave czeka trzykrotność czasu jednego znaku i jeśli żaden nowy znak nie nadszedł to to oznacza koniec ramki i dopiero zaczyna ją parsować. Więc przy 9600 czeka dużo dłużej niż przy 115200.

    Co ciekawe w Arduino przy 115200 i 16MHz masz 2,1% błędu. Osobiście używam, w jednym projekcie z Modbus, Arduino Nano 16MHz z prędkością 250000. Wtedy masz 0% błędu ;) Oczywiście przy tej prędkości Arduino odpowiada też szybciej.

    Inna sprawa przy W5100 czy Arduino obsługuje go przez Int czy go nie używa i tylko pooling czyli odpytuje okresowo Wizza czy w jego buforze czekają jakieś dane.
  • #14
    madiz08
    Level 14  
    Jeżeli chodzi o komunikację Arduino - PLC, to teraz uważam, że na chwilę obecna nie ma nic lepszego niż biblioteka settimino, gdzie w programie PLC nie ma potrzeby wstawiania jakichkolwiek bloków. Wartość z Arduino (ja teraz stosuję głównie ESP32, które ma 240MHz a nie 16MHz jak zwykłe arduino) jest przesyłana bezpośrednio do danego adresu w danym bloku danych. Co prawda częstotliwości przesyłu nie sprawdzałem, ale sprawdzę w wolnym czasie.
    ESP32 ma dwa procesory. Jeżeli sterujemy po WIFI, to wifi jest obsługiwane przez drugi procesor, czyli nie wpływa to na blokowanie drugiego procesora.

    Dodano po 3 [minuty]:

    Jeszcze odnośnie samego enkodera absolutnego, to za 10zł z przesyłką z chin można kupic AS5600 - enkoder absolutny z 12-bitowa rozdzielczością. Sprawują się świetnie