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

Atmega32A - Moduł L298 - Sterowanie silnikiem DC - PWM

01 Sty 2018 15:16 996 22
  • Poziom 16  
    Witam!

    Mam problem ze sterowaniem silnikiem DC przy pomocy PWM. Jeśli ustawie PWM jako stałą wartość np. wypełnienie 100% to wszystko ładnie działa, ale gdy chcę, aby silnik zmieniał prędkość, to dzieją się cuda...

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Objawy są następujące: Silnik uruchamia się i czasami rozkręci się do zadanej prędkości, a czasami potrafi kilka razy zatrzymać się i ponownie uruchamiać.

    Dodatkowo nie wiem czemu pętla zlicza w dół... w przeciwnym przypadku silnik zaczyna od max prędkości i zwalnia...(pewnie nie rozumiem PWM)

    W przerwaniu został użyty XOR(jeden przycisk do startowania i zatrzymywania silnika)

    Przycisk podłączony do masy i do linii 3 portu B.
    OCR0 podłączone do modułu do pinu IN0/IN1.

    Dziękuję!

    Pozdrawiam!
  • PCBway
  • Pomocny post
    Użytkownik usunął konto  
  • Pomocny post

    Poziom 13  
    Może spróbuj sterowania w inny sposób - za pomocą przerwania INT2 (wywoływanego przyciskiem) uruchamiaj i zatrzymuj licznik TC0 (parametry PWM są ustawione u Ciebie poprawnie) tzn ustawiaj bity TCCR0|=(1<<CS00)|(1<<CS01) kiedy chcesz uruchomić licznik i zeruj je jeżeli chcesz zatrzymać. Samo ustawianie wartości wypełnienia czyli rejestr OCR0 ustawiaj w przerwaniu od przepełnienia licznika - tam ma to sens ponieważ kończy się cykl PWM, ustawiasz nową wartość rejestru i startujesz ponownie. Aktywuj przerwanie przepełnienia od licznika T0, w przerwaniu wypróbuj na początek kod zwiększający wypełnienie np. z "prescalerem" bo pewnie przy pełnej prędkości nic nie zauważysz
    Code:

    ISR(TIMER0_OVF_vect)
    {
    static uint8_t presc = 20;
    if(!(presc--))
    {
    OCR0++;
    presc = 20;
    }
  • Poziom 16  
    R-MIK napisał:
    Pomijając to, że w petli for wystarczy unsigned char a zamiast znaczników code mogłes uzyc syntax, to uprość kod:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Silnik nie będzie sie kręcił przy wypełnieniu mniejszym niż np 10. Startował bedzie od np 20 (taka histereza).
    Moze częstotliwość PWM jest za duża dla tego silnika? Wtedy przy dużym wypełnieni działa, zakres regulacji jest jednak mały i nie da się uzyskac wolnych obrotów.


    Zastosowałem powyższa poprawkę, działa poprawne z tym, że prędkość silnika zależy od tego ile razy wcisnę przycisk... A ja bym chciał zrobić funkcję, która rozpędzi silnik tzw. soft start.

    electronics_design napisał:
    Może spróbuj sterowania w inny sposób - za pomocą przerwania INT2 (wywoływanego przyciskiem) uruchamiaj i zatrzymuj licznik TC0 (parametry PWM są ustawione u Ciebie poprawnie) tzn ustawiaj bity TCCR0|=(1<<CS00)|(1<<CS01) kiedy chcesz uruchomić licznik i zeruj je jeżeli chcesz zatrzymać. Samo ustawianie wartości wypełnienia czyli rejestr OCR0 ustawiaj w przerwaniu od przepełnienia licznika - tam ma to sens ponieważ kończy się cykl PWM, ustawiasz nową wartość rejestru i startujesz ponownie. Aktywuj przerwanie przepełnienia od licznika T0, w przerwaniu wypróbuj na początek kod zwiększający wypełnienie np. z "prescalerem" bo pewnie przy pełnej prędkości nic nie zauważysz
    Code:

    ISR(TIMER0_OVF_vect)
    {
    static uint8_t presc = 20;
    if(!(presc--))
    {
    OCR0++;
    presc = 20;
    }


    Jeżeli dobrze rozumiem, wymaga to zastosowania dwóch timerów? Jeden do wywoływania przerwania od przepełenienia, drugi do PWM?
  • Użytkownik usunął konto  
  • Poziom 16  
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Rozruch działa bardzo dobrze. Nie rozumiem jednak kilka kwestii. Timer0 jest ustawiony w tryb FAST PWM, w którym momencie ten timer ulegnie przepełnieniu? Tzn. Kiedy sygnał PWM ulega przepełnieniu? Druga sprawa co tak naprawdę robi ta funkcja warunkowa?
  • PCBway
  • Pomocny post

    Poziom 13  
    Tryb fast PWM działa w ten sposób, że licznik zaczyna zliczać od 0 do wartości 255 (w przypadku licznika 8 bitowego), przy każdym takcie zegara oprócz zwiększenia wartości licznika porównuje tę wartość z wartością rejestru OCR, jeżeli wartości są równe to neguje przypisane wyjście jednego z portów. Co z tego wynika - licznik zawsze zlicza w pełnym zakresie od 0 do 255 i ulega przepełnieniu (wtedy właśnie jest dobry moment żeby ustawić nową wartość rejestru OCR która może wynosić od 0 do 255). Tutaj poprawiłbym kolegę R-MIK bo wydaje mi się, że nie zrozumieliśmy się w kwestii aktualizacji wartości wypełnienia - aktualizując wartość w przerwaniu od porównania możemy dość do sytuacji, kiedy nowa wpisywana wartość będzie większa od aktualnej a to spowoduje kilkukrotne negowanie portu i zaburzy pracę całego przebiegu. Jeżeli chodziło Ci o coś innego to popraw mnie proszę.
    Funkcja warunkowa sprawia, że wartość wypełnienia będzie zwiększać się jak w przykładzie co 20 okresów przebiegu PWM, jeżeli masz zegar 1 MHz i prescaler zegara 8 tak jak ustawiłeś to częstotliwość PWM wynosi u Ciebie 1 000 000 / 8 / 256 = 488,28 Hz czyli rozpędzenie do pełnej wartości trwałoby około 0,5 sekundy i nic byś nie zauważył. Zmieniając wartość zmiennej presc w przerwaniu możesz regulować czas rozpędzania się silnika. Pobaw się tym kodem i potestuj swoje rozwiązania - tak najwięcej się nauczysz.
    Pozdrawiam
  • Użytkownik usunął konto  
  • Poziom 16  
    Dobrze, soft start w pełni działa poprawnie i rozumiem jak to działa(to najważniejsze)...

    Aktualnie próbuję rozwiązać problem z utrzymywaniem danej prędkości po rozruchu oraz wielokrotnym rozruchem silnika.

    Jeśli chodzi o utrzymywanie stałej prędkości po rozruchu, to dodałem funkcję warunkową w przerwaniu po przepełnieniu:
    Code:
    if(OCR0>250)
    
       {
          TIMSK&=(0<<TOIE0);
       }

    Oczywiście wartość 250 zastąpię jakaś zmienną, która będzie się zmieniać...

    Dodatkowo instrukcja:
    Code:

    TIMSK|=(1<<TOIE0);

    została przeniesiona do przerwania zewnętrznego, aby możliwy był ponowny rozruch silnika.
    Wewnątrz tego przerwania wyzerowałem też OCR0
    Code:

    OCR0=0;

    Ponieważ występował problem w momencie, gdy zatrzymywałem silnik w momencie rozruchu. tzn. po ponownym aktywowaniu timera, OCR0 przechowywało starą wartość, czyli potrafił się uruchomić z wypełnieniem, na którym zatrzymał się silnik.

    Czy dobrze rozwiązałem te problemy? Może da się coś zrobić w łatwiejszy sposób?

    Pozdrawiam!
  • Pomocny post
    Użytkownik usunął konto  

  • Poziom 13  
    Nie lepiej wyłączyć po prostu timer? Wyzerowanie bitów źródła sygnału zegara dla timera TCCR0&=~((1<<CS00)|(1<<CS01)) zatrzyma całkowicie peryferia zamiast pomijać przerwanie. Przy ponownym starcie wystarczy zerować dodatkowo OCR0 tak jak to robisz i uruchomić licznik TCCR0|=(1<<CS00)|(1<<CS01)

    Dodano po 2 [minuty]:

    A przepraszam...jeżeli chcesz żeby cały czas silnik pracował na zadanej prędkości to oczywiście twoje rozwiązanie jest ok. Nie możesz wyłączyć timera tylko omijać przerwanie.
  • Poziom 16  
    Dobra, wszystko jasne.

    Chciałbym dokonać zmiany kierunku obrotu silnika(posiadam moduł L298, w którym zmiany, kierunku obrotów dokonuje się poprzez podanie sygnału PWM na IN1 bądź IN2). Mając przycisk tak jak przypadki start i stopu chciałbym pojedynczym kliknięciem zmieniać kierunek. Problem tkwi w tym, że nie wiem w jaki sposób wykorzystać PWM generowany z OCR0? Nie chciałbym wykorzystywać do tego drugiego timera...
  • Pomocny post
    Użytkownik usunął konto  
  • Poziom 16  
    Jeśli dobrze rozumem, to sprzętowa zmiana kierunku obrotu polega na podaniu odpowiednich sygnałów na linie IN1 i IN2 w momencie przepełnienia timera z uwzględnieniem OCR0, tak aby zawsze "był ten soft start"?

    Atmega32A - Moduł L298 - Sterowanie silnikiem DC - PWM

    Zakładamy, że aktualnie silnik jest podłączony do IN1 i obraca się w lewo. W tym momencie nie wiem w jaki sposób użyć tego samego PWM do obrotu silnikiem w prawą stronę? Czy to w ogóle jest możliwe? Tzn. Jeden sygnał PWM ma być dostarczany na IN1 i IN2 w zależności od jakiegoś tam przycisku.

    Pozdrawiam!
  • Użytkownik usunął konto  
  • Poziom 16  
    Czyli tak na chłopski rozum, INT2 służy tylko i wyłącznie do "zwierania" odpowiednich styków w mostku H określając kierunek przepływu sygnału PWM tzn. Czy PWM biegnie przez zaciski S1 i S3(w lewo), czy przez S2 i S4(w prawo)? Oczywiście PWM może być na INT2, tak więc sterujemy kierunkiem za pomocą INT1?
  • Użytkownik usunął konto  
  • Poziom 16  
    Nie rozumiem jeszcze jednej kwestii...

    Jeżeli wystarczy zmieniać stan z wysokiego na niski i odwrotnie linii IN1/2, z uwzględnieniem zatrzymania silnika, to w jakim celu ten nasz PWM mamy negować?
  • Pomocny post
    Poziom 36  
    Warlok18 napisał:
    Czyli tak na chłopski rozum, INT2 służy tylko i wyłącznie do "zwierania" odpowiednich styków w mostku H określając kierunek przepływu sygnału PWM tzn. Czy PWM biegnie przez zaciski S1 i S3(w lewo), czy przez S2 i S4(w prawo)? Oczywiście PWM może być na INT2, tak więc sterujemy kierunkiem za pomocą INT1?


    Nie, NIE, Nie!!!
    Jest to absolutnie błędne rozumowanie...

    Prawdopodobnie masz moduł jak niżej:
    Atmega32A - Moduł L298 - Sterowanie silnikiem DC - PWM
    Najpierw zapoznaj się co które piny oznaczają i jaką spełniają funkcje.
    Jest to układ dwóch identycznych mostków H. Potrzebnych do wysterowania jednego dwufazowego (bipolar) steppera.
    Oryginalnie moduł ten jest dostarczany w konfiguracji do sterowania silników krokowych, dlatego ma załóżone zworki na piny: 7 i 12.
    Jezeli układ ten stosujesz do kontroli obrotów jednego tylko silnika (szczotkowego) DC, to wykorzystasz tylko jeden kanał, powiedzmy „DC motor 1” podłączony do pinów wyjściowych 1 i 2.
    W pirwszej kolejności należy usunąc zworkę z pinów 7 podającą na ten pin stan wysoki.
    Wysterowanie tego silnika będzie trzema pinami:
    7- podłączony na płytce do pinu Enable układu - tu dostarczysz PWM – regulacja obrotów
    IN1 i IN2 – kombinacja stanów logicznych na tych pinach określa kierunek obrotów (odpowiedno w data sheet piny C i D).
    Mogą wystąpic cztery kombinacje: (patrz tabela w datasheet str. 6/13) z czego interesują cię w zasadzie tylko dwa
    - lewo
    - prawo

    - free running
    - hamowanie
    Pozostałe piny (10, 11, 12) służą do wysterowania drugiego kanału z wyjściem 13 i 14 dla silnika ‘2’, w identyczny sposób jeżeli potrzebujesz ...

    e marcus
  • Użytkownik usunął konto  
  • Poziom 16  
    emarcus napisał:
    Warlok18 napisał:
    Czyli tak na chłopski rozum, INT2 służy tylko i wyłącznie do "zwierania" odpowiednich styków w mostku H określając kierunek przepływu sygnału PWM tzn. Czy PWM biegnie przez zaciski S1 i S3(w lewo), czy przez S2 i S4(w prawo)? Oczywiście PWM może być na INT2, tak więc sterujemy kierunkiem za pomocą INT1?


    Nie, NIE, Nie!!!
    Jest to absolutnie błędne rozumowanie...

    Prawdopodobnie masz moduł jak niżej:
    Atmega32A - Moduł L298 - Sterowanie silnikiem DC - PWM
    Najpierw zapoznaj się co które piny oznaczają i jaką spełniają funkcje.
    Jest to układ dwóch identycznych mostków H. Potrzebnych do wysterowania jednego dwufazowego (bipolar) steppera.
    Oryginalnie moduł ten jest dostarczany w konfiguracji do sterowania silników krokowych, dlatego ma załóżone zworki na piny: 7 i 12.
    Jezeli układ ten stosujesz do kontroli obrotów jednego tylko silnika (szczotkowego) DC, to wykorzystasz tylko jeden kanał, powiedzmy „DC motor 1” podłączony do pinów wyjściowych 1 i 2.
    W pirwszej kolejności należy usunąc zworkę z pinów 7 podającą na ten pin stan wysoki.
    Wysterowanie tego silnika będzie trzema pinami:
    7- podłączony na płytce do pinu Enable układu - tu dostarczysz PWM – regulacja obrotów
    IN1 i IN2 – kombinacja stanów logicznych na tych pinach określa kierunek obrotów (odpowiedno w data sheet piny C i D).
    Mogą wystąpic cztery kombinacje: (patrz tabela w datasheet str. 6/13) z czego interesują cię w zasadzie tylko dwa
    - lewo
    - prawo

    - free running
    - hamowanie
    Pozostałe piny (10, 11, 12) służą do wysterowania drugiego kanału z wyjściem 13 i 14 dla silnika ‘2’, w identyczny sposób jeżeli potrzebujesz ...

    e marcus


    Dziękuję za wsparcie, przydało się i uprościło znacznie kod.

    R-MIK napisał:
    emarcus napisał:
    Prawdopodobnie masz moduł jak niżej:

    W sumie od tego trzeba było zacząć.

    emarcus napisał:

    Mogą wystąpic cztery kombinacje:

    Raczej pięć, i jeśli użyje linii EN do PWM tofree running uzyska wyłączając PWM a nie przez kombinacje IN1 i IN2.

    Jak juz jesteśmy przy modułach, L298 to nie najlepszy pomysł. L6201/2/3 zadowolą sie mniejszym radiatorem albo nie będzie potrzebny wcale. Nie potrzeba 4 diod likwidujących przepięcia. W konsekwencji całość jest mniejsza i tańsza.
    Są tez malutkie A4950, A4952, A4953. Pytanie o jakie prądy chodzi.


    Nie mogę znaleźć informacji na temat pinu EN. Chodzi o możliwość "wyłączenia mostka H"?

    A teraz pytanie dotyczące kodu:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Problem mam z algorytmem odnośnie zmiany kierunku obrotu w momencie, gdy silnik obraca się z prędkością>0. W przypadku, gdy silnik nie obraca się, przełączanie kierunku i startowanie silnika działa poprawnie. Jeśli silnik pracuje, to wiadomo co się dzieje... szybka zmiana kierunku. Mój pomysł opierał się na algorytmie soft startu, z tym, muszę to wykonać w przerwaniu od przepełnienia...
    Umieszczenie dwóch instrukcji warunkowych, które sprawdzają stan na IN1 i IN2 i wykonują soft start, albo soft stop. No i teraz wpadałoby ponownie rozkręcić silnik do zadanej prędkości... tylko teraz warunki, które ustawiłem w if'ach mnie ograniczają... Nie mogę wymyśleć uniwersalnego algorytmu do tego zadania...

    Pozdrawiam!
  • Użytkownik usunął konto