Upload
danijel-mesaric
View
187
Download
1
Embed Size (px)
Citation preview
MEĐIMURSKO VELEUČILIŠTE U ČAKOVCU
SEMINARSKI RAD
UPRAVLJANJE KORAČNIM MOTORIMA
Kolegij: Uredsko poslovanje Student: Mesarić Danijel
Čakovec, lipanj 2011
Sadržaj
1. Uvod
2. Izolirano CNC sučelje - PBX-RF
3. Koračni motori - engl. (stepper motors)
4. ProboStep IV –Uni polar Microstepping Chopper Driver
5. Spajanje komponenti
6. Izgled gotovog uređaja za upravljanje koračnim motorima
7. Priprema za izradu programskog rješenja
8. Programsko rješenje za upravljanje koračnim motorima
9. Source kod programa za upravljanje koračnim motorima
10. Literatura
2
1. Uvod
Cilj ovog seminara je objasniti spajanje i upravljanje koračnim motorima putem računala.
Sam zadatak je krenuo sa idejom da izradimo upravljivu ˝humanoidnu˝ robotsku ruku što
vjernijih pokreta i dimenzija. Nakon dugotrajnije analize zaključili smo da se u prvom
projektu baziramo na upravljanje osnovna tri zgloba ruke : zglob u ramenu, laktu i zglobu
šake, tj. izrade elektroničkog dijela upravljanja. Samo upravljanje šake tj. prstiju bi se radilo u
naknadnom projektu. Odabravši broj zglobova koji želimo upravljati također smo definirali i
broj koračnih motora kojim ćemo upravljati tj. simulirati rad zglobova. Pretragom po
internetu zaključili smo da postoje već neka gotova rješenja za upravljanje koračnim
motorima koja se najčešće koriste kod upravljanja CNC strojevima. Jedan od takvih
proizvođača koja nudi kompletno rješenje je i tvrtka ˝PROBOTIX˝ na web adresi
www.probotix.com.
Sl. 1. Web stranica ˝www.probotix.com˝
3
Nakon odluke da projekt odrađujemo sa gotovim komponentama koje se nalaze na tržištu
trebalo je odlučiti koje ćemo komponente odabrati jer postoji više tipova komponenti koje se
razlikuju prema kvaliteti i cijeni. Na početku je trebalo odabrati kontroler za upravljanje
putem paralenog porta. Treba spomenuti da tek nakon naše narudžbe komponenti ta ista tvrtka
na tržište izbacuje novi kontroler kojim se upravlja putem USB sučelja što predstavlja bolju
opciju jer sva nova računala nemaju više paralelni port već USB sučelje.
2. Izolirano CNC sučelje - PBX-RF
Sl. 2. PBX-RF kontroler
Paralelni priključak,
DB25 ženski konektor,
fleksibilan dizajn,
dvostruki integrirani LM-317 sa 1.5 A
logičkim naponskim regulatorom,
USB Napajanje za PC stranu,
LED indikator napajanja,
PBX-RF Izolirani paralelni port dizajniran
posebno za hobi CNC strojeve,
izolacijski sloj štiti računalo od mogućih
oštećenja od kratkog spoja,
RF izolacijski čipovi se koriste u PBX-RF a
rade slično kao optički-izolator, osim što oni
koriste radio valove za slanje signala preko
izolacije, a ne svjetlost.
4
Sl. 3. Shematski prikaz PBX-RF kontrolera
Sl. 4. Shematski prikaz paralelnog porta PBX-RF kontrolera
3. Koračni motori - engl. (stepper motors)
Koračni motori su elektromehanički pretvornici energije, koji
pulsnu, odnosno koračnu električnu pobudu pretvaraju u koračni
mehanički pomak. Izrađuju se u rotacijskoj i translacijskoj izvedbi
5
(prevladava rotacijska). Na malim koračnim brzinama rotor se
zaustavlja na svakom koračnom položaju.
Sl. 5. Izgled i spajanje koračnog motora
60 Oz In. Hybrid
1.8° /200 koraka po punom okretu.
24 Volti
0.18 Ampera
5-žičani Uni-polarni
NEMA 23 Frame
4. ProboStep IV –Uni polar Microstepping Chopper Driver
Sl. 6. Upravljač koračnih motora ˝Probostep˝
Maksimalna struja 3 Ampera
Protekcija od kratkog spoja
Cijeli, 1/4, 1/2, 8th & 16th rezolucija koraka
Hardversko i softwersko određivanje
rezolucije
LED indikator napajanja
Veliki raspon napajanja koračnih motora od
10V do 44V
6
Sl. 7. Detaljan shematski prikaz ˝Probostep IV˝ upravljača
5. Spajanje komponenti
Nakon što smo kupili sve potrebne komponente trebalo je pristupiti spajanju svih tih
komponenti. Ideja je bila da komponente stavimo na pleksiglas i da ih pričvrstimo sa malim
šarafima i maticama. Izvor napajanja od 12 V uzeli smo od klasičnog napajanja koje se koristi
7
u računalima. Komponente smo spojili prema donjoj shemi te treba napomenuti da nismo
koristili zaštitne osigurače jer već postoji zaštita od kratkog spoja unutar postojećeg napajanja.
Sl. 8. Shematski prikaz spajanja probotix komponenata
Sl. 9. Prikaz ugrađenih probotix komponenti na pleksiglas ploči
6. Izgled gotovog uređaja za upravljanje koračnim motorima
8
Sl. 10. Izgled uređaja za upravljanje koračnim motorima
7. Priprema za izradu programskog rješenja
9
Nakon izrade hardwerskog dijela bilo je potrebno pristupiti izradi programskog rješenja za
upravljanje koračnim motorima. Odluka je pala da koristimo Visual Studio 2010 i da
programsko rješenje bude napisano u C# programskom jeziku. Da bi izradili program prvo
smo morali naći način da upravljamo paralelnim portom. Tu je postojalo nekoliko rješenja ali
na kraju smo odlučili raditi sa jednom komponentom koja omogućava potpunu kontrolu nad
paralelnim portom. Komponenta se zove TvicPort i može se skinuti na web adresi
http://www.entechtaiwan.com/dev/port/index.shtm te se mora obavezno instalirati prije
pokretanja programa čiji će kod biti objašnjen dalje u nastavku teksta.
Osim komponente za upravljanje paralelnim portom potrebno je znati i osnove o
paralelnom portu tj. njegovim pinovima kao što je prikazano slici 11.
Sl. 11. Detaljan prikaz rasporeda pinova paralelnog porta
Tablica 1. Opis bitova data registra paralelnog porta
10
Signal Pin Opis Vrsta Signala
D0 2 1. bit byta podataka Izlazni
D1 3 2. bit byta podataka Izlazni
D2 4 3. bit byta podataka Izlazni
D3 5 4. bit byta podataka Izlazni
D4 6 5. bit byta podataka Izlazni
D5 7 6. bit byta podataka Izlazni
D6 8 7. bit byta podataka IzlazniD7 9 8. bit byta podataka Izlazni
Tablica 2. Opis bitova status registra paralelnog porta
Signal Pin Opis Vrsta Signala
S0 Ne koristi se
S1 Ne koristi se
S2 Ne koristi se
S3 15 Impuls niskog nova koji signalizira grešku Ulazni
S4 13 Potvrđuje prisutnost printera Ulazni
S5 12 Paper Empty Ulazni
S6 10 ACK – Potvrdi impuls Ulazni
S7 11 Busy – Printer zauzet Ulazni
Tablica 3. Opis bitova control registra paralelnog porta
Signal Pin Opis Vrsta Signala
C0 1 Strobe Izlazni
C1 14 Auto Linefeed Izlazni
C2 16 Initialize Printer (Reset) Izlazni
C3 17 Select Printer Izlazni
C4 Enable IRQ Via Ack Line Izlazni
C5 Enable bi-directiona Port Izlazni
C6 Ne koristi se
C7 Ne koristi se
11
8. Programsko rješenje za upravljanje koračnim motorima
Sl. 12. Sučelje programa za upravljanje koračnim motorima
9. Source kod programa za upravljanje koračnim motorima
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using TVicPort_Cs;using System.Threading;
namespace StepMotori{ public partial class StepMotor : Form
12
{ bool DriverOpened = false; //boolean varijabla da znamo kad je otvoren paralelni port public StepMotor() { InitializeComponent(); }
/// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.Run(new StepMotor()); }
/// <summary> /// Kontrola za ukljucivanje gumba za otvaranje i zatvaranje paralelnog porta /// </summary> private void LockControls() { Open_Driver.Enabled = !DriverOpened; Close_Driver.Enabled = DriverOpened; }
/// <summary> /// Otvaramo paralelni port /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Open_Driver_Click(object sender, System.EventArgs e) { TVicPort.OpenTVicPort(); //otvaramo paralelni port DriverOpened = TVicPort.IsDriverOpened() != 0; //postavljanje boolean varijable da znamo kasnije dali je otvoren paralelni port LockControls(); //zakljucavamo gumbe za otvaranje paralelnog porta Set_LPT();
}
/// <summary> /// Setiranje paralelnog porta sve izlazne pinove od D0-D7 postavljamo na nulu /// </summary> private void Set_LPT() { if (DriverOpened) { TVicPort.SetLPTNumber(1); LockControls(); TVicPort.SetPin((byte)2, 0); //D0 TVicPort.SetPin((byte)3, 0); //D1 TVicPort.SetPin((byte)4, 0); //D2 TVicPort.SetPin((byte)5, 0); //D3 TVicPort.SetPin((byte)6, 0); //D4 TVicPort.SetPin((byte)7, 0); //D5 TVicPort.SetPin((byte)8, 0); //D6 TVicPort.SetPin((byte)9, 0); //D7
TVicPort.SetPin((byte)14, 0); //Control 14 TVicPort.SetPin((byte)16, 0); //Control 16 TVicPort.SetPin((byte)17, 0); //Control 17 } }
13
/// <summary> /// zatvarnje paralelnog porta /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Close_Driver_Click(object sender, System.EventArgs e) { Set_LPT(); TVicPort.CloseTVicPort(); //zatvaramo paralelni port DriverOpened = false; //status otvorenosti paralelnog porta stavljamo na false LockControls(); //otkljucavamo gubme za otvaranje paralelnog porta }
/// <summary> /// Load forme /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void StepMotor_Load(object sender, System.EventArgs e) { DriverOpened = false; //postavljamo boolean varijablu otvorenosti paralelnog porta na false LockControls(); //otkljucavamo gumbe }
/// <summary> /// Zatvaranje forme StepMotori /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void StepMotor_Closed(object sender, System.EventArgs e) { TVicPort.CloseTVicPort(); //zatvaramo paralelni port }
/// <summary> /// zatvaramo formu /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Command1_Click(object sender, System.EventArgs e) { Close(); }
/// <summary> /// Koracni motor 1 lijevi smjer /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void chkMotor1_Left_CheckedChanged(object sender, EventArgs e) { Motor1_lijevo(); }
/// <summary> /// Koracni motor 1 desni smjer /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void chkMotor1_Rght_CheckedChanged(object sender, EventArgs e) { Motor1_desno();
14
}
/// <summary> /// Koracni motor 2 lijevi smjer /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void chkMotor2_Left_CheckedChanged(object sender, EventArgs e) { Motor2_lijevo(); }
/// <summary> /// Koracni motor 2 desni smjer /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void chkMotor2_Rght_CheckedChanged(object sender, EventArgs e) { Motor2_desno(); }
/// <summary> /// Koracni motor 3 lijevi smjer /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void chkMotor3_Left_CheckedChanged(object sender, EventArgs e) { Motor3_lijevo(); }
/// <summary> /// Koracni motor 3 desni smjer /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void chkMotor3_Rght_CheckedChanged(object sender, EventArgs e) { Motor3_desno(); }
/// <summary> /// Koracni motor 1 lijevi smjer /// </summary> private void Motor1_lijevo() { bool Motor1_Left = false; byte Index3 = 3; byte Index2 = 2; int Sleep = 10; while (Motor1_Left == false) //vrtimo u petlji tako dugo dok je ukljucen Motor1 u lijevi smjer { Sleep = Math.Abs(trSpeed1.Value); //uzimamo apsolutnu vrijednost slidera za vrijeme cekanja tj .brzine Application.DoEvents(); //postavljamo kontrolu eventa na formi TVicPort.SetPin(Index3, 1); //setiramo vrijednost pina 3 tj D1 na 1 Thread.Sleep(Sleep); //cekamo odredjeno vrijeme definirano preko varijable Sleep TVicPort.SetPin(Index3, 0); //setiramo vrijednost pina 3 tj D1 na 0 TVicPort.SetPin(Index2, 1); //setiramo vrijednost pina 2 tj D0 na 1 Thread.Sleep(Sleep); //cekamo odredjeno vrijeme definirano preko varijable Sleep TVicPort.SetPin(Index2, 0); //setiramo vrijednost pina 2 tj D0 na 0
15
if (trMotor1.Value == 0) //ako je vrijednost slidera za Motor1 postavljamo boolean varijablu na false { Motor1_Left = true; //postavljamo boolean varijablu na false } } }
/// <summary> /// Koracni motor 1 desni smjer /// </summary> private void Motor1_desno() { bool Motor1_Rght = false; byte Index3 = 3; byte Index2 = 2; int Sleep = 10;
while (Motor1_Rght == false) //vrtimo u petlji tako dugo dok je ukljucen Motor1 u desni smjer {
Sleep = Math.Abs(trSpeed1.Value); //uzimamo apsolutnu vrijednost slidera za vrijeme cekanja tj .brzine Application.DoEvents(); //postavljamo kontrolu eventa na formi TVicPort.SetPin(Index3, 0); //setiramo vrijednost pina 3 tj D1 na 0 Thread.Sleep(Sleep); //cekamo odredjeno vrijeme definirano preko varijable Sleep TVicPort.SetPin(Index3, 1); //setiramo vrijednost pina 3 tj D1 na 1 TVicPort.SetPin(Index2, 0); //setiramo vrijednost pina 2 tj D0 na 0 Thread.Sleep(Sleep); //cekamo odredjeno vrijeme definirano preko varijable Sleep TVicPort.SetPin(Index2, 1); //setiramo vrijednost pina 2 tj D0 na 1 if (trMotor1.Value == 0) //ako je vrijednost slidera za Motor1 postavljamo boolean varijablu na false { Motor1_Rght = true; //postavljamo boolean varijablu na false } } }
/// <summary> /// Koracni motor 2 lijevi smjer /// </summary> private void Motor2_lijevo() { bool Motor2_Left = false; byte Index5 = 5; byte Index4 = 4; int Sleep = 10;
while (Motor2_Left == false) //vrtimo u petlji tako dugo dok je ukljucen Motor2 u lijevi smjer {
Sleep = Math.Abs(trSpeed2.Value); //uzimamo apsolutnu vrijednost slidera za vrijeme cekanja tj .brzine Application.DoEvents(); //postavljamo kontrolu eventa na formi TVicPort.SetPin(Index5, 1); //setiramo vrijednost pina 5 tj D3 na 1 Thread.Sleep(Sleep); //cekamo odredjeno vrijeme definirano preko varijable Sleep TVicPort.SetPin(Index5, 0);//setiramo vrijednost pina 5 tj D3 na 0 TVicPort.SetPin(Index4, 1); //setiramo vrijednost pina 4 tj D2 na 1 Thread.Sleep(Sleep); //cekamo odredjeno vrijeme definirano preko varijable Sleep TVicPort.SetPin(Index4, 0); //setiramo vrijednost pina 4 tj D2 na 0 if (trMotor2.Value == 0) //ako je vrijednost slidera za Motor2 postavljamo boolean varijablu na false { Motor2_Left = true; //postavljamo boolean varijablu na false } } }
16
/// <summary> /// Koracni motor 2 desni smjer /// </summary> private void Motor2_desno() { bool Motor2_Rght = false; byte Index5 = 5; byte Index4 = 4; int Sleep = 10;
while (Motor2_Rght == false) //vrtimo u petlji tako dugo dok je ukljucen Motor2 u desni smjer {
Sleep = Math.Abs(trSpeed2.Value); //uzimamo apsolutnu vrijednost slidera za vrijeme cekanja tj .brzine Application.DoEvents(); //postavljamo kontrolu eventa na formi TVicPort.SetPin(Index5, 0); //setiramo vrijednost pina 5 tj D3 na 0 Thread.Sleep(Sleep);//cekamo odredjeno vrijeme definirano preko varijable Sleep TVicPort.SetPin(Index5, 1); //setiramo vrijednost pina 5 tj D3 na 1 TVicPort.SetPin(Index4, 0); //setiramo vrijednost pina 4 tj D2 na 0 Thread.Sleep(Sleep); //cekamo odredjeno vrijeme definirano preko varijable Sleep TVicPort.SetPin(Index4, 1); //setiramo vrijednost pina 4 tj D2 na 1 if (trMotor2.Value == 0) //ako je vrijednost slidera za Motor2 postavljamo boolean varijablu na false { Motor2_Rght = true; //postavljamo boolean varijablu na false } } }
/// <summary> /// Koracni motor 2 lijevi smjer /// </summary> private void Motor3_lijevo() //vrtimo u petlji tako dugo dok je ukljucen Motor1 u lijevi smjer { bool Motor3_Left = false; byte Index7 = 7; byte Index6 = 6; int Sleep = 10;
while (Motor3_Left == false) //vrtimo u petlji tako dugo dok je ukljucen Motor 3 u lijevi smjer {
Sleep = Math.Abs(trSpeed3.Value); //uzimamo apsolutnu vrijednost slidera za vrijeme cekanja tj .brzine Application.DoEvents(); //postavljamo kontrolu eventa na formi TVicPort.SetPin(Index7, 1); //setiramo vrijednost pina 7 tj D5 na 1 Thread.Sleep(Sleep); //cekamo odredjeno vrijeme definirano preko varijable Sleep TVicPort.SetPin(Index7, 0); //setiramo vrijednost pina 7 tj D5 na 0 TVicPort.SetPin(Index6, 1); //setiramo vrijednost pina 6 tj D4 na 1 Thread.Sleep(Sleep); //cekamo odredjeno vrijeme definirano preko varijable Sleep TVicPort.SetPin(Index6, 0); //setiramo vrijednost pina 6 tj D4 na 0 if (trMotor3.Value == 0) //ako je vrijednost slidera za Motor3 postavljamo boolean varijablu na false { Motor3_Left = true; //postavljamo boolean varijablu na false } } }
/// <summary> /// Koracni motor 3 desni smjer /// </summary> private void Motor3_desno()
17
{ bool Motor3_Rght = false; byte Index7 = 7; byte Index6 = 6; int Sleep = 10;
while (Motor3_Rght == false) //vrtimo u petlji tako dugo dok je ukljucen Motor3 u desni smjer {
Sleep = Math.Abs(trSpeed3.Value); //uzimamo apsolutnu vrijednost slidera za vrijeme cekanja tj .brzine Application.DoEvents(); //postavljamo kontrolu eventa na formi TVicPort.SetPin(Index7, 0); //setiramo vrijednost pina 7 tj D5 na 0 Thread.Sleep(Sleep); //cekamo odredjeno vrijeme definirano preko varijable Sleep TVicPort.SetPin(Index7, 1); //setiramo vrijednost pina 7 tj D5 na 1 TVicPort.SetPin(Index6, 0); //setiramo vrijednost pina 6 tj D4 na 0 Thread.Sleep(Sleep); //cekamo odredjeno vrijeme definirano preko varijable Sleep TVicPort.SetPin(Index6, 1); //setiramo vrijednost pina 6 tj D4 na 1
if (trMotor3.Value == 0) //ako je vrijednost slidera za Motor3 postavljamo boolean varijablu na false { Motor3_Rght = true; //postavljamo boolean varijablu na false } } }
private void trMotor1_Scroll(object sender, EventArgs e) { trMotor2.Value = 0; trMotor3.Value = 0; //LIJEVO if (trMotor1.Value == -1) { Motor1_lijevo(); //pokrecem metodu za motor 1 u lijevu stranu } //DESNO if (trMotor1.Value == 1) { Motor1_desno(); //pokrecem metodu za motor 1 u desnu stranu }
//STOP if (trMotor1.Value == 0) //ako je status motora 1 iskljucen postavljam sve izlazne pinove na vrijednost 0 { TVicPort.SetPin((byte)2, 0); //D0 TVicPort.SetPin((byte)3, 0); //D1 TVicPort.SetPin((byte)4, 0); //D2 TVicPort.SetPin((byte)5, 0); //D3 TVicPort.SetPin((byte)6, 0); //D4 TVicPort.SetPin((byte)7, 0); //D5 TVicPort.SetPin((byte)8, 0); //D6 TVicPort.SetPin((byte)9, 0); //D7
TVicPort.SetPin((byte)14, 1); //Control 14 TVicPort.SetPin((byte)16, 1); //Control 16 TVicPort.SetPin((byte)17, 1); //Control 17 } }
private void trMotor2_Scroll(object sender, EventArgs e) { trMotor1.Value = 0; trMotor3.Value = 0; //LIJEVO
18
if (trMotor2.Value == -1) { Motor2_lijevo(); //pokrecem metodu za motor 2 u lijevu stranu } //DESNO if (trMotor2.Value == 1) { Motor2_desno(); //pokrecem metodu za motor 2 u desnu stranu }
//STOP if (trMotor2.Value == 0) //ako je status motora 2 iskljucen postavljam sve izlazne pinove na vrijednost 0 { TVicPort.SetPin((byte)2, 0); //D0 TVicPort.SetPin((byte)3, 0); //D1 TVicPort.SetPin((byte)4, 0); //D2 TVicPort.SetPin((byte)5, 0); //D3 TVicPort.SetPin((byte)6, 0); //D4 TVicPort.SetPin((byte)7, 0); //D5 TVicPort.SetPin((byte)8, 0); //D6 TVicPort.SetPin((byte)9, 0); //D7
TVicPort.SetPin((byte)14, 1); //Control 14 TVicPort.SetPin((byte)16, 1); //Control 16 TVicPort.SetPin((byte)17, 1); //Control 17 } }
private void trMotor3_Scroll(object sender, EventArgs e) { trMotor1.Value = 0; trMotor2.Value = 0; //LIJEVO if (trMotor3.Value == -1) { Motor3_lijevo(); //pokrecem metodu za motor 3 u lijevu stranu } //DESNO if (trMotor3.Value == 1) { Motor3_desno(); //pokrecem metodu za motor 3 u desnu stranu }
//STOP if (trMotor3.Value == 0) //ako je status motora 3 iskljucen postavljam sve izlazne pinove na vrijednost 0 { TVicPort.SetPin((byte)2, 0); //D0 TVicPort.SetPin((byte)3, 0); //D1 TVicPort.SetPin((byte)4, 0); //D2 TVicPort.SetPin((byte)5, 0); //D3 TVicPort.SetPin((byte)6, 0); //D4 TVicPort.SetPin((byte)7, 0); //D5 TVicPort.SetPin((byte)8, 0); //D6 TVicPort.SetPin((byte)9, 0); //D7
TVicPort.SetPin((byte)14, 1); //Control 14 TVicPort.SetPin((byte)16, 1); //Control 16 TVicPort.SetPin((byte)17, 1); //Control 17 } } }}
19
10. Literatura
[1] http://www.probotix.com
20