写完后从串口读取

我正在开发一个项目,让我的计算机与arduino板通信,读取传感器输出并仅在收到“t”时将其放在串口上。如下所示的arduino代码正常工作。

const int inputPin = 0; void setup(){ Serial.begin(9600); pinMode(13, OUTPUT);} void loop(){ if (Serial.available() > 0){ char c=Serial.read(); if(c=='t'){ int value = analogRead(inputPin); float celsius = (5.0 * value * 100.0)/1024.0; Serial.println(celsius); } } } 

当我试图读取arduino放在串口上的内容时,我的问题出现在C代码中。 我的C代码是:

 #include #include #include #include #include #include int main(){ int STATE_OK=0; int STATE_WARNING=1; int STATE_CRITICAL=2; char tempbuf[10]; int fd=open("/dev/ttyACM0",O_RDWR | O_NOCTTY | O_NONBLOCK); if(fd == -1){ printf("Unable to open /dev/ttyACM0\n"); return STATE_WARNING; } else { fcntl(fd, F_SETFL, FNDELAY); int w=write(fd, "t", 1); printf("The number of bytes written to the serial port is %d \n",w); fprintf(stderr, "fd = %d.\n", fd); sleep(10); int n=read(fd,tempbuf,5); printf("%d,%s \n",n,strerror(errno)); if(n>0){ float temp=atof(tempbuf); printf("Temperature is: %f Celsius\n", temp); if (temp>27){ return STATE_CRITICAL; }else{ printf("The temperature is %f Celsius and checked 10 seconds ago\n",temp); return STATE_OK; } } } close(fd); return 0; } 

n总是= 0,我无法弄清楚问题是什么。 提前致谢。

我无法弄清楚问题是什么

一个大问题是在“计算机”上运行的C程序是不完整的。

Arduino的程序执行至少波特率的串行端口设置(以及默认情况下可能执行的任何其他操作)。
但“计算机”C程序从未正确配置串口 。 串行端口将使用先前配置的任何属性(波特率,数据长度,奇偶校验设置,规范与原始模式),这将导致不可预测的读取和写入。 (环回测试可能会产生误报结果。)

使用POSIX串行端口指南或此答案获取示例代码。

对于规范模式,您可能需要添加代码(假设为8N1):

  rc = tcgetattr(fd, &tty); if (rc < 0) { /* handle error */ } savetty = tty; /* preserve original settings for restoration */ spd = B9600; cfsetospeed(&tty, (speed_t)spd); cfsetispeed(&tty, (speed_t)spd); tty.c_cflag &= ~PARENB tty.c_cflag &= ~CSTOPB tty.c_cflag &= ~CSIZE; tty.c_cflag |= CS8; tty.c_cflag &= ~CRTSCTS; /* no HW flow control? */ tty.c_cflag |= CLOCAL | CREAD; tty.c_iflag |= IGNPAR | IGNCR; tty.c_iflag &= ~(IXON | IXOFF | IXANY); tty.c_lflag |= ICANON; tty.c_oflag &= ~OPOST; rc = tcsetattr(fd, TCSANOW, &tty); if (rc < 0) { /* handle error */ } 

你可能应该删除该行

 fcntl(fd, F_SETFL, FNDELAY); 

以及open()调用中的O_NONBLOCK选项。

试试这个

 int n=read(fd,&tempbuf,sizeof(tempbuf)); 

代替

 int n=read(fd,tempbuf,5); 

你不应该终止用’\ 0’发送的数据吗? 哔叽

阅读read()的描述(如下所示)告诉我们当你到达文件末尾时n = 0。 由于串行未发送\ 0,因此读取将继续,直到到达文件末尾。 因此我认为n == 0是你想要的结果。

所以,也许你的if(n> 0)

测试应该是if(n == 0)

你能用调试器在缓冲区中看到你期望的字符吗?

read()#include int read(int handle,void * buffer,int nbyte);

read()函数尝试从与handle关联的文件中读取nbytes,并将读取的字符放入缓冲区。 如果使用O_TEXT打开文件,它将删除回车并检测文件的结尾。

该函数返回读取的字节数。 在文件结束时,返回0,错误时返回-1,设置errno以指示发生的错误类型。

谢谢您的回答。 这是我的最终代码:

 #include #include #include #include #include #include #include int main() { int STATE_OK=0; int STATE_WARNING=1; int STATE_CRITICAL=2; char tempbuf[10]; struct termios tty; int fd=open("/dev/ttyACM1",O_RDWR | O_NOCTTY); if(fd == -1){ printf("Unable to open /dev/ttyACM1\n"); return STATE_WARNING; }else { if(tcgetattr(fd, &tty)!=0){ perror("tcgetatt() error"); }else{ cfsetospeed(&tty, B9600); cfsetispeed(&tty, B9600); tty.c_cflag &= ~PARENB; tty.c_cflag &= ~CSTOPB; tty.c_cflag &= ~CSIZE; tty.c_cflag |= CS8; tty.c_cflag &= ~CRTSCTS; tty.c_cflag |= CLOCAL | CREAD; tty.c_iflag |= IGNPAR | IGNCR; tty.c_iflag &= ~(IXON | IXOFF | IXANY); tty.c_lflag |= ICANON; tty.c_oflag &= ~OPOST; tcsetattr(fd, TCSANOW, &tty); int w=write(fd, "t", 1);/*printf("%d\n",w); fprintf(stderr, "fd = %d.\n", fd);*/ usleep(1000); int n=read(fd,tempbuf,8);/*printf("%d \n",n);*/ tempbuf[9]=0; float temp=atof(tempbuf); if (temp>27){ printf("CRITICAL: %f celsius\n",temp); return STATE_CRITICAL; }else{ printf("Everything is OK and the temperature is %f Celsius\n",temp); return STATE_OK; } } } close(fd); return 0; }