Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 20/06/2016, à 19:30

axelou

programmation port serie C

Bonjour,

Je dois faire un programme dont l'un des objets à piloter est un ohmètre via le port serie et je suis dans la mouise parce que ça marche pas et que je comprends pas pourquoi. Tout me paraissait pourtant simple quand j'ai commencé. En plus le petit programme gtkterm fonctionne très bien, alors j'ai essayé de m'en inspirer. Mais même en lisant leur code j'ai pas réussi à trouver l'astuce qui fait que quand gtkterm utilise write le ohmètre réagit, quand c'est moi, ben aucune réaction. Les messages sont ignorés et j'en suis sûr parce que affichage du ohmètre.

Bref, voici le code:

#include <stdio.h> // standard input / output functions
#include <stdlib.h>//strtoul
#include <string.h> // string function definitions
#include <unistd.h> // UNIX standard function definitions

#include <termios.h> // POSIX terminal control definitionss
#include <fcntl.h> // File control definitions
#include <sys/ioctl.h>
#include <errno.h> // Error number definitions

#include "microhmetre.h"

#define SELF_TEST 1

int microhmetre_fd = -1;
struct termios tio_save;

int microhmetre_Init(void)
{
    microhmeter_close();
    char* portName = "/dev/ttyUSB0";
    /** open serial ports**/
    microhmetre_fd = open(portName, O_RDWR  | O_NOCTTY | O_NDELAY);

    if(microhmetre_fd==-1) {
        printf("openPort ERROR\n");
        return 1;
    }
    /**Configuring serial port transmission type**/
    struct termios newtio;

    if(!isatty(microhmetre_fd)) {
        printf("port %d is not a tty\n", microhmetre_fd);
        close(microhmetre_fd);
        microhmetre_fd = -1;
        return 1;
	}

    //bzero(&newtio, sizeof(newtio)); // clear struct for new port settings
    tcgetattr(microhmetre_fd, &newtio);
    memcpy(&tio_save, &newtio, sizeof(struct termios));

    //setting c_cflags
    newtio.c_cflag = B9600;//baud rate
    newtio.c_cflag |= CS8;//set 8 bits

    newtio.c_cflag |= CSTOPB;//|= CSTOPB; 2 stop bits &=~CSTOPB; 1 stop bit
    newtio.c_cflag |= (CREAD | CLOCAL); //enable receiver

    //l_flags
    newtio.c_lflag = 0;

    //i_flags
    newtio.c_iflag = IGNPAR | IGNBRK;

    //o_flags
    newtio.c_oflag = 0;

    //other flags
    newtio.c_cc[VMIN] = 0;
    newtio.c_cc[VTIME] = 1; //Inter-char timer 1s read timeout

    //apply settings

    if(tcsetattr(microhmetre_fd, TCSANOW, &newtio)<0) {
        printf("Unable to apply given port settings\n");
        close(microhmetre_fd);
        microhmetre_fd = -1;
        return 1;
	}
    tcflush(microhmetre_fd, TCOFLUSH);
    tcflush(microhmetre_fd, TCIFLUSH);

    return 0;
}

void microhmeter_close(void){
    if( microhmetre_fd != -1){
        tcsetattr(microhmetre_fd, TCSANOW, &tio_save);
        tcflush(microhmetre_fd, TCOFLUSH);
        tcflush(microhmetre_fd, TCIFLUSH);
        close(microhmetre_fd);
        microhmetre_fd = -1;
    }
}

int microhmeter_write(char * buf, int length)
{
    if (microhmetre_fd == -1) return 1;
    if (length = 0) return 0;
    int res, err;

    /*Write data*/
    res = write(microhmetre_fd, buf, length);
    if( res < 0){
        err = errno;
        printf("write failed: error %d\n", err);
        return 1;
    }
    else if (res != length){
        printf("write not completed\n");
        return 1;
    }
    else {
        tcdrain(microhmetre_fd);//attendre la fin de l'envoie.
    }

    return 0;
}


int microhmeter_configure(void)
{
    char * remote = "SYST:REM\n";

    if(microhmeter_write(remote, 9)){
        printf("configure remote failed\n");
        return 1;
    }
    sleep(1);
    char * trig_bus = "TRIG:SOURCE BUS\n";
    if(microhmeter_write(trig_bus, 16)){
        printf("configure trig bus failed\n");
        return 1;
    }
    sleep(1);
    return 0;

}

int microhmeter_read(int recvBytes, char * buf)
{
    unsigned long time;
    unsigned long mesure;
    int res;
    //select
    fd_set rfds;
    struct timeval tv;
    int retval = 0;

    FD_ZERO(&rfds);
    FD_SET(microhmetre_fd, &rfds);
    //Timeout 500ms
    tv.tv_sec = 3;
    tv.tv_usec = 500000;

    while(retval == 0) {
        retval = select(microhmetre_fd+1, &rfds, NULL, NULL, &tv);
        if(retval == -1) {
            printf("Select Error in read port\n");
            return 1;
        } else if (retval) {
            res = read(microhmetre_fd, buf, recvBytes);
            break;
        } else {
            printf("Read_port timeout\n");
            return 1;
        }
    }
    if(res==15){
        buf[res] = 0;
        //TODO enregistrer et renvoyer la mesure
    } else {
        printf("error in read microhmeter\n");
        return 1; //something is wrong
    }

    return 0;

}

int microhmeter_getMes(long double* mes)
{
    char * mes_cmd = "MEAS:FRES?\n";
    if(microhmeter_write(mes_cmd, 11)){
        printf("error microhmeter write\n");
        return 1;
    }
    char buf[16];
    if(microhmeter_read(16, buf)){
        printf("error microhmeter read\n");
        return 1;
    }
    char ** res;
    *mes = strtold(buf, res);
    return 0;
}
#if SELF_TEST
int main(void){

    long double mes;
    if(microhmetre_Init()) {
        printf("error init\n");
        return 1;
    } else printf("init succes\n");

    if(microhmeter_configure()) {
        microhmeter_close();
        return 1;
    }
    else printf("configure succes\n");

    if(microhmeter_getMes(&mes)) {
        microhmeter_close();
        return 1;
    }
    else printf("mesure succès\n");

    printf("mes = %Lf", mes);

    microhmeter_close();
    return 0;

}
#endif // SELF_TEST

J'ai l'impression de faire du code style années 70 avec termios, etc. Mais bon ça devrait marcher. C'est pour un prototype de code qui doit être fini cette semaine. Je suis dans la mouise...
L'appareil fonctionne en 8N2, 1 start bit, DTR/DSR handshake. Bref, normalement c'est ce que j'ai mis. Je compile avec gcc. Quelqu'un a une idée de bêtise que j'aurais faite?
Merci,

Hors ligne

#2 Le 04/07/2016, à 17:20

pires57

Re : programmation port serie C

Salut,

Pas d'erreur à la compilation? à l’exécution?


Utilisateur d'Archlinux, Ubuntu et Kali Linux
Administrateur système et réseau spécialisé Linux.
LinkedIn

Hors ligne