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



Teraz jest 20 kwi 2024, o 06:12


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 9 ] 
Autor Wiadomość
PostNapisane: 4 sie 2017, o 15:07 
Offline
Nowy

Dołączył(a): 03 maja 2017
Posty: 7
Pomógł: 0

Cześć

Mam zrobioną komunikację robota z modułem <WIFI>, która bazuje na wywołaniu przerwania i przesyłaniu pojedynczych bajtów, a mianowicie przesyłam bajt za pomocą uart.write(1,"5") co skutkuje tym, że jedzie on do przodu, itp.

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


To na czym mi obecnie zależy to zrobienie czegoś podobnego, ale nie na bajtach, a na stringach. W programowaniu urządzeń typu AVR jestem zielony i mam problem ze zrealizowaniem tego.

Moje próby ograniczyły się do realizacji mojego zamysłu na sposób, a mianowicie poprzez porównywanie stringów w języku C. Opracowany fragment kodu:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Opcja else posłużyła mi do debugowania, po przesłaniu stringa za pomocą uart.write(1,"111") robot nie reaguje prawidłowo, czyli zakładam, ze to nie jest tak proste jak przypuszczałem. Natomiast coś zostaje przesłane, bo robot kręci kołami z prędkością 200, tak jak jest to uwzględnione w zwykłym else. Bardzo prosiłbym o jakieś wskazówki. Caly kod źródłowy robota dostępny jest na stronie:
http://www.wobit.com.pl/produkt/7997/ro ... -minisumo/

Podsyłam cały kod pliku Uart_komunikacja.c dla lepszego przedstawienia problemu

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


<ocenzurowano nazwę modułu wifi > -- zły mod cenzor



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 sie 2017, o 09:24 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Aidan napisał(a):
 
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Tym sposobem:
  • tablica jest tworzona przy każdym wywołaniu procedury obsługi przerwania i (jako zmienna lokalna) będzie zawierać losowe wartości,
  • każdy odebrany znak wpisujesz tylko do ostatniego elementu tablicy odebrany_bajt[] (o indeksie 3), pozostałe zawierają losowe wartości,
  • porównujesz ciąg w tablicy z wzorcem, a tablica zawiera losowe wartości i odebrany znak na końcu.
Powinieneś wpisywać odebrane znaki po kolei do tablicy, która notabene powinna być zadeklarowana jako static.
Mogłoby to wyglądać mniej więcej tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

jednak dokładna implementacja zależy od tego, w jaki dokładnie sposób terminal/program (którym wysyłasz dane do robota) kończy transmisję ciągu znaków.

Poza tym używanie większej ilości porównań strcmp() w procedurze obsługi przerwania to nie najlepszy pomysł, ze względu na dość długi czas wykonania, a obsługa przerwania powinna być jak najkrótsza. Lepiej odebrać dane do jakiegoś bufora zadeklarowanego globalnie, w procedurze ustawić tyko flagę po odebraniu całego ciągu, a dekodowanie wykonywać w pętli głównej programu.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 sie 2017, o 12:44 
Offline
Nowy

Dołączył(a): 03 maja 2017
Posty: 7
Pomógł: 0

No niestety nie działa u mnie ta metoda. Przedstawione porównywanie stringów to tylko sposób żeby jakaś zmiana była widoczna po wprowadzeniu danych do robota. To co tak naprawdę chcę zrobić to przesłać string np. w postaci: "-600,-600". String byłby odbierany przez uart w robocie, następnie poprzez kod w języku C dzielony na 2 substringi, które z kolei byłyby konwertowane do postaci int. Mając zmienne całkowite mógłbym je wstawić jako parametry funkcji odpowiedzialnej za poruszanie się robota np. motor_set_speed(substring1, substring2). Także to całe porównywanie nie jest konieczne, natomiast kluczem do całej sprawy jest odebranie jakoś stringa w wyżej wymienionej postaci, oczywiście o ile jest to możliwe.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 5 sie 2017, o 13:10 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Aidan napisał(a):
No niestety nie działa u mnie ta metoda.

No ja przecież napisałem, że to tylko przykład (zarys metody), a nie kod gotowy do użycia, ale mniej więcej tak to należy zrobić. Musisz tylko sobie dostosować kod do tego, co jest wysyłane do robota. Zwykle np. terminale na końcu ciągu dołączają znak CR (Carriage Return) lub LF (Line Feed), lub obydwa te znaki, lub nie wysyłają żadnego, mogą wysyłać znak końca ciągu '\0' lub nie, wszystko zależy od tego, jakiego oprogramowania używasz do wysyłania komend i jak jest skonfigurowane. Ja nie posiadam tych informacji, więc nawet trudno coś konkretnego doradzić.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 sie 2017, o 10:28 
Offline
Nowy

Dołączył(a): 03 maja 2017
Posty: 7
Pomógł: 0

Tu też pojawia się problem, bo nie mogę doszukać się co jest u mnie znakiem końca linii, przesyłanie do robota wykonuje poprzez linijkę kodu uart.write(1,"5"), która jest fragmentem oprogramowania modułu WiFi, z tego co wiem można także przesyłać stringi np. w postaci uart.write(1,"Hello world\n") i tutaj znak końca linii jest widoczny, natomiast w przypadku przesyłania pojedynczego znaku nie znalazłem żadnej informacji o tym...



Ostatnio edytowano 8 sie 2017, o 13:34 przez Aidan, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 sie 2017, o 16:53 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Aidan napisał(a):
Tu też pojawia się problem, bo nie mogę doszukać się co jest u mnie znakiem końca linii

Niekoniecznie jakiś musi być. Niemniej wiedza na temat tego, co jest dokładnie do robota wysyłane, jest dość kluczowa dla napisania poprawnego, działającego kodu.

Można by spróbować dowiedzieć się tego jakoś eksperymentalnie, ale sądząc po wpisie cenzora w pierwszym poście, można się spodziewać, że ten wątek skończy w nicości...



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 10 sie 2017, o 17:31 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

OK. Wątek na razie przetrwał ;), więc spróbujmy może tak.
Zakładając, że Twój pierwszy kod obsługi przerwania z odbieraniem pojedynczych znaków wysłanych przez funkcję uart.write()działał prawidłowo, można przyjąć, że żaden znak nie jest dołączany na końcu.
Aidan napisał(a):
Przedstawione porównywanie stringów to tylko sposób żeby jakaś zmiana była widoczna po wprowadzeniu danych do robota. To co tak naprawdę chcę zrobić to przesłać string np. w postaci: "-600,-600". String byłby odbierany przez uart w robocie, następnie poprzez kod w języku C dzielony na 2 substringi, które z kolei byłyby konwertowane do postaci int. Mając zmienne całkowite mógłbym je wstawić jako parametry funkcji odpowiedzialnej za poruszanie się robota np. motor_set_speed(substring1, substring2). Także to całe porównywanie nie jest konieczne, natomiast kluczem do całej sprawy jest odebranie jakoś stringa w wyżej wymienionej postaci, oczywiście o ile jest to możliwe.

Zmodyfikowałem nieco Twoje założenia:
  • funkcja motor_set_speed() przyjmuje argumenty typu int16_t, zresztą tak chyba miałeś wcześniej, nie wiem dlaczego poźniej piszesz motor_set_speed(substring1, substring2)
  • format komend to ciąg znaków:
    • znak '-' [opcjonalnie]
    • jedna lub więcej (do czterech) cyfr
    • przecinek
    • znak '-' [opcjonalnie]
    • jedna lub więcej (do czterech) cyfr
    • znak końca transmisji '\n' obligatoryjnie
Stworzyłem następującą procedurę obsługi przerwania:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Nie mam oczywiście możliwości przetestowania, więc wypróbować musisz osobiście, ale myślę, że powinno zadziałać, jeśli pierwszy kod działał (i nadal działa) prawidłowo.
Sposób reakcji na sytuacje awaryjne, kiedy format odebranego ciągu nie jest zgodny z założeniem, należy ewentualnie zmienić/dopracować w zależności od potrzeb.
Docelowo napisałbym to inaczej. Głównie chodzi mi o wyniesienie interpretacji odebranego ciągu znaków do pętli głównej. Dla testów jednak taki kod powinien być wystarczająco dobry, o ile nie masz w programie oprócz niego obsługi jeszcze kilku przerwań, ewentualnie jakichś fragmentów kodu krytycznych czasowo.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 sie 2017, o 09:07 
Offline
Nowy

Dołączył(a): 03 maja 2017
Posty: 7
Pomógł: 0

Dziekuje kolego, ze interesujesz sie tematem, bo juz powoli stracilem nadzieje. Obecnie jestem na wakacjach i nie mam jak tego przetestowac, ale jak tylko wroce bede walczyl dalej



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 wrz 2017, o 13:06 
Offline
Nowy

Dołączył(a): 03 maja 2017
Posty: 7
Pomógł: 0

Rozwiązanie sprawdziłem i działa wyśmienicie, dokładnie to czego potrzebowałem, dziękuje andrews za poświęcony czas i trafne rozwiązanie problemu :)



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: 9 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 15 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