I'm trying to read data from an Xbee over serial. If I initialize the port by calling xbee_init() then I call xbee_read() For some reason I always read no data and get an error of -1. However the moment I use some third party program like gtkterm or the Arduino serial monitor to look at the port I suddenly start reading data from my program. It will then work properly until I end my program and restart it, then it's back to reading no data.
Does anyone have an idea why this is happening? I've tested this with both an Xbee and Arduino and it's the same behavior. I'm calling these functions from a larger C++ program. Thanks!
#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);
}
Here is the main function that calls my xbee functions. This is part of a ROS project and this node is designed to simply read data from the xbee over serial and publish it to the /xbee topic at 10Hz.
#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;
}