Я пытаюсь прочитать данные из 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 через последовательный порт и публикации его в тему/xbee с частотой 10 Гц.
#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;
}
1) Примечание: Если 'c_cflag' поле кода является шире, чем' unsigned', то '& = ~ various_int_constants;' может быть проблемой. 'tty-> c_cflag | = PARENB; tty-> c_cflag^= PARENB; 'избегает этой редкой проблемы. 2) Отправьте код, который вызывает 'xbee_read()' и другие 2 функции. – chux
Спасибо @chux вы положили меня на путь двойной проверки всех c_cflags – raab
* «Я всегда читаю данные и получаю ошибку -1.» * - Тогда вам нужно получить доступ к глобальной переменной ** errno ** to получить информацию об ошибке. Коренная проблема заключается в том, что вы используете неблокирующий режим. См. Http://stackoverflow.com/questions/1613916/linux-serial-port-read-returning-eagain – sawdust