2017-04-16 161 views
0

我想从arduino读取串口。我用这个代码:在linux下读取arduino串行使用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)); 
} 

我的Arduino的运行速度非常的简单草图:

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

这combinatin的输出是:

??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 ?? 

我的问题是如何使顺序出混沌。我发现这个问题发生在缓冲区结束并且新的开始时(更大的缓冲区更少的垃圾数据),但是我不能有无限的缓冲区。第一次读取时也有很多垃圾..有没有办法同步它或什么?

(还有我不是以英语为母语对不起任何错误。)

+0

尝试检查read'的'的返回值。 –

+0

@DavidCullen我启用了cannonical输入,现在垃圾只发生在行的开头..所以我现在假设它有一些额外的位输入..但我不知道从哪里(这是3字符,3个字节)。 – Kozlowsqi

+0

一面注意,试图增加波特率,看它是否解决了这个问题? – LethalProgrammer

回答

0

我找到答案,我自己的问题。我这次用C++来组织它的类(一个非常差的,因为它不处理任何错误,并在最不使用C++。)下面是代码:

#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; 
} 

这是更多的从“串行编程如何”一个骗人货:http://tldp.org/HOWTO/Serial-Programming-HOWTO/(形成的示例代码。)

这里是新穷人的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); 
}