aus /dev/ttyS0 ordentlich lesen



  • Hi leute!!

    ich habe so einen infrarot ir-232 transresiver der auch funktioniert. ich kann z.B die signale einer fernbedienung mit diesem empfangen(getestet hab ich dies mit minicom). nun moechte ich mir ein programm schreiben dass von /dev/ttyS0 die signale liest und wie minicom auf den bildschirm ausgiebt! soweit bin ich schon:

    /*ledController whith FERNBEDIENUNG!
     *(C) by Rainer Sickinger!
     *e-mail: unix4ever@gmx.net
     */
    
    #include <sys/ioctl.h>
    #include <sys/kd.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    #define INDEVICE "/dev/ttyS0"
    #define OUTDEVICE "/dev/tty1"
    
    #define BLOCKSIZE 8
    
    int main(void){
        int readBytes;
        int input;
        int output;
    
        char buffer[BLOCKSIZE];
    
        /*open the input device*/
        input = open(INDEVICE, O_RDONLY|O_NOCTTY);    
    
        /*open the output device*/
        output = open(OUTDEVICE, O_WRONLY);
    
        if(input == -1 || output == -1){
            fprintf(stderr, "ERROR konnte die Devices nicht oeffnen");
            return 1;
        }/*end if*/
    
        printf("lese...\n");
        read(input, buffer, BLOCKSIZE);
        printf("%s\n", buffer);
    
        return 0;
    }/*end main*/
    

    leider liest das programm irgendwie nischt? vielleicht kann mir von euch jemand helfen? waere super
    DANKE
    mfg
    --linuxuser--



  • Lies doch mal in einer Schleife. Und vor allem, sieh dir auch den Rückgabecode von read an (perror). Ausserdem solltest du, zum Testen, den eingelesenen Buffer genauer ausgeben und nicht nur als Zeichenkette.



  • hallo
    erstmal DrGreenthumb danke fuer die antwort!

    ich hab nun den code etwas abgeaendert laut DrGreenthumb:

    /*ledController whith FERNBEDIENUNG!
     *(C) by Rainer Sickinger!
     *e-mail: unix4ever@gmx.net
     */
    
    #include <sys/ioctl.h>
    #include <sys/kd.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    #define INDEVICE "/dev/ttyS0"
    #define OUTDEVICE "/dev/tty1"
    
    #define BLOCKSIZE 8
    
    int main(void){
        int readBytes;
        int input;
        int output;
    
        char buffer[BLOCKSIZE];
    
        /*open the input device*/
        input = open(INDEVICE, O_RDONLY|O_NOCTTY|O_NONBLOCK);    
    
        /*open the output device*/
        output = open(OUTDEVICE, O_WRONLY);
    
        if(input == -1 || output == -1){
            fprintf(stderr, "ERROR konnte die Devices nicht oeffnen");
            return 1;
        }/*end if*/
    
        while(1){
            printf("hallo\n");
            readBytes = read(input, buffer, BLOCKSIZE);
            perror("Fehler ");
            printf("%s,%d, - %d\n", buffer, buffer, readBytes);
        }
    
        return 0;
    }/*end main*/
    

    ich habe bei den parametern zum oeffnen des devices das O_NONBLOCK hinzugefuegt damit read schleife nicht blockiert!(waenn ich das nicht mache bleibt sie bei hallo einfach stehen). folgendes gibt mir dieses programm aus(natuerlich mehrmals 😉 ):

    hallo
    Fehler : Resource temporarily unavailable
    ,-1078294220, - -1
    

    was heisst dieses "Resource temporarily unavailable"?
    irgendwas habe ich noch vergessen da bin ich mir sicher!

    PS: waerend diese schleife laeuft druecke ich natuerlich kontinuirlich auf meiner fernbedienung herum!



  • Wenn read() hängt, dann deshalb, weil keine Daten kommen. Mit dem nonblock bewirkst du nur, dass read auch ohne etwas zu lesen zurückkehrt. Dann bekommst du diesen Fehler.

    Ausserdem solltest du, wie gesagt, den Buffer nicht nur als Zeichenkette ausgeben sondern lieber die wirklichen Werte. Sonst kannst du dir dein Programm auch schenken und einfach cat nehmen.

    Aber ich habe ja keine Ahnung, was der Infrarot-Empfänger da überhaupt sendet. Evtl. mal mit cfmakeraw den fd auf raw umschalten, damit du nicht Opfer des Linebuffers wirst.



  • hallo!

    ich hab nun den code wieder etwas abgeaendert es funkt leider immer noch nicht :-(:

    /*ledController whith FERNBEDIENUNG!
     *(C) by Rainer Sickinger!
     *e-mail: unix4ever@gmx.net
     */
    
    #include <sys/ioctl.h>
    #include <sys/kd.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <termios.h>
    #include <unistd.h>
    
    #define INDEVICE "/dev/ttyS0"
    
    #define BLOCKSIZE 8
    
    int main(void){
        int readBytes;
        int input;
        int run = 0;
    
        struct termios old_cons;
        struct termios new_cons;
    
        char buffer[BLOCKSIZE];
    
        /*open the input device*/
        input = open(INDEVICE, O_RDONLY|O_NOCTTY|O_NONBLOCK);  
    
        if(input == -1){
            fprintf(stderr, "ERROR konnte die Devices nicht oeffnen");
            return 1;
        }/*end if*/
    
        /*save consol*/
        if( (tcgetattr(input, &old_cons)) == -1){
            fprintf(stderr, "FEHLER bei \"consolensicherung\"");
            return 1;
        }/*end if*/
    
        cfmakeraw(&new_cons);
        tcsetattr(input, TCSANOW, &new_cons);
    
        while(1){
            system("clear");
            printf("Zyklus:%2d\n", run++);
            readBytes = read(input, buffer, BLOCKSIZE);
            perror("Fehler ");
            write(STDOUT_FILENO, buffer, BLOCKSIZE);
            if(run == 20) break;
            sleep(1);
        }
    
        /*set consol back*/
        tcsetattr(input, TCSANOW, &old_cons);
    
        /*close INDEVICE*/
        close(input);
    
        return 0;
    }/*end main*/
    

    also ich habe die konsolo in den raw modus geschickt und zwar mit:

    cfmakeraw(&new_cons);
        tcsetattr(input, TCSANOW, &new_cons);
    

    (TCSANOW damit aenderungen gleich wirksam werden!)
    weiters gebe ich den buffer nun direkt mit write wieder aus ich hoffe das ist in dem sinn wie du es mir gesagt hast 🙂 ausgabe nun:
    (z.B.)

    Zyklus:17
    Fehler : Resource temporarily unavailable
    

    habe ich das mit dem rawmodus richtig gemacht?
    ach ja der ir transresiver gibt auf dem minicom so ne mischung aus kaestchen und punkten usw aus einfach ascii salat!



  • --linuxuser-- schrieb:

    weiters gebe ich den buffer nun direkt mit write wieder aus ich hoffe das ist in dem sinn wie du es mir gesagt hast 🙂

    nein, das ist ja das gleiche. Meinte du sollst dir die Werte ausgeben:

    for(i=0; i<bytes_received; ++i) printf("%x, ", buffer[i]);

    habe ich das mit dem rawmodus richtig gemacht?

    sieht richtig aus.

    ach ja der ir transresiver gibt auf dem minicom so ne mischung aus kaestchen und punkten usw aus einfach ascii salat!

    ja, minicom versucht, genau wie du, das ganze als Text darzustellen. Sendet das Teil denn Text? Könnte auch sein, dass die Baudrate falsch ist. Musst du wissen, welche dort eingestellt werden muss.

    Ausserdem hast du immer noch nonblock an.. Lass das doch weg.



  • In der FAQ ist doch eine Lösung für die Ansteuerung der Schnittstelle!
    Statt der write(STDOUT_FILENO, ...)-Anweisung müssten "nicht-sichtbare" Zeichen halt noch mit printf("0x%x", ...) in HEX ausgegeben werden.

    Martin


Anmelden zum Antworten