serialIO.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *   http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
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 // Open Serial Port
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 // Send Data to Serial Port
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 // Send Data to Serial Port
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 // Read Data from Serial Port
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 // Check if Serial Port is opened
00146 bool SerialIO::isOpen()
00147 {
00148         return (_fd != -1);
00149 }
00150 
00151 // Close Serial Port
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 }


cob_light
Author(s): Benjamin Maidel
autogenerated on Sat Jun 8 2019 21:02:07