2017-04-16 2 views
0

Je souhaite lire des publications en série à partir d'arduino. J'utilise ce code:Lecture de la série arduino sous linux en utilisant C

#include <stdio.h> /* Standard input/output definitions */ 
#include <string.h> /* String function definitions */ 
#include <unistd.h> /* UNIX standard function definitions */ 
#include <fcntl.h> /* File control definitions */ 
#include <errno.h> /* Error number definitions */ 
#include <termios.h> /* POSIX terminal control definitions */ 
#include <sys/ioctl.h> 
int main(){ 
    char data[1024]; 
    char dev[] = "/dev/ttyACM1"; 
    int fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY); 
    fcntl(fd, F_SETFL, FNDELAY); 
    struct termios options; 
    tcgetattr(fd, &options); 
    cfsetispeed(&options, B9600); 
    cfsetospeed(&options, B9600); 
    options.c_cflag |= CS8; 
    options.c_cflag |= CS8; 
    options.c_cflag &= ~CRTSCTS; 
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); 
    tcsetattr(fd, TCSANOW, &options); 
    ioctl(fd, TCFLSH, 2); 
    while(1){ 
     read(fd, data, sizeof(data)); 
     printf(data); 
    } 
    //write(fd, data, sizeof(data)); 
} 

Mon arduino court sketch très simple:

int x; 
void setup() { 
    Serial.begin(9600); 
} 
void loop() { 
    Serial.println("DO YOU HEAR ME ??"); 
    delay(1000); 
} 

et la sortie de ce combinatin est que:

??OU HEAR ME ?? 
DO YOU HEAR ME ?? 
DO YOU HEAR ME ?? 
A¹­þ 
??OU HEAR ME ?? 
DO YOU HEAR ME ?? 
DO YOU HEAR ME ?? 
A¹­þ 
??OU HEAR ME ?? 
DO YOU HEAR ME ?? 
DO YOU HEAR ME ?? 

Ma question est de savoir comment faire pour sortir de le chaos. J'ai trouvé que ce problème se produit lorsque le tampon se termine et un nouveau commence (plus grand tampon moins de données indésirables) mais je ne peux pas avoir un tampon infini. En outre, il y a beaucoup de rebut quand il lit pour la première fois .. Y at-il un moyen de le synchroniser ou quelque chose?

(Aussi je ne suis pas anglais natif désolé pour les erreurs.)

+0

Essayez de vérifier la valeur de retour de 'read'. –

+0

@DavidCullen J'ai activé l'entrée cannonique et maintenant le junk ne se produit qu'au début de la ligne .. donc je suppose maintenant qu'il y a quelques bits supplémentaires sur l'entrée .. Mais je ne sais pas d'où (c'est comme 3 chars , 3 octets). – Kozlowsqi

+0

note d'un côté, essayez d'augmenter le débit en bauds et voyez-vous cela résout le problème? – LethalProgrammer

Répondre

0

J'ai trouvé réponse à mon problème. J'ai utilisé cette fois-ci C++ pour l'organiser en classe (très pauvre, car il ne gère aucune erreur et ne pas utiliser pas C++ dans le plus ..) Voici le code:

#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <termios.h> 

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <strings.h> 

#include <iostream> 
//Here I define some vars 
#define BAUDRATE B9600 
#define MODEMDEVICE "/dev/ttyACM0" 
#define _POSIX_SOURCE 1 

class serial{ 
public: 
serial(){ 
    fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY); 
    if (fd <0) {perror(MODEMDEVICE); exit(-1); } 
    // Improvement No. 1 I save old setting and clean the new one 
    tcgetattr(fd,&oldtio); 
    bzero(&newtio, sizeof(newtio)); 

    // Here I set all the flags to vars at once 
    newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; 
    newtio.c_iflag = IGNPAR | ICRNL; 
    newtio.c_oflag = 0; 
    newtio.c_lflag = ICANON; 
    //here I set some new flags.. 
    newtio.c_cc[VINTR] = 0;  /* Ctrl-c */ 
    newtio.c_cc[VQUIT] = 0;  /* Ctrl-\ */ 
    newtio.c_cc[VERASE] = 0;  /* del */ 
    newtio.c_cc[VKILL] = 0;  /* @ */ 
    newtio.c_cc[VEOF]  = 4;  /* Ctrl-d */ 
    newtio.c_cc[VTIME] = 0;  /* inter-character timer unused */ 
    newtio.c_cc[VMIN]  = 1;  /* blocking read until 1 character arrives */ 
    newtio.c_cc[VSWTC] = 0;  /* '\0' */ 
    newtio.c_cc[VSTART] = 0;  /* Ctrl-q */ 
    newtio.c_cc[VSTOP] = 0;  /* Ctrl-s */ 
    newtio.c_cc[VSUSP] = 0;  /* Ctrl-z */ 
    newtio.c_cc[VEOL]  = 0;  /* '\0' */ 
    newtio.c_cc[VREPRINT] = 0;  /* Ctrl-r */ 
    newtio.c_cc[VDISCARD] = 0;  /* Ctrl-u */ 
    newtio.c_cc[VWERASE] = 0;  /* Ctrl-w */ 
    newtio.c_cc[VLNEXT] = 0;  /* Ctrl-v */ 
    newtio.c_cc[VEOL2] = 0;  /* '\0' */ 
    // and I finally save the settings 
    tcflush(fd, TCIFLUSH); 
    tcsetattr(fd,TCSANOW,&newtio); 
} 
~serial(){ 
    close(fd); 
} 

    std::string sread(){ 
     res = read(fd,buf,255); 
     buf[res]=0; 
     return buf; 
    } 
    void swrite(const char* input){ 
     write(fd,input,sizeof(input)); 
    } 
private: 
    int fd,c,res; 
    struct termios oldtio,newtio; 
    char buf[255]; 
}; 


int main(){ 
    serial s; 
    s.swrite("Light"); 
    std::string buf = s.sread(); 
    std::cout << buf; 
} 

Ceci est plus un ripoff de "programmation série COMMENT": http://tldp.org/HOWTO/Serial-Programming-HOWTO/ (forment le code exemple ..)

Et voici le nouveau pauvre code arduino:

int x; 
String buff; 
int lpin = A0; 
int tpin = A1; 
int data; 
void setup() { 
    Serial.begin(9600); 
    pinMode(lpin,INPUT); 
    pinMode(tpin,INPUT); 
} 
void loop() { 
    if(Serial.available() == 1) 
    { 
    buff = Serial.readString(); 
    if(buff == "Light"){ 
     data = analogRead(lpin); 
     Serial.print(data); 
     Serial.print("\n"); 
    }else if(buff == "Temp"){ 
     data = analogRead(tpin); 
     Serial.print(data); 
     Serial.print("\n"); 
    }else{ 
     Serial.print("Something went wrong !"); 
     Serial.print("\n"); 
    } 
    } 
    delay(1); 
}