gpt4 book ai didi

c++ - 除非第三方程序打开端口,否则无法读取串行数据

转载 作者:行者123 更新时间:2023-11-30 16:55:12 25 4
gpt4 key购买 nike

我正在尝试通过串行方式从 Xbee 读取数据。如果我通过调用 xbee_init() 初始化端口,那么我会调用 xbee_read() 出于某种原因,我总是读取不到数据并收到 -1 错误。然而,当我使用 gtkterm 或 Arduino 串行监视器等第三方程序来查看端口时,我突然开始从程序中读取数据。然后它将正常工作,直到我结束程序并重新启动它,然后它又回到不读取数据的状态。

有人知道为什么会发生这种情况吗?我已经用 Xbee 和 Arduino 对此进行了测试,结果是相同的。我从一个更大的 C++ 程序中调用这些函数。谢谢!

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <termios.h>
#include "../include/m545_wireless_communication/readXbee.h"

int xbee_init (char *port, struct termios *tty) {

int fd=open(port,O_RDWR | O_NOCTTY | O_NONBLOCK);

if(fd == -1){return 0;}
else {
if(tcgetattr(fd, tty)!=0){return 0;}
else{
cfsetospeed(tty, B57600);
cfsetispeed(tty, B57600);

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);

}
}

return fd;
}


char* xbee_read (int fd, char *buffer) {

if(fd){
int n=read(fd,buffer,11);
printf("%d\n", n);
return buffer;
}else{
return NULL;
}
}

void xbee_close(int fd){
close(fd);
}

这是调用我的 xbee 函数的主函数。这是 ROS 项目的一部分,该节点旨在通过串行方式简单地从 xbee 读取数据并将其以 10Hz 发布到/xbee 主题。

#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
#include <termios.h>
#include "m545_wireless_communication/readXbee.h"


int main(int argc, char **argv)
{

ros::init(argc, argv, "Broadcaster");

ros::NodeHandle broadcasterHandle;
ros::Publisher broadPub = broadcasterHandle.advertise<std_msgs::String>("xbee", 1);

char *port = "/dev/ttyUSB1";
struct termios tty;
char buffer[11];

int fd = xbee_init(port,&tty);

ros::Rate loop_rate(10);

while (ros::ok())
{
char *message = xbee_read(fd, buffer);

std_msgs::String msg;

std::stringstream ss;
ss << message;
msg.data = ss.str();

ROS_INFO("I heard: %s", msg.data.c_str());

broadPub.publish(msg);

ros::spinOnce();

loop_rate.sleep();
}

ROS_INFO("Closing Port");
xbee_close(fd);

return 0;
}

最佳答案

我发现问题出在我声明 c_cflags 的方式上。 Xbee 需要以原始模式读取,因此我没有自己设置标志,而是使用了 cfmakeraw()。但是我仍然不确定我到底做错了什么,或者使用第三方程序打开端口如何帮助连接。

int xbee_init (char *port, struct termios *tty) {

int fd=open(port,O_RDWR | O_NOCTTY | O_NONBLOCK);

if(fd == -1){return 0;}//should be something better
else {
if(tcgetattr(fd, tty)!=0){return 0;}
else{
// cfsetospeed(tty, B57600);
// cfsetispeed(tty, B57600);

// 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_cflag |= PARENB;
// // tty->c_cflag ^= PARENB;

// tty->c_iflag |= IGNPAR | IGNCR;
// tty->c_iflag &= ~(IXON | IXOFF | IXANY);
// tty->c_lflag |= ICANON;
// tty->c_oflag &= ~OPOST;

cfmakeraw(&tty);
cfsetispeed(&tty, B57600);

tcsetattr(fd, TCSANOW, &tty);

}
}

return fd;
}

关于c++ - 除非第三方程序打开端口,否则无法读取串行数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40364467/

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