logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[mega8][Bascom] Problem z feedbackiem na RS485

misiakufal 10 Lis 2010 19:29 2018 9
REKLAMA
  • #1 8726808
    misiakufal
    Poziom 10  
    Witam!

    Usilnie próbuje opracowąć protokół komunikacji miedzy wieloma węzłami w sieci RS485 multimaster. Ramka wyglada tak:

    1 bajt - długosć ramki
    2 bajty - adres odbiorcy (word)
    2 bajty - adres nadawcy (word)
    x bajtów - dane właściwie
    1 bajt suma kontrolna z wszystkich poprzednich

    Transmisja odbywa się na prędkosci 19200bps przy użyciu transcieverów MAX1483. Uporałem się z przypadkiem, gdy jeden z węzłów chce nadawać w momencie, gdy inny już nadaje, poprzez sprawdzanie ile czasu minęło od odebrania poprzedniego bajtu. Jeśli ten czas jest wystarczajaco duży, to uC uznaje ze linia jest wolna i nadaje, a jak nie, to kręci się w kółko aż ustalony czas minie.
    Teraz męczę się z przypadkiem, gdy obydwa węzły miałyby ochotę nadawac w tym samym czasie. Wpadłem na pomysł, żeby automatycznie po wysłaniu wiadomości, odczytywać kolejne bajty tej wiadomosci. Coś na zasadzie feedbacku, sprzężenia zwrotnego, bo przecież wszystko co się pojawia na magistali może byc od razu odebrane przez wszystkie wężły - jak i przez węzeł nadający właśnie w celu sprawdzenia, czy to co miało zostać wysłane, zostało odebrane (a nie że przypadkiem 2 ramki się nałożyły na siebie).

    Jeśli chodzi o kod, to fragment odbioru danych (wykonywany po przerwaniu Urxc):

     
    Port:
    Buff = Inkey()                                   'odczytanie bajtu
     Bit_order_count = 0
     If Pind.3 = 0 Then                             'jeśli nie nadajemy (obca wiadomosć)
      Verif = Verif + Buff                           'Zliczamy sume kontrolną
      Tbuff(index) = Buff                          'wpisujemy dany bajt do tablicy
      If Index = 1 Then                            'Jeżeli jest to pierwszy bajt w ramce
       Leng = Buff                                   'Ustawiami długośc ramki
       Isbusy = 1                                    'Flaga zajętości linii (nie możemy w tym momencie niczego wysłać)
      End If
      If Leng = Index Then                       'jeżeli została osiągnieta długosć ramki
       Isbusy = 0                                    ' flaga zajętosci - można już nadawać jeśli trzeba
       Verif = Verif - Buff                          ' usuwamy z sumy kontrolnej sume kontrolną (ostatni bajt któwy w tą sumę nie wchodzi
       If Verif = Buff Then                         'jezeli suma kontrolna zgadza się z ostatnim bajtem
        Sendid = Tbuff(2);                         ' składanie adresu odbiorcy z 2 bajtów do zmiennej word
        Shift Sendid , Left , 8
        Sendid = Sendid + Tbuff(3)
         If Sendid = Id Then Isramkaok = 1    ' Jeżeli id odbiorcy zgadza się z ID urządzenia, ustaw flagę, że ramka jest ok.
       End If
      Index = 1                                       ' przygotowanie do odbioru następnej ramki
      Verif = 0
      Else
       Incr Index                                       'jeżeli nie została osiągnieta długosc ramki, zwiększaj index
      End If
     Else                                                  ' jeżeli nadajnik włączony = to nasza wiadomosć, i musimy sprawdzić czy się zgadza z tym co nadajemy
      Thelp(erro) = Buff
      Incr Erro
     End If
    Return
    



    Natomiast to jest fragment odpowiedzialny na wysyłanie:

    
    Portd.3 = 1                              'włączenie nadajnika
     Dlug = Dlug + 5                       'dodanie do długosci danych długosci narzutu (id odb, id nad, suma)
     Tbuffout(dlug + 1) = 0             ' czyszczenie sumy kontrolnej
     Tbuffout(1) = Dlug + 1             ' ustawienie końcowej dlugosci ramki
     Tbuffout(2) = High(adres)         'konwersja word do bajtów ramki
     Tbuffout(3) = Low(adres)
     Tbuffout(4) = High(id)
     Tbuffout(5) = Low(id)
     For I = 1 To Dlug                     ' generowanie sumy kontrolnej
      Tbuffout(dlug + 1) = Tbuffout(dlug + 1) + Tbuffout(i)
     Next I
     Incr Dlug
     Erro = 0                                 <---### TU BYŁ BŁĄD, indeksowanie zaczynamy od 0
     For I = 1 To Dlug                     ' wysyłanie kolejnych bajtów wiadomosci
      Print Chr(tbuffout(i));
     Next I
      Waitms 1
    For I = 1 To Dlug                      ' wysyłanie feedbacku (tego co sami odczytaliśmy z wiadomosci którą wysyłaliśmy)
     Print Chr(thelp(1));                   <---## TU BYŁ BŁĄD, w nawiasie ma być i a nie 1
    Next I
    Waitms 1
    Portd.3 = 0                              ' wyłączenie nadajnika
    Verif = 0
    


    Pod PORTD.3 podpięte jest wejscie uaktywniajace nadajnik w MAX'ie.
    Pod każde inne wyjście występujące w kodzie podpięte są diody.

    Ramka która jest wysyłana z urządzenia na komputerze jest odbierana w postaci:

    9 - Długośc ramki
    234 - Pierwszy bajt Odbiorcy (60000)
    96 - Drugi bajt Odbiorcy (60000)
    0 - Pierwszy bajt Nadawcy (1)
    1 - Drugi bajt Nadawcy (1)
    8 - Dane
    0 - Dane
    1 - Dane
    93 - Suma kontrolna (Suma wszystkich poprzednich mod 256)

    Natomiast sam węzeł widzi odebrane przez siebie dane w postaci:

    234
    234
    234
    234
    234
    234
    234
    234
    234

    Czy ktos ma jakiś pomysł co może powodowac takie zachowanie? Czy bascom/MAX1483/mega8 mają jakieś problemy z nadawaniem i równoczesnym odbieraniu danych w tym samym momencie? Z góry dzięki za pomoc:)
  • REKLAMA
  • #2 8727156
    xury
    Specjalista automatyka domowa
    Cytat:
    Czy ktos ma jakiś pomysł co może powodowac takie zachowanie? Czy bascom/MAX1483/mega8 mają jakieś problemy z nadawaniem i równoczesnym odbieraniu danych w tym samym momencie? Z góry dzięki za pomoc:)

    A kolega czytał DS'a i wyczytał różnicę pomiędzy MAX1482, a MAX 1483 ?
  • REKLAMA
  • #3 8727272
    misiakufal
    Poziom 10  
    czyzby chodziło o to, że MAX1483 jest half duplex, a MAX1482 jest fullduplex? to jest powód takiego zachowania? No niby jest to różnica, tylko powiedz mi prosze, jak podłączyć MAX1482 który ma wyjścia ABi ZY w zastosowaniu multimaster RS485? Bo ja tego za bardzo nie widzę...

    [mega8][Bascom] Problem z feedbackiem na RS485

    Tutaj pokazane jest jak to wygląda w praktyce... Ten sposób nie pozwala na wysłanie bajtu z każdego do każdego.

    PS. Chyba ze chodzi o to, że w takim wypadku zwiera się pary A-Z i B-Y?
  • REKLAMA
  • #4 8727392
    hotdog
    Poziom 26  
    w trybie full duplex urządzenia jeżeli masz więcej niż 2 połączone tak jak na obrazku który pokazałeś to każde urządzenie NIE MOŻE gadać z każdym.

    Na obrazku widać że urządzenie po lewej może wysłać paczki od 3 pozostałych. Te 3 mogą również wysłać paczkę do 1. dolne już nie mają możliwości komunikacji z prawym i odwrotnie.

    Takie układu robi się na half duplexie. Algorytm masz ogólnei dobry, chociaż ja w Twoim wypadku bym dodał kilka "bajerów" (preambuła kilku bajtowa, oraz długość pola danych).

    W samym sprzęcie robisz to tak, że ustawiasz wejście RE na stałe w stan niski. Później jak chcesz nadawać ustawiasz DE na wysoki i nadajesz. Po każdym bajcie sprawdzasz czy wysłał się on poprawnie na magistralę, czyli czy trafił do bufora odbiorczego.

    Po wykryciu kolizji, oba urządzenia powinny przestać nadawać przez losowy okres czasu (np zależny od ich adresu). Inaczej się program zatnie bo każde urządzenie będzie czekało ten sam okres czasu i znowu oba zaczną nadawać w tym samym czasie.
  • #5 8727428
    xury
    Specjalista automatyka domowa
    Nie wiem jak zrobić multi master na MAX1482, ale na pewno nie da się jednocześnie nadawać i odbierać w half-duplexie.
    Zresztą ja wolę układ jeden master i n slave'ów. Nie wiem dlaczego uparłeś się na multi master?
  • REKLAMA
  • #6 8727434
    misiakufal
    Poziom 10  
    No właśnie dlatego pomysł na użycie fullduplex dla mnie jest bez sensu w tym wypadku. Dlatego użyłem MAX1483.
    RE jest na stałe do masy, a DE podciagam jak chce coś nadawać. Przesyłanie ogólnie działa OK, tyle ze urządzenie które ma odebrać to co samo wysyła, co chwile odbiera bajt 234:/
    Ogólnie o zabawie z porównaniem wysłanego bajtu z odebranym i wycofanie się na losowy czas i ponownej próbie nadawania wiem, tak to zrobiłem na samym początku i nie działało.. dioda sygnalizowała ze od razu wykrywa kolizję.. no i przesłałem sobie do kompa to co wg urządzenia pojawiło się na linii.

    xury

    Właśnie niby można nadawać i odbierać w half duplexie, bo takie rzeczy się robi... Inaczej nie byłoby możliwosci stworzenia sieci MultiMaster na RS485 z wykrywaniem kolizji.
    Co do uparcia sie na multimaster, to TokenRing odpada, bo trzeba by czekać aż żeton przejdzie cały okrąg, do tego trzeba znać sąsiadów, problem jest jak jakieś urządzenie się zawiesi, bo zeton utyka. Co do przyznawania slotów czasowych też urządzenie musiało by czekać aż dostanie prawo do gadania, a bez sensu jest czekanie 2-3 sekundy aż światło się zapali. Tryb multimaster jest najlepszy pod tym wzgledem, tyle ze trzeba się troche napracować z wykrywaniem kolizji:/ Spróbuje zmniejszyć jeszcze prędkosć, ewentualnie wykastruje program i sprawdze na prawie czystym kodzie, czy odbiera to co nadaje.
  • #7 8727601
    hotdog
    Poziom 26  
    xury napisał:
    Nie wiem jak zrobić multi master na MAX1482, ale na pewno nie da się jednocześnie nadawać i odbierać w half-duplexie.


    Tu się kolega myli. Myśli kolega że czemu są 2 wejścia sterujące DE i RE?

    do autora: Masz układ już na 1483, który się do tego ogólnie nie nadaje. Ale przerobiłeś je na half duplex? Czy dalej masz 4 przewody miedzy urządzeniami?
  • #8 8727749
    misiakufal
    Poziom 10  
    Mam układ 1483, czemu on się do tego w ogóle nie nadaje? Ten układ jest w half duplexie, sa tylko 2 przewody, A i B. Co do fullduplexu, to ma go układ 1482 i wiem ze do multiM on się nie nadaje, bo nie ma komunikacji każdy z każdym.
    W każdym razie wykastrowałem program, żeby tylko sprawdzić czy na pojedyncze bajty odpowiada poprawie, i wygląda na to, że wszystko jest ok, wysyłam mu bajt 15, on odsyła mi to co odebrał, czyli 15, a następnie odsyła mi to co odebrał podczas swojego wysyłania, czyli znów 15. Tak wiec jest to zupełnie możliwe, tylko mam coś skopane w kodzie:/ no ale przynajmniej ważne, ze hardware jest w porządku:)
  • #9 8728193
    hotdog
    Poziom 26  
    No pomyliły mi się te modele. Ten obrazek mnie zmylił i myślałem że Ty wykorzystałeś ten full duplex'owy.

    1483 jest oczywiście w half duplexie. W 1482 byś musiał połączyć A-Z i B-Y, a przynajmniej nie widzę powodów czemu by to miało tak nie działać.

    Dalej już Tobie nie pomogę bo bascom'a nie znam.

    Pozdrawiam
  • #10 8732430
    misiakufal
    Poziom 10  
    No i sprawa się rozwiazała. Na kodzie naniosłem 2 miejsca w których były błędy. Oczywiscie błędy nie w rozumowaniu ;) tylko z roztargnienia popełnione z głupoty. Pozdrawiam wszystkich i dziękuje za pomoc.
REKLAMA