gpt4 book ai didi

c - 使用 C 在 Linux 中使用 USB 串行电缆从传感器串行读取

转载 作者:太空宇宙 更新时间:2023-11-04 10:03:59 24 4
gpt4 key购买 nike

我一直在尝试使用 USB 转串行转换器读取串行温度传感器的响应,该传感器连接到我的树莓派。

我可以看到写入传感器设备似乎有效。但是,当我尝试从串行芯片读回时,读取失败并返回 -1。

我确实尝试使用 realterm 程序使用相同的波特率 9600 8 位无奇偶校验设置,并且能够按预期读写十六进制值,请指出正确的方向。

void serial_write(char parameter,char value) {
int fd;
uint8_t bytes_wr;
char wr_buffer[3];
fd = open("/dev/ttyUSB0",O_RDWR | O_NOCTTY | O_NDELAY);

if (fd == -1)
ERROR("Error! in Opening ttyUSB0 \n");
else
DEBUG("ttyUSB0 Opened Successfully \n");

struct termios SerialPortSettings;
tcgetattr(fd, &SerialPortSettings);

cfsetispeed(&SerialPortSettings,B9600);
cfsetospeed(&SerialPortSettings,B9600);

SerialPortSettings.c_cflag &= ~PARENB;
SerialPortSettings.c_cflag &= ~CSTOPB;
SerialPortSettings.c_cflag &= ~CSIZE;
SerialPortSettings.c_cflag |= CS8;
SerialPortSettings.c_cflag &= ~CRTSCTS;
SerialPortSettings.c_cflag |= CREAD | CLOCAL;
SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);
SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
SerialPortSettings.c_oflag &= ~OPOST;

if ((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0)
ERROR("ERROR ! in Setting attributes \n");
else
DEBUG("BaudRate=9600\tStopBits=1\tParity=none \n");

wr_buffer[0] = write;
wr_buffer[1] = parameter;
wr_buffer[2] = value;

bytes_wr = write(fd, wr_buffer,sizeof(wr_buffer));
DEBUG("Total Bytes written: %d \n", sizeof(wr_buffer));

close(fd);
}

上面的函数似乎按预期写入串口,但是当我尝试读取时,读取失败并返回 -1

char serial_read(char parameter) {
int fd, read_length, i;
uint8_t bytes_wr;
char wr_buffer[2];
fd = open("/dev/ttyUSB0",O_RDWR | O_NOCTTY | O_NDELAY);

if (fd == -1)
ERROR("Error! in Opening ttyUSB0 \n");
else
DEBUG("ttyUSB0 Opened Successfully \n");

struct termios SerialPortSettings;
tcgetattr(fd, &SerialPortSettings);

cfsetispeed(&SerialPortSettings,B9600);
cfsetospeed(&SerialPortSettings,B9600);

SerialPortSettings.c_cflag &= ~PARENB;
SerialPortSettings.c_cflag &= ~CSTOPB;
SerialPortSettings.c_cflag &= ~CSIZE;
SerialPortSettings.c_cflag |= CS8;
SerialPortSettings.c_cflag &= ~CRTSCTS;
SerialPortSettings.c_cflag |= CREAD | CLOCAL;
SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);
SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
SerialPortSettings.c_oflag &= ~OPOST;

if ((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0)
ERROR("ERROR ! in Setting attributes \n");
else
DEBUG("BaudRate=9600\tStopBits=1\tParity= none\n");

wr_buffer[0] = read;
wr_buffer[1] = parameter;

bytes_wr = write(fd, wr_buffer,sizeof(wr_buffer));
DEBUG("Total Bytes written: %d \n", sizeof(wr_buffer));
usleep(8000);
tcflush(fd,TCIFLUSH);
char rd_buffer[4];
read_length = read(fd, rd_buffer,sizeof(rd_buffer));
DEBUG("Total bytes read = %d \n",read_length);

for (i==0;i<read_length;i++){
DEBUG("rd_buffer[%d]=%x \n",i,rd_buffer[i]);
}
close(fd);
return rd_buffer[0];
}

使用 realterm windows 应用程序,所有写入和读取似乎都可以正常工作。

最佳答案

来自 open(2) 联机帮助页:

   O_NONBLOCK or O_NDELAY
When possible, the file is opened in nonblocking mode.
Neither the open() nor any subsequent operations on the file
descriptor which is returned will cause the calling process to
wait.

对于串行连接,最终结果将是,如果您要求从串行端口读取一些字节并且没有字符等待,则读取将返回 -1 并且 'errno' 可能是 EAGAIN 或EWOULDBLOCK.

因此您的 usleep(8000) 可能是尝试等待足够长的时间让设备响应,但设备可能没有您的数据;特别是如果它处于 adc 操作的中间,它可能需要超过 8ms 的时间。

您可以做一些事情:

你可以(用伪代码):

int retries=10;
while(retries--) {
read_length = read(fd, rd_buffer,sizeof(rd_buffer));
if(read_length > 0)
break;
usleep(1000);
}

不幸的是,这样做的一个副作用是,如果温度传感器向您发送一个冗长的字符串,而您的程序在温度传感器仍在写入时读取(),您将得到一个部分字符串。因此,如果您知道正在等待接收的字符串的长度,则可以使用 ioctl() 来找出正在等待的字符数:

ioctl(fd, FIONREAD, &bytes_avail);

所以伪代码看起来更像:

int retries=10;
int bytes_avail=0;
while(retries--) {
if (ioctl(fd, FIONREAD, &bytes_avail) < 0) {
fprintf(stderr, "ioctl failed\n");
return; // Do something here
}
if (bytes_avail >= sizeof(rd_buffer)) {
read_length = read(fd, rd_buffer,sizeof(rd_buffer));
if(read_length > 0)
break;
}
usleep(1000);
}

如果温度传感器发送以换行符或回车符结尾的 ascii 字符串,则代码看起来会有所不同。

关于c - 使用 C 在 Linux 中使用 USB 串行电缆从传感器串行读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53914467/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com