original in en Katja et Guido Socher
en to fr John Perr
Katja est l'�ditrice Allemande de LinuxFocus. Elle aime Tux, les films et la photographie et la mer. Sa page personnelle est ici.
Guido est fan de Linux de longue date et il l'aime parce qu'il est con�u par des gens honn�tes et ouverts. C'est aussi une des raisons pour laquelle nous l'appelons "open source". Sa page personnelle est linuxfocus.org/~guido.
Les robots nous ont toujours fascin�s et nous avons �t� tr�s excit�s lorsque nous avons trouv�, il y a quelques temps; un livre sur les robots qui incluait un kit pour construire un petit robot insecto�de appel� Stiquito. Stiquito est un robot un peu sp�cial car il n'a pas de moteur mais marche gr�ce � ses pattes faites de nitinol. De cette fa�on, il progresse en silence comme un v�ritable insecte. Lors de sa construction, nous avons cependant not� qu'� cause du manque d'adh�rence de la surface sur laquelle il marchait, son d�placement �tait tr�s lent. Heureusement, le livre contenait des descriptions d'autres sortes de robots qui nous ont inspir�s pour aboutir � celui qui nous concerne ici.
Pour construire le robot nous avons utilis� les pi�ces suivantes:
![]() |
Fig 1: Circuit imprim� |
![]() |
Fig 2: pince � becs fins |
Vous devriez trouver la plupart des composants dans des magasins de
mod�lisme ou l'on se procure habituellement des pi�ces pour des petits
avions, des voitures radio-command�es etc... Si vous n'en trouvez pas
dans votre ville, recherchez l'�cole d'architecture la plus proche.
Comme les �tudiants doivent g�n�ralement construire des maquettes de maisons
et autres b�timents, vous trouverez s�rement un commerce o� il est possible
d'acheter des choses comme le tube de laiton tr�s fin.
Lors de l'achat des pinces � becs fins, assurez vous qu'elles ont une face
plate, sinon vous n'arriverez pas � plier le fil de nitinol.
![]() |
Traduction des termes du dessin: Holes = Trous Music Wire = Corde � Piano (Steel Wire) = (Fil d'acier) |
Fig 3: Les principaux composants du robot. |
Pour le corps vous avez d'abord besoin de trois morceaux de circuit
imprim�, un de 6x6 trous et deux de 6x7 trous ainsi que de 4 cm de tube de
laiton de 2 mm de diam�tre et 3,7 cm de corde � piano.
Fig 4: Colonne vert�brale et arbre de transmission (Ndt:Solder=Soudure)
Coupez le tube de laiton en morceaux de 8, 17,5 et 8mm comme montr� sur le dessin.
Cela peut �tre fait en le roulant d'avant en arri�re sous un couteau de cuisine bien
aiguis� puis en le tordant. Le tube se cassera � l'endroit du r�tr�cissement fait
par le couteau. Il est important que le tube central soit l�g�rement plus long que
le circuit imprim� de 6x6 trous. Coupez environ 3,7 cm de corde � piano afin qu'elle
soit plus longue d'environ 3 mm que l'ensemble des 3 tubes. Passer la corde �
piano dans les trois tubes.
Le tube central doit pouvoir tourner alors que les deux autres sont soud�s
sur la corde � piano.
![]() |
Traduction des termes du dessin: Middle part moves = La partie centrale est mobile Holes = Trous Solder = Soudure |
Fig 5: Souder les plaques � l'axe principal |
Ebarbez le tube de laiton de 1 mm et coupez plusieurs morceaux de
4 mm de long. Roulez le tube sur le couteau de cuisine puis courbez-le.
Vous avez besoin de 16 de ces cavaliers mais pr�parez-en quelques uns
de rechange.
Comme de nombreux sertissages sont n�cessaires, faites des essais avec
un peu de nitinol avant de commencer: placer le bout du fil de nitinol
dans le tube de laiton tr�s fin (1 mm de diam�tre externe) puis �crasez-le
avec la pince � becs fins. Cette op�ration s'appelle un sertissage. Vous
aurez besoin d'une pince de bonne qualit� car le sertissage des tubes de
laiton n�cessite une force importante. Vous pouvez aussi d�caper les bouts
du fil de nitinol avec du papier de verre grain 600 pour garantir de bonnes
connexions �lectriques.
Passons maintenant au fil de nitinol qui servira � monter et descendre les
pattes.
![]() |
Traduction des termes du dessin: Crimp = Sertissage Press with Finger = Appuyer avec le doigt -> Moves 2 mm = -> Bouge de 2 mm |
Fig 7: "Le pont" |
Fig 8: Pliez le fil
Coupez trois morceaux de corde � piano de 10 cm de long pour les pattes.
Pliez 1,5 cm de chaque cot� puis soudez-les aux trois corps du robot afin
qu'elles soient parall�les entre elles.
![]() |
TOP VIEW = VUE DE DESSUS |
![]() |
BOTTOM VIEW = VUE DE DESSOUS SOLDER = SOUDURE |
![]() |
STEEL WIRE = CORDE A PIANO 1 HOLE = 1 TROU |
Quand le robot est pr�t, vous pouvez souder des morceaux de 0,5 m (ou plus si vous voulez) de fil de cuivre vernis fin de 0.1 mm aux sertisseurs sur la carte, puis souder les sertisseurs du corps au circuit imprim�. Il faudra 9 fils, 6 pour les pattes, 2 pour le mouvement haut/bas et un pour le bus de puissance. Vous pouvez souder l'autre extr�mit� des fils � un petit connecteur que vous pourrez ensuite raccorder dans une prise correspondante sur le circuit pilote.
Notre insecte est con�u pour marcher � une allure de tripode. Cela signifie
que trois pattes sont sur le sol (2 d'un cot�, une de l'autre) pendant que
les trois autres sont en l'air. Quand le robot marche, les trois pattes
sur le sol se d�placent dans une direction pendant que celles en l'air vont
dans l'autre sens.
Fig 13: L'allure
Ce circuit imprim� vous permet d'utiliser votre PC pour contr�ler
les moteurs du robot et se branche sur le port parall�le.
Quand nous avons essay� notre programme, nous l'avons d'abord fait avec
des diodes �lectro-luminescentes (LED), et nous avons seulement
connect� le robot quand tout marchait correctement, c'est � dire que les
LED montraient une allure de marche correcte. Vous devriez faire de m�me
lors de vos essais avec le programme.
Le robot est plut�t gourmand et vous aurez besoin d'un courant de 200 � 250 mA
� travers le nitinol pour le contracter. Les fils de nitinol de 3 cm font
� peu pr�s 7 Ohms. D�marrez toujours le logiciel d'abord car celui-ci met
toutes les sorties � z�ro d�s le d�but pour �viter d'ab�mer le fil de nitinol.
Le bios affecte l'�tat des sorties du port parall�le al�atoirement. De ce fait,
certaines sorties pourraient �tre � l'�tat actif et le nitinol pourrait �tre
endommag� si le courant y circule plus longtemps qu'une seconde. Le temps
n�cessaire au nitinol pour se refroidir doit �tre 1,5 fois le temps de
chauffage.
Le sch�ma:
![]() |
Traduction des termes du sch�ma: Power Supply = Alimentation 7805 Voltage Regulator = R�gulateur 7805 The driver circuit for One leg.= L'interface pour 1 patte You need this 8 times: = A faire en 8 exemplaires Nitinol Wire = Fil de Nitinol Data in = entr�e To computer = Cot� ordinateur |
Fig 14: Sch�ma de principe |
Le port parall�le � �t� con�u pour servir de port de sortie sur
un ordinateur personnel auquel on connecte une imprimante. Certains
ports parall�les permettent � la fois des entr�es et des sorties. Ici nous
n'utilisons le port que pour les sorties. Dans un futur article, nous
brancherons des capteurs sur le robot et nous utiliserons alors les
capacit�s d'entr�es du port parall�le. Bien qu'il y ait 25 broches sur ce port,
nous n'en utilisons que 9. Huit sont utilis�es comme sorties de donn�es
et une autre sert de masse.
Le brochage du port parall�le est le suivant:
SUB-D 25 broches FEMELLE sur le PC. Broche Nom 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 GroundLe circuit se connecte � la broche 18 (Masse) et aux broches de donn�es, broches (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
Le logiciel utilise la biblioth�que ppdev issue du noyau 2.4.x (Vous devez avoir un noyau 2.3.x ou 2.4.x. Cela ne marchera pas avec une version plus ancienne). C'est une biblioth�que pour �crire des pilotes utilisateurs pour le port parall�le. Dans les noyaux plus anciens, nous aurions d� �crire un module pour le noyau ou utiliser une m�thode moins �l�gante qui aurait seulement permis au super utilisateur d'ex�cuter le programme. L'API ppdev utilise le fichier /dev/parport0. En changeant les permissions de ce fichier, vous pouvez contr�ler qui est autoris� � utiliser le port parall�le.
Pour compiler ppdev comme un module du noyau, vous devez compiler le module PARPORT en m�me temps que PPDEV. Voici ce que cela donne dans le fichier .config:
# # 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 #
Le programme initialise d'abord le port parall�le avec la commande
ioctl PPCLAIM. Puis il passe le terminal en mode non canonique. Cela permet
de r�cup�rer directement les entr�es du clavier sans que l'utilisateur ait �
taper la touche retour apr�s chaque entr�e. Ensuite, il entre dans une boucle
o� il regarde d'abord s'il y a eu des commandes utilisateur, puis fait
marcher le robot en accord avec la commande. Sans action de votre part,
le programme fera marcher le robot selon le dernier ordre re�u (par exemple
continuer � marcher en avant).
La commande ioctl(fd, PPWDATA, &bitpat); est utilis�e pour
changer l'�tat des lignes de donn�es.
Les broches de votre robot doivent �tre connect�es aux sorties du circuit d'interface de la mani�re suivante:
Pattes: A1------=------B1 = = B2------=------A2 = = A3------=------B3 Broches des pattes A � la masse=AD Broches des pattes B � la masse=BD Lignes de sorties correspondantes du circuit: data 0 A1 data 1 A2 data 2 A3 data 3 AD data 4 B1 data 5 B2 data 6 B3 data 7 BDLa ligne Data 0 est la sortie du circuit qui se raccorde � la broche 2 du port parall�le (D0).
Nous esp�rons que vous vous �tes bien amus�s en construisant ce robot. Tenez-nous au courant de la construction de votre robot, surtout s'il est construit diff�remment!