[LinuxFocus-icon]
Início  |  Mapa  |  Índice  |  Procura

Novidades | Arquivos | Links | Sobre LF
Este artigo está disponível em: English  Castellano  Deutsch  Francais  Nederlands  Portugues  Russian  Turkce  Arabic  

convert to palmConvert to GutenPalm
or to PalmDoc

[Photo of the Authors]
por Katja and Guido Socher

Sobre o autor:

A Katja é a editora alemã da LinuxFocus. Ela gosta do Tux, filme & fotografia e do mar. A sua página pessoal pode ser encontrada aqui.

O Guido é um fã do Linux de há longa data e gosta do Linux porque é desenhado por pessoas honestas e abertas. Isto é uma das razões porque se chama código aberto. A sua página pessoal está em linuxfocus.org/~guido.


Conteúdo:

 

Construindo um Robot Andante controlado pelo Linux

[Illustration]

Abstrato:

Neste artigo construímos um pequeno robot de seis pernas, andante, o qual depois controlamos com um PC com Linux através da interface da porta paralela.
Outros dispositivos podem também ser controlados de modo semelhante com a porta paralela.



 

Introdução

Os Robots sempre nos fascinaram e ficámos ambos excitados quando encontrámos um livro acerca de robots, há algum tempo atrás, o qual incluía o kit para construir um robot um pequeno insecto como um robot chamado Stiquito. O Stiquito é um tanto ao quanto especial porque não tem motor mas ando porque as pernas são arames com nitinol e deste modo anda totalmente silenciosamente como um insecto real. Mas quando o tivemos de construir, notámos que por não haver fricção com o chão onde andava o seu movimento era muito lento. Felizmente que o livro também incluía algumas descrições para outros desenhos de robots que nos inspiraram a construir o robot que aqui pode ler.

 

Nitinol

O nosso robot não tem motor e anda devido às pernas que têm arames alimentadas por nitinol. O nitinol é um arame com memória feito de níquel e titânio que se contraí como os músculos quando electrizado. Ao conduzir corrente eléctrica, o arame aquece e contraí (voltando à sua forma original). É requerida uma força oposta (no nosso caso através de uma corda de música) para retornar ao seu tamanho original. Quando alonga o arame só 3 a 5 porcento o cabo é muito consistente e fiável e pode correr milhões de ciclos.


 

Construindo o robot

Para construir o robot necessitamos do seguinte material:



[Alicate de ponta curva]
Fig 2: Alicate de Ponta Curva
Você deve ser capaz de obter uma boa parte do material numa loja de electrónica onde se vendem peças para pequenos aviões, carros telecomandados, etc... Se não existe nenhuma na sua cidade pode ver na universidade com um departamento de arquitectura mais perto. Pois os estudantes, normalmente têm de construir modelos das casas e outras construções e é bastante fácil de encontrar estes materiais bem como os tubos de bronze.
Quando comprar o alicate de boca plana e semi-redonda, assegure-se que têm face plana, caso contrário não conseguem "ondular" o cabo de nitinol.


[parts]
Fig 3: As principais partes do robot.

Construindo o corpo

Para o corpo precisa, primeiro, das três placas de circuito impresso, uma de 6x6 buracos e duas com 6x7 buracos bem como 4cm de tubo de bronze com 2 mm de diâmetro juntamente com 3.7 cm de cabo de música.

[Peça de metal]
Fig 4: a coluna vertebral e o powerbus

Corte o tubo de bronze em pedaços de 8, 17.5 e 8mm como mostrado na figura. Consegue fazê-lo deslizando o tubo sobre a faca de cozinha afiada e curvando-o depois. O tubo quebrar-se-à onde fez o corte com a faca. É importante que o tubo no meio seja ligeiramente mais longo que a placa de 6x6 buracos. Corte cerca de 3.7cm de cabo de música. O tamanho final deve ser à volta de 3 mm mais comprido que os 3 tubos juntos. Coloque o cabo de música dentro dos três tubos.
O tubo no meio deve ser capaz de rodar enquanto que os outros dois são soldados ao fio de música.

[solder the 3 body parts]
Fig 5: soldar a placa à coluna vertebral

O tubo do meio é agora soldado à placa de circuito com 6x6 buracos. Acautele-se para que possa rodar. Os outros dois tubos são soldados às outras duas placas de circuitos impressos.
Agora pegue na pequena placa de 2x7 buracos. Deve ficar em pé e a meio do tubo de bronze. A placa de circuito deve ser cortada com um pequeno fio ou com o cortador. Solde-a a meio do tubo de bronze e a meio da placa de circuito, como mostrado na figura:
[the flag]
Fig 6: adicionando a pequena placa de circuito

Lixe 1mm do tubo de bronze e corte-o em várias peças de 4mm de largura. Rode o tubo ao longo da faca de cozinha e vá dobrando-o. Precisa de 16 "curvas" mas faça mais algumas.

Como é necessário muito arredondamento você, antes de avançar, deve testar com um pouco de nitinol: Ponha o fim do cabo de nitinol dentro dos tubos de bronze finos (1mm de diâmetro externo) e depois aperto o tubo de bronze com o alicate de ponta curva. A isto chama-se frisar. Tome cuidado para comprar um bom alicate pois a força para apertar o tubo de bronze é muita força. Pode lixar as pontas do cabo de nitinol para obter uma boa conexão eléctrica.

Agora instalamos o cabo de nitinol que é preciso para mover as pernas para cima e para baixo.

[the bridge]
Fig 7: "a ponte"

Coloque o cabo de nitinol como se quisesse construir uma ponte. Comece por um lado. Aí porá o cabo de nitinol no último buraco que é possível à esquerda e no lado direito. Você faz um nó no cabo de nitinol (no sentido de assegurar uma melhor connecção) e põe um friso sobre o mesmo (usando o tubo de bronze de 4mm) e torça-o de maneira a que o cabo de nitinol fique apertado e para que possa atravessar o segundo buraco a contar do buraco do lado esquerdo, em cima apontado e depois atravessar o último buraco à esquerda e do lado direito. No topo é feito um nó e posto um friso e apertado bem (ver Fig. 7). O cabo de nitinol não deve estar muito apertado. Se o pressionar com o dedo devia mexer-se cerca de 2 a 4mm. Se não está muito apertado, ou muito solto o robot, mais tarde não se vai mover da forma mais correcta. Solde os frisos à placa.
Faça o mesmo do outro lado.
Antes de continuar experimente-o para ver se funciona. Utilize uma pilha de 1.5V AA e ligue-a a um dos cabos de nitinol. Quando o cabo se contraí a parte do meio do corpo deve rodar cerca de 10 a 20 graus. Tome precaução para não ligar a pilha mais do que 1 segundo. Pode danificar o cabo por sobre-aquecimento.

As pernas


[cabo de música para as pernas]
Fig 8: A forma do cabo

Para as pernas corte três longas partes de cabo de música com 10 cm. Em cada uma das partes dobre o cabo 1.5cm em cada lado. Depois solde cada uma das patas à parte inferior do robot. Procure que as mesmas fiquem paralelas.

[pernas vistas de cima]

[pernas vistas de baixo]
Fig 9, 10: pernas no robot

Agora deve pôr o nitinol nas 6 pernas.

[pernas e o nitinol]
Fig 11: adicionando os dispositivos eléctricos

Ponha o cabo de nitinol na parte de trás através de um dos tubos e num buraco da placa de circuito impresso. A distância para o cabo de música é de 3 buracos. Mantenha-o esticado (veja a figura em cima)
Prenda o cabo de nitinol numa ponta do cabo de música. Mantendo-o esticado. Agora vem a parte mais difícil. Segure o robot com uma prensa, fixe-o e curve as pernas. O cabo de música tem um comportamento oposto ao cabo de nitinol. Para isto trabalhar o cabo de nitinol não pode ter nenhuma folga. O cabo de música deve ser posto num dos buracos da placa de circuito em direcção ao nitinol e depois a parte "frisada" deve ser soldada à perna.
[o nitinol não deve estar solto]
Fig 12: o nitinol e o cabo de música no mesmo nível


Certifique-se que o cabo de música e o nitinol estão ao mesmo nível. As pernas não se devem mexer para cima ou para baixo quando o nitinol se contraí. As pernas devem mover-se na direcção de atrás.

Faça o mesmo com as outras cinco pernas.
As pernas e o cabo de música juntamente com o tubo de bronze no meio do robot actuam como um power bus e portanto deve estar conectados electricamente entre si. Mas, contudo a parte do meio tem mais liberdade porque pode rodar e assim não possui uma boa conexão, improvisámos utilizando 3 cm de cabo de cobre envernizado com 0.1mm de diâmetro e envolvemos o tubo de bronze para obter um bobine. Retire o tubo de bronze e depois solde esta bobine no meio das pernas do meio e a um dos pares de pernas exteriores. A forma de bobine do cabo garante maior flexibilidade.

Quando o robot estiver pronto pode soldar diversos cabos de cobre envernizado com 0.1 mm de diâmetro e 0.5 m de comprimento (ou mais comprido se o desejar) aos frisos da placa e solde os frisos do corpo à placa de circuito. Precisamos de 9 cabos, 6 para as pernas, 2 para cima/baixo e um para o powerbus comum. Pode soldar as outras partes finais dos cabos a um conector pequeno o qual pode depois encaixar num pequeno encaixe do circuito de condução.

 

O modo de andar

O nosso insecto é desenhado para andar num modo trípode. Este modo significa que 3 pernas tocam no chão (duas de um lado e uma do outro) enquanto que as outras 3 estão levantadas no ar. Quando o robot anda as 3 pernas que tocam no chão movem-se numa direcção enquanto que as pernas que estão no ar movem-se no sentido oposto.
[O modo de andar]
Fig 13: O modo de andar



 

Controlando o robot com um computador Linux

 

O circuito de condução

Este placa de circuito permite-nos utilizar o PC para controlar os dispositivos eléctricos no robot e ligá-los à porta paralela.
Quando desenvolvemos o nosso programa de computador, testámos em primeiro com os LEDs e só ligámos à placa de controlo do robot quando os LEDs mostraram um modo de andar correcto. Você devia fazer o mesmo para experimentar o programa.
O robot é um tanto ao quanto faminto. Precisa de aplicar uma corrente de 200 a 250 mA sobre o nitinol para que se contraia. Os cabos de nitinol de 3cm de comprimento têm cerca de 7 Ohms. Inicie sempre o software antes de ligar a energia ao circuito de condução porque todos os pinos de dados são desligados pelo software para prevenir o estrago dos cabos de nitinol. Como a bios do computador randomiza os valores dos pinos de dados, alguns podem estar activos e danificar o nitinol se a corrente passar por mais do que 1 segundo. O tempo para o nitinol arrefecer deve ser de 1.5 vezes o tempo que se aqueceu.

O diagrama de circuito:
[circuito]
Fig 14: o diagrama de circuito

Como pode ver pelo diagrama acima utilizámos uma fonte de energia eléctrica estável. Para assegurar uma alimentação boa e estável e para proteger a porta paralela. Como fonte de alimentação externa pode conectar qualquer fonte de alimentação DC entre 6 e 24 V. O 7805 é um regulador de voltagem standard. A única coisa a prestar atenção é onde são colocados os condensadores (470uF e 0.1uF), pois se estiverem muito perto do regulador de voltagem 7805, este chip pode começar a oscilar o que pode ser a sua destruição.

Este desenho repete-se 8 vezes. Um para cada perna e 2 para os movimentos de cima e baixo do robot. Utilizámos um pequeno transístor NPN Darlington porque o nosso robot precisa de imensa corrente. O BC875 ou BC618 pode comutar cerca de 500mA. A resistência de 47K conectada à entrada garante um circuito aberto (e.g. o computador não está ligado) é sempre equivalente a "off". O nível de voltagem na porta paralela é de cerca de 4V para o "on" e abaixo de 1V para o estado "off". O transístor trabalha somente como um comutador. As resistências de 15 Ohm limitam a corrente e protegem quer as pernas quer o robot e o transístor. Os LEDs mostram o estado (on ou off).

Em baixo tendes figuras do circuito. Os LEDs vermelhos (os que estão em paralelo com os dispositivos eléctricos do robot) são difíceis de ver pelo que usámos LEDs vermelhos transparentes. Construímos as resistências de 15 Ohm com cabo de constantan, pois tínhamos imenso cabo deste. É mais barato comprar resistências de 2W feitas.


[O circuito de condução final 1] [O circuito de condução final 2]
Fig 15: O circuito



 

A porta paralela

A porta paralela foi desenhada para servir de porte de saída de um computador pessoal e para ligar a uma impressora. Algumas portas paralelas são quer saída quer entrada. Aqui utilizámos só a porta para output. Num artigo posterior conectaremos sensores ao robot e então utilizaremos as linhas de entrada. Apesar de existirem 25 pinos para a porta paralela, só utilizaremos nove. Oito das linhas são usadas como saída de dados e só uma linha é que serve de terra.
O layout dos pinos para a porta paralela é como se segue:

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 Ground
Você conecta o circuito de condução ao pino 18 (GND) e aos pinos de dados (2-9).

O modo normal da porta paralela trabalhar é enviando um byte para a linha de dados e o computador depois activa o STROBE da linha a 1 para indicar à impressora que as linhas de dados estão prontas agora. Utilizámos directamente as linhas de dados directamente porque não precisamos de utilizar uma lógica suplementar para a linha de strobe.

 

O software

Pode fazer download do software > aqui <.
Descomprima-o com o comando tar zxvf pprobi*.tar.gz. As instruções de instalação estão incluídas.

O programa é escrito em C. Com as teclas de direcção e a tecla de espaço pode controlar o robot, fazendo andar a direito, direita, esquerda e de marcha atrás. Utilize a tecla de espaço para parar o robot e q (ou x) para sair do programa. Em vez das teclas das setas pode usar também as teclas h,j,k,l (mapa de teclas do vi) se quiser. Os valores de movimento das pernas está optimizado para o nosso robot. Cada robot é um pouco diferente, principalmente porque é difícil de obter a mesma tensão em todos os cabos de nitinol. O Seu robot trabalhará com o software mas nem todas as pernas se moveram na mesma proporção, você tem de experimentar até conseguir valores que se adeqúem ao seu robot da melhor forma. Tenha atenção para que nenhuma das pernas tenha sobre-aquecimento ou não tenha um tempo de refrescamento muito elevado.

==== 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 <katja@linuxfocus.org>
 *         and Guido Socher <guido@linuxfocus.org>
 *
 */
#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 <katja@linuxfocus.org>
 *        and Guido Socher <guido@linuxfocus.org>
 *
 */
#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


O software usa interface de programação ppdev, a partir do Kernel 2.4.x (Necessita do Kernel 2.3.x ou 2.4.x Kernel. O Programa não trabalhará com Kernels mais velhos). Isto é uma interface limpa e conveniente para programar drivers de utilizador para a porta paralela. Nos kernels mais velhos seria necessário escrever um módulo do Kernel ou utilizar um método triste que só permitia ao root executar o programa. A interface ppdev utiliza o ficheiro de dispositivo /dev/parport0 e ajustando o dono e as permissões do ficheiro pode controlar quem pode utilizar esta interface da porta paralela.

Para compilar o módulo ppdev no kernel precisa de compilar o módulo PARPORT juntamente com o dispositivo PPDEV. O que deve dar o seguinte ficheiro de .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
#


O programa, primeiro, inicializa a porta paralela com o comando ioctl PPCLAIM, Depois activa o terminal no modo canónico. Isto é para obter a entrada directamente do teclado sem que o utilizador esteja sempre a premir return após cada entrada. De seguida entra num ciclo à espera por uma entrada do utilizador deixando o robot andar consoante o comando. Se não fizer nada o programa continua com o último comando (e.g. continua a andar a direito).
O comando ioctl(fd, PPWDATA, &bitpat); é usado para configurar as linhas de dados com um determinado padrão de bit dado.

Os pinos do seu robot precisam de estar conectados às linhas de saída do circuito de condução como se segue:

Pernas:
  A1------=------B1
          =
          =
  B2------=------A2
          =
          =
  A3------=------B3


  Pin to set A-legs to ground= AD
  Pin to set B-legs to ground= BD

Correspondências às linhas de output e ao circuito de condução:
  data 0           A1
  data 1           A2
  data 2           A3
  data 3           AD
  data 4           B1
  data 5           B2
  data 6           B3
  data 7           BD

O Data 0 é a saída do circuito de condução que conecta à porta paralela no pino 2 (D0).

Eis aqui, o robot andante:
[sim, ele anda]
Move-se um pouco rápido neste gif animado. Na realidade é um pouco mais lento devido aos tempos de arrefecimento necessários para o nitinol voltar ao seu tamanho original.


Esperamos que se divirta a construir o robot. Fale-nos acerca do seu robot, especialmente se o seu for construído com um desenho diferente!

 

Referências

 

Forma de respostas para este artigo

Todo artigo tem sua própria página de respostas. Nesta página você pode enviar um comentário ou ver os comentários de outros leitores:
 página de respostas 

Páginas Web mantidas pelo time de Editores LinuxFocus
© Katja and Guido Socher, FDL
LinuxFocus.org

Clique aqui para reportar uma falha ou para enviar um comentário para LinuxFocus
Informação sobre tradução:
en -> -- Katja and Guido Socher
en -> pt Bruno Sousa

2001-08-22, generated by lfparser version 2.17