Szanowni Forumowicze,
mam problem z regulacją prędkości obrotowej silnika DC wyposażonego w enkoder za pomocą przerwań INT. Enkoder to czujnik Halla i odbiera impulsy z magnesu neodymowego na wale silnika (magnes 8-polowy). Prędkość kontroluję za pomocą generowanego PWM na atmedze podawanego na mostek L293DNE. Atmega pracuje na 1MHz, a licznik to Timer/Counter0 z preskalerem 1024, czyli czas między impulsami timera to ok. 1ms.
Z pomocą oscyloskopu doświadczalnie sprawdziłem, że silnik powinien pracować z prędkością 4 zmian stanu enkodera / 240ms.
Wg mnie algorytm powinien wyglądać tak:
1) licznik kręci aż do przepełnienia i w tym czasie odbieram impulsy z enkodera za pomocą przerwania INT0;
2) w momencie przepełnienia obsługuję przerwanie i reguluję zawartość OCR1B, czyli inaczej dostosowuję PWM:
- jeśli było więcej niż 4 impulsy podczas kręcenia licznika tzn., że kręci się za szybko więc zmniejszam OCR1B;
- jeśli było mniej niż 4 impulsy podczas kręcenia licznika tzn., że kręci się za wolno więc zwiększam OCR1B;
- jeśli miałem dokładnie 4 impulsy podczas kręcenia licznika tzn., że mam to co chcę i zostawiam OCR1B bez zmian;
3) na końcu obsługi przerwania od przepełnienia zeruję licznik impulsów z enkodera i procedura trwa od początku.
Problem polega na tym, że co bym nie zrobił to OCR1B ustala się na 400 i nie ważne czy dam w kodzie 4 impulsy czy 10 impulsów to ciągle jest to samo.
Oto kod do obsługi przerwań:
Ta regulacja jednak w ogóle nie działa i nie mam już pomysłów, siedzę nad tym dwa dni bez przerwy, a powyższy kod to i tak najlepsze co udało mi się osiągnąć... W poprzednich OCR1B ciągle leciał do 500, tutaj 'tylko' do 400...
Gdzie robię błąd? Proszę uprzejmie o wskazówki i pozdrawiam.[/code]
mam problem z regulacją prędkości obrotowej silnika DC wyposażonego w enkoder za pomocą przerwań INT. Enkoder to czujnik Halla i odbiera impulsy z magnesu neodymowego na wale silnika (magnes 8-polowy). Prędkość kontroluję za pomocą generowanego PWM na atmedze podawanego na mostek L293DNE. Atmega pracuje na 1MHz, a licznik to Timer/Counter0 z preskalerem 1024, czyli czas między impulsami timera to ok. 1ms.
Z pomocą oscyloskopu doświadczalnie sprawdziłem, że silnik powinien pracować z prędkością 4 zmian stanu enkodera / 240ms.
Wg mnie algorytm powinien wyglądać tak:
1) licznik kręci aż do przepełnienia i w tym czasie odbieram impulsy z enkodera za pomocą przerwania INT0;
2) w momencie przepełnienia obsługuję przerwanie i reguluję zawartość OCR1B, czyli inaczej dostosowuję PWM:
- jeśli było więcej niż 4 impulsy podczas kręcenia licznika tzn., że kręci się za szybko więc zmniejszam OCR1B;
- jeśli było mniej niż 4 impulsy podczas kręcenia licznika tzn., że kręci się za wolno więc zwiększam OCR1B;
- jeśli miałem dokładnie 4 impulsy podczas kręcenia licznika tzn., że mam to co chcę i zostawiam OCR1B bez zmian;
3) na końcu obsługi przerwania od przepełnienia zeruję licznik impulsów z enkodera i procedura trwa od początku.
Problem polega na tym, że co bym nie zrobił to OCR1B ustala się na 400 i nie ważne czy dam w kodzie 4 impulsy czy 10 impulsów to ciągle jest to samo.
Oto kod do obsługi przerwań:
Kod: C / C++
Ta regulacja jednak w ogóle nie działa i nie mam już pomysłów, siedzę nad tym dwa dni bez przerwy, a powyższy kod to i tak najlepsze co udało mi się osiągnąć... W poprzednich OCR1B ciągle leciał do 500, tutaj 'tylko' do 400...
Gdzie robię błąd? Proszę uprzejmie o wskazówki i pozdrawiam.[/code]
