Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Atmega32 - Pomiar czasu między zboczami narastającymi na ICP1

marrrtyn 13 Nov 2013 19:59 2577 12
  • #1
    marrrtyn
    Level 10  
    Witam.

    Chciałbym zmierzyć czas pomiędzy dwoma impulsami (stanami wysokimi) występującymi na pinie ICP1. Używam do tego celu timera1 oraz kodu znalezionego w internecie, zmodyfikowanego na własne potrzeby:

    Code: c
    Log in, to see the code


    Według mnie kod powinien działać poprawnie, lecz na wyświetlaczu LCD odświeżana jest przez cały czas liczba z przedziału 322**-322** (nie widać dwóch ostatnich cyfr ze względu na ciągłe odświeżanie). Według mnie jest coś nie tak z funkcją "pomiar gotowy", ponieważ, gdy w pętli głównej programu ustawię "if (pomiar_gotowy==0)", wyświetlacz przez cały czas jest pusty. Proszę o pomoc w poprawieniu kodu tak, abym mógł odczytywać na wyświetlaczu czas pomiędzy dwoma impulsami.
  • #3
    marrrtyn
    Level 10  
    Usunąłem linie

    Code: c
    Log in, to see the code


    które są u mnie zbędne, więc zamiast

    Code: c
    Log in, to see the code


    mam

    Code: c
    Log in, to see the code


    Usunąłem także zmienne "czas_jednego_obrotu" oraz "obrotow_na_sekunde", gdyż nie są potrzebne w moim projekcie. Myślę, że program powinien teraz działać poprawnie, lecz jest tak jak opisałem to dwa posty wyżej. Czy ktoś może mnie naprowadzić dlaczego program nie działa prawidłowo oraz skąd biorą się takie wartości na wyświetlaczu? Kiedy wyświetlam ilość przepełnień na wyświetlaczu widzę, że działa to poprawnie, gdyż liczba przepełnień cały czas rośnie.
  • #4
    pbuhne
    Level 15  
    Nie:
    Code: c
    Log in, to see the code


    a:
    Code: c
    Log in, to see the code


    potem zamiast itoa(); użyj ultoa();

    Pozdrawiam.
  • #5
    marrrtyn
    Level 10  
    Faktycznie, mój błąd. Postanowiłem jeszcze raz napisać kod od początku:

    Code: c
    Log in, to see the code


    Pod port PD6 mam podpięty kontaktron (teraz w fazie testów microswitch). Jedna nóżka jest podpięta do portu PD6, druga do masy. Dodałem do kodu również linię:

    Code: c
    Log in, to see the code


    Jeśli chodzi o kod, to zamieniając linię

    Code: c
    Log in, to see the code


    na

    Code: c
    Log in, to see the code


    na wyświetlaczu mam ciągle 0, czyli do zmiennej czas1 nie zapisuje mi się aktualny czas wystąpienia impulsu zapisany w ICR1. Gdy podmienię zmienną na czas2, podczas wystąpienia impulsu wartość zostaje wyświetlona na wyświetlaczu. Co może być nie tak w tym przypadku?
  • #6
    johnny99
    Level 17  
    Witam. Ja jak budowałem obrotomierz do swojego auta to też miałem problem z liczeniem czasu między impulsami. Po prostu za dużo zakłóceń było co kontroler traktował jako impuls. Zastosowałem przerzutnik monostabilny (74HC123) i obrotomierz działa już ponad dwa lata.

    Do czego służy twój projekt?
  • #7
    marrrtyn
    Level 10  
    Docelowo ma mierzyć prędkość wiatru. Kontaktron mam już zabudowany w wirniku i zaklejony tak więc na nim chciałbym oprzeć ten projekt.

    Postanowiłem wykonać taki test:

    Code: c
    Log in, to see the code


    i obie wartości (wynik oraz tym) pokazują to samo na wyświetlaczu - czyli "czas2". Widać, że działanie nie wykonuje się. Co zrobić w tej sytuacji?

    Prawdopodobnie funkcję:
    Code: c
    Log in, to see the code


    należy zmienić na:
    Code: c
    Log in, to see the code


    tak, aby cykl==1 ustawił się dopiero po złapaniu czasu, czy dobrze myślę?
  • #8
    johnny99
    Level 17  
    Nie bawiłem się z kontaktronami ale nie ma tam tak czasem zjawiska drgania styków?

    Jeśli występuje to musisz je wyeliminować programowo lub sprzętowo. Sprzętowo to możesz zastosować wspomniany przeze mnie wcześniej multiwibrator monostabilny 74hc123. Jeśli go nie wyeliminujesz to będzie Ci kontroler cuda zliczać.
  • #9
    dondu
    Moderator on vacation ...
    johnny99 wskazał Ci główny problem: http://mikrokontrolery.blogspot.com/2011/04/przycisk-drgania-stykow-debouncing.html
    marrrtyn wrote:
    Docelowo ma mierzyć prędkość wiatru. Kontaktron mam już zabudowany w wirniku i zaklejony tak więc na nim chciałbym oprzeć ten projekt.

    Z jaką prędkością maksymalną obracać się będzie wirnik?
    Od tego wiele zależy.
  • #10
    2rs232
    Level 18  
    marrrtyn wrote:

    Kontaktron mam już zabudowany w wirniku i zaklejony tak więc na nim chciałbym oprzeć ten projekt.

    Mimo to rozważ użycie czujnika Halla (np. TLE4906L, SL353) zamiast kontaktronu.
  • #11
    marrrtyn
    Level 10  
    Dziękuję za wszystkie porady, udało mi się już wszystko zrobić. Kontaktron działa jak należy, ustawiłem dość duży prescaler, więc drgania styków nie są wyłapywane przez mikrokontroler (przy małym prescalerze faktycznie dało się zauważyć drgania styków). Pozdrawiam
  • #12
    BlueDraco
    MCUs specialist
    Ja tylko dodam dwie uwagi:

    1. Oczywiście można każde dwie linie kodu (np. te, które ignorowałyby drgania styków) zastąpić przerzutnikiem czy uniwibratorem. Idąc w tym kierunku można wyrzucić mikrokontroler, wstawić kilkadziesiąt układów logicznych i mamy to samo, bez kłopotów z programowaniem. Pozostaje tylko kwestia sensowności takiego rozwiązania - jeśli już mamy uC, to lepiej dopisać te 2 linie.

    2. Pokazany kod nie działa poprawnie, gdy odstęp pomiędzy impulsami przekracza 65000. Programowe zliczanie przepełnień timera zawsze jest obarczone ryzykiem błędu - zgubienia lub nadmiarowego policzenia przepełnień. Należy zagwarantować, że okres obrotu będzie mniejszy od okresu timera, albo przewidzieć dwa tryby pomiarów - dla małych obrotów/zatrzymania i dla większej prędkości.
  • #13
    marrrtyn
    Level 10  
    BlueDraco wrote:
    Należy zagwarantować, że okres obrotu będzie mniejszy od okresu timera.


    Dokładnie, w moim przypadku okres obrotu zawsze będzie mniejszy od okresu timera. Dziękuję jeszcze raz za wszystkie odpowiedzi.