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

UART Atmega8 przesylanie wartosci z ADC i generowanie PWM

idzik15 08 Kwi 2016 19:27 1467 25
REKLAMA
  • #1 15589601
    idzik15
    Poziom 9  
    Witam,

    Tworzę prosty nadajnik i odbiornik do sterowania wykorzystujący do tego dwie Atmegi8. W nadajniku mam potencjometry. Sygnal jest konwertowany przez ADC i nastepnie wysylany do odbiornika, gdzie generowany jest sygnal PWM do serwomechanizmów.

    Problem polega na tym żeby odbiornik rozróżniał, z którego potencjometry wysyłana jest wartość i żeby odpowiedni serwomechanizm tą wartość otrzymał.

    Myślałem nad jakimś sposobem adresowania każdego potencjometru i póki co najbliżej działający pomysł wygląda tak:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Generalnie pomysł polega na tym, że idzie 1 bajt "adres", następnie 1 bajt "dana". I tak w kółko. Tylko mam problem z zaimplementowaniem tego.

    Sam ADC, PWM, UART itd działają OK kiedy przesyłam jedną wartość ( to jest tylko z jednego potencjometru, drugi mam zakomentowany). Kiedy mam oba to też działa ale ewidentnie sypią się błędy bo jednym potencjometrem czasami steruję jednym serwem a czasami dwoma.

    Za wszelką pomoc i sugestie dzięki :)
  • REKLAMA
  • #2 15589620
    Konto nie istnieje
    Poziom 1  
  • #3 15591918
    idzik15
    Poziom 9  
    Radzio M. napisał:
    Ramka komunikacyjna może być wysyłana np. co 100ms i wyglądać tak:

    '$' value_1':'value_2'#'

    gdzie znak '$' to początek transmisji, następnie wysyłana jest wartość 1, znak ':' separuje wartości i po nim następuje wysłanie wartości 2, znak '#' kończy komunikat. Dodatkowo można dorobić jakąś prostą sumę kontrolną.
    A tak na boku to po co 2 uC?


    A jak to zaimplementować w C?

    2uC jest w odbiorniku. Jeden w module nadawczym, drugi w odbiorczym :) polaczenie miedzy nimi za pomoca wlasnie UARTu
  • #4 15591951
    Konto nie istnieje
    Poziom 1  
  • #5 15603448
    idzik15
    Poziom 9  
    Zdecydowałem się na wykorzystanie tokenów.

    Wyglada to tak:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Z nadajnika wysyłam coś takiego (narazie stałe wartości w ramach testowania, później będą to odczyty z ADC):

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Problem polega na tym, że funkcja odbiorcza nie rozróżnia mi (nie wiem czemu) poszczególnych, powiedzmy adresów.
    To jest:

    Wysyłam z nadajnika tylko ramkę dla "silnik0". Odbiornik odbiera, ale nie przypisuje tego "silnikowi0", a pierwszemu napotkanemu (w funkcji analizuj_dane_rs232), czyli "silnik2". Reszta komend w nadajniku jest zakomentowana.

    Z kolei kiedy wyślę tylko komendy dla diody1 i diody2 (lecz komendy dla silników i serwa są zakomentowane) to odbiornik już rozróżnia prawidłowo. Kiedy jednak dodam do tego jeszcze komendę dla np. serwa to już się sypie i serwo dostaje jakiś misz masz.

    Suma sumarum wydaję mi się, że błąd polega po stronie odbiorczej. Coś chyba nie tak ze wskaźnikiem. No chyba, że nadajnik też miesza bajty, choć mało prawdopodobne.
  • #6 15604394
    Konto nie istnieje
    Konto nie istnieje  
  • #7 15604563
    idzik15
    Poziom 9  
    Prosze powiedz mi, ktory listing jest dla Ciebie trudny do przeanalizowania ze wzgledu na "balagan"?

    Wyswietlacza niestety nie mam. Sprobuje metody z testowaniem w "nadajniku"/
  • REKLAMA
  • #8 15604722
    Sparrowhawk
    Poziom 22  
    No tabulacja chyba na 8 znaków długa. Co druga linia jest pusta. Po co nam zakomentowany kod?

    Do tego masz zagłębienie w if'ach do co najmniej trzeciego poziomu. Po co takie długie tokeny?

    Może podłącz ten odbiornik do PC i testuj z użyciem jakiegoś terminala?
  • #9 15605050
    idzik15
    Poziom 9  
    Mam to tak napisane, bo dla mnie jest przejrzyściej niż linia w linie coś.
    Zapomniałem odkomentować - przykład kopiowałem zaraz po testowaniu, gdzie akurat tą część kodu wyłączyłem ze względu, że ona działa kiedy wysyłam tylko te komendy (dioda1/2), o czym wspomniałem wcześniej.

    takie tokeny wynikają z urządzeń podłączonych do uC.

    np.
    $ , serwo , wartosc z adc \r\n
    $ , dioda1, zapal / zgas \r\n
    itd.

    Jedyne czego mógłbym się pozbyć to '$', które oznacza u mnie początek ramki.

    Myślałem o podłączeniu do PC. Problem taki, że nie posiadam obecnie konwertera usb-rs232, czy bluetooth
  • #10 15605243
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #11 15605270
    idzik15
    Poziom 9  
    No to się nie obędzie bez tego najprawdopodobniej.

    Tylko nadal nie rozumiem i nikt nie postarał się nawet w tej kwestii pomóc, że kiedy wysyłam komendy dla diod LED, to wszystko jest odbierane prawidłowo i komunikaty są rozróżniane bez żadnych problemów. A chrzani się w przypadku, gdy wysyłam wartość liczbową zamienianą oczywiście na string (dla serwa bądź to silnika), a następnie przy odbieraniu tak jakby mi wskaźnik przestał wskazywać dobrze. Oczywiście konwersja ze stringu do liczby następuje przy użyciu funkcji atoi();
    Dodam, że kod opiera się na kodzie opisanym przez Mirka Kardasia w BB i GB.
  • #12 15605319
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #13 15605390
    idzik15
    Poziom 9  
    Oczywiście, że sprawdziłem. Kiedy wysyłam tylko komendę dla serwa (reszta komend zakomentowana) z jedną wartością np. 20, odbierana jest ona prawidłowo, a serwo trzyma zadaną pozycję. Nawet więcej - podłączyłem potencjometr i wszystko działa OK.
  • #14 15605432
    Konto nie istnieje
    Konto nie istnieje  
  • #15 15605438
    idzik15
    Poziom 9  
    Chodzi o to, że wysyłam np. liczbę 25 i jeżeli zostanie ona odebrana (a pozniej konwersja atoi() ) to np. zapali się LED? Sprawdziłem - działa
  • #16 15605459
    Konto nie istnieje
    Konto nie istnieje  
  • #17 15605508
    jnk0le
    Poziom 18  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    A te funkcje działają prawidłowo ?
  • #18 15605509
    idzik15
    Poziom 9  
    Może wcześniej nie jednoznacznie napisałem.

    Wysyłam 1 komendę z wartościa - DZIAŁA
    Wysyłam 2 różne komendy z wartościami - NIE DZIAŁA (tzn coś działa ale źle)

    Wysyłam komendy tylko tekst (do LEDÓW) - DZIAŁA
    Wysyłam to co powyżej (ledy) + 1 komendę z wartościa - NIE DZIAŁA
  • #19 15605622
    Sparrowhawk
    Poziom 22  
    Bo jak byś normalnie formatował ten kod to innym łatwiej było by go analizować.

    Najpierw proponuję usunąć te średniki po if'ach.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #20 15605708
    idzik15
    Poziom 9  
    Ok przesyłam ponownie.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Sparrowhawk napisał:
    Bo jak byś normalnie formatował ten kod to innym łatwiej było by go analizować.

    Najpierw proponuję usunąć te średniki po if'ach.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Bardzo prawdopodobne (raczej na pewno), że to jest przyczyną błędów. Sprawdzę wieczorem i dam znać czy działa.
  • #21 15610521
    idzik15
    Poziom 9  
    To było to. Teraz działa :) Głupi błąd, którego nie zauważyłem tymbardziej, że dla diod miałem dobrze napisane.

    Tak więc gdy teraz przesyłam polecenia dla serw/silników (4 naraz) to wszystko śmiga.

    Jednak pozostał problem w przypadku, gdy do nadawanych poleceń dla serw/silników dorzucę również polecenia dla diod LED. Gdy przesyłam wszystkie - diody nie reagują, a reszta tak.
    Z kolei gdy zakomentuję serwa/silniki, czyli zostaną tylko komendy dla diod to wtedy diody śmigają.

    Zrobiłem, też taki test, że do if'ów (dla led) wrzuciłem komendy dla serw/silników. I wtedy znów działają tylko serwo/silniki.

    Tak wygląda kod z poleceń nadawanych:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    A tak z funkcji odbierającej:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #22 15611449
    Sparrowhawk
    Poziom 22  
    Nie rozumiem jak to mogło działać? Przyjrzyj się tej instrukcji: wsk = strtok( NULL , "," ); w kontekście tego co wysłasz dla ledów.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Więc aby powyższy kod działał, to należy wysłać:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #23 15611751
    idzik15
    Poziom 9  
    Niestety, nie pomogło, dalej ten sam problem jest :(
  • #24 15611953
    Sparrowhawk
    Poziom 22  
    A zmieniłeś to dla jednej i drugiej diody?
    Po za tym ten kod z nadajnika jest wątpliwej jakości, zwłaszcza sprawdzanie stanu portów.

    A tak w ogóle, to nie lepiej napisać tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #25 15611961
    Konto nie istnieje
    Konto nie istnieje  
  • #26 15621087
    idzik15
    Poziom 9  
    Niestety nie znalazłem póki co przyczyny dlaczego działa tak, a nie inaczej. Po zakupie usb-rs232 i paru innych zabawek może mi się uda. Póki co dziękuję wszystkim za wypowiedzi.

    Wątek ten był zakładany w innym dziale, ale został tu przerzucony przez jakiegoś admina, więc jak coś to skargi do adminów ;)
REKLAMA