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

[ATxmega128A4U][C] - enkoder obrotowy, pomiar prędkości

pauln 07 Lis 2016 14:24 1353 24
REKLAMA
  • #1 16045894
    pauln
    Poziom 8  
    Witam, próbuję zaprogramować xmege aby mierzyła prędkość obrotową enkodera. Niestety mój pomiar to ciągle 0.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • Pomocny post
    #2 16046195
    dawid.barracuda
    Poziom 13  
    Co prawda nie do enkodera, a do czujnika HC-SR04, ale reguła ta sama, pomiar szerokości impulsu. Zrobiłem to na systemie zdarzeń. Kod:

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


    Obsługa przerwania:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    W taki sposób dostaniesz wynik w mikrosekundach.
  • REKLAMA
  • #3 16046480
    pauln
    Poziom 8  
    Próbując Twój kod dalej mikro nie reaguje, ciągle wyświetla 0. Sam pomiar szerokosci impulsu.
  • REKLAMA
  • #4 16046494
    dawid.barracuda
    Poziom 13  
    To jest Twój cały kod? Bo nigdzie nie widzę funkcji int main() oraz pętli głównej programu.
  • #5 16046645
    pauln
    Poziom 8  
    Nie, to jeden z plików, w funkcji main(); wywołuje funckcje enko();
  • #6 16047464
    dawid.barracuda
    Poziom 13  
    Pokaż jak to wygląda w mainie. Ogólnie całość kodu o ile jest taka możliwość. Ten kod musi działać bo sam go używam i działa bez zarzutu.
  • #7 16047878
    pauln
    Poziom 8  
    Kod zadziałał dopiero jak dodałem
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Poza tym jest problem taki ze enkoder dopiero po 2 obrotach się stabilizuje, podczas pomiaru to prawdopodobnie nie będzie przeszkadzać, zakładając ze enkoder będzie obracał się z dużą prędkością.
  • #8 16048405
    dawid.barracuda
    Poziom 13  
    No tak, przeoczyłem tę linijkę.
    Co masz na myśli mówiąc o stabilizacji? Chodzi Ci o to, że dopiero po dwóch obrotach masz stabilne odczyty?
  • #9 16048584
    BlueDraco
    Specjalista - Mikrokontrolery
    Jeśli ten kod działa, to przez czysty przypadek i tylko czasami. Jest tam parę istotnych błędów synchronizacji. Nie użyłeś nawet niezbędnego atrybutu volatile, który w tym przypadku i tak nie wystarczy - masz modyfikację 16-bitowej zmiennej w przerwaniu na 8-bitowym procesorze.
  • #10 16048595
    Pavlik71
    Poziom 15  
    Witam.

    Może pomoże Ci mój wątek na temat enkoderów.

    Link

    Program przedstawiony w tym wątku potrafi zliczyć ponad 70000 impulsów na sekundę przy dwóch kanałach enkodera. Dla przykładu enkoder o 24 kliknięciach na obrót, daje to prawie 3000 obrotów na sekundę i 178000 na minutę nie myląc się ani o grosz :) Liczy w przód i w tył bez błędów, które wprowadzją drgania styków.

    Pozdrawiam.
  • REKLAMA
  • #11 16048970
    dawid.barracuda
    Poziom 13  
    BlueDraco - mógłbyś rozwinąć temat synchronizacji? Chętnie nauczę się czegoś nowego :)

    Pomiar szerokości impulsu pisałem pod cyfrowy czujnik odległości oraz enkoder w postaci czujnika Halla traktowanego magnesem 8-polowym (rozwiązanie do silnika modelarskiego), więc problem drgania styków (o ile rozumiem) mnie nie dotyczy w tym przypadku.
  • #12 16050086
    BlueDraco
    Specjalista - Mikrokontrolery
    Na początek mamy volatile. Potem zauważamy, że kiedy 8-bitowy procesor inkrementuje w przerwaniu zmienną o wartości 255, to w tym samym czasie jej odczyt w pętli zdarzeń może potencjalnie zwrócić jedną z 4 możliwych wartości (a konkretnie jedną z trzech): 255, 256, 0 lub 511. Te dwie ostatnie zapewne spowodują ciekawe efekty w programie. Podobnie próba jej wyzerowania nie musi okazać się skuteczna. Trzeba to zrobić w sekcji krytycznej, a jeszcze lepiej - wyrzucić całkiem pętlę zdarzeń.
  • #13 16050446
    pauln
    Poziom 8  
    a coś więcej mógłbyś opisać?

    Pomijając to, da radę odczytać częstotliwość zmiany wartości QDEC ?
  • #14 16059883
    dawid.barracuda
    Poziom 13  
    BlueDraco napisał:
    [...]Potem zauważamy, że kiedy 8-bitowy procesor inkrementuje w przerwaniu zmienną o wartości 255, to w tym samym czasie jej odczyt w pętli zdarzeń może potencjalnie zwrócić jedną z 4 możliwych wartości (a konkretnie jedną z trzech): 255, 256, 0 lub 511. [...]


    Na początek - skąd takie wartości?
  • #15 16059923
    BlueDraco
    Specjalista - Mikrokontrolery
    Stąd, że inkrementujemy zmienną 16-bitową, którą zapisujemy jako dwa bajty, jeden po drugim i tak samo ją czytam - w kawałkach. Jeśli przerwanie zinkrementuje zmienną pomiędzy odczytem jednego i drugiego bajtu, to w pętli głwnej dostaniemy wartość, której jeden bajt jest już po inkrementacji, a drugi - przed. W zależności od kolejności odczytu obu bajtów możemy dostać 511 lub 0 podczas inkrementacji z 255 na 256.
  • #16 16059971
    dawid.barracuda
    Poziom 13  
    Ok, teraz rozumiem ideę problemu. Jak temu zaradzić praktycznie?
  • #17 16060015
    BlueDraco
    Specjalista - Mikrokontrolery
    Blokować przerwania na czas odczytu, lub zrobić tak, żeby w ogóle nie czytać tego poza przerwaniem, np. tylko wyświetlanie na LCD w pętli, a konwersja w przerwaniu. Nowy C ma słowo kluczowe _Atomic, które dałoby plokadę przerwań na czas odczytu.
  • #18 16060066
    dawid.barracuda
    Poziom 13  
    Mówiąc odczyt masz na myśli wywołanie zmiennej w pętli głównej programu celem wyświetlenia na LCD?

    I rozumiem, że cały czas mówimy o kodzie Kolegi pauln?
    Powiedz mi proszę, co sądzisz o moim rozwiązaniu z systemem zdarzeń? Czy są jakieś błędy?
  • #19 16060339
    BlueDraco
    Specjalista - Mikrokontrolery
    Mówimy o kodzie pauln, bo Twojego kodu jakoś nie widzę - tylko parę podstawień bez deklaracji zmiennych. Nie wiadomo, kiedy ktoś miałby użyć odczytu i skąd miałby się dowiedzieć, że ma go użyć. Wiadomo za to, że HC-SR04 wymaga kasowania impulsu, który sam się nie skończy, a Ty tego nie robisz. ;)
  • #20 16060345
    pauln
    Poziom 8  
    A jak z pomiarem częstotliwości? jest ona możliwa z QDEC?
  • #21 16060348
    dawid.barracuda
    Poziom 13  
    Bo ja podałem tylko konfigurację systemu zdarzeń do obliczania szerokości impulsu na pin PD1 :)

    Samo wyzwolenie pomiaru u mnie wygląda tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    No i ustawienie pinu PD0 jako wyjścia:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Zmienna pw_us to zmienna globalna typu uint16_t.
  • #22 16060396
    pauln
    Poziom 8  
    Lub zamiast pomiaru częstotliwości, to zliczanie impulsów w czasie np 10ms.
  • #23 16062336
    dawid.barracuda
    Poziom 13  
    Jeśli dobrze rozumiem pytanie to system zdarzeń ma możliwość pomiaru częstotliwości sygnału z enkodera.
  • #24 16065526
    pauln
    Poziom 8  
    Próbowałem zrobić pomiar częstotliwości, ale wyświetla mi jedynie -1.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #25 16074703
    pauln
    Poziom 8  
    nikt nie pomoże?
REKLAMA