rq_sensor_com.cpp
Go to the documentation of this file.
00001 /* Software License Agreement (BSD License)
00002 *
00003 * Copyright (c) 2014, Robotiq, Inc.
00004 * All rights reserved.
00005 *
00006 * Redistribution and use in source and binary forms, with or without
00007 * modification, are permitted provided that the following conditions
00008 * are met:
00009 *
00010 * * Redistributions of source code must retain the above copyright
00011 * notice, this list of conditions and the following disclaimer.
00012 * * Redistributions in binary form must reproduce the above
00013 * copyright notice, this list of conditions and the following
00014 * disclaimer in the documentation and/or other materials provided
00015 * with the distribution.
00016 * * Neither the name of Robotiq, Inc. nor the names of its
00017 * contributors may be used to endorse or promote products derived
00018 * from this software without specific prior written permission.
00019 *
00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 * POSSIBILITY OF SUCH DAMAGE.
00032 *
00033 * Copyright (c) 2014, Robotiq, Inc
00034 */
00035 
00043 
00044 //Includes
00045 
00046 //Platform specific
00047 #ifdef __unix__ /*For Unix*/
00048 #define _BSD_SOURCE
00049 #include <termios.h>
00050 #include <unistd.h>
00051 #elif defined(_WIN32)||defined(WIN32) /*For Windows*/
00052 #include <windows.h>
00053 #endif
00054 
00055 #include <dirent.h>
00056 #include <string.h>
00057 #include <unistd.h>
00058 #include <errno.h>
00059 #include <fcntl.h>
00060 
00061 //application specific
00062 #include "robotiq_force_torque_sensor/rq_sensor_com.h"
00063 
00064 // Definitions
00065 #define REGISTER_SELECT_OUTPUT 410
00066 #define REGISTER_SERIAL_NUMBER 510
00067 #define REGISTER_PRODUCTION_YEAR 514
00068 #define REGISTER_FIRMWARE_VERSION 500
00069 #define RQ_COM_MAX_STR_LENGTH 20
00070 #define RQ_COM_JAM_SIGNAL_CHAR      0xff
00071 #define RQ_COM_JAM_SIGNAL_LENGTH    50
00072 #define RQ_COM_TIMER_FOR_STREAM_DETECTION_MAX_VALUE 20 //20 * 4ms =  80ms without bytes means that the stream is stopped
00073 #define RQ_COM_TIMER_FOR_VALID_STREAM_MAX_VALUE     40 //40 * 4ms = 160ms without any valid message means that the communication is not working well
00074 
00076 // Private variables
00077 static float rq_com_received_data[6] = {0.0};
00078 static float rq_com_received_data_offset[6] = {0.0};
00079 
00080 static UINT_16 rq_com_computed_crc = 0;
00081 static UINT_16 rq_com_crc = 0;
00082 
00083 static INT_8 rq_com_str_sensor_serial_number[RQ_COM_MAX_STR_LENGTH];
00084 static INT_8 rq_com_str_sensor_production_year[RQ_COM_MAX_STR_LENGTH];
00085 static INT_8 rq_com_str_sensor_firmware_version[RQ_COM_MAX_STR_LENGTH];
00086 
00087 static UINT_32 rq_com_msg_received = 0;
00088 
00089 static UINT_8 rq_com_rcv_buff[MP_BUFF_SIZE];
00090 static UINT_8 rq_com_snd_buff[MP_BUFF_SIZE];
00091 static UINT_8 rq_com_rcv_buff2[MP_BUFF_SIZE];
00092 static INT_32 rq_com_rcv_len;
00093 static INT_32 rq_com_rcv_len2 = 0;
00094 
00095 static INT_32 rq_com_zero_force_flag = 0;
00096 static INT_32 rq_state_sensor_watchdog = 0;
00097 
00098 //variables related to the communication status
00099 static bool rq_com_stream_detected = false;
00100 static bool rq_com_valid_stream = false;
00101 static bool rq_com_new_message = false;
00102 static INT_32  rq_com_timer_for_stream_detection = 0;
00103 static INT_32  rq_com_timer_for_valid_stream = 0;
00104 
00106 //Private functions declaration
00107 static INT_8 rq_com_tentative_connexion(void);
00108 static void rq_com_send_jam_signal(void);
00109 static void rq_com_stop_stream_after_boot(void);
00110 
00111 static INT_32 rq_com_read_port(UINT_8 * const buf, UINT_32 buf_len);
00112 static INT_32 rq_com_write_port(UINT_8 const * const buf, UINT_32 buf_len);
00113 
00114 //Modbus functions
00115 static UINT_16 rq_com_compute_crc(UINT_8 const * adr, INT_32 length );
00116 static void rq_com_send_fc_03_request(UINT_16 base, UINT_16 n);
00117 static void rq_com_send_fc_16_request(INT_32 base, INT_32 n, UINT_8 const * const data);
00118 static INT_32 rq_com_wait_for_fc_03_echo(UINT_8 * const data);
00119 static INT_32 rq_com_wait_for_fc_16_echo(void);
00120 static INT_8 rq_com_send_fc_03(UINT_16 base, UINT_16 n, UINT_16 * const data);
00121 static INT_8 rq_com_send_fc_16(INT_32 base, INT_32 n, UINT_16 const * const data);
00122 
00123 static UINT_8 rq_com_identify_device(INT_8 const * const d_name);
00124 
00125 #ifdef __unix__ //For Unix
00126 static INT_32 fd_connexion = -1;
00127 static INT_8 set_com_attribs (INT_32 fd, speed_t speed);
00128 #elif defined(_WIN32)||defined(WIN32) //For Windows
00129 HANDLE hSerial;
00130 #endif
00131 
00133 //Function definitions
00134 
00141 INT_8 rq_sensor_com()
00142 {
00143 #ifdef __unix__ //For Unix
00144         UINT_8 device_found = 0;
00145         DIR *dir = NULL;
00146         struct dirent *entrydirectory = NULL;
00147 
00148         //Close a previously opened connection to a device
00149         close(fd_connexion);
00150         if ((dir = opendir("/sys/class/tty/")) == NULL)
00151         {
00152                 return -1;
00153         }
00154 
00155         //Loops through the files in the /sys/class/tty/ directory
00156         while ((entrydirectory = readdir(dir)) != NULL && device_found == 0)
00157         {
00158                 //Look for a serial device
00159                 if (strstr(entrydirectory->d_name, "ttyS") || 
00160                         strstr(entrydirectory->d_name, "ttyUSB"))
00161                 {
00162                         device_found = rq_com_identify_device(entrydirectory->d_name);
00163                 }
00164         }
00165 
00166         closedir(dir);
00167 
00168         if (device_found == 0)
00169         {
00170                 return -1;
00171         }
00172 #elif defined(_WIN32)||defined(WIN32) //For Windows
00173         DCB dcb;
00174         INT_32 i;
00175         INT_8 port[13];
00176         for(i = 0;i < 256; i++){
00177                 sprintf(port,"\\\\.\\COM%d",i);
00178                 hSerial = CreateFileA(port, GENERIC_READ | GENERIC_WRITE,
00179                                 0,NULL,OPEN_EXISTING,0,NULL);
00180                 if(hSerial != INVALID_HANDLE_VALUE){
00181                         dcb.DCBlength = sizeof(DCB);
00182                         if (!GetCommState(hSerial, &dcb)){
00183                                 CloseHandle(hSerial);
00184                                 hSerial = INVALID_HANDLE_VALUE;
00185                                 continue;//Permet de recommencer la boucle
00186                         }
00187                         dcb.BaudRate = CBR_19200;
00188                         dcb.ByteSize = 8;
00189                         dcb.StopBits = ONESTOPBIT;
00190                         dcb.Parity = NOPARITY;
00191                         dcb.fParity = FALSE;
00192 
00193                         /* No software handshaking */
00194                         dcb.fTXContinueOnXoff = TRUE;
00195                         dcb.fOutX = FALSE;
00196                         dcb.fInX = FALSE;
00197                         //dcb.fNull = FALSE;
00198 
00199                         /* Binary mode (it's the only supported on Windows anyway) */
00200                         dcb.fBinary = TRUE;
00201 
00202                         /* Don't want errors to be blocking */
00203                         dcb.fAbortOnError = FALSE;
00204 
00205                         /* Setup port */
00206                         if(!SetCommState(hSerial, &dcb)){
00207                                 CloseHandle(hSerial);
00208                                 continue;//Permet de recommencer la boucle
00209                         }
00210                         COMMTIMEOUTS timeouts={0};
00211                         timeouts.ReadIntervalTimeout=0;
00212                         timeouts.ReadTotalTimeoutConstant=1;
00213                         timeouts.ReadTotalTimeoutMultiplier=0;
00214                         timeouts.WriteTotalTimeoutConstant=1;
00215                         timeouts.WriteTotalTimeoutMultiplier=0;
00216                         if(!SetCommTimeouts(hSerial, &timeouts)){
00217                                 CloseHandle(hSerial);
00218                                 hSerial = INVALID_HANDLE_VALUE;
00219                                 continue;//Permet de recommencer la boucle
00220                         }
00221                         if (rq_com_tentative_connexion() == 1){
00222                                 return 0;
00223                         }
00224                         CloseHandle(hSerial);
00225                 }
00226         }
00227         return -1;
00228 #else
00229 #endif
00230         return 0;
00231 }
00232 
00238 static INT_8 rq_com_tentative_connexion()
00239 {
00240         INT_32 rc = 0;
00241         UINT_16 firmware_version [1];
00242         UINT_8 retries = 0;
00243 
00244         while(retries < 5 && rq_com_stream_detected == false)
00245         {
00246                 rq_com_listen_stream();
00247                 retries++;
00248         }
00249 
00250         rq_com_listen_stream();
00251         if(rq_com_stream_detected)
00252         {
00253                 rq_com_stop_stream_after_boot();
00254         }
00255 
00256         //Give some time to the sensor to switch to modbus
00257         usleep(100000);
00258 
00259         //If the device returns an F as the first character of the fw version,
00260         //we consider its a sensor
00261         rc = rq_com_send_fc_03(REGISTER_FIRMWARE_VERSION, 2, firmware_version);
00262         if (rc != -1)
00263         {
00264                 if (firmware_version[0] >> 8 == 'F')
00265                 {
00266                         return 1;
00267                 }
00268         }
00269 
00270         return -1;
00271 }
00272 
00280 #ifdef __unix__ //For Unix
00281 static INT_8 set_com_attribs (INT_32 fd, speed_t speed)
00282 {
00283         struct termios tty;
00284         memset (&tty, 0, sizeof (struct termios));
00285 
00286         if (tcgetattr (fd, &tty) != 0)
00287         {
00288                 return -1;
00289         }
00290 
00291         cfsetospeed (&tty, speed);
00292         cfsetispeed (&tty, speed);
00293 
00294         tty.c_cflag |= (CLOCAL | CREAD);
00295         tty.c_cflag &= ~CSIZE;
00296         tty.c_cflag |= CS8;
00297         tty.c_cflag &= ~CSTOPB;
00298         tty.c_cflag &= ~PARENB;
00299         tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
00300         tty.c_iflag &= ~ICRNL;
00301         tty.c_iflag &= ~INPCK;
00302         tty.c_iflag &= ~(IXON | IXOFF | IXANY);
00303         tty.c_cc[VMIN]  = 0;                    // read doesn't block
00304         tty.c_cc[VTIME] = 1;
00305 
00306         if (tcsetattr (fd, TCSANOW, &tty) != 0)
00307         {
00308                 printf("error %d from tcsetattr", errno);
00309                 return -1;
00310         }
00311 
00312         return 0;
00313 }
00314 #endif
00315 
00320 void rq_com_listen_stream(void)
00321 {
00322         static INT_32 last_byte = 0;
00323         static INT_32 new_message = 0;
00324         INT_32 i = 0;
00325         INT_32 j = 0;    
00326 
00327         //Capture and store the current value of the sensor and use it to
00328         //zero subsequent sensor values
00329         if(rq_com_zero_force_flag == 1)
00330         {
00331                 rq_com_zero_force_flag = 0;
00332 
00333                 for(i = 0; i < 6; i++)
00334                 {
00335                         rq_com_received_data_offset[i] = rq_com_received_data[i];
00336                 }
00337 
00338         }
00339 
00340         usleep(4000);
00341 
00342         //Increment communication state counters
00343         if(rq_com_timer_for_stream_detection++ > RQ_COM_TIMER_FOR_STREAM_DETECTION_MAX_VALUE)
00344         {
00345                 rq_com_timer_for_stream_detection = RQ_COM_TIMER_FOR_STREAM_DETECTION_MAX_VALUE;
00346                 rq_com_stream_detected = false;
00347         }
00348 
00349         if(rq_com_timer_for_valid_stream++ > RQ_COM_TIMER_FOR_VALID_STREAM_MAX_VALUE)
00350         {
00351                 rq_com_timer_for_valid_stream = RQ_COM_TIMER_FOR_VALID_STREAM_MAX_VALUE;
00352                 rq_com_valid_stream = false;
00353         }
00354 
00355         last_byte = 0;
00356         new_message = 0;
00357 
00358         //Data reception
00359         rq_com_rcv_len = rq_com_read_port(rq_com_rcv_buff, MP_BUFF_SIZE);
00360 
00361         //If at least a byte is received, we consider the sensor to stream
00362         if(rq_com_rcv_len > 0)
00363         {
00364                 rq_com_stream_detected = true;
00365                 rq_com_timer_for_stream_detection = 0;
00366         }
00367 
00368         //Copie les données au bout du buffer 2
00369         for(i = 0; i < rq_com_rcv_len; i++)
00370         {
00371                 //If the buffer overflows, set the index to the beginning
00372                 if(rq_com_rcv_len2 == MP_BUFF_SIZE)
00373                 {
00374                         //Next bytes will overwrite the begining of the buffer
00375                         rq_com_rcv_len2 = 0;
00376                         break;
00377                 }
00378 
00379                 rq_com_rcv_buff2[rq_com_rcv_len2++] = rq_com_rcv_buff[i];
00380         }
00381 
00382         //empty the buffers
00383         memset( rq_com_rcv_buff, 0, sizeof(rq_com_rcv_buff));
00384         memset( rq_com_snd_buff, 0, sizeof(rq_com_snd_buff));
00385 
00386         //If there is enough characters,...
00387         if(rq_com_rcv_len2 >= 16 && rq_com_rcv_len >= 1) 
00388         {        
00389                 //Search for a valid stream message in the buffer
00390                 for(i = rq_com_rcv_len2 - 16; i >= 0; i--)
00391                 {
00392                         //Header
00393                         if(rq_com_rcv_buff2[i] == 0x20 && rq_com_rcv_buff2[i+1] == 0x4E && new_message == 0)
00394                         {
00395 
00396                                 last_byte = i - 1;
00397 
00398                                 rq_com_computed_crc = rq_com_compute_crc(rq_com_rcv_buff2 + i * sizeof(*rq_com_rcv_buff2), 14);
00399 
00400                                 rq_com_crc                      = (rq_com_rcv_buff2[i+14] + rq_com_rcv_buff2[i+15] * 256);
00401 
00402                                 rq_com_msg_received++;
00403 
00404 
00405                                 //The crc is valid.. the message can be used
00406                                 if(rq_com_computed_crc == rq_com_crc)
00407                                 {
00408                                         last_byte = i + 15; //will erase the message
00409 
00410                                         //convert the efforts to floating point numbers
00411                                         for(j = 0; j < 3; j++)
00412                                         {
00413                                                 rq_com_received_data[j] = ((float)((INT_16)((UINT_8)rq_com_rcv_buff2[i+2+2*j] + ((INT_16)(UINT_8)rq_com_rcv_buff2[i+3+2*j]) * 256))) / 100 ;
00414                                         }
00415 
00416                                         for(j = 3; j < 6; j++)
00417                                         {
00418                                                 rq_com_received_data[j] = ((float)((INT_16)((UINT_8)rq_com_rcv_buff2[i+2+2*j] + ((INT_16)(UINT_8)rq_com_rcv_buff2[i+3+2*j]) * 256))) / 1000;
00419                                         }
00420 
00421                                         //Signal the stream as valid
00422                                         rq_com_valid_stream = true;
00423                                         rq_com_new_message = true;
00424                                         rq_com_timer_for_valid_stream = 0;
00425 
00426                                         new_message = 1;
00427                                         rq_state_sensor_watchdog = 1;
00428 
00429                                 }
00430                                 else
00431                                 {
00432                                         last_byte = i + 15;
00433                                         new_message = 1;
00434                                 }
00435                         }
00436                 }
00437 
00438                 if(last_byte > 0)
00439                 {
00440                         //On shift le buffer 2 afin de ne garder que ce qui dépasse le dernier caractère du dernier message complet
00441                         for(i = 0; i < (rq_com_rcv_len2 - last_byte - 1); i++)
00442                         {
00443                                 rq_com_rcv_buff2[i] = rq_com_rcv_buff2[last_byte + 1 + i];
00444                         }
00445                         rq_com_rcv_len2 = rq_com_rcv_len2 - last_byte - 1;
00446                 }
00447         }
00448 }
00449 
00454 static void rq_com_send_jam_signal(void)
00455 {
00456         //Build the jam signal
00457         memset(rq_com_snd_buff, RQ_COM_JAM_SIGNAL_CHAR, RQ_COM_JAM_SIGNAL_LENGTH);
00458 
00459         //Send the jam signal
00460         rq_com_write_port(rq_com_snd_buff,RQ_COM_JAM_SIGNAL_LENGTH);
00461 }
00462 
00463 
00469 static void rq_com_stop_stream_after_boot(void)
00470 {
00471         static INT_32 counter = 0;
00472         
00473         while(rq_com_stream_detected)
00474         {
00475                 counter++;
00476 
00477                 if(counter == 1)
00478                 {
00479                         rq_com_send_jam_signal();
00480                 }
00481                 else
00482                 {
00483                         rq_com_listen_stream();
00484 
00485                         if(rq_com_stream_detected)
00486                         {
00487                                 counter = 0;
00488                         }
00489                         else
00490                         {
00491                                 counter = 0;
00492                         }
00493                 }
00494         }
00495 }
00496 
00502 INT_8 rq_com_start_stream(void)
00503 {
00504         UINT_16 data[1] = {0x0200}; //0x0200 selects the stream output
00505         UINT_8 retries = 0;
00506         INT_8 rc = rq_com_send_fc_16(REGISTER_SELECT_OUTPUT, 2, data);
00507 
00508         if (rc == -1)
00509         {
00510                 while(retries < 5)
00511                 {
00512                         rq_com_listen_stream();
00513 
00514                         if(rq_com_stream_detected)
00515                         {
00516                                 return 0;
00517                         }
00518 
00519                         usleep(50000);
00520                 }
00521 
00522                 return -1;
00523         }
00524 
00525         return 0;
00526 }
00527 
00534 static INT_8 rq_com_send_fc_03(UINT_16 base, UINT_16 n, UINT_16 * const data)
00535 {
00536         UINT_8 bytes_read = 0;
00537         INT_32 i = 0;
00538         INT_32 cpt = 0;
00539         UINT_8 data_request[n]; 
00540         UINT_16 retries = 0;
00541 
00542         //precondition, null pointer
00543         if (data == NULL)
00544         {
00545                 return -1;
00546         }
00547 
00548         //Send the read request
00549         rq_com_send_fc_03_request(base,n);
00550 
00551         //Read registers
00552         while (retries < 100 && bytes_read == 0)
00553         {
00554                 usleep(4000);
00555                 bytes_read = rq_com_wait_for_fc_03_echo(data_request);
00556                 retries++;
00557         }
00558 
00559         if (bytes_read <= 0)
00560         {
00561                 return -1;
00562         }
00563 
00564         for (i = 0; i < n/2; i++ )
00565         {
00566                 data[i] = (data_request[cpt++] * 256);
00567                 data[i] = data[i] + data_request[cpt++];
00568         }
00569 
00570         return 0;
00571 }
00572 
00580 static INT_8 rq_com_send_fc_16(INT_32 base, INT_32 n, UINT_16 const * const data)
00581 {
00582         INT_8 valid_answer = 0;
00583         UINT_8 data_request[n];
00584         UINT_16 retries = 0;
00585         UINT_32 i;
00586 
00587         //precondition, null pointer
00588         if (data == NULL)
00589         {
00590                 return -1;
00591         }
00592 
00593         for (i = 0; i < n; i++ )
00594         {
00595                 if(i % 2 == 0)
00596                 {
00597                         data_request[i] = (data[(i/2)] >> 8);
00598                 }
00599                 else
00600                 {
00601                         data_request[i] = (data[(i/2)] & 0xFF);
00602                 }
00603         }
00604 
00605         rq_com_send_fc_16_request(base, n, data_request);
00606 
00607         while (retries < 100 && valid_answer == 0)
00608         {
00609                 usleep(10000);
00610                 valid_answer = rq_com_wait_for_fc_16_echo();
00611                 retries++;
00612         }
00613 
00614         if(valid_answer == 1)
00615         {
00616                 return 0;
00617         }
00618 
00619         return -1;
00620 }
00621 
00623 //Public functions
00624 
00631 void rq_sensor_com_read_info_high_lvl(void)
00632 {
00633         UINT_16 registers[4] = {0};//table de registre
00634         UINT_64 serial_number = 0;
00635         INT_32 result = 0;
00636 
00637         //Firmware Version
00638         result = rq_com_send_fc_03(REGISTER_FIRMWARE_VERSION, 6, registers);
00639         if (result != -1)
00640         {
00641                 sprintf(rq_com_str_sensor_firmware_version, "%c%c%c-%hhu.%hhu.%hhu",
00642                                 registers[0] >> 8, registers[0] & 0xFF, registers[1] >> 8,
00643                                 registers[1] & 0xFF, registers[2] >> 8, registers[2] & 0xFF);
00644         }
00645 
00646         //Production Year
00647         result = rq_com_send_fc_03(REGISTER_PRODUCTION_YEAR, 2, registers);
00648         if (result != -1)
00649         {
00650                 sprintf(rq_com_str_sensor_production_year, "%u", registers[0]);
00651         }
00652 
00653         //Serial Number
00654         result = rq_com_send_fc_03(REGISTER_SERIAL_NUMBER, 8, registers);
00655         if (result != -1)
00656         {
00657                 serial_number = (UINT_64) ((registers[3] >> 8) * 256 * 256 * 256
00658                                 + (registers[3] & 0xFF) * 256 * 256 + (registers[2] >> 8) * 256
00659                                 + (registers[2] & 0xFF));
00660 
00661                 if (serial_number == 0)
00662                 {
00663                         sprintf(rq_com_str_sensor_serial_number, "UNKNOWN");
00664                 }
00665                 else
00666                 {
00667                         sprintf(rq_com_str_sensor_serial_number, "%c%c%c-%.4lu", registers[0] >> 8,
00668                                         registers[0] & 0xFF, registers[1] >> 8, serial_number);
00669                 }
00670         }
00671 }
00672 
00680 static INT_32 rq_com_read_port(UINT_8 * const buf, UINT_32 buf_len)
00681 {
00682 #ifdef __unix__ //For Unix
00683         return read(fd_connexion, buf, buf_len);
00684 #elif defined(_WIN32)||defined(WIN32) //For Windows
00685         DWORD myBytesRead = 0;
00686         ReadFile(hSerial,buf,buf_len,&myBytesRead,NULL);
00687         return myBytesRead;
00688 #endif
00689 }
00690 
00698 static INT_32 rq_com_write_port(UINT_8 const * const buf, UINT_32 buf_len)
00699 {
00700         //precondition
00701         if (buf == NULL)
00702         {
00703                 return -1;
00704         }
00705 
00706 #ifdef __unix__ //For Unix
00707         return write(fd_connexion, buf, buf_len);
00708 #elif defined(_WIN32)||defined(WIN32) //For Windows
00709         DWORD n_bytes = 0;
00710         return (WriteFile(hSerial, buf, buf_len, &n_bytes, NULL)) ? n_bytes: -1;
00711 #endif
00712 }
00713 
00720 static UINT_16 rq_com_compute_crc(UINT_8 const * adr, INT_32 length )
00721 {
00722                 UINT_16 CRC_calc = 0xFFFF;
00723                 INT_32 j=0;
00724                 INT_32 k=0;
00725 
00726         //precondition, null pointer
00727         if (adr == NULL)
00728         {
00729                 return 0;
00730         }
00731 
00732         //Tant qu'il reste des bytes dans le message
00733         while (j < length)
00734         {
00735                 //Si c'est le premier byte
00736                 if (j==0)
00737                 {
00738                         CRC_calc ^= *adr & 0xFF;
00739                 }
00740                 //Sinon on utilisera un XOR sur le word
00741                 else
00742                 {
00743                         CRC_calc ^= *adr;
00744                 }
00745 
00746                 k=0;
00747                 
00748                 //Tant que le byte n'est pas complété
00749                 while (k < 8)
00750                 {
00751                         //Si le dernier bit est un 1
00752                         if (CRC_calc & 0x0001)
00753                         {
00754                                 CRC_calc =  (CRC_calc >> 1)^ 0xA001;    //Shift de 1 bit vers la droite et XOR avec le facteur polynomial
00755                         }
00756                         else
00757                         {
00758                                 CRC_calc >>= 1;                 //Shift de 1 bit vers la droite
00759                         }
00760         
00761                         k++;
00762                 }
00763         
00764                 //Incrémente l'adresse et le compteur d'adresse
00765                 adr++;
00766                 j++;
00767         }
00768         
00769         return CRC_calc;
00770 }
00771 
00778 static void rq_com_send_fc_03_request(UINT_16 base, UINT_16 n)
00779 {
00780         static UINT_8 buf[MP_BUFF_SIZE];
00781         INT_32 length = 0;
00782         UINT_8 reg[2];
00783         UINT_8 words[2];
00784         UINT_16 CRC;
00785         
00786         //Si le nombre de registre est impair
00787         if(n % 2 != 0)
00788         {
00789                 n += 1;
00790         }
00791         
00792         //Scinder en LSB et MSB
00793         reg[0]   = (UINT_8)(base >> 8); //MSB to the left
00794         reg[1]   = (UINT_8)(base & 0x00FF); //LSB to the right
00795         words[0] = (UINT_8)((n/2) >> 8); //MSB to the left
00796         words[1] = (UINT_8)((n/2) & 0x00FF); //LSB to the right
00797         
00798         //Build the request
00799         buf[length++] = 9; //slave address
00800         buf[length++] = 3;
00801         buf[length++] = reg[0];
00802         buf[length++] = reg[1];
00803         buf[length++] = words[0];
00804         buf[length++] = words[1];
00805         
00806         //CRC computation
00807         CRC = rq_com_compute_crc(buf, length);
00808         
00809         //Append the crc
00810         buf[length++] = (UINT_8)(CRC & 0x00FF);
00811         buf[length++] = (UINT_8)(CRC >> 8);
00812         
00813         //Send the request
00814         rq_com_write_port(buf, length);
00815 }
00816 
00823 static INT_32 rq_com_wait_for_fc_03_echo(UINT_8 * const data)
00824 {
00825         static UINT_8 buf[MP_BUFF_SIZE];
00826         static INT_32 length = 0;
00827         static INT_32 old_length = 0;
00828         static INT_32 counter_no_new_data = 0;
00829         UINT_8 n = 0;
00830         UINT_16 CRC = 0;
00831         INT_32 j = 0;
00832         INT_32 ret = rq_com_read_port(&buf[length], MP_BUFF_SIZE - length);
00833         
00834         if(ret != -1)
00835         {
00836                 length = length + ret;
00837         }
00838 
00839         //If there is no new data, the buffer is cleared
00840         if(length == old_length)
00841         {
00842                 if(counter_no_new_data < 5)
00843                 {
00844                         counter_no_new_data++;
00845                 }
00846                 else
00847                 {
00848                         length = 0;
00849                 }
00850         }
00851         else
00852         {
00853                 counter_no_new_data = 0;
00854         }
00855         
00856         old_length = length;
00857         
00858         if(length > 0)
00859         {
00860                 //If there is not enough data, return
00861                 if(length <= 5)
00862                 {
00863                         return 0;
00864                 }
00865                 else
00866                 {
00867                         if(buf[1] == 3) //3 indicates the response to a fc03 query
00868                         {
00869                                 n = buf[2];
00870                                 if(length < 5 + n)
00871                                 {
00872                                         return 0;
00873                                 }
00874                         }
00875                         else //unknown fc code
00876                         {
00877                                 length = 0;
00878                                 return 0;
00879                         }
00880                 }
00881                 CRC = rq_com_compute_crc(buf, length - 2);
00882                 
00883                 //Verifies the crc and the slave ID
00884                 if(CRC != (UINT_16)((buf[length - 1] * 256) + (buf[length - 2])))
00885                 {
00886                         //On clear le buffer
00887                         buf[0] = 0;
00888                         length = 0;
00889                         return 0;
00890                 }
00891                 else
00892                 {
00893                         n = buf[2];
00894                         
00895                         //Writes the bytes to the return buffer
00896                         for(j = 0; j < n; j++)
00897                         {
00898                                 data[j] = buf[j + 3];
00899                         }
00900                         
00901                         //Clears the buffer
00902                         buf[0] = 0;
00903                         length = 0;
00904                         return n;
00905                 }
00906         }
00907         
00908         return 0;
00909 }
00910 
00911 
00918 static void rq_com_send_fc_16_request(INT_32 base, INT_32 n, UINT_8 const * const data)
00919 {
00920         static UINT_8 buf[MP_BUFF_SIZE];
00921         INT_32 length = 0;
00922 
00923         //Byte of the query
00924         UINT_8 reg[2];
00925         UINT_8 words[2];
00926         UINT_16 CRC;
00927         INT_32 n2 = 0;
00928         INT_32 i = 0;
00929 
00930         if (data == NULL)
00931         {
00932                 return;
00933         }
00934         
00935         //Manage if the number of bytes to write is odd or even
00936         if(n %2 != 0)
00937         {
00938                 n2 = n+1;
00939         }
00940         else
00941         {
00942                 n2 = n;
00943         }
00944         
00945         //Split the address and the number of bytes between MSB ans LSB
00946         reg[0]   = (UINT_8)(base >> 8);       //MSB to the left
00947         reg[1]   = (UINT_8)(base & 0x00FF);   //LSB to the right
00948         words[0] = (UINT_8)((n2/2) >> 8);     //MSB to the left
00949         words[1] = (UINT_8)((n2/2) & 0x00FF); //LSB to the right
00950         
00951         
00952         //Build the query
00953         buf[length++] = 9; //slave address
00954         buf[length++] = 16;
00955         buf[length++] = reg[0];
00956         buf[length++] = reg[1];
00957         buf[length++] = words[0];
00958         buf[length++] = words[1];
00959         buf[length++] = n2;
00960         
00961         //Copy data to the send buffer
00962         for(i = 0; i < n; i++)
00963         {
00964                 buf[length++] = data[i];
00965         }
00966         
00967         if(n != n2)
00968         {
00969                 buf[length++] = 0;
00970         }
00971         
00972         CRC = rq_com_compute_crc(buf, length);
00973         
00974         //Append the crc to the query
00975         buf[length++] = (UINT_8)(CRC & 0x00FF);
00976         buf[length++] = (UINT_8)(CRC >> 8);
00977         
00978         //Send the query
00979         rq_com_write_port(buf, length);
00980 }
00981 
00987 static INT_32 rq_com_wait_for_fc_16_echo(void)
00988 {
00989         static UINT_8 buf[MP_BUFF_SIZE];
00990         static INT_32 length = 0;
00991         static INT_32 old_length = 0;
00992         static INT_32 counter_no_new_data = 0;
00993         UINT_16 CRC = 0;
00994 
00995         length = length + rq_com_read_port(&buf[length], MP_BUFF_SIZE - length);
00996 
00997         //Clear the buffer if no new data
00998         if(length == old_length)
00999         {
01000                 if(counter_no_new_data < 5)
01001                 {
01002                         counter_no_new_data++;
01003                 }
01004                 else
01005                 {
01006                         length = 0;
01007                 }
01008         }
01009         else
01010         {
01011                 counter_no_new_data = 0;
01012         }
01013 
01014         old_length = length;
01015 
01016         if(length > 0)
01017         {
01018                 //If not enough data, return
01019                 if(length < 8)
01020                 {
01021                         return 0;
01022                 }
01023                 else
01024                 {
01025                         //if it's a reply to a fc16 query then proceed
01026                         if(buf[1] == 16)
01027                         {
01028                                         length = 8;
01029 
01030                                         CRC = rq_com_compute_crc(buf, length - 2);
01031 
01032                                         //Check the crc an the slave ID
01033                                         if(CRC != (UINT_16)((buf[length - 1] * 256) + (buf[length - 2])))
01034                                         {
01035                                                 //Clear the buffer
01036                                                 length = 0;
01037 
01038                                                 return 0;
01039                                         }
01040                                         else
01041                                         {
01042                                                 //Clear the buffer
01043                                                 length = 0;
01044 
01045                                                 return 1;
01046                                         }
01047 
01048                         }
01049                         else //Clear the buffer
01050                         {
01051                                         length = 0;
01052                                         return 0;
01053                         }
01054                 }
01055 
01056         }
01057 
01058         return 0;
01059 }
01060 
01061 
01066 void rq_com_get_str_serial_number(INT_8 * serial_number)
01067 {
01068         strcpy(serial_number, rq_com_str_sensor_serial_number);
01069 }
01070 
01075 void rq_com_get_str_firmware_version(INT_8 * firmware_version)
01076 {
01077         strcpy(firmware_version, rq_com_str_sensor_firmware_version);
01078 }
01079 
01084 void rq_com_get_str_production_year(INT_8 * production_year)
01085 {
01086         strcpy(production_year,rq_com_str_sensor_production_year);
01087 }
01088 
01093 bool rq_com_get_stream_detected()
01094 {
01095         return rq_com_stream_detected;
01096 }
01097 
01101 bool rq_com_get_valid_stream()
01102 {
01103         return rq_com_valid_stream;
01104 }
01105 
01111 float rq_com_get_received_data(UINT_8 i)
01112 {
01113         if(i >= 0 && i <= 5)
01114         {
01115                 return rq_com_received_data[i] - rq_com_received_data_offset[i];
01116         }
01117 
01118         return 0.0;
01119 }
01120 
01128 bool rq_com_got_new_message()
01129 {
01130         bool tmp = rq_com_new_message;
01131         rq_com_new_message = false;
01132         return tmp;
01133 }
01134 
01140 void rq_com_do_zero_force_flag()
01141 {
01142         rq_com_zero_force_flag = 1;
01143 }
01144 
01149 void stop_connection()
01150 {
01151 #if defined(_WIN32)||defined(WIN32) //For Windows
01152         CloseHandle(hSerial);
01153         hSerial = INVALID_HANDLE_VALUE;
01154 #endif
01155 }
01156 
01157 
01163 static UINT_8 rq_com_identify_device(INT_8 const * const d_name)
01164 {
01165         INT_8 dirParent[20] = {0};
01166         INT_8 port_com[15] = {0};
01167 
01168         strcpy(dirParent, "/dev/");
01169         strcat(dirParent, d_name);
01170         strcpy(port_com, dirParent);
01171         fd_connexion = open(port_com, O_RDWR | O_NOCTTY | O_NDELAY | O_EXCL);
01172 
01173         //The serial port is open
01174         if(fd_connexion != -1)
01175         {
01176                 if(set_com_attribs(fd_connexion,B19200) != -1)
01177                 {
01178                         //Try connecting to the sensor
01179                         if (rq_com_tentative_connexion() == 1)
01180                         {
01181                                 return 1;
01182                         }
01183                 }
01184                 
01185                 //The device is identified, close the connection
01186                 close(fd_connexion);
01187         }
01188 
01189         return 0;
01190 }


robotiq_force_torque_sensor
Author(s): Jonathan Savoie
autogenerated on Thu Jun 6 2019 17:58:03