communication avec un programme c

Salut a tous

J'ai un petit souci :~ avec un programme c trouvé à cette adresse: todbot blog – Random experiments, circuits, code, rapid prototyping, sometimes things to buy, and the odd tune by Tod Kurt. qui permet de recevoir des données. voici le code c:

#include <stdio.h>    
#include <stdlib.h> 
#include <stdint.h>   
#include <string.h>   
#include <unistd.h> 
#include <fcntl.h>  
#include <errno.h> 
#include <termios.h> 
#include <sys/ioctl.h>
#include <getopt.h>

void usage(void);
int serialport_init(const char* serialport, int baud);
int serialport_writebyte(int fd, uint8_t b);
int serialport_write(int fd, const char* str);
int serialport_read_until(int fd, char* buf, char until);

void usage(void) {
    printf("Usage: arduino-serial -p <serialport> [OPTIONS]\n"
    "\n"
    "Options:\n"
    "  -h, --help                   Print this help message\n"
    "  -p, --port=serialport        Serial port Arduino is on\n"
    "  -b, --baud=baudrate          Baudrate (bps) of Arduino\n"
    "  -s, --send=data              Send data to Arduino\n"
    "  -r, --receive                Receive data from Arduino & print it out\n"
    "  -n  --num=num                Send a number as a single byte\n"
    "  -d  --delay=millis           Delay for specified milliseconds\n"
    "\n"
    "Note: Order is important. Set '-b' before doing '-p'. \n"
    "      Used to make series of actions:  '-d 2000 -s hello -d 100 -r' \n"
    "      means 'wait 2secs, send 'hello', wait 100msec, get reply'\n"
    "\n");
}

int main(int argc, char *argv[]) 
{
    int fd = 0;
    char serialport[256];
    int baudrate = B9600;  // default
    char buf[256];
    int rc,n;

    if (argc==1) {
        usage();
        exit(EXIT_SUCCESS);
    }

    /* parse options */
    int option_index = 0, opt;
    static struct option loptions[] = {
        {"help",       no_argument,       0, 'h'},
        {"port",       required_argument, 0, 'p'},
        {"baud",       required_argument, 0, 'b'},
        {"send",       required_argument, 0, 's'},
        {"receive",    no_argument,       0, 'r'},
        {"num",        required_argument, 0, 'n'},
        {"delay",      required_argument, 0, 'd'}
    };
    
    while(1) {
        opt = getopt_long (argc, argv, "hp:b:s:rn:d:",
                           loptions, &option_index);
        if (opt==-1) break;
        switch (opt) {
        case '0': break;
        case 'd':
            n = strtol(optarg,NULL,10);
            usleep(n * 1000 ); // sleep milliseconds
            break;
        case 'h':
            usage();
            break;
        case 'b':
            baudrate = strtol(optarg,NULL,10);
            break;
        case 'p':
            strcpy(serialport,optarg);
            fd = serialport_init(optarg, baudrate);
            if(fd==-1) return -1;
            break;
        case 'n':
            n = strtol(optarg, NULL, 10); 
            rc = serialport_writebyte(fd, (uint8_t)n);
            if(rc==-1) return -1;
            break;
        case 's':
            strcpy(buf,optarg);
            rc = serialport_write(fd, buf);
            if(rc==-1) return -1;
            break;
        case 'r':
            serialport_read_until(fd, buf, '\n');
            printf("lire: %s\n",buf);
            break;
        }
    }

    exit(EXIT_SUCCESS);    
} 
    
int serialport_writebyte( int fd, uint8_t b)
{
    int n = write(fd,&b,1);
    if( n!=1)
        return -1;
    return 0;
}

int serialport_write(int fd, const char* str)
{
    int len = strlen(str);
    int n = write(fd, str, len);
    if( n!=len ) 
        return -1;
    return 0;
}

int serialport_read_until(int fd, char* buf, char until)
{
    char b[1];
    int i=0;
    do { 
        int n = read(fd, b, 1);  
        if( n==-1) return -1;    
        if( n==0 ) {
            usleep( 10 * 1000 ); 
            continue;
        }
        buf[i] = b[0]; i++;
    } while( b[0] != until );

    buf[i] = 0;  
    return 0;
}

int serialport_init(const char* serialport, int baud)
{
    struct termios toptions;
    int fd;
    
    //fprintf(stderr,"init_serialport: ouvre le port %s @ %d bps\n",
    //        serialport,baud);

    fd = open(serialport, O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd == -1)  {
        perror("init_serialport: impossible d'ouvrir le port ");
        return -1;
    }
    
    if (tcgetattr(fd, &toptions) < 0) {
        perror("init_serialport: imposible de recevoir les options du terminal");
        return -1;
    }
    speed_t brate = baud; 
    switch(baud) {
    case 4800:   brate=B4800;   break;
    case 9600:   brate=B9600;   break;
#ifdef B14400
    case 14400:  brate=B14400;  break;
#endif
    case 19200:  brate=B19200;  break;
#ifdef B28800
    case 28800:  brate=B28800;  break;
#endif
    case 38400:  brate=B38400;  break;
    case 57600:  brate=B57600;  break;
    case 115200: brate=B115200; break;
    }
    cfsetispeed(&toptions, brate);
    cfsetospeed(&toptions, brate);

    // 8N1
    toptions.c_cflag &= ~PARENB;
    toptions.c_cflag &= ~CSTOPB;
    toptions.c_cflag &= ~CSIZE;
    toptions.c_cflag |= CS8;
    // no flow control
    toptions.c_cflag &= ~CRTSCTS;

    toptions.c_cflag |= CREAD | CLOCAL;  // turn on READ & ignore ctrl lines
    toptions.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl

    toptions.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw
    toptions.c_oflag &= ~OPOST; // make raw

    toptions.c_cc[VMIN]  = 0;
    toptions.c_cc[VTIME] = 20;
    
    if( tcsetattr(fd, TCSANOW, &toptions) < 0) {
        perror("init_serialport: Couldn't set term attributes");
        return -1;
    }

    return fd;
}

coté arduino c'est un truc simple du genre:

void setup() {
Serial.begin(9600);
Serial.println("test");
}

void loop() {
}

sous mac il n'y a pas de probleme la compilation se deroule normalement et la sortie ressemble à:

  • ~>./arduino-serial -p /dev/tty.usbmodem1d11 -r
  • read: test
  • ~>

Sous linux la compilation marche tout aussi bien mais la sortie me donne:

  • ~>./arduino-serial -p /dev/ttyACM0 -r
  • read: ?
  • ~>

je ne comprend pas d'ou vient ce point d'interogation et pourquoi sa marche sous mac alors que se sont tous deux des systemes unix... :frowning:
Est ce que quelqu'un a deja fait face a ce meme probleme? car j'avoue que je ne pas trop comprendre :astonished:

Désolé j'ai poster ce topic en double :~ petite éreur de manipulation. je ne voit pas comment suprimer l'autre? :blush:

Bon ben j'ai trouver un peu d'aide sur irc, on ma conseiller de changer le format de sortie du printf dans le code en c:

printf("read: %s\n",buf); -> printf("read: %x\n",buf);

Deja la sorti s'affiche en hexa et il n'y a plus de caractere ? mais un autre probleme survient c'est que ce chiffre en hexa est different a chaque fois que je lance le programme:

  • ./arduino-serial -p /dev/ttyACM0 -r
  • read: bfcf43dc
  • ./arduino-serial -p /dev/ttyACM0 -r
  • read: bfac5d1c
  • ./arduino-serial -p /dev/ttyACM0 -r
  • read: bfce31bc

le mystère reste entier :astonished: