Difference between revisions of "Comunica prin lpt"
From linux360
(Fixed control sequence nibble, FIXME removed) |
|||
(11 intermediate revisions by 7 users not shown) | |||
Line 1: | Line 1: | ||
==Intro== | ==Intro== | ||
Acesta se vrea un mini ghid despre controlul unui motor pas cu pas unipolar cu ajutorul linux-ului si a portului lpt. | Acesta se vrea un mini ghid despre controlul unui motor pas cu pas unipolar cu ajutorul linux-ului si a portului lpt. | ||
− | < | + | |
+ | ==Motoarele pas cu pas unipolare== | ||
+ | [[Image:5wire.jpg|left|thumb|100px|Schema unui motor cu 5 fire.]] | ||
+ | [[Image:6wire.jpg|left|thumb|100px|Schema unui motor cu 6 fire.]] | ||
+ | [[Image:Step.gif|left|thumb|200px|Modul de control al motoarelor pas cu pas.]] | ||
+ | |||
+ | Motoarele la care voi face referinta sunt motoare de curent continuu care se alimenteaza la 12-25V si au proprietatea de a putea | ||
+ | controla fiecare pas facut de aceste motoare. Un pas are de obicei 1,8 grade, ceea ce inseamna ca o rotatie completa inseamna 200 | ||
+ | de pasi. | ||
+ | Motoarele pas cu pas unipolare au de obicei 5 sau 6 fire, exista si cu 8 fire dar exista posibilitatea ca acestea sa fie si bipolare. | ||
+ | |||
+ | Asa cum observam din cele doua scheme constructia este asemanatoare, singura diferenta fiind alimentarea. La motorul cu 5 fire numai un fir este de alimentare (firul marcat common) restul de control la cel cu 6 fire sunt 2 fire de alimentare (firele marcate A si B). Daca la motorul cu 6 fire unim cele 2 fire de alimentare obtinem un motor pas cu pas cu 5. Concluzia daca invatam sa comandam unul din cele 2 il vom comanda si pe celalalt. | ||
+ | Pentru a afla care sunt firele noastre de alimentare vom masura rezistenta intre fire. Intre firul de alimentare si capete va fi o | ||
+ | rezistenta pe jumatate decat in cazul masurarii rezistentei intre 2 capete. La motorul cu 6 fire Orice combinatie A(+-)B(+-) nu va intoarce nici o rezistenta cele 2 fire nefiind legate. | ||
+ | Motoarele pas cu pas se controleaza aplicand o tensiune pe firele de control. Modul de control este prezentat in figura alaturata. | ||
+ | |||
+ | Pentru schimbarea sensului de rotatie pur si simplu se trimit comenzile in sens invers. | ||
+ | |||
+ | ==Schema portului lpt== | ||
+ | [[Image:Lpt.jpg]] | ||
+ | Asa cum se vede si din imagine pinii 18-25 sunt pentru masa, iar cei folositi de noi pentru transmiterea datelor vor fi pinii 2-8 | ||
+ | |||
+ | ==Cum facem montajul== | ||
+ | Deoarece motorul lucreaza cu tensiuni cu mult peste posibilitatile portului nostru lpt. O sa avem nevoie de o alimentare externa, | ||
+ | dar si de o protectie a portului nostru. Pentru aceasta o sa folosim cipul uln2003 sau uln2803a si o dioda zenner de 12V | ||
+ | |||
+ | Schema este urmatoarea [[Image:Lptmot.jpg]] | ||
+ | |||
+ | Trebuie sa mai adaugam o legatura intre unul din pinii de gnd(18-25) de la portul lpt cu masa si una de la pin-ul gnd al chip-ului cu masa. Si sa avem grija, ca firele motorului sa fie legate A+B+A-B- la pinii 2-5 ai portului lpt. | ||
+ | |||
+ | ==Programul de test== | ||
+ | <code><c/> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <fcntl.h> | ||
+ | #include <unistd.h> | ||
+ | #include <asm/io.h> | ||
+ | #include <signal.h> | ||
+ | #include <errno.h> | ||
+ | #include <linux/ppdev.h> | ||
+ | |||
+ | const char *filename; | ||
+ | int fd; | ||
+ | |||
+ | void cleanup_and_exit() { | ||
+ | printf("Lasam portul paralel in pace..."); | ||
+ | ioctl(fd, PPRELEASE); | ||
+ | close(fd); | ||
+ | printf("Terminat."); | ||
+ | exit(0); | ||
+ | } | ||
+ | |||
+ | int main(int argc, char *argv[]) { | ||
+ | unsigned char data; | ||
+ | int data_dir; | ||
+ | |||
+ | filename = "/dev/parport0"; | ||
+ | fd = open(filename, O_RDWR); | ||
+ | if (fd < 0) { | ||
+ | printf("Nu am putut accesa %s\n", filename); | ||
+ | return EINVAL; | ||
+ | } | ||
+ | |||
+ | /* Programul se opreste cu CTRL+C */ | ||
+ | signal(SIGINT, cleanup_and_exit); | ||
+ | |||
+ | ioctl(fd, PPEXCL); | ||
+ | if (ioctl(fd, PPCLAIM)) { | ||
+ | printf("Nu pot obtine controlul portului paralel."); | ||
+ | close(fd); | ||
+ | return EBUSY; | ||
+ | } | ||
+ | |||
+ | /* Vom scrie pe pinii Data 0 - 7, nu vom citi */ | ||
+ | data_dir = 0; | ||
+ | ioctl(fd, PPDATADIR, &data_dir); | ||
+ | |||
+ | #define LPT_WRITE(x) data = x; ioctl(fd, PPWDATA, &data) | ||
+ | for (;;) { | ||
+ | LPT_WRITE(9); | ||
+ | usleep(20*1000); | ||
+ | LPT_WRITE(3); | ||
+ | usleep(20*1000); | ||
+ | LPT_WRITE(6); | ||
+ | usleep(20*1000); | ||
+ | LPT_WRITE(12); | ||
+ | usleep(20*1000); | ||
+ | } | ||
+ | |||
+ | /* N-ar trebui sa se ajunga aici */ | ||
+ | return ENOSYS; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Programul utilizeaza [http://old.kernelnewbies.org/documents/kdoc/parportbook/parportguide.html acest API] si nu acceseaza direct portul paralel (via outb()) pentru a nu interfera negativ cu driverului din kernel. | ||
+ | |||
+ | [[Category:Howto]] | ||
+ | [[Category:Programming]] |
Latest revision as of 13:33, 9 July 2006
Contents
Intro
Acesta se vrea un mini ghid despre controlul unui motor pas cu pas unipolar cu ajutorul linux-ului si a portului lpt.
Motoarele pas cu pas unipolare
Motoarele la care voi face referinta sunt motoare de curent continuu care se alimenteaza la 12-25V si au proprietatea de a putea controla fiecare pas facut de aceste motoare. Un pas are de obicei 1,8 grade, ceea ce inseamna ca o rotatie completa inseamna 200 de pasi. Motoarele pas cu pas unipolare au de obicei 5 sau 6 fire, exista si cu 8 fire dar exista posibilitatea ca acestea sa fie si bipolare.
Asa cum observam din cele doua scheme constructia este asemanatoare, singura diferenta fiind alimentarea. La motorul cu 5 fire numai un fir este de alimentare (firul marcat common) restul de control la cel cu 6 fire sunt 2 fire de alimentare (firele marcate A si B). Daca la motorul cu 6 fire unim cele 2 fire de alimentare obtinem un motor pas cu pas cu 5. Concluzia daca invatam sa comandam unul din cele 2 il vom comanda si pe celalalt. Pentru a afla care sunt firele noastre de alimentare vom masura rezistenta intre fire. Intre firul de alimentare si capete va fi o rezistenta pe jumatate decat in cazul masurarii rezistentei intre 2 capete. La motorul cu 6 fire Orice combinatie A(+-)B(+-) nu va intoarce nici o rezistenta cele 2 fire nefiind legate. Motoarele pas cu pas se controleaza aplicand o tensiune pe firele de control. Modul de control este prezentat in figura alaturata.
Pentru schimbarea sensului de rotatie pur si simplu se trimit comenzile in sens invers.
Schema portului lpt
Asa cum se vede si din imagine pinii 18-25 sunt pentru masa, iar cei folositi de noi pentru transmiterea datelor vor fi pinii 2-8
Cum facem montajul
Deoarece motorul lucreaza cu tensiuni cu mult peste posibilitatile portului nostru lpt. O sa avem nevoie de o alimentare externa, dar si de o protectie a portului nostru. Pentru aceasta o sa folosim cipul uln2003 sau uln2803a si o dioda zenner de 12V
Trebuie sa mai adaugam o legatura intre unul din pinii de gnd(18-25) de la portul lpt cu masa si una de la pin-ul gnd al chip-ului cu masa. Si sa avem grija, ca firele motorului sa fie legate A+B+A-B- la pinii 2-5 ai portului lpt.
Programul de test
<c/>
- include <stdio.h>
- include <stdlib.h>
- include <fcntl.h>
- include <unistd.h>
- include <asm/io.h>
- include <signal.h>
- include <errno.h>
- include <linux/ppdev.h>
const char *filename; int fd;
void cleanup_and_exit() {
printf("Lasam portul paralel in pace..."); ioctl(fd, PPRELEASE); close(fd); printf("Terminat."); exit(0);
}
int main(int argc, char *argv[]) {
unsigned char data; int data_dir; filename = "/dev/parport0"; fd = open(filename, O_RDWR); if (fd < 0) { printf("Nu am putut accesa %s\n", filename); return EINVAL; }
/* Programul se opreste cu CTRL+C */ signal(SIGINT, cleanup_and_exit);
ioctl(fd, PPEXCL); if (ioctl(fd, PPCLAIM)) { printf("Nu pot obtine controlul portului paralel."); close(fd); return EBUSY; } /* Vom scrie pe pinii Data 0 - 7, nu vom citi */ data_dir = 0; ioctl(fd, PPDATADIR, &data_dir);
- define LPT_WRITE(x) data = x; ioctl(fd, PPWDATA, &data)
for (;;) { LPT_WRITE(9); usleep(20*1000); LPT_WRITE(3); usleep(20*1000); LPT_WRITE(6); usleep(20*1000); LPT_WRITE(12); usleep(20*1000); }
/* N-ar trebui sa se ajunga aici */ return ENOSYS;
}
Programul utilizeaza acest API si nu acceseaza direct portul paralel (via outb()) pentru a nu interfera negativ cu driverului din kernel.