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

KURS HOME ASSISTANT

Chcesz zautomatyzować swój dom bez skomplikowanego kodowania?
Zastanawiasz się nad wyborem sprzętu, oprogramowania i aplikacji?
Od czego zacząć przygodę z HA? Co będzie najlepsze na start?

Nasz kurs Home Assistant nauczy Cię krok po kroku, jak łatwo zautomatyzować swój dom i oszczędzić na rachunkach za prąd i ogrzewanie. Bez chmur, bez zbędnych abonamentów. Twoja przygoda z Home Assistant zaczyna się tutaj!

↓↓↓

    Szanujemy Twoją prywatność. Możesz wypisać się w dowolnym momencie.




    Teraz jest 10 lip 2025, o 21: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 ] [ Zaznacz wszystko ]
    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 ] [ Zaznacz wszystko ]
    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 ] [ Zaznacz wszystko ]
    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 9 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