Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "serialIO.h"
00019 #include "sys/select.h"
00020 #include <iostream>
00021 #include <cstring>
00022
00023 #include <ros/ros.h>
00024
00025 SerialIO::SerialIO() :
00026 _fd(-1), _device_string(""), _baudrate(9600)
00027 {
00028 }
00029
00030 SerialIO::~SerialIO()
00031 {
00032 stop();
00033 closePort();
00034 }
00035
00036
00037 int SerialIO::openPort(std::string devicestring, int baudrate)
00038 {
00039 if(_fd != -1) return _fd;
00040
00041 _device_string = devicestring;
00042 _baudrate = baudrate;
00043
00044 speed_t baud = getBaudFromInt(baudrate);
00045 std::memset(&port_settings,0,sizeof(port_settings));
00046 port_settings.c_iflag = 0;
00047 port_settings.c_oflag = 0;
00048 port_settings.c_cflag = CS8|CREAD|CLOCAL;
00049 port_settings.c_lflag = 0;
00050 port_settings.c_cc[VMIN]=1;
00051 port_settings.c_cc[VTIME]=5;
00052
00053 _fd=open(devicestring.c_str(), O_RDWR | O_NONBLOCK);
00054 cfsetospeed(&port_settings, baud);
00055 cfsetispeed(&port_settings, baud);
00056
00057 tcsetattr(_fd, TCSANOW, &port_settings);
00058
00059 return _fd;
00060 }
00061
00062
00063 int SerialIO::sendData(std::string value)
00064 {
00065 boost::mutex::scoped_lock lock(_mutex);
00066 int wrote = -1;
00067 if(_fd != -1)
00068 wrote = write(_fd, value.c_str(), value.length());
00069 return wrote;
00070 }
00071
00072
00073 int SerialIO::sendData(const char* data, size_t len)
00074 {
00075 boost::mutex::scoped_lock lock(_mutex);
00076 int wrote = -1;
00077 if(_fd != -1)
00078 wrote = write(_fd, data, len);
00079 return wrote;
00080 }
00081
00082
00083 int SerialIO::readData(std::string &value, size_t nBytes)
00084 {
00085 boost::mutex::scoped_lock lock(_mutex);
00086 fd_set fds;
00087 FD_ZERO(&fds);
00088 FD_SET(_fd, &fds);
00089 struct timeval timeout = {0, 100000};
00090 char buffer[32];
00091 size_t rec = -1;
00092 if(select(_fd+1, &fds, NULL, NULL, &timeout))
00093 {
00094 rec = read(_fd, buffer, nBytes);
00095 value = std::string(buffer, rec);
00096 }
00097
00098 return rec;
00099 }
00100
00101 void SerialIO::start()
00102 {
00103 if(_thread == NULL)
00104 _thread.reset(new boost::thread(&SerialIO::run, this));
00105 }
00106
00107 void SerialIO::stop()
00108 {
00109 if(_thread != NULL)
00110 {
00111 _thread->interrupt();
00112 _thread->join();
00113 _thread.reset();
00114 }
00115 }
00116
00117 void SerialIO::run()
00118 {
00119 ros::Rate r(maxUpdateRate);
00120 std::vector<ioData_t> data;
00121 while(true)
00122 {
00123 _oQueue.wait_pop(data);
00124 for(size_t i = 0; i < data.size(); i++)
00125 this->sendData(data[i].buf, data[i].len);
00126 r.sleep();
00127 }
00128 }
00129
00130 void SerialIO::enqueueData(std::vector<ioData_t> data)
00131 {
00132 _oQueue.push(data);
00133 }
00134
00135 void SerialIO::enqueueData(const char* buf, size_t len)
00136 {
00137 struct ioData data;
00138 data.buf=buf;
00139 data.len=len;
00140 std::vector<ioData_t> vec;
00141 vec.push_back(data);
00142 _oQueue.push(vec);
00143 }
00144
00145
00146 bool SerialIO::isOpen()
00147 {
00148 return (_fd != -1);
00149 }
00150
00151
00152 void SerialIO::closePort()
00153 {
00154 if(_fd != -1)
00155 {
00156 close(_fd);
00157 _fd = -1;
00158 }
00159 }
00160
00161 bool SerialIO::recover()
00162 {
00163 closePort();
00164 if(openPort(_device_string, _baudrate))
00165 {
00166 usleep(50000);
00167 tcflush(_fd, TCIOFLUSH);
00168 return true;
00169 }
00170 else
00171 return false;
00172 }
00173
00174
00175 speed_t SerialIO::getBaudFromInt(int baud)
00176 {
00177 speed_t ret;
00178 switch(baud)
00179 {
00180 case 0: ret=B0; break;
00181 case 50: ret=B50; break;
00182 case 75: ret=B75; break;
00183 case 110: ret=B110; break;
00184 case 134: ret=B134; break;
00185 case 150: ret=B150; break;
00186 case 200: ret=B200; break;
00187 case 300: ret=B300; break;
00188 case 1200: ret=B1200; break;
00189 case 1800: ret=B1800; break;
00190 case 2400: ret=B2400; break;
00191 case 4800: ret=B4800; break;
00192 case 9600: ret=B9600; break;
00193 case 19200: ret=B19200; break;
00194 case 38400: ret=B38400; break;
00195 case 57600: ret=B57600; break;
00196 case 115200: ret=B115200; break;
00197 case 230400: ret=B230400; break;
00198 default:
00199 ret=B230400;
00200 break;
00201 }
00202 return ret;
00203 }