Etablir une liaison série en langage C

Bonjour ,
Je suis entraîne de faire un projet et j'ai besoin d'un programme en langage C qui permet de récupérer les données envoyé par l'Arduino via Serial Moniteur pour cela j'ai installé un programme qui s'appelle PuTTY qui récupére lui aussi les même données que le Moniteur série.

Merci ,

Sur ordinateur? linux? MacOS? Windows? Tout dépend de votre OS, ce n'est pas une fonction C standard de base.

Bonjour,

Regarde la bibliothèque "Boost".

Merci , oui c'est sur ordinateur sous l'unix

lisez cela

Merci pour toute les informations,
mais j'ai trouvé un peut trop pour moi comme j'ai un peu de connaissance en langage C :slight_smile: .
je veux commencer par un simple programme .
l'Arduino envois une lettre ( 's' par exemple) via le port série (ça je le sais faire)
un programme en langage C qui permet d'établir la liaison série et récupère la lettre 's';
le programme vérifier qu'il a bien reçu la lettre 's' .
et si oui le programme réponds par envoyer la lettre 'y'.

Merci :slight_smile:

Tu attends que quelqu'un te fasse le programme ?
Sinon, à part ça, que veux-tu faire au final ? Pourquoi as-tu besoin d'un programme en C qui lise le port série ?

ARdoman:
Merci pour toute les informations,
mais j'ai trouvé un peut trop pour moi comme j'ai un peu de connaissance en langage C :slight_smile: .
je veux commencer par un simple programme .
l'Arduino envois une lettre ( 's' par exemple) via le port série (ça je le sais faire)
un programme en langage C qui permet d'établir la liaison série et récupère la lettre 's';
le programme vérifier qu'il a bien reçu la lettre 's' .
et si oui le programme réponds par envoyer la lettre 'y'.

Merci :slight_smile:

dans ce cas ne le faites pas en C pour le moment...

Explorez plutôt Processing qui vous donnera des objets de plus hauts niveau pour faire abstraction du port série.

1)nn je veux pas quelqu'un pour faire le programme je veux juste les grandes lignes et les fonctions :slight_smile:

  1. je suis obligé de travailler en langage C

3)j'ai déjà fais ce programme en python :

#!/usr/bin/env python

-- coding: utf-8 --

import serial
from time import sleep

try:
port = 'COM4'
baud = 9600

ser = serial.Serial(port=port, baudrate=baud , timeout=3)

sleep(2)

ser.write("s")

comment = ser.read(1)
reply="No connection"
if comment == '1' :
reply = 'bouton fermé'
if comment == '2' :
reply = 'bouton ouvert'
ser.close()

except:
reply="erreur"

print "Content-Type: text/html"
print """

etat du bouton %s

Oui mais c'est un langage déjà à plus haut niveau d'abstraction

[color=red]import serial
try:
   port = 'COM4'
   baud = 9600
   ser = serial.Serial(port=port, baudrate=baud , timeout=3)[/color]

vous n'avez pas un appel en C qui vous fait cela tout seul.. vous pouvez bien ouvrir un file descriptor sur le device associée à votre port USB, du genre    int fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_SYNC);mais ce sera loin d'être suffisant!

Soit vous prenez des librairies tierces parties vous offrant un niveau d'abstraction équivalent mais dans ce cas vous n'avez rien écrit vous même, soit vous lisez la doc et vous codez...

si vous cherchez un peu sur internet vous verrez des trucs comme cela:

 #include <errno.h>
#include <fcntl.h> 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

int set_interface_attribs(int fd, int speed)
{
    struct termios tty;

    if (tcgetattr(fd, &tty) < 0) {
        printf("Error from tcgetattr: %s\n", strerror(errno));
        return -1;
    }

    cfsetospeed(&tty, (speed_t)speed);
    cfsetispeed(&tty, (speed_t)speed);

    tty.c_cflag |= (CLOCAL | CREAD);    /* ignore modem controls */
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;         /* 8-bit characters */
    tty.c_cflag &= ~PARENB;     /* no parity bit */
    tty.c_cflag &= ~CSTOPB;     /* only need 1 stop bit */
    tty.c_cflag &= ~CRTSCTS;    /* no hardware flowcontrol */

    /* setup for non-canonical mode */
    tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
    tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    tty.c_oflag &= ~OPOST;

    /* fetch bytes as they become available */
    tty.c_cc[VMIN] = 1;
    tty.c_cc[VTIME] = 1;

    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        printf("Error from tcsetattr: %s\n", strerror(errno));
        return -1;
    }
    return 0;
}

void set_mincount(int fd, int mcount)
{
    struct termios tty;

    if (tcgetattr(fd, &tty) < 0) {
        printf("Error tcgetattr: %s\n", strerror(errno));
        return;
    }

    tty.c_cc[VMIN] = mcount ? 1 : 0;
    tty.c_cc[VTIME] = 5;        /* half second timer */

    if (tcsetattr(fd, TCSANOW, &tty) < 0)
        printf("Error tcsetattr: %s\n", strerror(errno));
}


int main()
{
    char *portname = "/dev/ttyUSB0";
    int fd;
    int wlen;

    fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
    if (fd < 0) {
        printf("Error opening %s: %s\n", portname, strerror(errno));
        return -1;
    }
    /*baudrate 115200, 8 bits, no parity, 1 stop bit */
    set_interface_attribs(fd, B115200);
    //set_mincount(fd, 0);                /* set to pure timed read */

    /* simple output */
    wlen = write(fd, "Hello!\n", 7);
    if (wlen != 7) {
        printf("Error from write: %d, %d\n", wlen, errno);
    }
    tcdrain(fd);    /* delay for output */


    /* simple noncanonical input */
    do {
        unsigned char buf[80];
        int rdlen;

        rdlen = read(fd, buf, sizeof(buf) - 1);
        if (rdlen > 0) {
#ifdef DISPLAY_STRING
            buf[rdlen] = 0;
            printf("Read %d: \"%s\"\n", rdlen, buf);
#else /* display hex */
            unsigned char   *p;
            printf("Read %d:", rdlen);
            for (p = buf; rdlen-- > 0; p++)
                printf(" 0x%x", *p);
            printf("\n");
#endif
        } else if (rdlen < 0) {
            printf("Error from read: %d: %s\n", rdlen, strerror(errno));
        }
        /* repeat read to get full message */
    } while (1);
}

To make the program treat the received data as ASCII codes, compile the program with the symbol DISPLAY_STRING, e.g. [color=blue]cc -DDISPLAY_STRING demo.c[/color]

J-M-L:
Soit vous prenez des librairies tierces parties vous offrant un niveau d'abstraction équivalent mais dans ce cas vous n'avez rien écrit vous même, soit vous lisez la doc et vous codez...

Oui enfin c'est pas interdit de se simplifier la vie, sinon on coderait toujours en assembleur.

Avec Boost, voici ce que ça donne en C++ (en espérant que "langage C" est un raccourci pour "langage C/C++":

#include <iostream>
#include <boost/asio/serial_port.hpp> 
#include <boost/asio.hpp>

using namespace std;
using namespace boost;

string serialLine;
asio::io_service io;
asio::serial_port serial(io);

int main(int argc, char* argv[])
{
    try {

        serial.open("COM12");
        serial.set_option(asio::serial_port_base::baud_rate(115200));
        // This option is a must. Otherwise, we get weird characters
        serial.set_option(asio::serial_port_base::character_size(asio::serial_port_base::character_size::character_size(8U)));

        
        // Read a line on serial port
        int endLine = 0;
        char c;
        while (!endLine) {
            asio::read(serial,asio::buffer(&c,1));
            // End of line is characterized by \n
            switch(c)
            {
                case '\r':
                    break;
                case '\n':
                    endLine = 1;;
                default:
                    serialLine += c;
            }
        }

        cout<<serialLine<<endl;

    } catch(boost::system::system_error& e)
    {
        cout<<"Error: "<<e.what()<<endl;
        return 1;
    }
}

J'ai fait récemment un programme qui envoie des données via le port série, pour lequel j'ai utilisé Qt. la bibliothèque QSerialPort proposé par l'environnement Qt est d'un emploi assez facile, peut-être une piste à explorer?

Par contre, il y a un inconvénient: Qt est un environnement qui surcharge beaucoup de fonctions natives du C, certain lui reprochent donc de cloisonner, d'une certaine manière, et d'avoir une approche qui n'est pas tout à fait standard pour certains points. Quoi qu'il en soit c'est un assortiment d'outils puissant, qui est conçu de manière assez homogène

Pour information, mon code source est ici: GitHub - troisiemetype/c-projecteur-laser. La partie qui t'intéresse est bien sûr dans serial.cpp et .h.