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

[AVR][C] jednoczesne sterowanie 6 silnikami krokowymi

nelik1987 29 Sep 2009 16:58 4072 13
  • #1
    nelik1987
    Level 31  
    Witam pisze program który będzie sterował jednocześnie 6 silnikami krokowymi, miałem problemy z zaprojektowaniem takiego programu. Na początek napisałem program w którym podawało się który silnik w którą sitronę i ile razy ma się obrócić (ile ma zrobić kroków), problem polegał na tym że nie dało się w ten sposób sterować kilkoma silnikami na raz, na raz mógł działać tylko jeden silnik jak skończył całą pracę mógł pracować następny.

    najlepiej było użyć licznika dla każdego silnika ale tyle timerów atmega16 nie ma :/

    pomyślałem ze zrobię inaczej:
    użyję jednego licznika do odmierzania 100µs, po każdym takim czasie zwiększane będą zmienne k1,k2,k3... które będą taki jak by licznikami dla każdego silnika.

    pokażę to na przykładzie jednego silnika:
    krok w tym silniku ma być co 2 ms, więc gdy zmienna k1 osiągnie wartość 20 (100µs * 20 = 2ms), wtedy zostanie ustawiona ustawiona zmienna a1 na wartość 0 a zmienna k1 wyzerowana. Zmienna a1 gdy będzie miała wartość 0 będzie to oznaczać zezwolenie na zmianę stanu wyjść co obróci silnik o jeden krok.

    Każdy z silników bedzie sterowany przyciskami (później za pomocą programu)

    więc żeby obrócić silnik na przykład w prawo, sprawdzam czy przycisk przyciśnięty następnie sprawdzam czy jest zezwolenie (czy a1==0) wtedy można wykonać jeden krok, a zmienna a1 zostaje ustawiona na wartośc różną od 0, następnie gdyby nie było opóźnienia w kolejnej pętli silnik znów chciał by zmienić swoje położenie (tak szybka zmiana stanów nie obróciła by silnika tylko by drgał), więc po kolejnej pętli programu sprawdzane jest znów czy wciśnięto przycisk i czy wartość a1==0 ale będzie ona różna od zera bo wyzeruje się dopiero po upływie 2ms

    czy takie rozwiązanie problemu jest dobre? czy są lepsze metody?

    na początku do jednego silnika wykorzystywał opóźnienia delay_ms ale jak wiadomo zatrzymywało to cały program a przy 6 silnikach tak być nie może
  • #2
    gothye
    Level 33  
    a czy nie lepiej skorzystać z gotowego drivera do silników krokowych ,po za tym o samych silnikach nic nie napisałeś ,tzn rodzaj sterowania silnika ,oraz sam jego rodzaj
  • #3
    nelik1987
    Level 31  
    korzystam z 4 silników bipolarnych i 2 silników unipolarnych. Silniki bipolarne to: 42BYGH 118-01B a silniki unipolarne to:35BY 48B09
    Tutaj można znaleźć ich noty katalogowe:
    http://wobit.pl/download/pdf/sterowniki_silniki_krok_short_04.2007.pdf

    do sterowania silników bipolarnych wykorzystuję scalne 2 mostki H z układy L293 a do sterowania silnikami unipolarnymi ULN2003

    nie mogę korzystać z gotowego sterownika silników w któych podaje się krok kierunek i sygnał PWM do sterowania
  • #4
    tmf
    Moderator of Microcontroller designs
    Dlaczego nie mozesz? Zamiast stosowac jakies prehistoryczne uklady typu L293 zainteresuj sie oferta firmy allegro-micro - maja cala serie driverow do silnikow z wbudowanymi mostkami H na MOSFETach, a nie grzejacych sie tranzystorach bipolarnych, z mikrokrokami, kontrola pradu uzwojenia, kontrolowanymi czasami opoznien galezi mostka itd. Znajdziesz tez uklady z wejsciem szeregowym + sygnal CS wiec twoje 6 silnikow to maly pryszcz. Calosc i tak zajmie mniej miejsca na PCB i bedzie dzialac lepiej.
  • #5
    nelik1987
    Level 31  
    nie mogę użyć zewnętrznych sterowników bo takie dostałem zadanie :)

    co do tych układów zaintersuje się i porozmawiam z promotorem chociaż z tego co wiem on by chciał zeby można było to zrobić bez gotowych sterownikó a jak najwięcej z wykorzystaniem samego procesora
  • #6
    tmf
    Moderator of Microcontroller designs
    No tak, na promotora nie ma rady :) Jesli nie potrzebujesz mikrokrokow to sprawa jest prosta - jak pisales, zrobic przerwanie co jakis interwal czasowy w ktorym ustawiasz odpowiednio porty sterujace mostkami. Wtedy tylko dla kazdego silnika definiujesz zmienna, ktora zawiera ilosc krokow do zrobienie - lewo prawo. Tylko pamietaj, ze dostep do takiej zmiennej musi byc atomowy - wiec w programie glownym blokujesz przerwania na czas dostepu do niej - w avr-glibc masz makra ATOMICBLOCK. Do tego do kazdego silnika wykorzystywany w przerwaniu licznik w kodzie Graya do generowania sygnalow sterujacych mostkiem. Tu widze tylko jedna komplikacje - przydaloby sie wprowadzac jakies dead time, zeby jednoczesnie nie przewodzily gorne i dolne tranzystory mostka. Poniewaz one moga sie wylaczac dosyc wolno, wiec opoznienia w przerwaniu to kiepski pomysl. Wiec mozna analogicznie ilosc krokow w przerwaniu przerabiac na komendy na mostek, ktore w kolejny (odpowiednio czesciej wywolywanym przerwaniu) beda zamieniane na stany logiczne sterujace poszczegolnymi galeziami mostka, dzieki temu mialbys programowy czas opoznienia pomiedzy wylaczeniem jednej galezi a wlaczeniem kolejnej. Ten AVR ma jeszcze cos robic oprocz sterowania tymi silnikami?
  • #7
    nelik1987
    Level 31  
    problem w tym ze na razie piszę to na AVR tak dla siebie, żeby się wprawić w pisaniu programów w C ale później będą do tego wykorzystywane bardziej zaawansowane procesory. Chciałem jeszcze zrobić tak by każdy silnik pracował z inna ale z góry ustaloną prędkością dlatego miał by być przerwanie a w nim inkrementacja zmiennych k1,k2,k3 które będą taki jak by licznikami dla poszczególnych silników i po ich "przepełnieniu" a dokładniej osiągnięciu pewnej wartości bedzie można zmienić stan dla mostków,

    czy to dobry pomysł?
  • #8
    tmf
    Moderator of Microcontroller designs
    Jasne, ze dobry. Policz tylko czy procesor sie wyrobi. Jak szybko chcesz krecic tymi silnikami? Ile maja krokow na obrot?
  • #10
    janbernat
    Level 38  
    Może rozwiązanie mniej ortodoksyjne, mniej eleganckie ale wykorzystujące zasoby procesora.
    Są trzy timery i sześć silników.
    Z tego można stworzyć sporo kombinacji.
    Może jeden timer do odliczania czasu "globalnego" a dwa pozostałe do sterowania silników?
    Wtedy sprzęt obsługuje część silników a program resztę.
    T0- zwykły licznik.
    T2- ma rejestr 0CR2.
    T1- 16 bitowy i ma trochę rejestrów dodatkowych.
  • #11
    nelik1987
    Level 31  
    no tak tylko chce jak najmniej obciążać procesor bo później dołożę, jeszcze rs232, do tego będzie trzeba obliczać sporo informacji dotyczących położenia ramienia w przestrzeni (obliczenia na macierzach). sukcesem jest to że mój promotor zgodził się na sterowania silnikami za pomocą ATMEGA lub podobnego pocesora :):):)
  • #12
    janbernat
    Level 38  
    Ale:
    Wykorzystanie timerów (o ile są wolne) nie obciąża programu i czasu procesora a tylko wykorzystuje wolny sprzęt (timery).
    Dokładniej- w znacznie mniejszym stopniu obciąża procesor i czas.
    Z tego co piszesz wynika że powinieneś przyzwyczajać się do 128 albo większej atmegi a nie do 16.
    Ceny ostatnimi laty mocno spadły.
    Ale 16 jest też dobra do treningu.
    Jeżeli w napisanym programie zauważysz jakiś nieużywany timer to będzie znaczyło że procesor ma niewykorzystane zasoby sprzętowe.
    A po to są zaimplementowane żeby odciążyć program procesora.
    Należy próbować wykorzystać wszystko co "fabryka dała".
    To nie jest "czysty, elegancki software" ale też sprzęt.
    Oba miewają "narowy".

    Dodano po 1 [minuty]:

    No i RS też jest przecież sprzętowy.
    A czasem nawet 2.
  • #13
    asembler
    Level 32  
    W asemblerze sie da zrobic i sporo mocy zostaje:-)
  • #14
    kamyczek
    Level 38  
    Samo działanie liczników i uarta sprzętowego nie obciąża procesora poza obsługą przerwań i konfiguracją. Jak brakuje portów i pojemności można zastosować ATMEGA 2560 w 100-pinowej obudowie.