Linux Denetimli Yürüyen Robot Yapımı

ArticleCategory: [Es gibt verschiedene Artikel Kategorien]

Hardware

AuthorImage:[Ein Bild von Dir]

[Photo of the Authors]

TranslationInfo:[Autor und Übersetzer]

original in en Katja and Guido Socher 

en to tr Mert Deva , Tuncer Birtan, Doğucan Kanal 

AboutTheAuthor:[Eine kleine Biographie über den Autor]

Katja LinuxFocus'un Alman editörüdür. Tux, film, fotografçılığı ve denizi sever. Ana sayfasına buradan ulaşabiliriz.

Guido uzun zamandan beri bir Linux hayranı ve o Linux'u dürüst ve açık insanlar tarafından tasarlandığı için seviyor. İşte bu ona açık kodlu dememizin bir nedeni... Guido'nun sanaldoku sayfası: linuxfocus.org/~guido

Abstract:[Hier sollte eine kleine Zusammenfassung stehen]

Bu makalede bir linux pc nin paralel port arabirimini kullanarak altı bacaklı bir robotu yapacağız ve yönetimini sağlayacağız.

ArticleIllustration:[Das Titelbild des Artikels]

[Illustration]

ArticleBody:[Der eigentliche Artikel. Überschriften innerhalb des Artikels sollten h2 oder h3 sein.]

Giriş

Robotlar herzaman bizi heyecanlandırmıştır.Bu makalede Stiquito adlı ufak böceğe benzeyen bir robot yapacağız.Stiquito biraz özel bir robottur,çünkü onun herhangi bir motoru olmamasına rağmen ninitol telli ayakları sayesinde yürüyebilir ve bunu bir böcek gibi sessiz bir şekilde yapabilir. Ama bu robotu yaptığımızda gördük ki,yeterli sürtünme olmayışı nedeniyle çok yavaş yürüyebiliyordu.Şans eseri, elimizdeki robot kitabı diğer robot tasarımlarının açıklamalarını da içeriyordu ve burada anlattığımız robot yapımı hakkında bize ilham verdi.

Nitinol


Robotumuz motorsuz olmasına rağmen nitinolle güçlendirilmiş tellerle oluşmasından dolayı yürüyebilmektedir.Nitino Şekil-hafızalı alaşıma sahip devinimli bir tele sahiptir.Bu tel nikel ve titanyum alaşımlıdır ve ısıtıldığında kaslar gibi kasılır.Elektrik akımı yollandığında tel ısınır ve kısalır(yani uzamamış şekline geri döner).Bir karşı güç te (müzikteli gibi) nitinolü eski haline getirmek için kullanılır.Eğer nitinolü %3 ile %5 arasında gerersek kas teli çok tutarlı ve güvenilir bir hal alacaktır ve milyonlarca sinyali çalıştırabilecektir.

Robotun Yapımı

Robotu yapmak için gerekli olan parçalar:



[pliers]
Şekil 2: Kargaburun tarzı bir alet
Bir çok parçayı mağazalarda bulabilirsiniz. Eğer bulamazsanız en yakın mimarlık fakültesine başvurunuz. Çünkü mimarlık fakültesi öğrencileri bu aletleri bulundururlar. Bu tel pensesinin düzgün yüzlü olmasına dikkat ediniz, aksi takdirde nitinol teli bükemezsiniz.


[parts]
Şekil 3: Robotun Ana Parçaları

Gövdenin Yapımı

Gövde için devre kartının 3 parçasına sahip olmalıyız.:Bir tane 6*6 delikli ve 2 tane 6*7 delikli yani 2mm çaplı 4 cm boyundaki pirinç tüple birleştirilmiş 3.7 cm müzik teli

[hinge]
Şekil 4: Omurga ve Güç Kaynağı Yolu

Pirinç tüpü 8,17.5 and 8 mm halinde şekil 4 deki gibi kesiniz. Tüpün üzerine ufak çentikler atarak makas yardımıyla kırılmasını sağlayabiliriz.Ortadaki tüpün 6*6 deliklik kontrol kartından biraz daha uzun olması önemlidir.Müzik teli 3.7 cm uzunluğunda kesin.Ortadaki tüp sağ ve soldaki tüpler mizk teline lehimlendiğinde rahatça dönebilmelidir.
[solder the 3 body parts]
Şekil 5: Kartları omurgaya lehimleyin

Ortadaki tüp de şimdi 6*6 delikli denetim kartına lehimlenmiş olmalı, yalnız rotasyon hareketi yapabilmesi sağlanmalıdır.Diğer iki tüp de diğer iki kontrol kartına lehimlenmiş olmalıdır.
Şimdi 2*7 delikli bir denetim kartını ele alalım. Bu tüp ortadaki pirinç tüpün kenarında dik bir şekilde durmalıdır.Denetim kartı kesici bir aletle çentiklenmiş olmalıdır ve bunun ortadaki pirinç tüpe lehimlenmiş olması gerekmektedir.Bkz Şekil 6:
[the flag]
Şekil 6: Ufak Devre Kartını Eklemek

Pirinç tüpü 1 mm kalınlığında zımparalayın ve 4 mm uzunluğunda tüp parçaları kesin.Tüpü mutfak bıçağı yardımıyla bükün.Bunun için 16 tane tutturucuya(crimp) gereksinim var.
Bu birden çok tutturma işlemine başlamadan evvel bir parça nitinolle test etmek gerekir.Nitinol telin bir ucunu çok ince pirinç tüpün(1mm dış çaplı) içine koyun ve sonra pirinç tüpü kargaburun tarzı aletle ezeriz.İşte bu olaya tutturma denir.Yalnız burada dikkat etmeniz gereken nokta kargaburunun kalitelisini almaktır çünkü pirinç tüpleri sıkıştırmak için gerekli kuvvet çok büyüktür.Ayrıca iyibir elektrik bağlantısı sağlamak için nitinol telin üzerini 600 gridlik zımparayla zımparalamak gerekir.

Şimdi ayakları hareket ettirmek için nitinol teli bağlayacağız.

[the bridge]
Şekil 7: "köprü"

Eğer bir köprü yapmak istiyorsanız nitinol teli boydan boya uzatmalıyız. Bir taraftan başlayalım.NItinol teli en son delikten geçiririz ve bir düğüm atarız(iyi bir bağlantı sağlayabilmek için).Bu düğümün üzerine bir tutturucu koyalım ve bu tutturucuyla öyle sıkı bağlayalım ki nitinol tel ikinci bir deliği tutabilsin.En aşağıda da nitinol tele bir düğüm atalım ve üzerine bir tuttucu daha ekleyelim ve bu tutturucuyu da sıkıca bağlayalım.Bkz Şekil 7
Devam etmeden önce nasıl çalıştığını bir deneyelim. Bunun için; 1.5 V AA mignom bataryası kullanın ve bunu nitinol tellerin birisine bağlayın. Tel bağlantı kurduğunda gövdenin orta kısmı 10 ile 20 derecede dönebilmelidir.Yalnız bataryayı 1 sn. den fazla tutmamaya çalışın yoksa ntinol teli yakabilirsiniz.

Bacaklar


[music wire for legs]
Şekil 8: teli bükün

10 cm uzunluğunda müzik teli keseriz.Bu tellerin başında ve sonunda 1.5 cm lik kıvrımlar oluştururuz ve bu 3 teli birbirlerine paralel olarak robotun gövdesine lehimleriz. Bkz. Şekil 8

[legs top view]

[legs bottom viewl]
Şekil 9, 10: robot üzerindeki bacaklar

Şimdi nitinol telini 6 ayağa bağlayacağız

[leg and nitinol]
Şekil 11: Devindiricilerin eklenmesi

Nitinol telini tutturucunun içinden geçirip denetim kartındaki deliğe sokarız bu arada nitinol telinin müzik teline uzaklığı 3 delik kadar olmalıdır.Daha sonra tutturucuyu müzik teliinin üzerinden diz kıvrımı oluşana kadar çekeriz.Bkz.Şekil 11. Nitinol telini bunun içinden geçiririz. Şimdi işin en zor kısmına geldik.Robotu sıkıca tutun ve sabitleyin daha sonra ayaklarını bakır telle bağlayın.Müzik teli nitinole karşı bir kuvvet oluşturacaktır. Bunun işlemesi için nitinolün gevşek olmaması lazım.Müzik teli bir kontrol kartı deliği boyunca nitinole doğru çekilmeli ve sonra tutturucu bacağa lehimlenmelidir.
[nitinol must not be loose]
Şekil12: Nitinol Tel ile Müzik Teli Aynı Seviyede


Müzik telinin ve nitnolün aynı seviyede olduğuna dikkat edin.Ayaklar nitinol kasılırken yukarı ve aşağı hareket etmemelidirler.Bir bacak sadece arkaya doğru hareket etmelidir.

Bu işlemi diğer beş bacak için de uygulayın.Bacaklar ve robotun ortasında bulunan pirinç tüplü müzik teli hızlı bir yolu oluşturular.Bu yüzden müzik teli, bacaklar ve pirinç tüp arasında iyi bir bağlantı oluşacaktır.Orta gövde kısmı diğer parçalardan bağımsız olmasına rağmen(çünkü dönebiliyor) orada güzel bir bağlantı oluşmaz.Bu bağlantıyı geliştirebilmek için 0.1 mm lik verniklenmiş bakır telden 3 cm alırız ve onu yedek bakır tübün çevresine bobin elde edebilmek için sararız. Bakır teli dışarı çıkarır daha sonra da ortadaki bobini içteki ayak çiftine lehimleriz.Böylece bobinin şekli maksimum esneklilipe sahip olur. Robot hazır olduğu zaman 0.5 m uzunluğunda verniklenmiş bakır teli kontrol kartı üzerindeki tutturuculara lehimleriz.Daha sonra gövdeyle tutturucuları kontrolkartına lehimleriz. 9 tane tele gereksinimimiz vardır: Bunların 6 tanesi bacaklar için 2 tanesi yukarı aşağı görev yapmak için 1 tanesi de güç kaynağı bağlantısı için. Ayrıca parçaların son kısımlarına ufak konnektörleri de lehimleyebiliriz ki böylece konnektörleri sürücü devresi üzerindeki soketlere bağlayabiliriz

Yürüyüş

Robotumuz 3 bacaklı yürümeye uygun şekilde tasarlanmıştır. 3 bacaklı yürüyüş demek 3 bacağın yerde olması(2 tanesi bir tarafta 1 tanesi diğer tarafta) ve 3 bacağın da havada olması demektir. Robot yürürken yerdeki 3 bacakla havadaki 3 bacak ters yünde hareket ederler
[The gait]
Şekil 14: Yürüyüş



Robotun Linux ile denetimi

Sürücü Devresi

Bu devre kartı bize robotun devinimdiricilerini pc yardımıyla kullanmamıza izin verir.Bilgisayar programımızı geliştirdiğimizde testi ledlerle yaparız ve sadece robotun kontrol tellerini kart üzerindeki sokete sokar ve ledlerin doğru çalışıp çalışmadığına bakarız.Bu programı bu deneyi yaparken kullanabilirsiniz. Robotumuz oldukça açtır. Nitinolün kasılabilmesi için 200 - 25- mA akım geçirilmesi gerekmektedir.3 cm uzunluğundaki bacaktaki nitinol teller 7 Ohm kadar direnç oluştururlar. Herzaman yazılımı ilk olarak çalıştırın.(Sürücü devresine güç vermeden önce).Çünkü bütün veri pinleri yazılım tarafından nitnol tele zarar vermemek amacıyla kapatılmıştır.Bilgisayarı BIOS'u paralel port veri pinlerine rasgele değişik değerler verir. Bu değerlerden bazıları açık durumda olabilir.Yani tele 1 sn den fazla uygulandığında telin zarar görmesine neden olabilir.Nitinolün soğuması için gerekli olan süre ısınması için gerekli olan sürenin 1.5 katıdır. Bkz. Devre Diagramı (Hemen aşağıda)

Devre Diagramı :
[circuit]
Şekil 14: Devre Diagramı

Şekil 14'deki devre diyagramından da görüldüğü gibi elektronik olarak sabitlenmiş bir güç desteği kullanacağız.Bu da bize kalıcı bir güç sağlayacak böylece paralel portu korumuş olacağız.Dış elektrik beslemesi yapmak istersek herhangi bir 6-24 V arası DC güç kaynağı kullanabiliriz.7805 standart voltaj regülatörüdür.Burada dikkat etmemiz gereken tek şey iki tane kapasitörün 7805 voltaj regülatörüne çok yakın konulmuş olmalıdır.Aksi takdirde 7805 çipimiz zarar görecektir.Güncel sürücü 8 kere yapılmalıdır.BIr tanesi bacak için iki tanesi robotun sağa sola devinimi için kullanılmalıdır.Biz küç bir NPN Darlington tranzistörü kullanacağız.Çünkü bizim robotumuzun çok miktarda akıma gereksinimi var.BC875 veya BC618 500mA civarında çalışır. Girişteki 47K açık devrenin kapalı olmasını sağlar.Paralel porttaki voltaj seviyesi açık durumda 4 Volttan fazla, kapalı durumda da 1 voltan azdır. Tranzistör devreyi açma kapama görevini yapar.1 Ohmluk dirençler akımı sınırlarlar ve robotun ayaklarını koururlar ve tabii ki tranzistörleri de. LED ler de açık mı kapalı mı olduğunu gösterir.Şekil 15 de devrenin resimlerini görebilirsiniz. Kırmızı LED leri(robotun devindiricilerine paralel olan) görmek zordur çünkü bizim kullandığımız LED'ler saydam kırmızıdır.Konstantan tel bobininden 15 Ohmluk dirençler yaptık ,ama bu telden yapmamızın nedeni bu telden çok bulunmasıdır. 2 W hazır direnç almak daha uygundur.


[the final drivercircuit1] [the final drivercircuit2]
Şkil 15: devre



Parallel port

Paralel port bir PC den çıkış portu olarak çalışmak ve yazıcı takmak için tasarlanmıştır. Bazı paralel portlar hem giriş hem de çıkış portu olarak da çalışabilirler.Ama biz burada sadece çıkış portunu kullanacağız. Daha sonraki yazıda sensörleri robota bağlayacağız ve giriş hatlarını kullanacağız.Paralel port için 25 pin bulunmasına rağmen biz 9 tane kullanacağız.Bu hatlardan 8 tanesi veri çıkışı için kullanaılacaktır. Pin çıkışları aşağıda gösterilmiştir.

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
Sürücü devresini 18.pine ve veri pinlerine(2-9) bağlayın.

Paralel port normalde şöyle çalışır:1 Byte'ın veri hatlarına yazılması ve sonra bilgisayar stroboskop hatlarını 1 olacak şekilde ayarlar ,böylece bunu yazıcıya gösterir ve veri hatları geçerli olur.Biz veri hatlarını doğrudan kulllanacağız çünkü stroboskop hatları için ayrı bir mantığa gereksinimimiz yoktur.

Yazılım

Yazılımı adresinden> yükleyebilirisiniz <.
Bu programı tar zxvf pprobi*.tar.gz komutuyla açabilirsiniz.Kurulum açıklamaları bulunmaktadır

Bu program C dilinde yazılmıştır.Ok tuşlarının yardımıyla ve space tuşuyla robotu kontrol edebilirsiniz.Robotu yürütmek için ok tuşları ,durdurmak için space tuşu kullanılır ve q(veya x) tuşuyla programdan çıkabilirsiniz.Ok tuşları yerine h,j,k,l tuşlarını kullanabilirsiniz.Bacak hareketleri için kullandığımız değerler robotumuz için uygun hale getirilmiştir.Her robot biraz birbirinden farklıdır.Genel olaral tüm nitinol tellerinden aynı gerilimi almak zordur.Robotunuz yazılımla beraber çalışacaktır.Ama tüm bacaklar aynı şekilde hareket etmeyebilir ve robotunuza uyan en iyi değerleri bulana kadar biraz deney yapmalısınız.Robotunuzun hiç bir ayağnın ısınmamasına dikkat edin, ayrıca soğuması için gerekli zaman bulabilmesine dikkat edin .

==== 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


Yazılımımız 2.4.x çekirdektenden kalma ppdev programlama arayüzünü kullanır.Bu arayüz paralel port aygıt sürücüleri yazmak için uygun ve temiz bir arayüzdür.Eski çekirdeklere(2.3.x veya 2.4.x den daha düşük sürümlerde) yeni bir çekirdek modülü yazmak zorunda kalırız veya daha çirkin bir yöntem kullanabiliriz.Bu yöntem sadece root'un programı kulanabilmesine izin vermektir. ppdev arayüzü /dev/parport0 aygıt dosyasını kullanır.Bu dosyanın kullanıcı izinlerini ayarlayabilmek için paralel port arayüzünü kullanan kullanıcıya başvurun.

ppdev'i bir modül olarak çekirdeğin içine derlemek istersek PARPORT modülünü PPDEV aygıtıyla beraberce derlemelyiz.Bu aşağıdaki gibi gözükecektir.

#
# 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
#


Program ilk olarak paralel portu ioctl komutu olan PPCLAIN ile başlatır.Terminali kuralsal olmayan moda geçirir(non canonical). Bu doğrudan klavyeden kullanıcının her giriş sonunda enter'a basmasını engelleyerek kullanıcının giriş yapmasını sağlar.Daha sonra program herhangi bir kullanıcı girişi olup olmadığına bakan ve robotu komuta göre yöneten bir döngü içine girer.Eğer herhangi bir emir vermezseniz program son komutu uygulamaya devam edecektir( yürümeye devam etmek gibi). ioctl (fd, PPWDATA, &bitpat); komutu veri hatlarının verilmiş örneğe göre ayarlanması için kullanılır.

Robotun pinlerinin şekildeki gibi sürücü devresinin çıkış hatlarına bağlanması gereklidir.

Bacaklar:
  A1------=------B1
          =      
          =      
  B2------=------A2
          =      
          =      
  A3------=------B3
 
 
  Pin to set A-legs to ground= AD
  Pin to set B-legs to ground= BD

Sürücü kartının çıkış çizgilerinin uyumu :
  data 0           A1
  data 1           A2
  data 2           A3
  data 3           AD
  data 4           B1
  data 5           B2
  data 6           B3
  data 7           BD

Data 0 sürücü devresini paralel portun 2.pinine bağlayan çıkıştır. (D0).

İşte, yürüyen robotumuz:
[yes, it walks]
Bu canlandirim gif'teki biraz daha hızlı yürüyor. Gerçek hayatta nitinolü eski boyuna getirmek için gerekli olan soğutma zamanından dolayı; biraz daha yavaş yürüyor.


Robotu yaparken zevk alacağınızı umuyoruz. Hadi bize kendi robotunuz hakkında bilgi verin; özellikle sizinki bizimkinden farklı tasarlanmışsa.

Kaynaklar