Autor: TPT
Redakcja: Dondu
Najczęściej w tego typu układach stosowane są dwufazowe silniki krokowe, więc takimi też się zajmiemy. Każdy, kto zajmuje się elektroniką na pewno ma dostęp do np. starej drukarki, więc nie jest ciężko zdobyć mały silnik krokowy, przez co można wykorzystać go do amatorskich projektów mechatronicznych.
Ponieważ z mojego doświadczenia wynika, że częściej w tego typu małych układach wykorzystywane są dwufazowe silniki unipolarne niż bipolarne, więc pomęczymy właśnie unipolarny silnik wyciągnięty z drukarki HP.
Czym się różni silnik bipolarny od unipolarnego? W dużym skrócie: silnik unipolarny posiada 5 lub 6 przewodów, sterujemy nim puszczając prąd przez jego uzwojenia zawsze w jednym kierunku. W silniku bipolarnym polaryzacje na uzwojeniach zmienia się, z reguły posiada 4 wyprowadzenia.
Więcej o silnikach krokowych (budowa, zasady sterowania, wady i zalety) można poczytać tutaj:
- Silniki krokowe od podstaw, cz. 1 (kopia),
- Silniki krokowe od podstaw, cz. 2 (kopia),
- Silniki krokowe od podstaw, cz. 3 (kopia),
- Silniki krokowe od podstaw, cz. 4 (kopia),
- Silniki krokowe od podstaw, cz. 5 (kopia),
- Silniki krokowe od podstaw, cz. 6 (kopia).
Silniki unipolarne (jak już wspomniałem) posiadają 5 lub 6 wyprowadzeń, z czego jedno (dla 5. wyprowadzeń) lub dwa (dla 6. wyprowadzeń) są zasilaniem silnika. Można je wyznaczyć za pomocą omomierza, środek uzwojenia (oznaczany jako COMA/COMB) ma najmniejszą rezystancję. W moim przypadku między końcówkami uzwojeń rezystancja wyniosła 150Ω, między zasilaniem/końcówką 75Ω.
W przypadku silników z pięcio-przewodowymi wyprowadzeniami mamy zadanie utrudnione, gdyż przewód zasilający jest wspólny, więc nie ustalimy tą metodą par uzwojeń, ale to już można ustalić w czasie podłączania do sterownika (jeśli silnik będzie się wiercił w lewo i w prawo to będzie oznaczało, że podłączyliśmy źle).
Aby sprawdzić, czy silnik jest sprawny i nadaje się do użytku można zbudować sterownik "mechaniczny" - cztery switche (#1 - #4), które będą zwierać końcówki uzwojeń z GND, COM podłączamy do zasilania. Naciskając po kolei switche obracamy wałem, jeśli podłączymy końcówki w odpowiedniej kolejności naciskając przyciski w sekwencji #1 do #4 będziemy obracali wałem ciągle w jedną stronę, jeśli nie- podłączenie jest złe. Jeśli zaś silnik w ogóle nie reaguje - prawdopodobnie silnik jest uszkodzony.
Do sterowania wyżej wspomnianym silnikiem wykorzystałem ATmega16 (z wewnętrznym generatorem 8MHz) wraz z dedykowanym sterownikiem silników krokowych, popularnym układem L297 oraz N- MOSFET-y BS170 (0,3A).
Oczywiście sterowników silników krokowych jest więcej, wybrałem L297 ze względu na jego wszechobecność w sklepach elektronicznych. Zamiast MOSFET-ów można użyć tranzystorów bipolarnych w układzie Darlingtona (stosując np. układ U2003).
Po zapoznaniu się z dokumentacją przystąpiłem do podłączenia układu na płytce stykowej zgodnie ze schematem poniżej.
![]() |
Schemat sterownika unipolarnego silnika krokowego. |
Rezystory R2-4-6-8 są po to, aby wymusić tzw. polaryzację zamykającą, dzięki czemu unikniemy niekontrolowanego włączenia tranzystora (w naszym przypadku zakłócałoby to pracę silnika). Więcej na ten temat znajdziesz w artykule: Tranzystor MOSFET: Wiedza tajemna.
Diody LED włożyłem aby było widać gdzie jest w danym momencie sygnał (do tego efektownie to wygląda oraz, jak wiadomo, człowiekowi zawsze lepiej na duszy, gdy się mu coś zaświeci).
Z ciekawszych wejść układu L297:
- ENABLE - po podaniu na nie zera logicznego blokujemy prąd płynący przez silnik
- DIRECTION - w zależności od stanu logicznego podanego na ten pin kręcimy wałem w lewo lub prawo (w zależności od podłączenia silnika)
- CLOCK - sterowanie kolejnymi krokami silnika. Silnik wykonuje krok w chwili pojawienia się narastającego zbocza sygnału (jeden sygnał = jeden krok).
- HALF/FULL - stan wysoki, to sterowanie półkrokowe (dwukrotnie większa rozdzielczość), stan niski, to sterowanie pełnokrokowe.
Oryginał na koncie autora: Unipolar Stepper Motor Controller
Do moich testów dorzucam często wyświetlacz LCD oraz diody kontrolne, w tym przypadku:
- niebieska - pokazuje kiedy pojawia się sygnał podawany na wejście CLOCK, pokazuje też częstotliwość podawania
- czerwona - włączenie podawania sygnału
- zielona i żółta - kierunek obrotu.
Dzięki temu układ staje się czytelniejszy, a tak poza tym to nie ukrywam - lubię świecące zabawki :-)
Program jaki napisałem do moich testów znajduje się poniżej. Jak można było się dowiedzieć z odnośnika podanego wyżej - silniki krokowe są (stosunkowo) wolnoobrotowe, maksymalna częstotliwość z jaką udało mi się sterować silnikiem wyniosła 31250Hz. Przy większej częstotliwości silnik jedynie „wiercił” się.
W poniższym programie prędkość ustawiamy w warunku if-a przy komentarzu //SPEED (im większy parametr cnt2, tym mniejsza prędkość).
Wyświetlacz wykorzystany przeze mnie zgodny z HD44780.
Program służył tylko i wyłącznie do testów i służył do kręcenia silnikiem w lewo i prawo.
/* TEST krokowca (pod unipolarny) // TPT // mega16+LCD // mLCD (C0-C5) // 14.07.2013 // aktualizacja 17.07.2013 // stan:OK!!! // // UWAGA!!! // W pliku HD44780.h należy zdefiniować piny, do których podłączysz LCD. */ //#define F_CPU 8000000UL //Program dla 8MHz. Ustaw w opcjach projektu lub //usuń znaki komentarza #include <avr/io.h> #include <avr/interrupt.h> #include "HD44780.h" #define SW1 PD6 #define SW2 PD5 #define SW3 PD4 #define DIR PD3 #define LEDG PB0 #define LEDY PB1 #define LEDR PB2 #define CLOCK PD2 volatile unsigned int i=0; // ON/OFF volatile unsigned int j=0; // Direction volatile unsigned int cnt = 0; volatile unsigned int cnt2 = 0; // Zmienne do kontroli przycisków uint8_t oldkey[2]; uint8_t key[2]; //***************************************************************** void io_init(void){ //Ustawienia pinów //atmega16 DDRA |= 0b00000000; DDRB |= 0b00000111; DDRD |= 0b10001100; //Pull Up-y PORTD |= (1<<SW1) | (1<<SW2) | (1<<SW3); i=0; cnt=0; } //***************************************************************** void timer_init(void) { TIMSK |= (1<<TOIE0); //Włącz przerwanie overflow (przepełnienie timera) TCCR0 |= (1<<CS01) | (1<<CS00); //preskaler } //***************************************************************** void left (void) // Kręcenie w lewo { PORTD &= ~(1<<DIR); PORTB |= (1<<LEDG); PORTB &= ~(1<<LEDY); } //***************************************************************** void right (void) // Kręcenie w prawo { PORTD |= (1<<DIR); PORTB &= ~(1<<LEDG); PORTB |= (1<<LEDY); } //***************************************************************** void defaultThis() // Reset { PORTB &= ~(1<<LEDG); PORTB &= ~(1<<LEDY); PORTB &= ~(1<<LEDR); PORTD &= ~(1<<CLOCK); } //***************************************************************** void lcd_layout(void) // Obsługa LCD { LCD_Clear(); LCD_GoTo(0,0); if (i == 1) { LCD_WriteText("Engine: OFF"); LCD_GoTo(0,1); LCD_WriteText("Direction: OFF"); defaultThis(); } if ((i == 2) && (j == 0)) { LCD_WriteText("Engine: ON"); LCD_GoTo(0,1); LCD_WriteText("Direction: LEFT"); } if ((i == 2) && (j == 1)) { LCD_WriteText("Engine: ON"); LCD_GoTo(0,1); LCD_WriteText("Direction: RIGHT"); } } //***************************************************************** void readButtons() // Obsluga przycisków { oldkey[0] = 1; oldkey[1] = 1; oldkey[2] = 1; key[0]= PIND & (1<<SW1); key[1]= PIND & (1<<SW2); key[2]= PIND & (1<<SW3); if((key[0]^oldkey[0]) && (key[0]==0)) { j=0; left(); lcd_layout(); } if((key[1]^oldkey[1]) && (key[1]==0)) { j=1; right(); lcd_layout(); } if((key[2]^oldkey[2]) && (key[2]==0)) { if (i == 1) { i = 2; lcd_layout(); OCR2 = 0; PORTB |= (1<<LEDR); if ( j == 0 ) { PORTB |= (1<<LEDY); PORTB &= ~(1<<LEDG); } if ( j == 1 ) { PORTB |= (1<<LEDG); PORTB &= ~(1<<LEDY); } } else { i = 1; lcd_layout(); OCR2 = 255; } } } //***************************************************************** int main (){ //Początek programu io_init(); timer_init(); LCD_Initalize(); sei(); LCD_GoTo(0,0); LCD_WriteText("TEST KROKOWCA"); LCD_GoTo(0,1); LCD_WriteText("MIKROKONTROLERY"); i=1; while (1) { //pętla główna } } //***************************************************************** ISR(TIMER0_OVF_vect)//przerwanie po przepełnieniu timera { cnt++; if (cnt == 100) //eliminacja drgań styków { readButtons(); cnt=0; } if( i == 2) { cnt2++; if (cnt2 == 50) // SPEED { PORTD ^= (1<<CLOCK); cnt2=0; } } }
Do pobrania kompletny projekt AVR Studio 4.18: SILNIK_1.zip (kopia)
W przypadku pytań chętnie odpowiem.
Pozdrawiam,
TPT