39 #include "SerialPortIO.hh"
40 #include <Base/Debug/Error.hh>
41 #include <Base/Common/W32Compat.hh>
62 serialFD_ = CreateFile(port.c_str(),
63 GENERIC_READ | GENERIC_WRITE,
67 FILE_ATTRIBUTE_NORMAL,
70 if(serialFD_==INVALID_HANDLE_VALUE){
71 if(GetLastError()==ERROR_FILE_NOT_FOUND){
72 if (verbose_) BIASERR(
"Port:"<<port<<
" does not exist.");
75 if (verbose_) BIASERR(
"Could not open port:"<<port);
78 cout<<
"Created port!"<<endl;
82 serialFD_ = open(port.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
85 if (verbose_) BIASERR(
"Could not open port:"<<port);
89 cout<<
"Created port!"<<endl;
90 fcntl(serialFD_, F_SETFL, 0);
101 if (verbose_) BIASERR(
"Serial port was not opened!");
105 CloseHandle(serialFD_);
114 bool hardwareFlowControl,
bool canonicalInput,
115 bool softwareFlowControl,
int stopbits ){
117 if (verbose_) BIASERR(
"Serial port was not opened!");
121 DCB dcbSerialParams = {0};
122 dcbSerialParams.DCBlength=
sizeof(dcbSerialParams);
123 if (!GetCommState(serialFD_, &dcbSerialParams)) {
124 if (verbose_) BIASERR(
"Error getting com port state!");
129 dcbSerialParams.BaudRate=CBR_110;
132 dcbSerialParams.BaudRate=CBR_300;
135 dcbSerialParams.BaudRate=CBR_600;
138 dcbSerialParams.BaudRate=CBR_1200;
141 dcbSerialParams.BaudRate=CBR_2400;
144 dcbSerialParams.BaudRate=CBR_4800;
147 dcbSerialParams.BaudRate=CBR_9600;
150 dcbSerialParams.BaudRate=CBR_19200;
153 dcbSerialParams.BaudRate=CBR_38400;
156 dcbSerialParams.BaudRate=CBR_57600;
159 BIASWARN(
"Not a valid Baudrate, setting to 9600 instead");
160 dcbSerialParams.BaudRate=CBR_9600;
164 dcbSerialParams.ByteSize=8;
166 dcbSerialParams.StopBits=ONESTOPBIT;
171 dcbSerialParams.Parity=NOPARITY;
174 dcbSerialParams.Parity=EVENPARITY;
177 dcbSerialParams.Parity=ODDPARITY;
180 BIASERR(
"Invalid partity value!");
185 if(!SetCommState(serialFD_, &dcbSerialParams)){
186 BIASERR(
"Error setting com port state!");
189 struct termios options;
191 tcgetattr(serialFD_, &options);
195 cfsetispeed(&options, B0);
196 cfsetospeed(&options, B0);
199 cfsetispeed(&options, B50);
200 cfsetospeed(&options, B50);
203 cfsetispeed(&options, B75);
204 cfsetospeed(&options, B75);
207 cfsetispeed(&options, B110);
208 cfsetospeed(&options, B110);
211 cfsetispeed(&options, B134);
212 cfsetospeed(&options, B134);
215 cfsetispeed(&options, B150);
216 cfsetospeed(&options, B150);
219 cfsetispeed(&options, B200);
220 cfsetospeed(&options, B200);
223 cfsetispeed(&options, B300);
224 cfsetospeed(&options, B300);
227 cfsetispeed(&options, B600);
228 cfsetospeed(&options, B600);
231 cfsetispeed(&options, B1200);
232 cfsetospeed(&options, B1200);
235 cfsetispeed(&options, B1800);
236 cfsetospeed(&options, B1800);
239 cfsetispeed(&options, B2400);
240 cfsetospeed(&options, B2400);
243 cfsetispeed(&options, B4800);
244 cfsetospeed(&options, B4800);
247 cfsetispeed(&options, B9600);
248 cfsetospeed(&options, B9600);
251 cfsetispeed(&options, B19200);
252 cfsetospeed(&options, B19200);
255 cfsetispeed(&options, B38400);
256 cfsetospeed(&options, B38400);
259 cfsetispeed(&options, B57600);
260 cfsetospeed(&options, B57600);
263 BIASWARN(
"Not a valid Baudrate, setting to 9600 instead");
264 cfsetispeed(&options, B9600);
265 cfsetospeed(&options, B9600);
270 options.c_cflag |= (CLOCAL | CREAD);
276 options.c_cflag &= ~PARENB;
277 options.c_cflag &= ~CSIZE;
278 options.c_cflag |= CS8;
281 options.c_cflag |= PARENB;
282 options.c_cflag &= ~PARODD;
283 options.c_cflag &= ~CSIZE;
284 options.c_cflag |= CS7;
287 options.c_cflag |= PARENB;
288 options.c_cflag |= PARODD;
289 options.c_cflag &= ~CSIZE;
290 options.c_cflag |= CS7;
293 BIASERR(
"Invalid partity value!");
301 options.c_cflag &= ~CSTOPB;
303 options.c_cflag |= CSTOPB;
307 options.c_iflag &= ~(INPCK | ISTRIP);
308 options.c_oflag &= ~OPOST;
311 if(hardwareFlowControl)
312 options.c_cflag |= CRTSCTS;
314 options.c_cflag &= ~CRTSCTS;
318 options.c_lflag |= (ICANON | ECHO | ECHOE);
320 options.c_lflag &= ~(ICANON | ECHO | ECHOE |ISIG);
323 if(softwareFlowControl)
324 options.c_iflag |= (IXON | IXOFF | IXANY);
326 options.c_iflag &= ~(IXON | IXOFF | IXANY);
328 options.c_cc[VMIN]=0;
329 options.c_cc[VTIME]=3;
332 tcsetattr(serialFD_, TCSANOW, &options);
333 tcflush(serialFD_,TCIFLUSH);
345 int ReadTotalTimeoutMultiplier,
int ReadTotalTimeoutConstant,
346 int WriteTotalTimeoutMultiplier,
int WriteTotalTimeoutConstant){
348 COMMTIMEOUTS timeouts;
349 timeouts.ReadIntervalTimeout = ReadIntervalTimeout;
350 timeouts.ReadTotalTimeoutMultiplier = ReadTotalTimeoutMultiplier;
351 timeouts.ReadTotalTimeoutConstant = ReadTotalTimeoutConstant;
352 timeouts.WriteTotalTimeoutMultiplier = WriteTotalTimeoutMultiplier;
353 timeouts.WriteTotalTimeoutConstant = WriteTotalTimeoutConstant;
354 if (!SetCommTimeouts(serialFD_, &timeouts))
356 BIASERR(
"Error setting com port state!");
360 struct termios options;
362 tcgetattr(serialFD_, &options);
363 options.c_cc[VMIN]=0;
364 options.c_cc[VTIME]=ReadIntervalTimeout;
366 int ret = tcsetattr(serialFD_, TCSANOW, &options);
369 BIASERR(
"Error setting com port state!");
372 tcflush(serialFD_,TCIFLUSH);
380 BIASERR(
"Serial port was not opened!");
384 const int length = 255;
385 char buffer[length+1]={0};
402 DWORD dwBytesRead = 0;
403 if(!ReadFile(serialFD_, buffer, length, &dwBytesRead, NULL)){
404 BIASERR(
"Error reading from serial port!");
420 while ((nbytes = read(serialFD_, bufptr, buffer +
sizeof(buffer) - bufptr - 1)) > 0)
423 if (bufptr[-1] ==
'\n' || bufptr[-1] ==
'\r')
433 ReadBytes(
unsigned char* message,
int nrBytes,
bool waitForMessage){
435 BIASERR(
"Serial port was not opened!")
440 COMMTIMEOUTS timeouts={0};
442 timeouts.ReadIntervalTimeout=5000;
443 timeouts.ReadTotalTimeoutConstant=50;
444 timeouts.ReadTotalTimeoutMultiplier=10;
447 timeouts.ReadIntervalTimeout=50;
448 timeouts.ReadTotalTimeoutConstant=50;
449 timeouts.ReadTotalTimeoutMultiplier=10;
451 if(!SetCommTimeouts(serialFD_, &timeouts)){
452 BIASWARN(
"Error setting timeouts to port!");
455 DWORD dwBytesRead = 0;
456 if(!ReadFile(serialFD_, message, nrBytes, &dwBytesRead, NULL)){
457 BIASERR(
"Error reading from serial port!");
461 return (
int)dwBytesRead;
465 fcntl(serialFD_, F_SETFL, 0);
467 fcntl(serialFD_, F_SETFL, FNDELAY);
471 nbytes = read(serialFD_, message, nrBytes);
480 BIASERR(
"Serial port was not opened!")
484 DWORD dwBytesWritten = 0;
485 if(!WriteFile(serialFD_, message.c_str(), message.size(), &dwBytesWritten, NULL)){
486 BIASERR(
"Error writing to serial port!");
491 for(
int i=0;i<attempts;i++){
492 n = write(serialFD_, message.c_str(), message.size());
497 BIASERR(
"Error writing to serial port!");
510 DWORD dwBytesWritten = 0;
511 if(!WriteFile(serialFD_, message, nrBytes, &dwBytesWritten, NULL)){
512 BIASERR(
"Error writing to serial port!");
517 for(
int i=0;i<attempts;i++){
518 n = write(serialFD_, message, nrBytes);
523 BIASERR(
"Error writing to serial port!");
527 cout<<
"Wrote:"<<n<<
" bytes.\n";
536 int length = message.length();
539 std::string start = message.substr(0,4);
540 std::string chiptype = message.substr(5,4);
541 std::string
id = message.substr(9,16);
542 std::string separator = message.substr(25,1);
543 std::string control = message.substr(26,4);
bool GetPetScanRFIDFromString(std::string message, std::string &rfid)
parses values of PetScan RT100 V5 format Start Chip Value *Control U FDXB945 000000869846*FFA9 ...
int ReadBytes(unsigned char *message, int nrBytes, bool waitForMessage=true)
Read bytes from the port, port has to be open.
bool ReadString(std::string &message, bool waitForMessage=true)
Read a string from port, port has to be open.
bool ClosePort()
Close port.
bool WriteBytes(unsigned char *message, int nrBytes)
Write bytes to the port, port has to be open.
bool OpenPort(std::string port)
Open port, e.g.
SerialPortIO(bool verbose=true)
standard constructor
bool SetTimeOuts(int ReadIntervalTimeout, int ReadTotalTimeoutMultiplier, int ReadTotalTimeoutConstant, int WriteTotalTimeoutMultiplier, int WriteTotalTimeoutConstant)
in linux all exept ReadTotalTimeoutConstant is ignored
virtual ~SerialPortIO()
standard destructor
bool WriteString(std::string message)
Write a string to the port, port has to be open.
bool SetOptions(unsigned baudrate=9600, SerialPortParityMode parity=SPPM_NoParity, bool hardwareFlowControl=false, bool canonicalInput=true, bool softwareFlowControl=false, int stopbits=1)
Set Options for opened port, use OpenPort before.