rs232.cpp
Go to the documentation of this file.
00001 
00029 #include "sr_communications/serial_port/rs232.h"
00030 
00032 
00033 int Rs232::initCommunication(int baudrate, char *serialDevice, char *semFile)
00034 {
00036 
00037     key_t semKey;
00038     struct termios newtio;
00039 
00040     int error; 
00041 
00042     error = createKey(&semKey, semFile);
00043     if (error < 0) {
00044         ROS_ERROR("Error cretaing semaphore Key");
00045         return (-4);
00046     }
00047     error = getSemID(semKey, &_semID);
00048     if (error < 0) {
00049         ROS_ERROR("Error in getSemID. semKey = %x semFile = %s\n", semKey, semFile);
00050         return (-4);  // Semaphore related error
00051     }
00052 
00053     error = waitSem(_semID);
00054     if (error < 0) {
00055         ROS_ERROR("RS232.c - initCommunication: Error in waitSem\n\r");
00056         freeSem(_semID);
00057         rmSem(_semID);
00058         return (-4);  // Semaphore related error
00059     }
00060 
00061     // Do not use O_NOCTTY, not supported on kernels 2.6.31+
00062     //*RSd = open( serialDevice, O_RDWR | O_NOCTTY );
00063     _RSd = open(serialDevice, O_RDWR | O_NONBLOCK | O_NDELAY);
00064     if (_RSd < 0) {
00065         ROS_ERROR("Error opening serial device: %s", serialDevice);
00066         freeSem(_semID);
00067         rmSem(_semID);
00068         return (-2);
00069     }
00070 
00071     bzero((void*) &newtio, sizeof(newtio));
00072     switch(baudrate) {
00073         case 4800:
00074             newtio.c_cflag = B4800 | CS8 | CLOCAL | CREAD;
00075             break;
00076         case 9600:
00077             newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
00078             break;
00079         case 19200:
00080             newtio.c_cflag = B19200 | CS8 | CLOCAL | CREAD;
00081             break;
00082         case 38400:
00083             newtio.c_cflag = B38400 | CS8 | CLOCAL | CREAD;
00084             break;
00085         case 57600:
00086             newtio.c_cflag = B57600 | CS8 | CLOCAL | CREAD;
00087             break;
00088         case 115200:
00089             newtio.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
00090             break;
00091         default:
00092             newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
00093     }
00094     newtio.c_iflag = IGNPAR | ICRNL;
00095     newtio.c_oflag = 0;
00096     //newtio.c_lflag |= (ICANON | ECHO | ECHOE);                //modo canonico
00097     newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);  //modo raw
00098     newtio.c_cc[VINTR] = 0;
00099     newtio.c_cc[VQUIT] = 0;
00100     newtio.c_cc[VERASE] = 0;
00101     newtio.c_cc[VKILL] = 0;
00102     newtio.c_cc[VEOF] = 4;
00103     newtio.c_cc[VSWTC] = 0;
00104     newtio.c_cc[VSTART] = 0;
00105     newtio.c_cc[VSTOP] = 0;
00106     newtio.c_cc[VSUSP] = 0;
00107     newtio.c_cc[VEOL] = 0;
00108     newtio.c_cc[VREPRINT] = 0;
00109     newtio.c_cc[VDISCARD] = 0;
00110     newtio.c_cc[VWERASE] = 0;
00111     newtio.c_cc[VLNEXT] = 0;
00112     newtio.c_cc[VEOL2] = 0;
00113     newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
00114     newtio.c_cc[VMIN] = 0;   //1  /* blocking read until 1 chars received */
00115     tcflush(_RSd, TCIFLUSH);
00116     tcflush(_RSd, TCOFLUSH);
00117 
00118     if (tcsetattr(_RSd, TCSANOW, &newtio)) {
00119         ROS_ERROR("Error configurating serial port dev = %s\n", serialDevice);
00120         freeSem(_semID);
00121         rmSem(_semID);
00122         return -1;
00123     }
00124 
00125     if (tcflush(_RSd, TCIOFLUSH) < 0) {
00126         ROS_ERROR("Error flushing serial port dev = %s\n", serialDevice);
00127         freeSem(_semID);
00128         rmSem(_semID);
00129         return -1;
00130     }
00131 
00132     freeSem(_semID);
00133 
00134     return ERR_NOERR;
00135 }
00136 
00138 
00139 int Rs232::endCommunication()
00140 {
00141     waitSem(_semID);
00142     close(_RSd);
00143     freeSem(_semID);
00144 
00145     return rmSem(_semID);
00146 }
00147 
00149 
00150 int Rs232::writeToRS232(char* command, int commandSize)
00151 {
00152     if (waitSem(_semID) < ERR_NOERR) {
00153         ROS_ERROR("Error when waiting the semaphore\n\r");
00154         freeSem(_semID);
00155         return ERR_SEM;
00156     }
00157 
00158     if (write(_RSd, command, commandSize) <= ERR_NOERR) {
00159         ROS_ERROR("Error when writing in the serial port file descriptor\n\r");
00160         freeSem(_semID);
00161         return ERR_WRI;
00162     }
00163 
00164     freeSem(_semID);
00165     return ERR_NOERR;
00166 }
00167 
00169 
00170 int Rs232::readFromRS232(char * buff)
00171 {
00172     int i = 0;
00173     //int timeOut = SP_READ_TIMEOUT;
00174     int readResult;
00175     int status = 1;
00176     int bytes = 0;          
00177 
00178     struct timeval before, now;
00179 
00180     if (waitSem(_semID) < ERR_NOERR) {
00181         ROS_ERROR("Error when waiting the semaphore\n\r");
00182         freeSem(_semID);
00183         return ERR_SEM;
00184     }
00185 
00186     gettimeofday(&before, 0);
00187     do {                                // Begin reading from the serial port
00188 
00189         ioctl(_RSd, FIONREAD, &bytes);   // Check if there is some information
00190         if (bytes > 0) {                // There is information buffer ready to be readed
00191             readResult = read(_RSd, &buff[i], 1);
00192             if (readResult < 0) {
00193                 ROS_ERROR("Reading Error");
00194                 freeSem(_semID);
00195                 return (ERR_READ);
00196             }
00197             else {
00198                 i += readResult;        // Add to i the number of readed bytes
00199             }
00200 
00201             if (i > 1) {
00202                 if ((buff[i - 2] == '\n') && (buff[i - 1] == '\n')) {
00203                     status = 0;         // We have readed data from the serial port
00204                 }
00205             }
00206         }
00207 
00208         gettimeofday(&now, 0);
00209         if (SP_READ_TIMEOUT < timeDifferenceMsec(&before, &now)) {
00210             freeSem(_semID);
00211             return (ERR_TIMEOUT);
00212         }
00213 
00214         usleep(1);
00215     }
00216     while(status);
00217 
00218     freeSem(_semID);
00219 
00220     return (status);
00221 }
00222 
00224 
00225 int Rs232::askToRS232(char *command, int commandSize, char *response)
00226 {
00227     int i = 0;
00228     //int timeOut = SP_READ_TIMEOUT;
00229     int readResult;
00230     int status = 1;
00231     int bytes = 0;          
00232 
00233     struct timeval before, now;
00234 
00235     if (waitSem(_semID) < ERR_NOERR) {
00236         ROS_ERROR("Error when waiting the semaphore\n\r");
00237         freeSem(_semID);
00238         return ERR_SEM;
00239     }
00240 
00241     // Sending the command to the serial port
00242     if (write(_RSd, command, commandSize) <= ERR_NOERR) {
00243         ROS_ERROR("Error when asking (writing) to the serial port file descriptor\n\r");
00244         freeSem(_semID);
00245         return ERR_WRI;
00246     }
00247 
00248     // Reading the response from the serial port
00249     gettimeofday(&before, 0);
00250     do {                             // Begin reading from the serial port
00251 
00252         ioctl(_RSd, FIONREAD, &bytes); // Check if there is some information
00253         if (bytes > 0) {        // There is information buffer ready to be readed
00254             readResult = read(_RSd, &response[i], 1);
00255             if (readResult < 0) {
00256                 ROS_ERROR("Reading Error");
00257                 freeSem(_semID);
00258                 return (ERR_READ);
00259             }
00260             else {
00261                 i += readResult;                // Add to i the number of readed bytes
00262             }
00263 
00264             if (i > 1) {
00265                 if ((response[i - 2] == '\n') && (response[i - 1] == '\n')) {
00266                     status = ERR_NOERR;         // We have readed data from the serial port
00267                 }
00268             }
00269         }
00270 
00271         gettimeofday(&now, 0);
00272         if (SP_READ_TIMEOUT < timeDifferenceMsec(&before, &now)) {
00273             freeSem(_semID);
00274             ROS_ERROR("Timeout Error. Error when asking to the serial port file descriptor\n\r");
00275             ROS_ERROR("status : %d\n", status);
00276             return (ERR_TIMEOUT);
00277         }
00278         usleep(100);
00279     }
00280     while(status);
00281 
00282     freeSem(_semID);
00283 
00284     return (status);
00285 }
00286 
00288 
00290 
00291 int Rs232::readSerial(char *response, int responseSize)
00292 {
00293     int i = 0;
00294     int readResult;
00295     int status = 1;
00296     int bytes = 0;          
00297 
00298     struct timeval before, now;
00299 
00300     gettimeofday(&before, 0);
00301     do {                                // Begin reading from the serial port
00302 
00303         ioctl(_RSd, FIONREAD, &bytes);   // Check if there is some information
00304         if (bytes > 0) {                // There is information buffer ready to be readed
00305             readResult = read(_RSd, &response[i], responseSize);
00306 
00307             if (readResult < 0) {
00308                 ROS_ERROR("Reading Error: %d.", readResult);
00309                 freeSem(_semID);
00310                 return (ERR_READ);
00311             }
00312             else if (readResult == 0) {
00313                 //ha llegado al final del fichero, pero no entraría porque comprobamos que haya datos con ioctl
00314                 ROS_ERROR("Reading Error: EOF reached");
00315                 freeSem(_semID);
00316                 return (ERR_READ);
00317             }
00318             else {
00319                 i += readResult;        // Add to i the number of readed bytes
00320             }
00321 
00322             //we have readed the desired data
00323             if (i == responseSize) {
00324                 status = 0;         // We have readed data from the serial port
00325             }
00326         }
00327 
00328         gettimeofday(&now, 0);
00329         if (SPLT_READ_TIMEOUT < timeDifferenceMsec(&before, &now)) {
00330             freeSem(_semID);
00331             ROS_ERROR("Timeout ERROR while reading");
00332             return (ERR_TIMEOUT);
00333         }
00334 
00335         // do not delete this usleep
00336         usleep(500);
00337 
00338     }
00339     while(status);
00340 
00341     //devolvemos el número de caracteres leídos
00342     return (i);
00343 }
00344 
00346 
00347 int Rs232::askToSerial(char *command, int commandSize, char *response, int responseSize)
00348 {
00349     int i = 0;
00350     int readResult;
00351     int status = 1;
00352     int bytes = 0;          
00353 
00354     struct timeval before, now;
00355 
00356     // Sending the command to the serial port
00357     if (write(_RSd, command, commandSize) <= ERR_NOERR) {
00358         ROS_ERROR("Error when asking (writing) to the serial port file descriptor\n\r");
00359         freeSem(_semID);
00360         return ERR_WRI;
00361     }
00362 
00363     // Reading the response from the serial port
00364     gettimeofday(&before, 0);
00365     do {                                // Begin reading from the serial port
00366 
00367         ioctl(_RSd, FIONREAD, &bytes);   // Check if there is some information
00368         if (bytes > 0) {                // There is information buffer ready to be readed
00369             readResult = read(_RSd, &response[i], responseSize);
00370 
00371             if (readResult < 0) {
00372                 ROS_ERROR("Reading Error: %d.", readResult);
00373                 freeSem(_semID);
00374                 return (ERR_READ);
00375             }
00376             else if (readResult == 0) {
00377                 //ha llegado al final del fichero, pero no entraría porque comprobamos que haya datos con ioctl
00378                 ROS_ERROR("Reading Error: EOF reached");
00379                 freeSem(_semID);
00380                 return (ERR_READ);
00381             }
00382             else {
00383                 i += readResult;        // Add to i the number of readed bytes
00384             }
00385 
00386             //we have readed the desired data
00387             if (i == responseSize) {
00388                 status = 0;         // We have readed data from the serial port
00389             }
00390         }
00391 
00392         gettimeofday(&now, 0);
00393         if (SPLT_READ_TIMEOUT < timeDifferenceMsec(&before, &now)) {
00394             freeSem(_semID);
00395             ROS_ERROR("Timeout ERROR while reading (asking)");
00396             return (ERR_TIMEOUT);
00397         }
00398 
00399         // do not delete this usleep
00400         usleep(500);
00401 
00402     }
00403     while(status);
00404 
00405     return (i);
00406 }
00407 
00409 
00410 long int Rs232::timeDifferenceMsec(struct timeval *before, struct timeval *after)
00411 {
00413     return ((after->tv_sec - before->tv_sec) * 1000 + (after->tv_usec - before->tv_usec) / 1000);
00414 }
00415 


sr_communications
Author(s): Raul Perula-Martinez , Victor Gonzalez
autogenerated on Wed Aug 26 2015 16:26:47