Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 28 mar 2024, o 16:29


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 18 ] 
Autor Wiadomość
PostNapisane: 15 paź 2017, o 09:58 
Offline
Użytkownik

Dołączył(a): 29 maja 2013
Posty: 33
Pomógł: 0

Witam. Mam problem z funkcją odbierania danych z RS232: procesor się na niej zacina. Czasem nie odbiera nic, czasem odbiera dane przesunięte o kilka bajtów, czasem odbiera krzaki.

Funkcja, którą napisałem, do odbierania danych i zapisywania ich do odpowiednich zmiennych:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


I funkcja UR() (z noty aplikacyjnej ATmegi16)
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Komputer wysyła dane w prawidłowej kolejności, czyli gdy wyśle znak 'c' to potem lecą dwa razy po 6 znaków.
Następnie te dane są wysyłane po SPI do innych procesorów, a te procesory wyświetlają je na swoich wyświetlaczach. I tu pojawia się problem:
na wyświetlaczach LCD procesorów Slave nie pojawia się to co wysyłam z komputera.

Debugowałem to diodą i Putty. Doszedłem do takich wniosków:
1. SPI działa prawidłowo. Problem leży w części komputer - przejściówka - procesor Master
2. Przejściówka działa prawidłowo
3. W zmiennych w procesorze Masater nie jest to co wysłałem z komputera. Więc problem leży w odbieraniu danych.

Dodatkowo po debugowaniu Putty doszedłem do wniosku, że po zakomentowaniu funkcji Receive() procesor działa prawidłowo (tylko danych nie odbiera). Nie zawiesza się. Main() po debugowaniu wygląda tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Natomiast gdy Receive() nie było zakomentowane to procesor wysłał kilka razy wszystkie zmienne, a potem przestał. Zawiesił się.

Domyślam się, że coś zepsułem z pętlami w tej funkcji, że nie tak się powinno odbierać te dane. Tylko w takim razie jak odebrać jeden znak (powiedzmy 'n') a następne 6 odebranych znaków zapisać do jednej zmiennej, a jeszcze kolejne 6 do innej zmiennej i potem kolejny znak, 12 znaków, jeden znak, 4 znaki i tak w kółko?

PS: Oczywiście checklisty do RS232 i filmy Pana Mirka o RS232 obejrzałem i wszystko działało jak na filmach



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 10:28 
Offline
Użytkownik

Dołączył(a): 25 lip 2013
Posty: 2561
Pomógł: 126

Po pierwsze spróbuj odsyłać do PC to co z niego odebrałeś.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 10:46 
Offline
Użytkownik

Dołączył(a): 29 maja 2013
Posty: 33
Pomógł: 0

Próbowałem zapętlić samą przejściówkę zworką na Rx i Tx z pominięciem procesora. Takie echo działa.
Ale odsyłanie z procesora tego co odebrałem nie działa prawidłowo. Już próbowałem, wyglądało to tak:
w pętli, powiedzmy 'c' zaraz po przypisaniu odebranej wartości do com[i] = UR(); dałem aby wysłał USART_Transmit(com[i]);. Nie wysyłał nic. Najprawdopodobniej zdążył się zawiesić



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 11:05 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 17 paź 2013
Posty: 45
Pomógł: 2

Zrób tak jak Mirek zawsze pokazuje. Czyli najpierw uruchom podstawową komunikację - odbieranie i wysyłanie pojedynczego znaku pomiędzy komputerem a atmegą. Potem dodaj jedną funkcę i sprawdź czy działa. Potem kolejną - za każdym razem kopmpiluj i wgrywaj. Wylapiesz problem na etepie pisania softu. No i wywal tego paskudnego _delay_ms ;)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 11:15 
Offline
Użytkownik

Dołączył(a): 29 maja 2013
Posty: 33
Pomógł: 0

Dokładnie tak robiłem. Wszystko działa do etapu bardziej rozbudowanego odbierania danych, czyli funkcji Receive(). Podstawowe wysyłanie działa, podstawowe odbieranie działa. Podstawowe echo działa. Wszystko działa. Gdy dodałem funkcję Receive() zaczyna się sypać, zawieszać, nie odbiera danych prawidłowo. Tylko właśnie nie rozumiem jak odbierać takie ciągi danych na bieżąco.
Nie wiem czy on nie nadąża? Czy może powinienem to zrobić w przerwaniach i zamiast w locie przechwycić daną i ja zapisać do zmiennej to zapisywać wszystko do jakiegoś bufora i potem z niego je odczytać i zapisać do zmiennej? Tylko tu nie wiem czy taki bufor by się nie przepełnił. Komputer cały czas wysyła dane, a procesor musi je odebrać, odczytać, przypisać do zmiennych i rozesłać do pozostałych procesorów po SPI (a tych procesorów i zmiennych będzie więcej... Sporo więcej, na razie są dwa procesory Slave)

A delay jest tylko do debugowania :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 11:18 
Offline
Użytkownik

Dołączył(a): 25 lip 2013
Posty: 2561
Pomógł: 126

Sprawdzanie zworką rx-tx sprawdza hardware i dobrze, że to też sprawdziłeś. Teraz zrób jak proponuje kolega Espablo - odpal najprostszą komunikację i odeślij to, coś odebrał.
P. S. Taktowanie procka i parametry transmisji masz dobrze ustawione? Patrzyłeś w pdf'a procka jaki procent błędów jest dla wybranych przez Ciebie parametrów?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 11:36 
Offline
Użytkownik

Dołączył(a): 29 maja 2013
Posty: 33
Pomógł: 0

Najprostsze funkcje z filmów Pana Mirka i z PDF do odbierania i wysyłania działają perfekcyjnie. Przerobiłem dosłownie wszystkie filmiki o RS232, zarówno sprzętowe jak i programowe. Wszystko działo się dokładnie tak jak u Pana Mirka. Krzaki były w tym samym momencie, wysyłanie znaku 'A' działało też w tym samym momencie. Więc tu mam wszystko prawidłowo skonfigurowane.

Procek taktowany 16MHz z zewnętrznego kwarcu, baud rate 9600. Procent błędu 0.2%
Putty ustawione na 9600-n-1. Program na PC wysyłający dane też ustawiony na 9600-n-1

Od tej strony wszystko sprawdziłem kilka razy. Sprawdzałem nawet czy kabel USB idący obok trzech kabli zasilających nie zbiera jakiś zakłóceń i też wszystko wygląda prawidłowo.

Dodam jeszcze coś o czym zapomniałem napisać na początku:
Gdy wysyłałem tylko 't' i 4 znaki już widziałem, że te dane się trochę rozjeżdżają. Teraz te wszystkie dane wysyłam z pewnym opóźnieniem, bo wydawało mi się, że coś tu nie nadąża i widać wyraźnie, że coś tu nie działa.

I jeszcze jedno: zdarza się, że przez jakąś godzinkę wszystko działa prawidłowo. To jest losowe. Ale najczęściej to nie działa. Gdy był czas, że to nie działało zacząłem debugować, żeby się dowiedzieć w czym dokładnie leży problem. Wtedy sprawdziłem diodą czy powiedzmy nav[2] == '3'. Gdy wysłałem takie dane, że dioda powinna się zaświecić to nie świeciła się. Czyli nie odebrał tego prawidłowo.
Debugowałem w Putty w taki sposób:
co sekundę wysyłałem 'A'. Działało.
Odbierałem dane wysyłane "z palca" po Putty i je odsyłałem ('A' też wysyłałem). Działało.
Włączyłem wysyłanie danych po SPI. Nadal wysyłał 'A', czyli działa
Włączyłem Receive(); Wysłał 'A' kilka razy co sekundę, potem parę razy kilka sekund wolniej. Potem się zaciął na dobre. Stąd wiem na pewno, że to problem z funkcją Receive()



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 11:56 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 17 paź 2013
Posty: 45
Pomógł: 2

kanaron napisał(a):
Domyślam się, że coś zepsułem z pętlami w tej funkcji, że nie tak się powinno odbierać te dane. Tylko w takim razie jak odebrać jeden znak (powiedzmy 'n') a następne 6 odebranych znaków zapisać do jednej zmiennej, a jeszcze kolejne 6 do innej zmiennej i potem kolejny znak, 12 znaków, jeden znak, 4 znaki i tak w kółko?

To się nazywa parsowanie danych i rewelacyjnie jest opisane w zielonej książce Mirka

Ja na Twoim miejscu zrobiłbym sobie funkcję, która po odebraniu np 'n' ma coś wykonać. Na razie tylko 'n' i nic więcej i na tym bym się skupił. Potem dodawałbym kolejne i za pomocą case przełączałbym się pomiędzy nimi



Ostatnio edytowano 15 paź 2017, o 12:00 przez Espablo, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 11:59 
Offline
Użytkownik

Dołączył(a): 29 maja 2013
Posty: 33
Pomógł: 0

Niestety zielonej książki nie mam, ani nie ma jej w żadnej bibliotece (ani na uczelni ani w pobliżu).
Mógłbyś jakoś przybliżyć ten temat?

PS: Cofam co powiedziałem. W pobliskiej bibliotece zaopatrzyli się w Greenbook ;) I nawet nie jest wypożyczony, więc jutro go dostanę :D
Niemniej jakbyś mógł przekazać jakieś wskazówki co powinienem "przygotować" w kodzie? Niedziela cała wolna, szkoda by było siedzieć nad tym bezczynnie ;)

PS2: Dzięki, zaraz taką funkcję napiszę.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 12:44 
Offline
Użytkownik

Dołączył(a): 25 lip 2013
Posty: 2561
Pomógł: 126

A masz jakikolwiek analizator stanów logicznych? Nawet ten najtańszy? Do interface'ów komunikacyjnych to moim zdaniem niezbędne narzędzie.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 13:02 
Offline
Użytkownik

Dołączył(a): 29 maja 2013
Posty: 33
Pomógł: 0

Nie, nie mam żadnych. Ale powiedz mi co miałbym przeanalizować, jakie masz podejrzenia? Komunikacją RS232, bawię się nie od wczoraj ;) Nad tym konkretnym błędem, który opisuję siedzę kilka dni i próbowałem wielu rozwiązań, wiele debugowałem i wiele testowałem, wszystkiego co już zrobiłem na pewno tu nie opisałem, bo za dużo tego było. Może już sprawdziłem to co podejrzewasz :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 13:09 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27212
Lokalizacja: Szczecin
Pomógł: 1041

Z tego co pobieżnie przeczytałem to twoim problemem jest to - że zamiast sobie ułatwiać życie to sam utrudniasz - tak mi się wydaje. Bo zamiast stosować komunikację ASCII czyli o ramki zakończone enterem - to ty brniesz tak na prawdę w transmisję binarną i to co opisujesz to jest PIERWSZY TYPOWY efekt początkującej osoby w tym zakresie ...

kanaron napisał(a):
Ale powiedz mi co miałbym przeanalizować, jakie masz podejrzenia?

Zobacz Pan sobie to:



i nie chodzi tu koledze micky o podejrzenia - tylko o to - jak łatwo sprawdzić dzięki analizatorowi gdzie robisz babola - bo takiego robisz niestety - dzięki analizatorowi w 5 sekund zobaczyłbyś co się dzieje na kablach ;)

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 13:25 
Offline
Użytkownik

Dołączył(a): 29 maja 2013
Posty: 33
Pomógł: 0

Jeszcze co do tego co miałem zrobić z funkcją:
Wyrzuciłem wszystko z funkcji Receive()
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


To powinno zadziałać. Funkcja test() to proste zgaszenie diody na sekundę i ponowne zapalenie. Z głównej pętli programu wywaliłem wszystko. Została tylko ta funkcja Receive(). Żadnych zbędnych _delay_ms. I... nie działa :shock: Wysyłam przez Putty 'n' i nic. Dopiero jak przytrzymam klawisz 'n' dłużej to wtedy dioda zgaśnie na sekundę (czasem kilka razy)... Czyli coś gdzieś się gubi... Zaraz znowu spróbuję najprostszą transmisję zrobić, czyli echo z procka, bo trochę teraz zgłupiałem... Spróbuję też to przenieść na stykówkę, bo może mi coś na płytce prototypowej nie styka.


mirekk36 napisał(a):
zamiast stosować komunikację ASCII czyli o ramki zakończone enterem - to ty brniesz tak na prawdę w transmisję binarną i to co opisujesz to jest PIERWSZY TYPOWY efekt początkującej osoby w tym zakresie ...


Przyznaję, że do tej pory zajmowałem się tylko transmisją binarną i... działało w taki sposób jaki miało. Ale to były projekty z innymi założeniami.

Dzięki, zaraz obejrzę ten film :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 13:26 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 paź 2014
Posty: 1020
Lokalizacja: Trójmiasto
Pomógł: 188

kanaron napisał(a):
Włączyłem Receive(); Wysłał 'A' kilka razy co sekundę, potem parę razy kilka sekund wolniej. Potem się zaciął na dobre. Stąd wiem na pewno, że to problem z funkcją Receive()
Nie dokońca musi to być wina funkcji Receive(), może po prostu połączenie kilku czynników sprawia problem. Transmisję UART masz zbudowaną w sposób blokujący, nie wiem jak wygląda Twoje ISP, ale może wszystko się rozjeżdża bo procek nie nadąża ze wszystkim. Masz BB a w nim masz przecież opisaną transmisję UART z buforem cyklicznym - możesz go tak zmodyfikować by bufor reagował na znaki t, n , c a następnie pobierał twoje 6 kolejnych znaków i wtedy bufor wystawia flagę że odebrany cały ciąg gotowy do przesłania dalej.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 13:47 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27212
Lokalizacja: Szczecin
Pomógł: 1041

xentis napisał(a):
Masz BB a w nim masz przecież opisaną transmisję UART z buforem cyklicznym - możesz go tak zmodyfikować

No toż od tego warto w ogóle zacząć, bo i do binarki buforowanie się przydaje - a wtedy trzeba sobie już tylko obrabiać w buforze własny format ramek i obsługiwać timeouty

Tymczasem:
kanaron napisał(a):
rzyznaję, że do tej pory zajmowałem się tylko transmisją binarną i... działało w taki sposób jaki miało

Jeśli działałeś tak jak tutaj i bez buforowania to po prostu trafiałeś akurat na pomyślny splot okoliczności, że ci działało ...

tak jak wyżej kolega pisze - to co robisz - nawet bez delayów jest tu mega blokujące

Cytuj:
char UR( void ) {
while ( !( UCSRA & ( 1 << RXC ) ) );
return UDR;
}


czy nie widzisz tutaj pętli nieskończonej ? Przy twoim podejściu do tej niby binarki to to - jest właśnie pierwszy gwóźdź do elektronicznej trumny, więc jeśli gdzieś ci się procek zawiesza - to właśnie tutaj na tej pętli nieskończonej ... niestety przy takim podejściu i próbie budowania już ciut rozbudowanej komunikacji binarnej ZAWSZE będą takie efekty - zawsze

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 13:55 
Offline
Użytkownik

Dołączył(a): 29 maja 2013
Posty: 33
Pomógł: 0

Znaczy do tej pory działałem w drugą stronę: binarna transmisja z urządzenia do komputera i obrabianie tego na PC. W ten sposób zawsze działało. Natomiast wysyłanie z PC do procka to jeszcze nigdy przedtem nie robiłem.

A funkcję UR() szczerze mówiąc wziąłem na ślepo z pdf'a ATmegi16. Nad nią za długo nie siedziałem, nie analizowałem jej, zaufałem Atmelowi ;) . Tyle co nazwę funkcji zmieniłem.

Za chwilkę przerobię kod na ten z BB :D



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 14:01 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27212
Lokalizacja: Szczecin
Pomógł: 1041

kanaron napisał(a):
Natomiast wysyłanie z PC do procka to jeszcze nigdy przedtem nie robiłem.

a no to nie ma co się martwić - każdy z nas musi przejść tę drogę ;) .... ale dlatego ci mówię - że MILION razy lepiej robić to metodą ASCII a nie binarną - szczególnie na starcie

kanaron napisał(a):
A funkcję UR() szczerze mówiąc wziąłem na ślepo z pdf'a ATmegi16. Nad nią za długo nie siedziałem, nie analizowałem jej, zaufałem Atmelowi

A czemu miałoby się nie ufać - toż to MEGA PODSTAWOWA funkcja i tylko chwalić Atmela, że w swoich notach ładnie pokazuje najprostsze przykłady - toż nigdzie nie znajdziesz w żadnej nocie procka ;) żadnej rodziny - jakichś rozbudowanych przykładów ;) nie ma takiej możliwości

W BB zajrzyj do przykładu projektu wielozadaniowego - jak już przerobisz i zaskoczysz rozdział o buforowaniu cyklicznym bo to PODSTAWA PODSTAW przy działaniach z UARTem - bo w tym projekcie wielozadaniowym masz przykłady jak reagować na pojedyncze odbierane znaki

a jak będziesz chciał w końcu do tego podejść tak jak się należy - to weźmiesz GB w łapki i tam zobaczysz jak to się robi poprawnie na zdarzeniach z callbackami itp ...

zajrzyj do byle pierwszego mojego poradnika wideo gdzie coś robię z komunikacją UART (z ostatnich poradników) a jest ich sporo - to zobaczysz JAK MEGA PROSTO się korzysta z tego mechanizmu opisanego w GB

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 paź 2017, o 18:41 
Offline
Użytkownik

Dołączył(a): 29 maja 2013
Posty: 33
Pomógł: 0

Więc... Co zrobiłem przez ostatnie godziny:
-przeczytałem kilkukrotnie rozdział z BB o UART.
-Napisałem po swojemu ten program. Nie działa. Wysyła, nie odbiera, nie przypisuje do zmiennej, dioda debugująca nie zaświeca się. Jedno co dobre z tego wyszło to to, że zrozumiałem w końcu przerwania :D Tylko czemu tak długo się ich obawiałem?
-Przeczytałem raz jeszcze, niemal przepisałem żywcem kod z książki. Nie działa.
-Wziąłem kod z płyty z BB, wgrałem, nieco zmodyfikowałem aby nie kombinował z kalibracją OSCCAL tylko, żeby wysyłał to co odbierze i zaświecał diodę gdy odbierze to co chcę aby odebrał. Nie działa. No jak to nie działa to coś jest mocno źle zrobione.
-Przeniosłem procka na stykówkę. Podłączyłem, nic nie zmieniałem w kodzie... Działa. Biorę miernik do ręki... Brak styku na linii RX od procka na płytce prototypowej... TRZY dni męczenia się z tym, a wszystko przez JEDEN kabelek... :x
Cóż... Tego się nie spodziewałem :) Widać musiał być słaby styk, dlatego raz odbierał prawidłowo, raz jakieś krzaki a raz w ogóle nic nie odbierał :D

Poprawiłem styk, przeniosłem na płytkę prototypową i działa :D

Niemniej zostaję z buforem cyklicznym, nie wracam do binarki :D

Zmodyfikowałem program, odbieram dane prawidłowo, wysyłam prawidłowo, wszystko działa perfekcyjnie :D Dzięki wielkie wszystkim :)

Szkoda tylko, że po SPI muszę wysyłać dane co 5ms między każdą daną, bo inaczej na siebie jakby nachodzą, a przez to dane z komputera muszę wysyłać z przerwami co 80ms, bo inaczej bufor mi się przepełnia... Da się jakoś przyspieszyć SPI?
PS: Już nie istotne, źle przepisałem jedną funkcję i SPI działało z dużym opóźnieniem :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 18 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 13 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO