|
|
Dieser Artikel ist verfübar in: English Castellano Deutsch Francais Nederlands Portugues Russian Turkce Arabic |
von Katja und Guido Socher <katja(at)linuxfocus.org, guido.socher(at)linuxfocus.org> Über die Autoren: Katja ist die deutsche Redakteurin von LinuxFocus. Sie mag Tux, Film & Fotografie und das Meer. Ihre Homepage findet sich hier. Guido ist ein langjähriger Linuxfan und er mag Linux, weil es von ehrlichen und offenen Leuten entwickelt wurde. Dies ist einer der Gründe, warum wir es Open Source nennen. Seine Homepage ist auf linuxfocus.org/~guido. Übersetzt ins Deutsche von: Katja Socher <katja(at)linuxfocus.org> Inhalt: |
Zusammenfassung:
In diesem Artikel bauen wir einen kleinen, sechsbeinigen, laufenden Roboter, den wir dann mit einem Linux PC über den Parallelport ansteuern. Andere Geräte können auf ähnliche Weise über den Parallelport gesteuert werden.
Roboter haben uns schon immer fasziniert, so daß wir beide begeistert waren, als wir vor einiger Zeit ein Buch über Roboter entdeckten, das schon gleich den Roboterbausatz enthielt, um einen kleinen, insektenartigen Roboter namens Stiquito zu bauen. Stiquito ist ein etwas besonderer Roboter, da er keinen Motor hat, sondern dadurch läuft, daß seine Beine mit Nitinol verdrahtet sind. Auf diese Weise läuft er völlig leise, fast wie ein echtes Insekt. Aber als wir ihn gebaut hatten, stellten wir fest, daß seine tatsächliche Bewegung sehr sehr langsam ist, weil er nur sehr wenig Reibung mit der Oberfläche hat, auf der er läuft. Glücklicherweise enthielt das Buch noch einige weitere Beschreibungen von anderen Roboterdesigns, die uns schließlich dazu inspirierten, den Roboter, über den du hier lesen kannst, zu bauen.
Um den Roboter zu bauen, haben wir die folgenden Teile benutzt:
Abb. 1: Platine |
Abb. 2: Spitzzange |
Für den Körper braucht man zuerst drei der Platinenteile, die mit 6x6 Löchern
und die zwei mit 6x7 Löchern sowie das 4cm lange Messingröhrchen mit 2 mm
Durchmesser zusammen mit 3.7 cm Stahldraht.
Abb. 4: Rückgrat und Powerbus
Schneide das Messingröhrchen in Stücke von 8, 17.5 und 8mm wie im Bild gezeigt. Man
kann das durch Hin-
und Herrollen des Röhrchens unter dem scharfen Küchenmesser und durch Biegen
erreichen. Die Röhrchen brechen dort, wo du die Kerben mit dem Messer gemacht hast. Es
ist wichtig, daß das mittlere Röhrchen etwas länger ist als die
6x6 Löcher Platine. Schneide ca. 3.7cm Stahldraht ab. Die endgültige Länge muß
ca. 3mm länger sein als die drei Röhrchen zusammen. Stecke den Stahldraht durch die
drei Röhrchen.
Das Röhrchen in der Mitte
muß in der Lage sein, zu rotieren, während die anderen beiden an den Stahldraht
angelötet werden.
Abb. 5: Löte die Platinen an das Rückgrat
Das mittlere Röhrchen wird jetzt an die 6x6 Löcher Platine gelötet. Paß auf, daß
sie rotieren können. Die anderen beiden Röhrchen werden an die anderen beiden
Platinen gelötet.
Jetzt nimm die vierte, die kleine 2x7 Löcher Platine. Sie soll hochkant auf dem
mittleren Messingröhrchen stehen. Die Platine muß mit einer kleinen Feile oder
dem Seitenschneider eingekerbt werden. Löte sie, wie im Bild gezeigt, an das mittlere
Messingröhrchen und die mittlere Platine an:
Abb. 6: Hinzufügen der kleinen Platine
Schmiergel das Messingröhrchen mit 1mm Durchmesser und schneide einige 4mm
lange Stücke aus
dem Röhrchen. Rolle das Rohr unter dem Küchenmesser und bieg es dann. Du
brauchst 16 von diesen Crimps, aber mach lieber ein paar mehr.
Da jetzt eine ganze Menge Crimpen gebraucht wird, probierst du es besser mit
einem kleinen Stück Nitinol aus, bevor du richtig loslegst: Stecke das Ende des
Nitinoldrahtes in das sehr dünne Messingröhrchen (1mm Außendurchmesser) und
drücke dann das Messingröhrchen fest mit der Spitzzange. Dies nennt man Crimpen.
Paß auf, daß du eine gute Spitzzange verwendest, da die Kraft zum
Zusammendrücken der Messingröhrchen sehr hoch ist. Du kannst die Enden des
Nitinols auch durch feines 600körniges Schmiergelpapier gleiten lassen, um gute
elektrische Verbindungen zu bekommen.
Jetzt verdrahten wir das Nitinol, das benötigt wird, um die Beine hoch und
runter zu bewegen.
Abb. 7: "die Brücke"
Man spannt den Nitinoldraht so, als wollte man eine Brücke bauen. Man fängt auf
einer Seite an. Dort zieht man den Nitinoldraht durch das letzte Loch, das auf
der linken und geraden Seite möglich ist. Man macht einen Knoten in das Nitinol
(um eine bessere Verbindung sicherzustellen)
und setzt eine Crimp (ein ca. 4mm langes Messingröhrchen) darüber und crimpt es
fest, so daß es fest sitzt und der Nitinoldraht durch das zweite Loch von oben
auf der linken Seite und dann durch das letzte mögliche Loch auf der linken und
geraden Seite gezogen werden kann (sieh Abb. 7). Der Nitinoldraht muß fest sein, aber nicht zu
fest. Wenn du mit dem Finger das Nitinol berührst, sollte es sich 2-4mm bewegen.
Wenn es nicht fest genug ist oder zu fest sitzt, wird sich der Roboter
später nicht ordentlich bewegen. Löte die Crimpen an die Platine.
Mach dasselbe auf der rechten Seite.
Bevor du weitermachst, probier aus, ob es funktioniert. Benutze eine 1.5 V
Batterie und verbinde sie mit dem Nitinoldraht. Wenn der Draht sich
zusammenzieht, muß der mittlere Körpterteil um 10-20 Grad rotieren. Paß auf, daß
du die Batterie nicht länger als eine Sekunde anschließt. Du beschädigst sonst
den Draht, wenn du ihn überhitzt.
Abb. 8: Biegen des Drahts
Für die Beine schneidest du drei 10cm lange Teile aus dem Stahldraht. Jedes Teil
wird auf beiden Seiten um 1.5cm gebogen. Dann werden sie an die drei Körperteile
des Roboters gelötet. Sie sollten parallel zueinander sein.
Abb. 9, 10: die Roboterbeine
Jetzt mußt du das Nitinol mit den sechs Beinen verdrahten.
Abb. 11: Hinzufügen des Antriebs
Ziehe Nitinol von oben durch eine Crimpe und durch ein Loch in der Platine. Der
Abstand zum Stahldraht beträgt drei Löcher. Crimp es fest (sieh die Bilder oben).
Dann zieh eine Crimp über den Stahldraht bis du das Kniegelenk erreichst. Zieh
den Nitinoldraht hindurch und crimp es fest. Jetzt kommt der schwierigste Teil.
Halte den Roboter mit einem kleinen Schraubstock, fixiere ihn und spann die Beine
mit Klebeband oder extra Kupferdraht an, um spannungsfrei löten zu können. Der Stahldraht wirkt als Gegenkraft zum
Nitinol. Damit dies funktioniert, darf das Nitniol überhaupt nicht lose sein.
Der Stahldraht muß ein Platinenloch zum Nitinol gezogen werden und dann muß die
Crimp an das Bein festgelötet werden.
Abb. 12: Nitinol und Stahldraht auf derselben Ebene
Stell sicher, daß der Stahldraht und das Nitinol auf derselben Ebene sind. Die
Beine dürfen sich nicht nach oben oder unten bewegen, wenn sich das Nitinol
zusammenzieht, sondern sie müssen sich nach hinten bewegen.
Mach dasselbe mit den anderen fünf Beinen.
Die Beine und der Stahldraht mit den Messingröhrchen in der Mitte des Roboters
fungieren als Powerbus und deshalb muß eine elektrische Verbindung zwischen
allen von ihnen bestehen. Da jedoch der mittlere Körperteil mehr Freiheit hat, da
er rotieren kann und daher keine gute Verbindung besteht, haben wir dies dadurch
verbessert, daß wir 3cm des 0.1mm lackierten Kupferdrahtes genommen haben und
ihn um ein übriggebliebenes Messingröhrchen gewickelt haben, um eine kleine
Spule zu bekommen. Nimm das Messingröhrchen heraus und löte die Spule so, daß
die inneren Beinpaare mit den äußeren Beinpaare verbunden sind. Die
Wicklungsform des Drahtes stellt die maximale Flexibilität sicher.
Wenn der Roboter fertig ist, kannst du 0.5m lange Stücke (oder länger, wenn du willst) aus 0.1mm lackiertem Kupferdraht an die Crimps auf der Platine löten. Löte dann die Körpercrimps selbst an die Platine. Wir brauchen neun Drähte, sechs für die Beine, zwei für hoch/runter und eins für den allgemeinen Powerbus. Du kannst die anderen Enden des Drahtes an einen kleinen Stecker löten, den du dann in die entsprechende kleine Buchse der Treiberschaltung stecken kannst.
Unser Insekt wurde für einen Dreifußgang (tripod) entwickelt. Ein Dreifußgang meint,
daß drei Beine am Boden sind (zwei Füße auf der einen und ein Fuß auf der
anderen Seite), während die anderen drei in der Luft sind. Wenn der Roboter
geht, dann bewegen sich die drei Beine am Boden in die eine Richtung, während
sich die Beine in der Luft in die entgegengesetzte Richtung bewegen.
Abb. 13: Der Gang
Diese Platine erlaubt es uns, unseren PC zum Steuern des Antriebs unseres
Roboters zu benutzen und wird in den Parallelport gesteckt.
Als wir unser Computerprogramm entwickelt haben, haben wir es zuerst mit LEDs
getestet und die Robotersteuerungsdrähte erst in den Sockel der Platine
gesteckt, als es korrekt funktioniert hat und die LEDs einen korrekten Laufgang
anzeigten. Du solltest dasselbe tun, wenn du mit dem Programm experimentierst.
Der Roboter ist recht hungrig. Du mußt zwischen 200 und 250 mA Strom durch den
Nitinoldraht schicken, damit er sich zusammenzieht. Die 3cm langen Nitinoldrähte
an den Beinen haben ungefähr 7 Ohm. Starte immer zuerst die Software, bevor du den Strom
an die Treiberschaltung anschließt, weil alle Datenpins von der Software zuerst
auf "aus" gesetzt
werden, um ein Beschädigen des Nitinoldrahtes zu verhindern. Das Bios des
Computers setzt die Datenpins des Parallelports auf Zufallswerte. Einige davon
könnten deshalb dann im Zustand "an" sein.
Das Nitinol kann beschädigt werden, wenn du einen Strom viel länger als eine
Sekunde hindurchschickst. Die Zeit für das Nitinol, um abzukühlen, sollte 1.5mal
so lang sein, wie die Zeit, die du es erhitzt hast.
Das Schaltbild:
Abb. 14: Schaltbild
Wie du im obigen Schaltbild sehen kannst, benutzen wir eine elektronisch
stabilisierte Stromquelle, um einen guten und sicheren Strom
sicherzustellen und um den Parallelport zu schützen. Als externe Stromquelle
kannst du jede DC Stromquelle zwischen 6 und 24V anschließen. Der 7805 ist ein
Standardspannungsregler. Das einzige, was du hier beachten mußt, ist, daß
die zwei Kondensatoren (470uF und 0.1uF) sich nahe zum 7805 Spannungsregler
befinden, weil es ansonsten passieren könnte, daß der 7805 Chip anfängt, zu
oszillieren, was den 7805 zerstören könnte.
Der tatsächliche Treiber muß achtmal gebaut werden. Eins für jedes Bein und zwei
für das Drehen des Roboters (Hoch und Runter der Beine). Wir benutzen einen
kleinen NPN
Darlingtontransistor, weil unser Roboter eine Menge Strom verbraucht. Der BC875
oder BC618 können ungefähr 500mA schalten. Die 47K bei der Eingabe stellen
sicher, daß ein offener Stromkreis (z.B. der Computer ist nicht angeschlossen)
immer mit "aus" äquivalent ist. Das Spannungsniveau des Parallelports liegt über
4V für "an" und unter 1V für den Zustand "aus". Der Transistor arbeitet nur als
Schalter. Die 15 Ohm Widerstände begrenzen den Strom
und schützen sowohl die Beine des Roboters als auch den Transistor. Die LEDs
zeigen den Zustand an (ein oder aus).
Unten siehst du Bilder des Schaltkreises. Die roten LEDs (die, die parallel zu
den Roboterantrieben sind), sind schwierig zu sehen, weil wir transparente rote
LEDs benutzt haben. Wir haben die 15 Ohm Widerstände aus
Konstantandrahtwicklungen gebaut, aber dies war nur der Fall, weil wir sehr viel
von diesem Draht zur Verfügung hatten. Es ist billiger, fertige 2W Widerstände
zu kaufen.
Der Parallelport wurde entwickelt, um als Ausgangsport von einem Computer zu
dienen und an einen Drucker angeschlossen zu werden. Einige Parallelports
erlauben sowohl Ein- als auch Ausgang. Hier benutzen wir nur den
Ausgangsport. In einem späteren Artikel werden wir Sensoren an unseren Roboter
anschließen und dann auch den Eingangsport benutzen. Obwohl der Parallelport 25 Pins
hat, benutzen wir nur neun. Acht werden als Datenausgangsverbindungen benutzt
und einer dient als Erdung.
Die Pinbelegung für den Parallelport sieht wie folgt aus:
25 PIN D-SUB FEMALE at the PC. Pin Name Dir Description 1 STROBE [-->] Strobe 2 D0 [-->] Data Bit 0 3 D1 [-->] Data Bit 1 4 D2 [-->] Data Bit 2 5 D3 [-->] Data Bit 3 6 D4 [-->] Data Bit 4 7 D5 [-->] Data Bit 5 8 D6 [-->] Data Bit 6 9 D7 [-->] Data Bit 7 10 ACK [<--] Acknowledge 11 BUSY [<--] Busy 12 PE [<--] Paper End 13 SEL [<--] Select 14 AUTOFD [-->] Autofeed 15 ERROR [<--] Error 16 INIT [-->] Initialize 17 SELIN [-->] Select In 18 GND [---] Signal Ground 19 GND [---] Signal Ground 20 GND [---] Signal Ground 21 GND [---] Signal Ground 22 GND [---] Signal Ground 23 GND [---] Signal Ground 24 GND [---] Signal Ground 25 GND [---] Signal GroundDu verbindest die Treiberschaltung mit Pin 18 (GND) und mit den Datenpins (2-9).
==== pprobi.c ===== /* vim: set sw=8 ts=8 si : */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License. * See http://www.gnu.org/copyleft/ for details. * * Written by Katja Socher <[email protected]> * and Guido Socher <[email protected]> * */ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <math.h> #include <signal.h> #include "robi.h" /* ----------- */ static int opt_r=0; static int fd=0; /* ----------- */ /* ----------- */ void help() { printf("pprobi -- control software for a walking robot\n\ USAGE: pprobi [-h] [parport-device]\n\ \n\ OPTIONS:\n\ -h this help\n\ -r reset the parallel port data pins (all zero) and exit\n\ \n\ The default device is /dev/parport0 \n\ "); #ifdef VERINFO puts(VERINFO); #endif exit(0); } /* Signal handler: all off then exit */ void offandexit(int code) { robi_setdata(fd,0); set_terminal(0); exit(0); } /* ----------- */ int main(int argc, char **argv) { int state,bpat,alternate; char *dev; /* The following things are used for getopt: */ int ch; extern char *optarg; extern int optind; extern int opterr; opterr = 0; while ((ch = (char)getopt(argc, argv, "hr")) != -1) { switch (ch) { case 'h': help(); /*no break, help does not return */ case 'r': opt_r=1; break; case '?': fprintf(stderr, "serialtemp ERROR: No such option. -h for help.\n"); exit(1); /*no default action for case */ } } if (argc-optind < 1){ /* less than one argument */ dev="/dev/parport0"; }else{ /* the user has provided one argument */ dev=argv[optind]; } fd=robi_claim(dev); /* robi_claim has its own error checking */ /* catch signals INT and TERM and switch off all data lines before * terminating */ signal(SIGINT, offandexit); signal(SIGTERM, offandexit); /* initialize parpprt data lines to zero: */ robi_setdata(fd,0); set_terminal(1); /* set_terminal has its own error handling */ state=0; alternate=0; if (opt_r){ offandexit(1); } while(1){ ch=getchoice(); if (ch!=0) state=ch; if (ch == ' '){ printf("Stop\n"); robi_setdata(fd,0); usleep(500*1000); } if (ch == 'q'|| ch == 'x'){ printf("Quit\n"); break; } if (state=='l'){ /*right */ printf("walking right\n"); walkright(fd); } if (state=='h'){ /*left */ printf("walking left\n"); walkleft(fd); } if (state=='j'){ printf("walking back\n"); walkback(fd); } if (state=='k'){ if (alternate){ printf("walking straight on a\n"); walkstraight_a(fd); }else{ printf("walking straight on b\n"); walkstraight_b(fd); } alternate=(alternate +1) %2; } } /* we get here if q was typed */ set_terminal(0); return (0); } ==== robi.c ===== /* vim: set sw=8 ts=8 si : */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License. * See http://www.gnu.org/copyleft/ for details. * * Written by Katja Socher <[email protected]> * and Guido Socher <[email protected]> * */ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <sys/types.h> #include <sys/time.h> #include <fcntl.h> #include <unistd.h> #include <signal.h> #include <linux/ppdev.h> #include <sys/ioctl.h> #include <termios.h> #include "robi.h" /* like printf but exit the program */ static int die(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); exit(1); } /* get one character from stdin * Returns non zero if char was read otherwise zero * The arrow keys are mapped as follows: * <- = h * -> = l * v = j * ^ = k */ int getchoice() { int c; char s[20]; if (fgets(s,20,stdin)){ c=s[0]; switch (c){ case 0x1b: /* ESC */ if (s[1] == 0x5b){ /* arrow keys are pressed */ switch (s[2]){ case 0x41: /*up arrow*/ c='k'; break; case 0x42: /*down arrow*/ c='j'; break; case 0x44: /*l arrow*/ c='h'; break; case 0x43: /*r arrow*/ c='l'; break; default: c=0; } }else{ c=0; } break; case ' ': case 'h': case 'j': case 'k': case 'l': case 'q': case 'x': break; default: c=0; } return(c); } return(0); } /* Set the Terminal to Non Canonical mode with echo off * or reset the terminal. * USAGE: set_terminal(1) for canonical */ int set_terminal(int canonical) { static struct termios originalsettings; struct termios newsettings; static int origok=0; /* set if originalsettings valid */ if (canonical){ /* save original settings and set canonical mode*/ tcgetattr(fileno(stdin),&originalsettings); newsettings=originalsettings; newsettings.c_lflag &= ~ICANON; newsettings.c_lflag &= ~ECHO; newsettings.c_cc[VMIN]=0; /* do not block */ newsettings.c_cc[VTIME]=1; /* 100 ms */ if (tcsetattr(fileno(stdin),TCSANOW,&newsettings) !=0){ die("ERROR: could not set terminal attributes on stdin\n"); } origok=1; }else{ if (origok){ /* restore settings */ tcsetattr(fileno(stdin),TCSANOW,&originalsettings); } } return(0); } /* open /dev/parportX device and claim it. * USAGE: fd=robi_claim("/dev/parport0"); * The return value is a file descriptor used by other * functions such as robi_setdata */ int robi_claim(char *dev) { int fd,i; fd = open(dev, O_RDWR ); if (fd < 0) { die("ERROR: cannot open device %s\n",dev); } i=0; /* we need exclusive rights as we do not set the control lines*/ /*ioctl(fd, PPEXCL, &i)&&die("ERROR: request for exclusive rights failed\n");*/ ioctl(fd, PPCLAIM, &i)&&die("ERROR: could not claim parport\n"); return(fd); } /* Walk left */ int walkleft(int fd) { /* first B legs to ground */ robi_setdata(fd,LEGBD); usleep(400 *1000); /* all A legs 1 step */ robi_setdata(fd, LEGB1 | LEGB3 ); usleep(1100 *1000); /* first A legs to ground, cool B*/ robi_setdata(fd,LEGAD); usleep(400 *1000); robi_setdata(fd,0); usleep(1000 *1000); return(0); } /* Walk right */ int walkright(int fd) { /* first A legs to ground */ robi_setdata(fd,LEGAD); usleep(500 *1000); robi_setdata(fd, LEGA3 | LEGAD); usleep(300 *1000); /* all A legs 1 step */ robi_setdata(fd, LEGA1 | LEGA3 ); usleep(1100 *1000); /* first B legs to ground, cool A*/ robi_setdata(fd,LEGBD); usleep(400 *1000); robi_setdata(fd,0); usleep(1000 *1000); return(0); } /* Walk with all 3 legs 1 step forward */ int walkstraight_a(int fd) { /* first A legs to ground */ robi_setdata(fd,LEGAD); usleep(800 *1000); /* all A legs 1 step */ robi_setdata(fd, LEGA1 | LEGA2 | LEGA3 ); usleep(1000 *1000); /* first B legs to ground, cool A*/ robi_setdata(fd,LEGBD); usleep(500 *1000); robi_setdata(fd,0); usleep(1200 *1000); return(0); } /* Walk with all 3 legs 1 step forward */ int walkstraight_b(int fd) { /* first B legs to ground */ robi_setdata(fd,LEGBD); usleep(400 *1000); /* all B legs 1 step */ robi_setdata(fd,LEGB1 | LEGB2 | LEGB3); usleep(1000 *1000); /* A down and cool */ robi_setdata(fd,LEGAD); usleep(800 *1000); robi_setdata(fd,0); usleep(1200 *1000); return(0); } /* Walk with all 6 legs 1 step back */ int walkback(int fd) { /* first A legs to ground */ robi_setdata(fd,LEGAD); usleep(800 *1000); /* all B legs 1 step in the air*/ robi_setdata(fd, LEGB1 | LEGB2 | LEGB3 ); usleep(500 *1000); /* first B legs to ground, cool A*/ robi_setdata(fd,LEGBD); usleep(500 *1000); /* all A legs 1 step in the air*/ robi_setdata(fd,LEGA1 | LEGA2 | LEGA3); usleep(500 *1000); /* A down and cool */ robi_setdata(fd,LEGAD); usleep(800 *1000); robi_setdata(fd,0); usleep(1000 *1000); return(0); } /*---------*/ /* Write a bit pattern to the data lines * USAGE: rc=robi_setdata(fd,bitpat); * The return value is 0 on success. */ int robi_setdata(int fd,unsigned char bitpat) { int rc; rc=ioctl(fd, PPWDATA, &bitpat); return(rc); } ==== robi.h ===== /* vim: set sw=8 ts=8 si et: */ #ifndef H_ROBI #define H_ROBI 1 #define VERINFO "version 0.2" /* the first thing you need to do: */ extern int robi_claim(char *dev); /* write a bit pattern to the data lines of the parallel port: */ extern int robi_setdata(int fd,unsigned char bitpat); /* input and terminal functions */ extern int set_terminal(int canonical); extern int getchoice(); extern int walkstraight_a(int fd); extern int walkstraight_b(int fd); extern int walkback(int fd); extern int walkleft(int fd); extern int walkright(int fd); /* data pins to legs: * A1------=------B1 * = * = * B2------=------A2 * = * = * A3------=------B3 * * * Pin to set A-legs to ground= AD * Pin to set B-legs to ground= BD * * parallel port leg name * ------------------------- * data 0 A1 * data 1 A2 * data 2 A3 * data 3 AD * data 4 B1 * data 5 B2 * data 6 B3 * data 7 BD */ #define LEGA1 1 #define LEGA2 2 #define LEGA3 4 #define LEGAD 8 #define LEGB1 16 #define LEGB2 32 #define LEGB3 64 #define LEGBD 128 #endif
Die Software benutzt die ppdev Programmierschnittstelle des 2.4.x Kernels (du brauchst einen 2.3.x oder 2.4.x Kernel. Es funktioniert nicht mit einem älteren Kernel). Dies ist eine saubere und angenehme Schnittstelle zum Schreiben von user space parallel port Gerätetreibern. In älteren Kerneln hätten wir ein Kernelmodul schreiben oder eine häßliche Methode benutzen müssen, die es nur dem Benutzer root erlaubt hätte, das Programm laufen zu lassen. Die ppdev Schnittstelle benutzt die Gerätedatei und durch Anpassen des Eigentümers und der Rechte der Datei kannst du festlegen, wem es erlaubt ist, diese Parallelportschnittstellle zu benutzen.
Um das ppdev als ein Modul in deinen Kernel zu kompilieren, mußt du das PARPORT Modul zusammen mit dem PPDEV device kompilieren. Dies sollte dann wie folgt in der .config Datei aussehen:
# # Parallel port support # CONFIG_PARPORT=m CONFIG_PARPORT_PC=m CONFIG_PARPORT_PC_FIFO=y # CONFIG_PARPORT_PC_SUPERIO is not set # CONFIG_PARPORT_AMIGA is not set # CONFIG_PARPORT_MFC3 is not set # CONFIG_PARPORT_ATARI is not set # CONFIG_PARPORT_SUNBPP is not set CONFIG_PARPORT_OTHER=y CONFIG_PARPORT_1284=y # # Character devices # CONFIG_PPDEV=m #
Das Programm beansprucht (initialisiert) zuerst den Parallelport mit dem
ioctl Befehl PPCLAIM. Dann setzt es das Terminal in non canonical mode.
Dies wird gemacht, um die Eingabe direkt von der Tastatur zu erhalten, ohne daß
der Benutzer nach jeder Eingabe Return drücken muß. Als nächstes geht es in eine
Schleife, wo zuerst überprüft wird, ob es irgendeine Benutzereingabe gab und dann
der Roboter entsprechend dem Befehl laufen gelassen wird. Wenn du nichts machst, macht
das Programm mit dem letzten Befehl weiter (z.B. fährt es fort, den Roboter
geradeaus laufen zu lassen).
Der Befehl ioctl(fd, PPWDATA, &bitpat); wird benutzt, um die
Datenverbindung auf ein gegebenes Bitmuster zu setzen.
Die Pins deines Roboters müssen mit den Ausgabeverbindungen der Treiberschaltung wie folgt verbunden sein:
Legs: A1------=------B1 = = B2------=------A2 = = A3------=------B3 Pin to set A-legs to ground= AD Pin to set B-legs to ground= BD Corresponding output lines of the driver circuit: data 0 A1 data 1 A2 data 2 A3 data 3 AD data 4 B1 data 5 B2 data 6 B3 data 7 BDData 0 ist die Ausgabe der Treiberschaltung, die mit dem Parallelport an Pin 2 (D0) verbunden wird.
Wir hoffen, daß du beim Bauen des Roboters viel Spaß hattest. Laß uns von deinem Roboter wissen, besonders dann, wenn deiner mit einem anderen Design gebaut wurde!
|
Der LinuxFocus Redaktion schreiben
© Katja und Guido Socher, FDL LinuxFocus.org Einen Fehler melden oder einen Kommentar an LinuxFocus schicken |
Autoren und Übersetzer:
|
2001-11-01, generated by lfparser version 2.21