Go Down

Topic: communication avec un programme c (Read 544 times) previous topic - next topic

AKkarol7

Salut a tous

J'ai un petit souci avec un programme c trouvé à cette adresse: http://todbot.com/blog/ qui permet de recevoir des données. voici le code c:
Code: [Select]

#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:
Code: [Select]

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

  • ~>


En revanche sous linux l

sdnatcher

Salut,

Perso, j'ai écris un script en bash qui va chercher les données sur le port COM.

En outre pour évité les problèmes de chariot et de config port COM, j'ai installer ser2net qui permet d'établir une communication TELNET/SSH sur un port locale(ou réseau) vers ton port COM.

Exemple en bash :
Tu déclare ta commande, évidement ici c'est un exemple, il est préférable de taper un case dans ton script.

Code: [Select]
$CHECK=T

Tu encapsule ta commande vers l'arduino et ensuite tu récupère le résultat.

Code: [Select]
{ sleep 2 ; echo "$CHECK"; sleep 3;} | telnet 127.0.0.1 > resultat.tmp

Il est préférable d'installer dos2unix pour changer le transcodage du fichier surtout en mode telnet.

Quote
dos2unix resultat.tmp


Du côtés arduino :
Code: [Select]
void setup() {
  Serial.begin(9600);
  if (Serial.available() > 0) {
    int command = Serial.read();
    Serial.println("Arduino Hello, please command ?");
    Serial.println("Ready !");
    switch(command) {
    case 'T':
      {
        Serial.println("Hello Word TEST ");
        setup();
      }
     default:
      Serial.println("Error");
      Serial.println("Unreconize command");
      setup();
    }
  }
}


En espérant que j'ai pu t'apporter quelques idées.
Quand tu indique que cela ne fonctionne pas soucis linux, tu as plus de détails ?
Tu arrive à le compiler et il ne fonctionne pas ?

Bonne journée,


sdnatcher

Vient de voir ton deuxième poste.

J'ai u le même problème en bash ... Je me retrouve avec un fichier de résultat en format "windows" avec des caractères de fin ligne comme ^M
juste changer le transcodage du résultat et je n'ai plus u de problème.


Donc oublie mes questions :) vue que tu as trouver la solution toi même.
Bonne journée,

AKkarol7

hey

Ben a vrai dire, j'ai envoyer ce post par erreur sans l'avoir terminer :smiley-sweat: le post complet est ici:http://arduino.cc/forum/index.php/topic,149310.0.html

Dans l'absolut je souhaiterais traiter les données recu par l'arduino et créer une interface graphique donc j'ai besoin de coder en c

AKkarol7

Oui c'est ce que j'allait dire :P en tout cas merci de ton aide  :)

Go Up