Skocz do zawartości

MAX485 i Raspberry Pi


Pomocna odpowiedź

Przepraszam, że nie odpowiadam tak od razu, ale miałem trochę 6-grudniowych zajęć 🙂

Acha, więc 74HC14. Jest to 6 identycznych bramek-inwerterów wyposażonych w przerzutnik Schmitta. To oznacza, że w środku każdej bramki siedzi prosty układzik wyposażony w histerezę, tj. ma inny próg przełączania gdy napięcie wejściowe rośnie a inny gdy maleje. Poza tym jest to zwykły inwerter czyli z 1 robi 0 i odwrotnie - gdyby nie ta histereza to nie byłoby czym się podniecać. Dzięki niej 74HC14 jest odporny na bardzo wolno zmieniające się sygnały. Jest to wyjątek wśród układów logicznych, bo normalne bramki wariują w okolicy połowy zasilania. Taki właśnie, wolno zmieniający się przebieg mamy na wyjściu układu RC, który będzie tu pełnił rolę wyznaczania opóźnienia.

Czyli mamy tak: pierwszy inwerter (U1A) separuje nam układ RC od wyjścia TXD. Nie możemy przecież pozwolić, by wyjście z Maliny było w jakiś sposób obciążane kondensatorem, bo to zniekształciłoby przebieg nadawany. Na wyjściu U1A mamy układ RC, który dzięki połączeniu jako filtr dolnoprzepustowy opóźnia nam sygnał wejściowy. Czy to dobrze? No nie do końca. Celem naszym jest uzyskanie sygnału DE, czyli odblokowania nadajnika. Musimy zaczynać nadawanie już od pierwszej chwili trwania bitu startu pierwszego znaku a kończyć dopiero chwilę po nadaniu ostatniego znaku. To opóźnienie nie jest symetryczne. Jak powinno to działać? Po prostu: w stanie spoczynku na wyjściu UARTa jest stan 1. Wtedy nadajnik musi być wyłączony, czyli DE=0. Gdy zaczyna się transmisja znaku, jako pierwszy wypada bit startu, zawsze = 0. I dokładnie wtedy, najlepiej z zerowym opóźnieniem powinien włączyć się nadajnik. Układ RC działa symetrycznie: tak samo opóźnia zera jak i jedynki ale my jesteśmy sprytniejsi 🙂 , bo mamy diodę. Ona powoduje, że gdy na wyjściu U1A zrobi się stan wysoki (czyli mamy bit startu lub zero pochodzące z nadawanych danych), kondensator bardzo szybko się przez tę diodę ładuje do napięcia 3.3V i tak zostaje przez cały czas trwania stanu niskiego na wejściu U1A. Dalej mamy dwa inwertery połączone szeregowo więc polaryzacja się nie zmienia: jeżeli na kondensatorze jest 3.3V to na wyjściu też, czyli DE=1 i nadajnik jest załączony.

Gdy zaczynamy nadawać jedynkę (bo np. skończył się znak i linia TXD przeszła w stan nieaktywny) to na wyjściu U1A robi się zero. Kondensator nie może się rozładować szybko przez diodę, bo ta jest wtedy spolaryzowana zaporowo i musi swój ładunek "upłynnić" przez R1 a ten jest spory. Napięcie na C1 będzie więc spadało powoli aż osiągnie dolny próg przełączania U1B czyli ok. 1.1V. Elementy RC są tak dobrane, by czas ten wynosił ok. 2ms. Tak więc linia DE wróci do poziomu niskiego i przełączy układ MAX485 do trybu "odbiór" dopiero w 2ms po ostatnio nadanym zerze. Ponieważ znaki nadawane są jeden po drugim, to nawet jeśli będziesz nadawał same 0xFF to co 10 bitów będzie pojawiał się bit startu = 0 a to wystarczy, by podtrzymać transceiver RS485 w stanie nadawania. Dopiero zaprzestanie transmisji znaków spowoduje, że w 2ms później nastąpi automatyczne przejście na nasłuch. Dioda wprowadza asymetrię w opóźnieniu. To tak, jakby w jedną stronę opornik był mały (kilkadziesiąt omów) a w drugą 200k.

Ten układ jest prymitywny jak cep, bo nie rozumie co się nadaje. Nie obchodzą go formaty danych, ramki itp. Widzi tylko jedynki i zera i dlatego musi być dopasowany do szybkości transmisji. Jeżeli nadajesz z prędkością 9600, to na każdy bit przypada 1/9600s czyli ok. 100us. Cały znak, składający się z bitu startu, 8 bitów danych i bitu stopu ma 10 bitów czyli trwa ok. 1ms. Tak więc, nawet jeśli ostatni znak będzie 0xFF, to jego bit startu wyzwoli nadawanie na ostatnie 2ms które "pokryją" sam znak i jeszcze 1ms "ciszy". Protokół Modbus przewiduje takie zachowanie i wymusza, by urządzenia odpowiadały nie szybciej niż po przerwie trwającej ok. 3.5 długości znaku. To właśnie jest czas potrzebny na przełączenie kierunku transceiverów. Gdyby prędkość transmisji była inna, trzeba by zmodyfikować opóźnienie "trzymania" nadawania.

Czy to jest jasne? No to schemat i miejmy to z głowy 🙂 :

Układ 74HC14 musi być zasilany. Tego na schematach bramek zwykle się nie rysuje by nie zaciemniać, ale pamiętaj by pin 14 podłączyć do +3.3V a pin 7 do GND.

Nieużywane wejścia pozostałych trzech inwerterów musisz podłączyć do czegoś sensownego - nie mogą wisieć "w powietrzu". GND jest dobrym pomysłem. Jeden z tych nadmiarowych inwerterów możesz też wykorzystać np. do sterowania diodką LED pokazującą aktualny kierunek transmisji. Niech np. świeci gdy nadajesz 🙂 - od razu będzie widać czy coś się na drutach dzieje.

Na powyższym schemacie wyjście DE powinno być także pociągnięte do /RE transceivera RS485 żeby blokować odbiór własnych danych, ale nie wiem czy jest to konieczne w tej konkretnej implementacji biblioteki. Jeżeli ta akurat radzi sobie z powracającymi własnymi danymi, to odbiornik może być zawsze włączony i jego /RE możesz podpiąć na stałe do GND. Rozwiązanie ze sterowaniem zwartymi DE=/RE jest oczywiście bezpieczniejsze.

EDIT: Kilka zdań wyjaśnień dopisałem po przeczytaniu i próbie zrozumienia 🙂

Wreszcie się odkopałem z innych rzeczy i jutro zamierzam podłączyć wszystko. Będę informować jak wyszło 🙂

Edit:

Dioda Shottky-iego może być 1N5819 ? Bo mam akurat takie.

Kupiłem złe kondensatory :/ zamiast 10nF to 10uF 😉 Jutro podejdę i kupie dobre.

Obecnie włącza 1 na DE i wysyła dobrze , zaś ze względu że nie mam odpowiedniego kondensatora dostaję CRC przy odczycie.

Ok przetestowane i w dalszym ciągu dostaję CRC

rc 1
write OK!
Reading regs:
[80][03][00][00][00][01][9A][1B]
Waiting for a confirmation...
<80><03><00><00><00>
ERROR CRC received 0 != CRC calculated 70D8
[80][03][00][01][00][01][CB][DB]
Waiting for a confirmation...
<80><03><00><01><00>
ERROR CRC received 100 != CRC calculated 70D8
[80][03][00][02][00][01][3B][DB]
Waiting for a confirmation...
<80><03><00><02><00>
ERROR CRC received 200 != CRC calculated 70D8
[80][03][00][03][00][01][6A][1B]
Waiting for a confirmation...

Zapisywać zapisuje, tylko widać jakby nie odbierał wszystkiego i tylko urywał połączenie bez czekania na zakończenie odbioru.

/RE mam podłączone do GND bo połączone z DE nie działa i dostaję wtedy "ERROR Connection timed out"

W stanie gdy nie komunikuje się na TDX mam stan 1. Podłączyłem tez diodę aby zobaczyć czy stan się zmienia i dioda miga gdy odpalę program.

Widzisz, to trochę zaczyna wyglądać tak, jakbyś oczekiwał, że ja z dalekiego miejsca zgadnę i napiszę Ci co byś widział na swoim oscyloskopie gdybyś go miał i podłączył. To trochę głupie, nie?

Byłoby miło, gdybyś komentował te swoje cytaty z ekranu bo skąd niby mam wiedzieć co oznaczają kolejne linie. Mam cichą nadzieję, że chociaż Ty wiesz. Zanim jednak to nastąpi, napiszę ci jak rozumiem to co widzę. Podpieram się tym opisem protokołu Modbus:

http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf

No to mamy:

[80][03][00][00][00][01][9A][1B]

To jest ramka wysyłana z Maliny do slave'a, zawierająca:

80 - adres modułu slave (czyli tej zielonej płytki - czy taki miał być?)

03 - kod operacji Read Holding Registers (str. 15 w opisie protokołu)

0000 - adres pierwszego odczytywanego rejestru

0001 - liczba odczytywanych rejestrów

9A1B - kontrolne CRC

Jak powinna wyglądać odpowiedź? Mniej więcej tak:

<80><03><02>

gdzie:

80 i 03 znaczą to samo co w zapytaniu,
02 - długość odpowiedzi (liczona w bajtach, rejestry są 16-bitowe a prosiłeś o jeden)

xxxx - zawartość odczytywanego rejestru

CRC- wiadomo

a jak wygląda rzeczywiście?

<80><03><00><00><00>

Widzisz jakąś korelację? Z czym? No właśnie, to jest Twoje własne zapytanie zinterpretowane jak odpowiedź. Ponieważ zaraz po 80 03 jest bajt = 00 to znaczy, że nie ma pola danych i końcowe 00 00 zostały potraktowane jak CRC. Dla takiej ramki powinno ono wynosić 70D8 a odebrało się 00 00, co potwierdza poniższy komunikat:

ERROR CRC received 0 != CRC calculated 70D8

Dalej jest to samo kilka razy. Jak myślisz dlaczego tak się dzieje? Coś świta? Podłączając /RE do masy spowodowałeś, że do odbiornika Maliny wracają jej własne zapytania. Gdy wysyłanie zostanie zakończone, nagle okazuje się, że w buforze odbiornika jest już jakaś odpowiedź. Czytamy ją i jest błędna, no to wypisujemy komunikat alarmowy. Moim zdaniem powinieneś zewrzeć DE z /RE i dopiero wtedy zacząć zastanawiać się dlaczego nie działa. Wyciągasz ruskie wnioski, bo działa "lepiej" gdy coś w ogóle odbiera? Przykro mi. Musisz blokować odbiornik podczas nadawania. Zrób tak i przyjrzyj się dokładnie otrzymywanym odpowiedziom.

Czy coś w ogóle przychodzi? Czy timeout oznacza, że zielona płytka nic nie wysyła czy może nie przychodzi tyle bajtów ile trzeba? Może ma inny adres albo wysyła w trybie 4-drutowym i w związku z tym nie na tej parze? Może gubimy tylko pierwszy bajt a potem składnia odpowiedzi rozpada się bo odbiornik inaczej interpretuje nadchodzące znaki? Musisz to wiedzieć. Układ przełączania jest zrobiony bezpiecznie, 2ms po ostatnim bicie startu. Czy na pewno pracujesz na 9600? Możesz ten czas skrócić przez np. 2-krotne zmniejszenie opornika w obwodzie RC. Być może będziesz jednak musiał poprosić o pomoc kolegę z oscyloskopem. Nie wszystko da się rozwiązać przez domyślanie się i gdybanie. Z resztą trochę szkoda na to czasu. Mojego i Twojego. Typowo taki problem rozwiązuje się jednym pomiarem w czasie 30 sekund, więc może nie ma co brnąć w domysły.

Jest tak jak piszesz.

Ok połączyłem /RE i DE razem, poniżej wynik

Opening /dev/ttyAMA0 at 9600 bauds (N, 8, 1)
Slave_address: 128
Setting reg 00 val: 38
[80][06][00][00][00][26][16][01]
Waiting for a confirmation...
ERROR Connection timed out: select
Bytes flushed (0)
rc -1
write Faild!
Reading regs:
[80][03][00][00][00][01][9A][1B]
Waiting for a confirmation...
ERROR Connection timed out: select
Bytes flushed (0)
[80][03][00][01][00][01][CB][DB]
Waiting for a confirmation...
ERROR Connection timed out: select
Bytes flushed (0)

Postaram się podejść do znajomego i sprawdzić to oscyloskopem.

Dzięki za pomoc.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...