Elektroda.pl
Elektroda.pl
X
PCBway
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Przesyłanie danych float po uart

omnixcrs 29 Paź 2019 21:19 837 52
  • #31
    krisRaba
    Poziom 28  
    Generalnie teraz jest klops numer dwa, bo standardowy UART nie jest siecią multidrop, czyli właściwie bezpośrednio powinieneś łączyć tylko 2 urządzenia po UART lub zastosować transceiver np. RS485, który to sprawia, że do linii komunikacyjnych można łączyć większą ilość odbiorników. Albo w jednym esp użyć dwóch UARTów (jeśli jest tam taka opcja, bo nie wiem ile jest wyprowadzonych), to wtedy wiesz z kim i o czym rozmawiasz, no i masz połączenie punkt-punkt, a nie multidrop. Gdybyś stosował jednak coś w rodzaju RS485, to możesz wprowadzić adresację sterowników i wtedy wysyłasz ID i zmienną, po czym jesteś w stanie rozpoznać co to za dane i od kogo. Bo same bajty zmiennej w buforze Ci tego nie powiedzą i możesz te bajty wpisać do czegokolwiek i "system" się nie zająknie...
    A jaką masz topologię? Te 3 esp są w jakiej odległości od siebie? Bo może Tobie wystarczy jedno, które obsłuży wszystkie slave'y po I2C i całość jest przekombinowana? Bo zasobów w pojedynczym esp zapewne masz wystarczająco.

    Dodano po 2 [minuty]:

    PS. jeśli masz jakieś większe odległości, to wyciąganie gołego UART na świat, to niezbyt dobry pomysł. A jeśli krótkie, to nie potrzebujesz 3 esp ;)
  • PCBway
  • #32
    khoam
    Poziom 35  
    Problem polega na tym, że Serial1 w ESP8266 nie może zostać użyty do odczytu danych, lecz tylko do ich wysyłania.
    http://arduino.esp8266.com/Arduino/versions/2.3.0/doc/reference.html#serial

    Dodano po 4 [minuty]:

    Można skorzystać z tzw. software-serial w ESP8266: https://github.com/plerup/espsoftwareserial
    Wtedy można dla drugiego portu szeregowego wybrać inne piny w esp.
    W jakiej odległości od siebie są te esp?
  • #33
    omnixcrs
    Poziom 11  
    Nie są w żadnej odległości. Są umieszczone na jednej płytce z tym że jest to układ wieloprocesorowy z uwagi na realizacje różnych zdań w różnych trybach.

    Dodano po 4 [minuty]:

    na tą chwilę nie używam żadnego podziału serial.
  • #34
    khoam
    Poziom 35  
    Połącze je po prostu szyną I2C z zastrzeżeniem, że tylko jeden z nich może być master. Masz już informację na ten temat w poście #21.

    Oczywiście ten jeden master będzie musiał obsługiwać inne I2C slave, czyli ekspander oraz wyświetlacz.
  • #35
    krisRaba
    Poziom 28  
    Czyli pewnie dałoby się to zrobić na jednym, tylko trzeba lepiej zorganizować kod i podzielić go funkcjonalnie podobnie jak teraz dzielisz na kilka esp ;-) Z tego co piszesz, to i tak działasz na ekspanderach, wyświetlacz masz z kontrolerem itp.
    Taki pseudo-multicore, to raczej do złożonych zadań, gdzie w jednym się nie zmieścisz, albo dla zapewnienia redundancji ;-)
    Przyjrzyj się temu, czy nie przekombinowałeś ;-)
    A jak chcesz mieć podzielone funkcjonalnie bloki, to jakiś multitasking załatwia sprawę i jeden wątek nie musi przejmować się co robi niezależnie drugi, a jak potrzebujesz, to zmienną sobie przepchniesz między wątkami, a nie między mikrokontrolerami ;-)
  • PCBway
  • #36
    omnixcrs
    Poziom 11  
    Witam panowie,
    Poszedłem za waszymi radami i uproscilem układ. Mam jedno esp-12f obslugujace jeden ekspander do przyciskow i lcd 2x16 po i2c oraz NodeMcu V3 obslugujace expander do wyjsc. Polączenie pomiedzy nimi to tylko 5v 0v tx i rx - nic wiecej. I2c są osobno. No niby wszystko smiga ale niestety ciagle mam problemy z komunikacja uart - raz jest dobrze za chwile same 0 itp. Moje urzadzenie może pracować w dwoch trybach AUTO i MANUAL. W przypadku trybu auto nodemuc przesyla co jakiś czas zmienne do esp i tu raczej wszystko dziala ale w przypadku trybu MANUAL komunikacja musi odbywać się w dwie strony i tu już jest gorzej. Wstawiam ponizej uproszczone kody komunikacji może coś wyłapiecie:

    Kod na nodemcu:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Kod na esp:

    Kod: c
    Zaloguj się, aby zobaczyć kod
  • #37
    khoam
    Poziom 35  
    Spróbuj użyć funkcji Serial.availableForWrite():
    https://www.arduino.cc/reference/tr/language/...tions/communication/serial/availableforwrite/
    Poniżej przykład zmodyfikowanego kodu funkcji UART_wysylanie() dla ESP-12:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Może wystąpić efekt uboczny polegający na tym, że pomimo spełnienia warunku (tryb_button == 1) nie zostaną wysłane dane, ponieważ w buforze wyjściowym nie będzie wystarczająco miejsca. Powinieneś taką sytuację obsłużyć np. przez restart timer'a, który wywołuje UART_wysylanie().
  • #38
    omnixcrs
    Poziom 11  
    Ok spróbuje. A powiedz mi jak dokładniej działa transmisja po UART. Np jeśli wyślę 48 bajtów do esp to tyle miejsca zajmę w jego buforze i teraz jak je odczytam za pomocą Serial.readBytes to one zostają usunięte z bufora czy nadal zajmują te 48 bajtów ??
  • #39
    khoam
    Poziom 35  
    Zostaną usunięte, jeżeli zostały odczytane.

    Dodano po 10 [minuty]:

    Serial.write() zwraca informację o ilości "wysłanych" bajtów. Możesz to też dodatkowo sprawdzać.
    Jeżeli bufor wyjściowy jest przepełniony, wtedy Serial.write() blokuje działanie programu, stąd też zasugerowałem użycie funkcji Serial.availableForWrite() w celu dokładnego sprawdzenia, czy można wysłać paczkę danych o określonej wielkości.
  • #40
    omnixcrs
    Poziom 11  
    No masz rację, czasem program mi się wieszał. To już wiem czemu. A dlaczego dochodzi do przepełnienia bufora wysyłania i jak go unikać?
  • #41
    khoam
    Poziom 35  
    omnixcrs napisał:
    A dlaczego dochodzi do przepełnienia bufora wysylania i jak go unikac ?

    Jak już pisałem wcześniej, bufor ma ograniczony rozmiar. Nie należy wysyłać więcej niż to w danym momencie jest możliwe tzn. nie zostało odebrane przez drugą stronę. Limitem jest również prędkość transmisji danych po UART.
  • #42
    omnixcrs
    Poziom 11  
    No ok, ale skoro ja wysyłam co 35 s, a odbieram co 20 to zawsze wszystko będzie odebrane, tak?
  • #43
    khoam
    Poziom 35  
    omnixcrs napisał:
    No ok, ale skoro ja wysyłam co 35s, a odbieram co 20 to zawsze wszystko będzie odebrane, tak?

    omnixcrs napisał:
    ale w przypadku trybu MANUAL komunikacja musi odbywać się w dwie strony i tu już jest gorzej.

    Komunikacja Serial-Serial odbywa się w trybie half-duplex. Oznacza to, że w danej chwili UART może wysyłać dane albo je odbierać, ale nie równocześnie. Jak UART nie będzie mógł wysłać danych, to będą trzymane w buforze wyjściowym do czasu, kiedy wysłanie będzie możliwe.
  • #44
    krisRaba
    Poziom 28  
    Czemu tam jest tak dziwnie? Jest jakiś transceiver RS? Czy tak głupio napisane biblioteki?
    Przecież normalnie UART śmiga w full-duplexie...
  • #45
    khoam
    Poziom 35  
    krisRaba napisał:
    Czemu tam jest tak dziwnie? Jest jakiś transceiver RS? Czy tak głupio napisane biblioteki?

    Zamiast Serial.begin(512000) można użyć np. Serial.begin(512000, SERIAL_8N1, SERIAL_FULL) :)
    Oczywiście po obu stronach. Ta opcja z SERIAL_FULL pojawiła się w ESP8266 oraz ESP32. Nie ma jej w standardowym Arduino HAL.
  • #46
    krisRaba
    Poziom 28  
    Czyli jednak głupio napisane biblioteki ;-)
  • #47
    khoam
    Poziom 35  
    omnixcrs napisał:
    No ok, ale skoro ja wysyłam co 35 s, a odbieram co 20 to zawsze wszystko będzie odebrane, tak?

    Może się też zdarzyć, że będą jakieś zakłócenia lub w przerwy w transmisji. W jakiej odległości są te ESP od siebie?
  • #48
    krisRaba
    Poziom 28  
    Swoją droga po co tak udziwniać program i utrudniać sobie życie? W normalnych MCU odczyt robi się gdy coś przyjdzie, a nie sztucznie czeka nie wiadomo ile.
    Pomiędzy tymi interwałami 20s usypiasz wszystko, że nie może sobie sprawdzić, czy już przyszły dane?
  • #49
    khoam
    Poziom 35  
    krisRaba napisał:
    W normalnych MCU odczyt robi się gdy coś przyjdzie, a nie sztucznie czeka nie wiadomo ile.

    W tym "normalnym" MCU też można z wykorzystaniem handlerów do przerwań z UART.
    Tutaj jest prosty przykład:
    https://github.com/nkolban/Sample-ESP8266-App/tree/master/Sample%20FreeRTOS%20App

    Dodano po 32 [sekundy]:

    krisRaba napisał:
    Pomiędzy tymi interwałami 20s usypiasz wszystko, że nie może sobie sprawdzić, czy już przyszły dane?

    Nie usypia. Może w tym czasie robić inne rzeczy.
  • #50
    krisRaba
    Poziom 28  
    Ok, czyli da się to zrobić jak trzeba, tylko kwestia sięgnięcia po odpowiednie źródła. Już myślałem, że to wszystko zrobili takie toporne i kulawe ;-)
  • #51
    omnixcrs
    Poziom 11  
    odległość żadna, są obok siebie na płytce
  • #52
    krisRaba
    Poziom 28  
    omnixcrs napisał:
    Poszedłem za waszymi radami i uproscilem układ. Mam jedno esp-12f obslugujace jeden ekspander do przyciskow i lcd 2x16 po i2c oraz NodeMcu V3 obslugujace expander do wyjsc. Polączenie pomiedzy nimi to tylko 5v 0v tx i rx - nic wiecej. I2c są osobno.

    omnixcrs napisał:
    odległość żadna, są obok siebie na płytce

    To czemu nie uprościłeś tego jeszcze bardziej i nie zostawiłeś tylko jednego???? :) Wtedy nie masz komunikacji po UART i problem z głowy :P
    Trochę utrudniasz sobie życie...
    Jeśli dobrze rozumiem, to ten ekspander wyjść jest na I2C? I wyświetlacz też? I ekspander do przycisków też? Jeny, to aż się prosi to wszystko wrzucić na jedną lub dwie magistrale I2C w JEDNYM procku i po temacie. Po co to tak mnożyć? Osobne programy, komunikacje między kontrolerami itp. Już nawet pomijam fakt, że dotąd miałeś do tego 3 procki 8-O :crazyeyes:
  • #53
    khoam
    Poziom 35  
    omnixcrs napisał:
    Są umieszczone na jednej płytce z tym że jest to układ wieloprocesorowy z uwagi na realizacje różnych zdań w różnych trybach.

    Jeszcze raz przeczytałem Twoje założenia i tak się zastanawiam, czy nie powinieneś połączyć ESP-12 z NodeMCU po SPI, jeżeli chcesz się przybliżyć nieco do modelu układu wieloprocesorowego. Oczywiście wtedy potrzebne aż 4 piny z każdego układu (MOSI, MISO, SS, SCK) i nie wiem, czy to możliwe.

    Tak, na marginesie ESP-32 ma dwa rdzenie ;)