Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

AVR Atmega16 - Funkcja arctg, implementacja, przykłady

AoT_Hunter_PL 05 Sie 2013 16:32 2001 11
  • #1 05 Sie 2013 16:32
    AoT_Hunter_PL
    Poziom 21  

    Witam czy mógłbym poprosić o pomoc, próbuję stworzyć funkcję arctg dla AVR Atmega16


    Czy można prosić jakiś działający prosty i szybki (dla procka) przykład funkcji arctg w C dla AVR.

    Chce zaimplementować funkcję arctg(Y/X) która miałaby jako argument podawany już wyliczony iloraz dwóch zmiennych w postaci wyniku ze znakiem.

    Domyślam się, że musiałbym wrzucać zmienne typu float (4,45)

    bo arctg(4,45)
    a arctg(445)

    to zupełnie co innego.

    Następnie chciałbym aby wynik po obliczeniu np. -78,45 był (wyliczony, ucinany lub zaokrąglany z rozdzielczością / dokładnością tylko do 1 stopnia)
    ... = 78^


    dodam od siebie, że znalazłem coś takiego na necie:

    Kod: c
    Zaloguj się, aby zobaczyć kod



    tłumaczneie z eng:

    "Szybka przybliżeniu arctan / atan funkcja

    W poszukiwaniu szybkiego zbliżenia ArcTan natknąłem tej pracy:

    "Efektywne przybliżenia dla Arcus tangens funkcja", Rajan, S. Sichun Wang Inkol, R. Joyal, A., maj 2006

    Niestety nie mam dostępu do dokumentów (IEEE pomimo płacenia za rocznego członkostwa, co za żart ...), ale na szczęście papier pojawił się w książce, że Google ma do podglądu (dla wybranych stron), "Usprawnienie przetwarzania sygnału cyfrowego: a sztuczki z handlu przewodnika ". Jeszcze więcej szczęścia, Google miał ważnych stron na podglądzie. Przedstawiono 7 inny zbliżenia, każdy z różnym stopniem dokładności i złożoności.

    Oto jeden algorytm Próbowałem, który ma zgłoszonego błędu maksymalna 0,0015 radianów (0,085944 stopni), najniższy błędów w pracy.

    Poprawny zakres dla x jest między -1 i 1. Porównując powyżej standardowej funkcji atan C do 1.000.000 połączeń przy użyciu GCC daje

    FastArcTan 17,315 [ms]
    Standardowy C atan 60,708 [ms]

    O 3x razy szybciej, bardzo dobre!
    "


    Tu jest masowo opisane trochu po eng, ale ja tego jeszcze nie kumam :/
    http://www.coranac.com/documents/arctangent/


    z góry dziękuje za pomoc.

    0 11
  • #2 05 Sie 2013 17:45
    tmf
    Moderator Mikrokontrolery Projektowanie
  • #3 05 Sie 2013 18:28
    AoT_Hunter_PL
    Poziom 21  

    Witam Panie Tomku, jeszcze nie .. naczytałem się, że wbudowana funkcja arctg może nieźle zamulić procka.

    Ogólnie chcę zmierzyć przesunięcie fazowe pomiędzy dwoma sygnałami.

    Chciałbym aby to w miarę płynnie poszło dlatego poszperałem za jakimiś alternatywami.

    Czytałem też że można zrobić tablice z wartościami i wg tego przeliczać.
    ale skoro sygnał będzie się zmieniał przyjmijmy -90 0 90^ z dokładnością co do 1^ musiałbym trochę poprzeliczać, żeby porobić tablice choćby dla wartości od 0-90.

    Dlatego wole się zapytać może ktoś bawił się w podobne sprawy i ma coś do zaproponowania.

    Pozdrawiam (oczywiście w międzyczasie wypróbuje wbudowaną)

    0
  • #5 05 Sie 2013 18:51
    tmf
    Moderator Mikrokontrolery Projektowanie

    Nie jest tak źle, właśnie testowałem, atan potrzebuje ok. 2850 cykli, to dla 16 MHz daje czas wykonania około 178 mikrosekund. Funkcja atan2, która robi to co chcesz (stosunek dwóch argumentów) wykonuje się ciut krócej - ok. 2830 cykli. Także np. ATMega może wykonać ok. 5600 takich operacji na sekundę. Niewiele ale może wystarczy. Oczywiście tak jak pisze kolega piotrva tablicowanie jest najszybsze i proste. Taka tablica nie zajmie też dużo pamięci, dla 90 stopni z dokładnością do stopnia zajmuje raptem 360 bajtów. Jeśli wystarczy ci ograniczona dokładność funkcji to można też arcus tangens aproksymować wielomianami, będzie ciut szybciej niż oryginalna funkcja, ale zdecydowanie wolniej niż tablicowanie.

    0
  • #6 05 Sie 2013 19:07
    AoT_Hunter_PL
    Poziom 21  

    hm..

    dzięki za zaangażowanie właśnie teraz kombinuje co i jak niby ~200ms wróć przepraszam nie doczytałem czas w mikrosekundach to nie dużo musiałbym doczytać jak to wygląda w wykrywaczach metali.

    (gdyż dla takiego urządzenia próbuje zrobić moduł identyfikacji odczyt 2 sygnałów DC kanał X , oraz Y i obliczenie między nimi przesunięcia fazowego)


    ------------------------------------------------------------------------------
    Sygnały będą zmieniać się 2,5V ---> 0V (i) 2,5V --->5V

    0-1023

    czyli muszę jeszcze odejmować - 512 aby wyskalować wynik do badania napięcia ujemnego i dodatniego

    512 - będzie stanem neutralnym
    ------------------------------------------------------------------------------

    Niby sondą nie przemiata się super szybko ale odpowiedź sygnału od metalu jest nagła, ale machając w te i tamte ;] wynik na lcd musiałby się raczej zmieniać w przedziale 100ms LCD... tak mi się wydaje.



    no tak musiałbym obliczyć wartości tg(x)

    gdzie x = 1...90

    wartości zaokraglic w tablicy.


    Przy różnym stosunku 2 sygnałów ze znakiem +\- musiałbym też zaokrąglić wynik aby dopasować do tablicy.

    Chyba dobrze myślę :)

    0
  • #7 06 Sie 2013 21:07
    AoT_Hunter_PL
    Poziom 21  

    Witam mam pytanie testuje funkcję wbudowaną atan2 ()

    mam dwie zmienne typu int:ADC1, ADC2


    dla przykładu atan2 (ADC2, ADC1)*(180/M_PI) = (510/-471)*(180/M_PI)

    daje mi wynik 132 --- błąd


    natomiast odwrotne działanie np.

    atan2 (ADC2, ADC1)*(180/M_PI) = (-393/504)*(180/M_PI)

    daje wynik prawidłowy -37^



    atan2(-ADC2/-ADC1) *(180/M_PI)

    daje również wynik nieprawidłowy (dzielenie -/-)


    W czym może być problem ?


    Kod: c
    Zaloguj się, aby zobaczyć kod




    Za pomoc z góry dziękuje

    0
  • #9 06 Sie 2013 21:20
    AoT_Hunter_PL
    Poziom 21  

    Zmieniłem zmienne na float nic nie pomogło niestety :/.

    0
  • #10 06 Sie 2013 21:26
    tmf
    Moderator Mikrokontrolery Projektowanie

    Ja tam widzę, że w każdym przypadku zwraca wartość prawidłową. Znaki przy atan2 służą wyłącznie do określenia kwadrantu. W pierwszym przypadku mamy drugi kwadrant (argumenty mają znaki +,-), stąd do wyniku dodawane jest pi - 90 stopni i mamy 132 stopnie - prawidłowo.

    0
  • #11 06 Sie 2013 21:34
    AoT_Hunter_PL
    Poziom 21  

    To może ja czegoś nie rozumiem

    Myślałem ze atan2 zwraca bezpośrednio wartość (dla dwóch zmiennych podzielonych przez siebie)

    czyli odpowiednio atan2(510/-471) = powinno być -47^

    510 * (1/-471) = liczba ujemna



    bynajmniej tak mi podaje kalkulator już w stopniach :)

    -------------------------------------------------------------

    (PI - 90) +X = 132

    X= 132 - (PI-90)
    X= 132-87
    X= 45



    PI ..... nie kumam :)

    tak samo mam atan2 (-387/-512)

    wg obliczeń na kalkulatorze w stopniach powinno być 37


    wg wyniku programu jest -142

    jak to obliczyc

    0
  • Pomocny post
    #12 07 Sie 2013 08:24
    tmf
    Moderator Mikrokontrolery Projektowanie

    Nie, atan2 zwraca wartość dla wartości bezwzględnej stosunku argumentów (zakres 0-pi), natomiast na podstawie ich znaków określa ćwiartkę i stosownie modyfikuje wyniki. Rozrysuj sobie argumenty w układzie współrzędnych to zobaczysz dlaczego masz takie a nie inne wyniki. Zauważ, że jeśli interesuje cię po prostu arcus tangens stosunku dwóch argumentów, to po prostu użyj funkcji atan.

    0