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.

Obrotomierz na Atmega8A na transoptorze odbiciowym

cierpliwosci123 18 Mar 2018 20:36 228 6
  • #1 18 Mar 2018 20:36
    cierpliwosci123
    Poziom 4  

    Hej rebjata,
    próbuję wykonać obrotomierz na Atmedze8A, jednak utkwiłem w martwym punkcie.
    Obrotomierz działa w oparciu o transoptor odbiciowy CNY70. Mierzy obrotu silnika BLDC.
    Obrotomierz na Atmega8A na transoptorze odbiciowym
    Połowa rotora silnika jest czarna a połowa biała. Transoptor jest przyłożony do rotora, w czasie obrotu silnika fototranzystor transoptora raz przewodzi a raz nie - zależnie jaki kolor jest aktualnie pod czujnikiem. Port ICP1 reaguje na te zmiany koloru generując przerwanie. Mamy 4 możliwości aktualnego stanu pomiaru: 'nieudany', 'start_pomiaru', 'wykonuje_pomiar', 'zakonczony'.
    Tak to ma działać w założeniu:
    Warunek wyświetlający wyniki na LCD czeka aż stan pomiaru będzie 'zakonczony'
    1.Zbocze generuje przerwanie. Zerujemy wartość timera1. Stan:wykonuje_pomiar.
    2. Następne zbocze. Przechwytujemy wartość timera1, obliczamy czas jaki upłynął oraz prędkość obrotu. Stan:'zakonczony'. Wyłączamy przerwanie od ICP1.
    3. Wyświetlamy wyniki na LCD. Zmianiam stan na start_pomiaru. Włączam przerwanie od ICP1. I znowu punkt 1.
    Czyli wszystko ma się odbywać niejako po kolei. Najpierw pojedynczy pomiar, zablokowanie kolejnego, wyswietlenie, zezwolenie na kolejny. Jednak nie wiedzieć dlaczego nie chce to działać, a mianowicie pokazuje zły wynik. Od strony sprzętowej wszystko jest okej na 100%, problem leży w kodzie. Tylko w którym miejscu? Wiem, że wpływ na zły wynik ma opóźnienie _delay_ms(300) jednak nie wiem dlaczego? Ratunku! Pomocy!

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0 6
  • #2 18 Mar 2018 21:14
    tmf
    Moderator Mikrokontrolery Projektowanie

    Od strony sprzętowej nie jest ok. Bo bez rezystora podciągającego na kolektorze tranzystora nie ma prawa to działać.
    Poza tym dla BLDC można mierzyć obroty z back-EMF, licząc czas pomiędzy przejściami przez zero lub korzystając z silnika z czujnikami halla,. Któraś z tych dwóch technik i tak jest zastosowana w użytym przez ciebie sterowniku silnika, więc wystarczy się podpiąć do odpowiedniego sygnału.
    A twój pomiar na timerze można uprościć - przechwytuj kolejne zdarzenia ICP i liczy różnicę między nimi. Zerowanie timera i manglowanie jego stanem nie jest potrzebne.

    0
  • #3 18 Mar 2018 21:19
    ghost2000
    Poziom 17  

    tmf napisał:
    Od strony sprzętowej nie jest ok. Bo bez rezystora podciągającego na kolektorze tranzystora nie ma prawa to działać.

    W kodzie jest
    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #4 18 Mar 2018 21:38
    tmf
    Moderator Mikrokontrolery Projektowanie

    ghost2000 napisał:
    tmf napisał:
    Od strony sprzętowej nie jest ok. Bo bez rezystora podciągającego na kolektorze tranzystora nie ma prawa to działać.

    W kodzie jest
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Niby fajnie, tyle, że pullup w ATMega ma 20-50k, co może być zbyt dużą wartością przy zadanej częstotliwości. W nocie jest jako obciążenie rezystor 1k.

    0
  • #5 18 Mar 2018 21:45
    cierpliwosci123
    Poziom 4  

    Tak jak zauważył kol. ghost2000 pin jest podciągnięty do Vcc. Ani BEMF ani czujniki Halla nie są zastosowane w sterowniku - wiem bo to moja konstrukcją :-o
    Najpewniej, że pomiar da się uprościć, tylko aktualnie pytanie dotyczy tego co w tym sposobie pomiaru nie trybi, ja sam błędu nie potrafię znaleźć dlatego szukam pomocy tu. Mógłbym spróbować inaczej do tego podejść tylko wtedy nigdy bym się nie dowiedział co było w tym sposobie źle - byłbym biedniejszy o jakąś tam wiedzę/doświadczenie.
    EDIT: Silnik testuję przy małych częstotliwościach rzędu kilku Hz.

    0
  • #6 18 Mar 2018 21:56
    tmf
    Moderator Mikrokontrolery Projektowanie

    Oprócz wskazanych wcześniej błędów w programie brakuje np. volatile dla zmiennej stan, co zapewne powoduje, że kompilator sporą część kodu wyrzuca w kosmos.

    cierpliwosci123 napisał:
    Ani BEMF ani czujniki Halla nie są zastosowane w sterowniku - wiem bo to moja konstrukcją :-o

    To ciekawe jak wykrywasz moment, w którym trzeba zmienić komutację? Silnik jasne, będzie się kręcił przy paru Hz, ale mocy w nim za wiele nie będzie.
    BTW, jeśli nie określasz momentu komutacji, a twój program steruje silnikiem, to przecież wiesz co ile robisz kolejne kroki komutacji, z czego możesz wyliczyć prędkość. W sumie jeśli nie znasz pozycji rotora, to wszystko jedno.

    0
  • #7 18 Mar 2018 22:09
    cierpliwosci123
    Poziom 4  

    Dodałem volatile - niestety nie pomogło :(
    Silnikiem kręcę na czuja - przy użyciu _delay_ms i _delay_us - co ciekawe udało mi się go rozpędzić do 6000 obr/min ;)
    EDIT: Tak właśnie stąd wiem, że obrotomierz źle działa. A będzie mi bardzo potrzebny, jeśli będę chciał przejść na BEMF, a będę, i w ogóle to przydatna rzecz jest.
    EDIT2: Udało mi się ustalić, że jeśli obrót trwa więcej niż 300ms (dla delay 300ms) - obrotomierz działa dobrze. Poniżej 300 ms obrotu silnika- pokazuje stałą wartość, ale błędną. Jeśli ustawię obrót na 216ms a mam delay 300ms - pokazuje błędnie. Jeśli zmienię delay na 200ms - pokazuje dobrze. Tylko dlaczego tak się dzieje??

    0