Problems with Serial port code for Ros
I wanted the ROS pc to communicate over the UART with a microcontroller on mobile robot, I canot use ros serial as on the controller I canot use C++ code, so I have used a wrapper code for serial port in linux following the example code from this link: https://code.google.com/p/team-diana/...
My code is as follows:
#define DEFAULT_BAUDRATE 115200
#define DEFAULT_SERIALPORT "/dev/ttyUSB0"
//Global data
FILE *fpSerial = NULL; //serial port file pointer
ros::Publisher ucResponseMsg;
ros::Subscriber ucCommandMsg;
int ucIndex; //ucontroller index number
int FileDesc;
unsigned char crc_sum=0;
//Initialize serial port, return file descriptor
FILE *serialInit(char * port, int baud)
{
int BAUD = 0;
int fd = -1;
struct termios newtio, oldtio;
FILE *fp = NULL;
//Open the serial port as a file descriptor for low level configuration
// read/write, not controlling terminal for process,
fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
ROS_INFO("FileDesc : %d",fd);
if ( fd<0 )
{
ROS_ERROR("serialInit: Could not open serial device %s",port);
return fp;
}
// save current serial port settings
tcgetattr(fd,&oldtio);
// clear the struct for new port settings
bzero(&newtio, sizeof(newtio));
//Look up appropriate baud rate constant
switch (baud)
{
case 38400:
default:
BAUD = B38400;
break;
case 19200:
BAUD = B19200;
break;
case 115200:
BAUD = B115200;
break;
case 9600:
BAUD = B9600;
break;
case 4800:
BAUD = B4800;
break;
case 2400:
BAUD = B2400;
break;
case 1800:
BAUD = B1800;
break;
case 1200:
BAUD = B1200;
break;
} //end of switch baud_rate
if (cfsetispeed(&newtio, BAUD) < 0 || cfsetospeed(&newtio, BAUD) < 0)
{
ROS_ERROR("serialInit: Failed to set serial baud rate: %d", baud);
close(fd);
return NULL;
}
// set baud rate, (8bit,noparity, 1 stopbit), local control, enable receiving characters.
newtio.c_cflag = BAUD | CRTSCTS | CS8 | CLOCAL | CREAD;
// ignore bytes with parity errors
newtio.c_iflag = IGNPAR;
// raw output
newtio.c_oflag = 0;
// set input mode to non - canonical
newtio.c_lflag = 0;
// inter-charcter timer
newtio.c_cc[VTIME] = 0;
// blocking read (blocks the read until the no.of charcters are read
newtio.c_cc[VMIN] = 0;
// clean the line and activate the settings for the port
tcflush(fd, TCIFLUSH);
tcsetattr (fd, TCSANOW,&newtio);
//Open file as a standard I/O stream
fp = fdopen(fd, "r+");
if (!fp) {
ROS_ERROR("serialInit: Failed to open serial stream %s", port);
fp = NULL;
}
ROS_INFO("FileStandard I/O stream: %d",fp);
return fp;
} //serialInit
//Process ROS command message, send to uController
void ucCommandCallback(const geometry_msgs::TwistConstPtr& cmd_vel)
{
unsigned char msg[14];
float test1,test2;
unsigned long i;
// build the message packet to be sent
msg = packet to be sent;
msg[13] = crc_sum;
for (i=0;i<14;i++)
{
fprintf(fpSerial, "%c", msg[i]);
}
tcflush(FileDesc, TCOFLUSH);
} //ucCommandCallback
//Receive command responses from robot uController
//and publish as a ROS message
void *rcvThread(void *arg)
{
int rcvBufSize = 200;
char ucResponse[10];//[rcvBufSize]; //response string from uController
char *bufPos;
std_msgs::String msg;
std::stringstream ss;
int BufPos,i;
unsigned char crc_rx_sum =0;
while (ros::ok()) {
BufPos = fread((void*)ucResponse,1,10,fpSerial);
for (i=0;i<10;i++)
{
ROS_INFO("T: %x ",(unsigned char)ucResponse[i]);
ROS_INFO("NT: %x ",ucResponse[i]);
}
msg.data = ucResponse;
ucResponseMsg.publish(msg ...