Git Product home page Git Product logo

serial's Introduction

Serial Communication Library

Build Status(Linux and OS X) Build Status(Windows)

This is a cross-platform library for interfacing with rs-232 serial like ports written in C++. It provides a modern C++ interface with a workflow designed to look and feel like PySerial, but with the speed and control provided by C++.

This library is in use in several robotics related projects and can be built and installed to the OS like most unix libraries with make and then sudo make install, but because it is a catkin project it can also be built along side other catkin projects in a catkin workspace.

Serial is a class that provides the basic interface common to serial libraries (open, close, read, write, etc..) and requires no extra dependencies. It also provides tight control over timeouts and control over handshaking lines.

Documentation

Website: http://wjwwood.github.io/serial/

API Documentation: http://wjwwood.github.io/serial/doc/1.1.0/index.html

Dependencies

Required:

  • catkin - cmake and Python based buildsystem
  • cmake - buildsystem
  • Python - scripting language
    • empy - Python templating library
    • catkin_pkg - Runtime Python library for catkin

Optional (for documentation):

  • Doxygen - Documentation generation tool
  • graphviz - Graph visualization software

Install

Get the code:

git clone https://github.com/wjwwood/serial.git

Build:

make

Build and run the tests:

make test

Build the documentation:

make doc

Install:

make install

License

The MIT License

Authors

William Woodall [email protected] John Harrison [email protected]

Contact

William Woodall [email protected]

serial's People

Contributors

achronop avatar aleksey-sergey avatar ashgti avatar avian2 avatar bakercp avatar billiegoose avatar bmoyer avatar bsbaliga avatar cralilley avatar daniser avatar darkdemiurg avatar davidhodo avatar dawid-aurobit avatar dontsovcmc avatar ericfont avatar hansmaad avatar jacobperron avatar jdiez17 avatar konstantinacc avatar linquize avatar mbehr1 avatar mikepurvis avatar natem345 avatar pao avatar rhd avatar rimco avatar robinkrens avatar seanyen avatar trainman419 avatar wjwwood avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

serial's Issues

Cannot flush I/O

Right now flushing is not supported, because it is not supported by boost... I have come up with a poor man's flush here:

this->serial_port.setTimeoutMilliseconds(1);
this->serial_port.read(1000); // Or some other big number
this->serial_port.setTimeoutMilliseconds(this->timeout);

It isn't optimal, but it will work.

If SetCommState fails shouldn't we close fd_ handle?

Hello,

I was wondering if in win.cc file, function Serial::SerialImpl::reconfigurePort (), lines 244-246:

  if (!SetCommState(fd_, &dcbSerialParams)){
    THROW (IOException, "Error setting serial port settings.");
  }

shouldn't we close fd_ handle if SetCommState function fails, before throwing the exception?

Thank you in advance.

Cross platform tests

Right now, the test source advertises that you need a hardware loopback, which isn't actually the case: it hooks up a Serial instance to a pty slave and talks to it using the corresponding master fd, all very posix-centric voodoo.

The obvious advantage of doing tests through a loopback is that the same test source could test both implementations—either using a hardware peripheral or software loopbacks.

On Windows, the magical com0com driver can provide a pair of virtual serial ports connected up to each other.

On Linux, we actually used to ship with Kingfisher a simple virtual serial program which did the same thing—provided a serial loopback pair.

At least on Linux, it could be automatic: the CMake target which runs the tests would have some pre- and post- rules attached to it which bring up and down the loopback, and then pass the port names/strings into the test via environment variables. It being automatic would allow the tests to run on Travis (which does not presently happen, but probably should).

FTDI D2XX impl

Just throwing this out here for consideration— it may be possible to detect when the connected serial device is a USB FTDI, and switch to using its native API:

http://www.ftdichip.com/Support/Documents/ProgramGuides/D2XX_Programmer's_Guide(FT_000071).pdf

The principal gain would be in readline performance, since the FTDI api provides a "block until character" mechanism. Unfortunately, the present design of Serial has readline provided by the main class rather than the impl, so some re-architecting would be necessary to realise this benefit.

Anyhow, feel free to close this if it's completely out-of-scope.

Compilation warning: "will be initialized after ..."

Initialization in a constructor is out of order, resulting in a warning (ArchLinux x86_64, gcc version 4.8.2 20131219 (prerelease))

The warning is:

In file included from tools.cpp:4:
serial.h: In copy constructor 'serial::IOException::IOException(const serial::IOException&)':
serial.h:647:15: warning: 'serial::IOException::e_what_' will be initialized after [-Wreorder]
    std::string e_what_;
            ^
serial.h:646:7: warning:   'int serial::IOException::line_' [-Wreorder]
    int line_;
    ^
serial.h:671:3: warning:   when initialized here [-Wreorder]
    IOException (const IOException& other) : e_what_(other.e_what_), line_(other.line_), errno_(other.errno_) {}

Buffer fillup issue with 20+ hz data stream

It appears that the call to select/pselect in Linux yields the thread, even when data is immediately available, and it should be a noop. I can't find documentation of this behaviour, but it's very clearly evident by monitoring serial_->available() on a sensor which returns data sentences at 50Hz.

I believe the fix is to prepopulate the read buffer from a ::read call prior to the first select call. This prevents select from ever being invoked if sufficient data is immediately available.

This issue affects both the master branch as well as the timespec refactor. I've added the fix for this in a9bf8d8, on the timespec refactor branch (ref #45). Would prefer not to bother with back-porting it.

Package for ROS Groovy

This is a great package! You should package and include it with ROS Groovy Galapagos.

Make errors on OS X

I just made a fresh checkout from source and I now receive the following errors:

They only appear on OS X because OS X is the only OS we enable warnings on.

Note: We should probably enable warnings on other operating systems. They can be really helpful for tracking down errors.

cd build && cmake -DSERIAL_BUILD_TESTS=1 -DSERIAL_BUILD_EXAMPLES=1 ..
Building stand alone
-- Found GTest: /usr/local/lib/libgtest.dylib
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/serial/build
cd build && make
Scanning dependencies of target serial
[ 25%] Building CXX object CMakeFiles/serial.dir/src/serial.o
In file included from /tmp/serial/src/serial.cc:3:
/tmp/serial/include/serial/serial.h:81:23: error: commas at the end of enumerator lists are a C++0x-specific feature [-pedantic]
flowcontrol_software,
^
/tmp/serial/src/serial.cc:136:24: error: variable length arrays are a C99 feature, accepted as an extension [-Wvla]
unsigned char buffer_[size];
^
/tmp/serial/src/serial.cc:145:46: warning: implicit conversion loses integer precision: 'size_t' (aka 'unsigned long') to 'char' [-Wconversion]
if (string(buffer_[read_so_far-eol_len], eol_len) == eol) {
~~~~~~ ^~~~~~~
/tmp/serial/src/serial.cc:132:27: warning: unused parameter 'buffer' [-Wunused-parameter]
Serial::readline (string &buffer, size_t size, string eol)
^
/tmp/serial/src/serial.cc:169:24: error: variable length arrays are a C99 feature, accepted as an extension [-Wvla]
unsigned char buffer_[size];
^
/tmp/serial/src/serial.cc:178:47: warning: implicit conversion loses integer precision: 'unsigned long' to 'char' [-Wconversion]
std::string(buffer_[start_of_line], read_so_far-start_of_line));
~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/serial/src/serial.cc:182:46: warning: implicit conversion loses integer precision: 'size_t' (aka 'unsigned long') to 'char' [-Wconversion]
if (string(buffer_[read_so_far-eol_len], eol_len) == eol) {
~~~~~~ ^~~~~~~
/tmp/serial/src/serial.cc:185:45: warning: implicit conversion loses integer precision: 'unsigned long' to 'char' [-Wconversion]
std::string(buffer_[start_of_line], read_so_far-start_of_line));
~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/serial/src/serial.cc:191:47: warning: implicit conversion loses integer precision: 'unsigned long' to 'char' [-Wconversion]
std::string(buffer_[start_of_line], read_so_far-start_of_line));
~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~
6 warnings and 3 errors generated.
make[3]: *** [CMakeFiles/serial.dir/src/serial.o] Error 1
make[2]: *** [CMakeFiles/serial.dir/all] Error 2
make[1]: *** [all] Error 2
make: *** [test] Error 2

General purpose mock/fake to aid testing serial port code

I'm just wrapping up work on a ROS sensor driver using Serial, and it would be really convenient if there were a general-purpose mock I could pass in, with back doors for filling out the read-from buffer and inspecting the contents of the written-to buffer.

Is such a thing available or in the works? If not, would there be interest in a pull request to add it?

From a quick look at the Serial source, it seems like it would be necessary to make a small modification to the existing source—either move the pimpl_ pointer to protected, so that an inheriting FakeSerial could change it to point somewhere else, or introduce a new constructor which allows the user to simply pass in the desired implementation (dependency injection).

From the perspective of a user of the library, it's possible of course to template it away and then use googlemock or similar, but it would be very convenient if testing helpers were simply provided.

Mixture of timeval and timespec in src/impl/unix.cc

Consider moving the select calls to use pselect instead, which takes a timespec in place of timeval.

Additionally, some of the time-related manipulation may be better served by an inheriting class which implements operators, some get_total_millis/set_total_millis methods, etc. Instances of such a class could be passed to system functions which expect timespec structs. Similar things found elsewhere:

https://code.google.com/p/solidground/source/browse/trunk/system/timespec.hpp#32
http://www.libcxx.org/libcxx/ref/classx_1_1timespec.html

Computer Freezes (OSX)

When running the below code on Max OSX my computer will completely freeze every third or fourth time at the end of the program, instead of exiting.

The screen will still refresh, but the entire computer ignores all keyboard and mouse input. The only solution I have found is to hold the power button to restart. I have replicated it with several different Arduino boards on the other end of the serial connection, also also with an official FTDI usb cable going to a microprocessor.

#include <iostream>
#include <cstdio>


// OS Specific sleep
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif

#include "serial/serial.h"

using namespace std;


struct SEND_DATA_STRUCTURE {
    uint8_t a;
    uint8_t b;
    uint8_t c;
    uint8_t d;
    uint8_t e;
    uint8_t f;
} __attribute__((packed));

SEND_DATA_STRUCTURE txdata;


void _os_sleep(unsigned long milliseconds) {
#ifdef _WIN32
      Sleep(milliseconds); // 100 ms
#else
      usleep(milliseconds*1000); // 100 ms
#endif
}


void help() {
    cerr << "Usage: test serial_port baudrate" << endl;
}


int run(int argc, char **argv) {

    if(argc < 3) {
        help();
        return 1;
    }

    string port(argv[1]);
    unsigned long baudrate;
#ifdef WIN32
    sscanf_s(argv[2], "%lu", &baudrate);
#else
    sscanf(argv[2], "%lu", &baudrate);
#endif

    // port, baudrate, timeout in milliseconds
    serial::Serial my_serial(
        port,
        baudrate,
        serial::Timeout::simpleTimeout(1000)
    );

    cout << "Is the serial port open?";
    if(my_serial.isOpen()) {
        cout << " Yes." << endl;
    } else {
        cout << " No." << endl;
    }

    uint8_t * address = (uint8_t *) &txdata;
    uint8_t magic1 = 0x06;
    uint8_t magic2 = 0x85;
    uint8_t size = 0;
    uint8_t CS = 0;

    // The send-recieve loop
    for(int i=0; i<10; i++) {
        txdata.a = 20;

        // Send
        size_t bytes_wrote = 0;
        bytes_wrote += my_serial.write(&magic1, 1);
        bytes_wrote += my_serial.write(&magic2, 1);
        size = sizeof(txdata);
        CS = size;
        bytes_wrote += my_serial.write(&size, 1);
        bytes_wrote += my_serial.write(address, size);
        for(int i=0; i<size; i++) {
            CS ^= *(address+i);
        }
        bytes_wrote += my_serial.write(&CS, 1);

        printf("Wrote %lu bytes, data payload was %u long\n", bytes_wrote, size);

        _os_sleep(1000);
    }


    return 0;
}


int main(int argc, char **argv) {
    try {
        return run(argc, argv);
    } catch (exception &e) {
        cerr << "Unhandled Exception: " << e.what() << endl;
    }
}

My computer is running OSX 10.9.1 (Late 2011 Mac Book Air) and I am compiling with g++ (the built in clang LLVM compiler). My directory structure was as follows;

screen shot 2014-01-07 at 3 04 51 pm

Apart from this issue, the library seems to work perfectly. Not sure if this is a bug with my code, or a bug with the library (I wasn't able to reduce my test case much more sorry).

Documentation request: exception list

As a user trying to write robust code using the serial library, it would be useful to know which exceptions might be thrown from each function, so that I can catch them and handle each error appropriately.

Loss of data in readlines

I have commands sent by an arduino board terminated with the eol ';'. When receiving multiple commands in the serial port very often, i noticed that there were some loss of data. For example, take a look at these two commands.
0,56,45;
1,34,34;
if, for example, at the momment of a call to readlines, and if there's only a simple timeout set, i receive some incomplete command, like '0,56,4', and a timeout occurs, this command is gonna be lost. That's not a desired behavior, since it's happening a lot with me. I had to make my own function to process the lines with some intermediary buffer, to hold that uncompleted line, or command.

Could this be improved somehow? Thanks

Build fail. Deps are installed. On arch linux machine

[cyborg@evo-van serial]$ make
cd build && cmake -DCMAKE_INSTALL_PREFIX=/tmp/usr/local ..
CMake Error at CMakeLists.txt:5 (find_package):
  By not providing "Findcatkin.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "catkin", but
  CMake did not find one.

  Could not find a package configuration file provided by "catkin" with any
  of the following names:

    catkinConfig.cmake
    catkin-config.cmake

  Add the installation prefix of "catkin" to CMAKE_PREFIX_PATH or set
  "catkin_DIR" to a directory containing one of the above files.  If "catkin"
  provides a separate development package or SDK, be sure it has been
  installed.


-- Configuring incomplete, errors occurred!
See also "blurrystuffIdontwantpeopletoseeeeee/serial/build/CMakeFiles/CMakeOutput.log".
Makefile:35: recipe for target 'serial' failed
make: *** [serial] Error 1

Can't compile sources on Kubuntu - Catkin issue

I tried to compile this library, but when i give make i receive this error message:

cd build && cmake -DCMAKE_INSTALL_PREFIX=/tmp/usr/local ..
CMake Error at CMakeLists.txt:5 (find_package):
  By not providing "Findcatkin.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "catkin", but
  CMake did not find one.

  Could not find a package configuration file provided by "catkin" with any
  of the following names:

    catkinConfig.cmake
    catkin-config.cmake

  Add the installation prefix of "catkin" to CMAKE_PREFIX_PATH or set
  "catkin_DIR" to a directory containing one of the above files.  If "catkin"
  provides a separate development package or SDK, be sure it has been
  installed.


-- Configuring incomplete, errors occurred!

I installed catkin with pip:

$ sudo pip install catkin_pkg

and i get the same error..

Sorry for my bad eng,
Thanks a lot...

Page fault when used with ROS.

Here's the simple piece of code that I'm trying to run:

#include <serial/serial.h>
#include <string.h>
#include <ros/ros.h>
#include <ros/console.h>

using std::string;

string stop("printtrigger 0 set drop\r\n");
string mask("printmask time_trigger yawt_trigger or roll_trigger or pitch_trigger or temp_trigger or accelp_trigger or magp_trigger or gyrop_trigger or set drop\r\n");
string rate("printmodulus 1 set drop\r\n");
string start("printtrigger printmask set drop\r\n");

int main(int argc, char **argv)
{

    string port("/dev/tty.usbserial-FTFUUY6A");
    unsigned int baudrate = 115200;

    ros::init(argc, argv, "IMU");


    serial::Serial IMU(port, baudrate, serial::Timeout::simpleTimeout(1000));

    IMU.write(stop);
    IMU.write(mask);
    IMU.write(rate);
    IMU.write(start);
    int c = 0;

    while(ros::ok() && c < 100){
        ROS_INFO("here");
        c++;
        ros::spinOnce(); //remove this and it works again
    }

    return 0;
}

As highlighted in the snipped, spinOnce() is causing a page fault. Here's the trace:

Sat May 10 19:20:13 2014
panic(cpu 1 caller 0xffffff802e2dbe7e): Kernel trap at 0x0000000000000000, type 14=page fault, registers:
CR0: 0x000000008001003b, CR2: 0x0000000000000000, CR3: 0x00000000307c5000, CR4: 0x00000000001606e0
RAX: 0xffffff8042c70280, RBX: 0xffffff804303b0b0, RCX: 0x0000000000000000, RDX: 0xffffff804303c110
RSP: 0xffffff81113f3bb8, RBP: 0xffffff81113f3c30, RSI: 0xffffff8042dc9900, RDI: 0xffffff8042e63a80
R8:  0x0000000000000000, R9:  0x0000000000000000, R10: 0xffffff8042e91e00, R11: 0xffffff802e6ae9a0
R12: 0x000000000000003e, R13: 0x000000000000003e, R14: 0xffffff804303b000, R15: 0x000000000000003e
RFL: 0x0000000000010246, RIP: 0x0000000000000000, CS:  0x0000000000000008, SS:  0x0000000000000010
Fault CR2: 0x0000000000000000, Error code: 0x0000000000000010, Fault CPU: 0x1

Backtrace (CPU 1), Frame : Return Address
0xffffff81113f3840 : 0xffffff802e222fa9 
0xffffff81113f38c0 : 0xffffff802e2dbe7e 
0xffffff81113f3a90 : 0xffffff802e2f3376 
0xffffff81113f3ab0 : 0x0 
0xffffff81113f3c30 : 0xffffff7faecdc7fd 
0xffffff81113f3d30 : 0xffffff7faee45166 
0xffffff81113f3de0 : 0xffffff7faee45f51 
0xffffff81113f3e20 : 0xffffff7faee5383e 
0xffffff81113f3ed0 : 0xffffff7faee5b475 
0xffffff81113f3ef0 : 0xffffff802e6ae0d0 
0xffffff81113f3f30 : 0xffffff802e6acb72 
0xffffff81113f3f80 : 0xffffff802e6acc47 
0xffffff81113f3fb0 : 0xffffff802e2d7047 
      Kernel Extensions in backtrace:
         com.apple.iokit.IOUSBFamily(675.4)[5C861553-BC5A-3979-A6B4-58C57879DD40]@0xffffff7faecd9000->0xffffff7faed39fff
            dependency: com.apple.iokit.IOPCIFamily(2.9)[EDA75271-4E9D-34E7-A2C5-14F0C8817D37]@0xffffff7fae8ba000
         com.apple.driver.AppleUSBXHCI(670.4)[91761100-07BD-32B9-AAE7-6BE5C6623809]@0xffffff7faee44000->0xffffff7faee60fff
            dependency: com.apple.iokit.IOUSBFamily(675.4.0)[5C861553-BC5A-3979-A6B4-58C57879DD40]@0xffffff7faecd9000
            dependency: com.apple.iokit.IOPCIFamily(2.9)[EDA75271-4E9D-34E7-A2C5-14F0C8817D37]@0xffffff7fae8ba000

BSD process name corresponding to current thread: kernel_task

Mac OS version:
13C1021

Kernel version:
Darwin Kernel Version 13.1.0: Wed Apr  2 23:52:02 PDT 2014; root:xnu-2422.92.1~2/RELEASE_X86_64
Kernel UUID: E9CF78E2-1E9F-3B6F-81A4-FEE6C6D0E4D5
Kernel slide:     0x000000002e000000
Kernel text base: 0xffffff802e200000
System model name: MacBookPro10,2 (Mac-AFD8A9D944EA4843)

I can verify that there is nothing wrong with the serial device as anything without ros::Spin() or ros::spinOnce() works as supposed to.

Compile-Time Error: Undefined reference to 'openpty'

I cloned the Serial git repository into a directory in my ROS_PACKAGE_PATH and when I run "make test", I get the following error:

CMakeFiles/serial_tests.dir/tests/serial_tests.o: In function SetUp': /home/liang/ros_workspace/serial/tests/serial_tests.cc:47: undefined reference toopenpty'
../lib/libserial.so: undefined reference to `clock_gettime'
collect2: ld returned 1 exit status

I got the above error on two different machines, one running Ubuntu 12.04 and ROS Fuerte and the other running Ubuntu 11.10 and ROS electric.

When I run "rosmake" it compiles without failure on both machines.

boostless branch doesn't compile on Ubuntu Maverick

When I try to build serial (git:boostless:c3a8275) on Ubuntu Maverick, using the build with ROS option I get this:

∫ make
mkdir -p bin
cd build && cmake -Wdev -DCMAKE_TOOLCHAIN_FILE=`rospack find rosbuild`/rostoolchain.cmake  ..
Building with ROS
[rosbuild] Building package serial
[rosbuild] Including /opt/ros/electric/stacks/ros_comm/clients/rospy/cmake/rospy.cmake
[rosbuild] Including /opt/ros/electric/stacks/ros_comm/clients/roslisp/cmake/roslisp.cmake
[rosbuild] Including /opt/ros/electric/stacks/ros_comm/clients/cpp/roscpp/cmake/roscpp.cmake
-- Configuring done
-- Generating done
-- Build files have been written to: /home/william/atrv_ws/serial/build
cd build && make 
make[1]: Entering directory `/home/william/atrv_ws/serial/build'
make[2]: Entering directory `/home/william/atrv_ws/serial/build'
make[3]: Entering directory `/home/william/atrv_ws/serial/build'
make[3]: Leaving directory `/home/william/atrv_ws/serial/build'
[  0%] Built target rospack_genmsg_libexe
make[3]: Entering directory `/home/william/atrv_ws/serial/build'
make[3]: Leaving directory `/home/william/atrv_ws/serial/build'
[  0%] Built target rosbuild_precompile
make[3]: Entering directory `/home/william/atrv_ws/serial/build'
make[3]: Leaving directory `/home/william/atrv_ws/serial/build'
make[3]: Entering directory `/home/william/atrv_ws/serial/build'
[ 20%] Building CXX object CMakeFiles/serial.dir/src/impl/unix.o
/home/william/atrv_ws/serial/src/impl/unix.cc: In member function ‘void serial::Serial::SerialImpl::reconfigurePort()’:
/home/william/atrv_ws/serial/src/impl/unix.cc:218: error: aggregate ‘serial_struct ser’ has incomplete type and cannot be defined
/home/william/atrv_ws/serial/src/impl/unix.cc:221: error: ‘baudrate’ was not declared in this scope
/home/william/atrv_ws/serial/src/impl/unix.cc:223: error: ‘ASYNC_SPD_MASK’ was not declared in this scope
/home/william/atrv_ws/serial/src/impl/unix.cc:224: error: ‘ASYNC_SPD_CUST’ was not declared in this scope
/home/william/atrv_ws/serial/src/impl/unix.cc:226: error: ‘buf’ was not declared in this scope
make[3]: *** [CMakeFiles/serial.dir/src/impl/unix.o] Error 1
make[3]: Leaving directory `/home/william/atrv_ws/serial/build'
make[2]: *** [CMakeFiles/serial.dir/all] Error 2
make[2]: Leaving directory `/home/william/atrv_ws/serial/build'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/home/william/atrv_ws/serial/build'
make: *** [all] Error 2

Not sure what is the deal here, a missing header?

Return value of close(fd_) in unix.cc

Hello,

In Serial::SerialImpl::close () function of unix.cc file the return value of close(fd_) is not checked. Nevertheless, function close() returns 0 on success and -1 on error and is recommended to check the return value.

Please see link: http://linux.die.net/man/2/close

Is there any special reason that the return value of the function is ignored?

Thank you,
K.

serialConfig.cmake not found

I was able to successfully build and install serial but I can't include it in my CMake project.

This is the error I get:

CMake Warning at src/CMakeLists.txt:21 (find_package):
  By not providing "Findserial.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "serial", but
  CMake did not find one.

  Could not find a package configuration file provided by "serial" with any
  of the following names:

    serialConfig.cmake
    serial-config.cmake

  Add the installation prefix of "serial" to CMAKE_PREFIX_PATH or set
  "serial_DIR" to a directory containing one of the above files.  If "serial"
  provides a separate development package or SDK, be sure it has been
  installed.

I believe it's because serial itself doesn't provide a package configuration file. Is there any solution to this problem?

Thread safety

Make sure that the serial port is properly thread safe.

Also, look into removing boost from the threading components to remove another dependency on boost.

Example Arduino Code in serial_example missing return type

In the comments at the top of serial/examples/serial_example.cc, there is an example Arduino program that transforms the Arduino into a serial loop-back device. The code is missing a "void" return type in the definitions of the setup() and loop() methods.

Make test fails to link properly on Ubuntu 11.04

On Ubuntu 11.04 when I try to build make test it fails to link against libgtest.so properly because it seems to be missing pthreads? I will look into the issue.

$ make test
cd build && cmake -DSERIAL_BUILD_TESTS=1 -DSERIAL_BUILD_EXAMPLES=1 ..
Building stand alone
-- Found GTest: /usr/lib/libgtest.so
-- Configuring done
-- Generating done
-- Build files have been written to: /home/parallels/Projects/serial/build
cd build && make
make[1]: Entering directory /home/parallels/Projects/serial/build' make[2]: Entering directory/home/parallels/Projects/serial/build'
make[3]: Entering directory /home/parallels/Projects/serial/build' make[3]: Leaving directory/home/parallels/Projects/serial/build'
[ 50%] Built target serial
make[3]: Entering directory /home/parallels/Projects/serial/build' Scanning dependencies of target serial_example make[3]: Leaving directory/home/parallels/Projects/serial/build'
make[3]: Entering directory /home/parallels/Projects/serial/build' [ 75%] Building CXX object CMakeFiles/serial_example.dir/examples/serial_example.o Linking CXX executable ../bin/serial_example make[3]: Leaving directory/home/parallels/Projects/serial/build'
[ 75%] Built target serial_example
make[3]: Entering directory /home/parallels/Projects/serial/build' Scanning dependencies of target serial_tests make[3]: Leaving directory/home/parallels/Projects/serial/build'
make[3]: Entering directory /home/parallels/Projects/serial/build' [100%] Building CXX object CMakeFiles/serial_tests.dir/tests/serial_tests.o Linking CXX executable ../bin/serial_tests /usr/lib64/libgtest.so: undefined reference topthread_key_create'
/usr/lib64/libgtest.so: undefined reference to pthread_getspecific' /usr/lib64/libgtest.so: undefined reference topthread_key_delete'
/usr/lib64/libgtest.so: undefined reference to pthread_setspecific' collect2: ld returned 1 exit status make[3]: *** [../bin/serial_tests] Error 1 make[3]: Leaving directory/home/parallels/Projects/serial/build'
make[2]: *** [CMakeFiles/serial_tests.dir/all] Error 2
make[2]: Leaving directory /home/parallels/Projects/serial/build' make[1]: *** [all] Error 2 make[1]: Leaving directory/home/parallels/Projects/serial/build'
make: *** [test] Error 2

Setting timeout with simpleTimeout() prevents reading

Not sure if this is a bug or an error of mine, but still reporting just in case.

I'm running this on Windows 7 64 bits for now.

The constructor I use with Serial is empty. I then call specific set*() functions to configure the serial port:

sr.setPort(port);
sr.setBaudrate(9600);
sr.setBytesize(serial::eightbits);
sr.setParity(serial::parity_none);
sr.setStopbits(serial::stopbits_one);

If I then set the timeout, for example using:

serial::Timeout to = serial::Timeout::simpleTimeout(2000);
sr.setTimeout(to);

then I cannot read from the port (writing works). My device is normally responding with 6 bytes after a 6 bytes write. When setting the timeout as above, Only 1 byte is read, and it seems to be 0.

If I don't call setTimeout() at all, then everything works as expected...

Anything I'm doing wrong? Or is it really an issue with the library?

Implement Select Based UNIX inerface

We need to implement a select based unix implementation that also considers the possibility of using kqueue or epoll or Windows calls in the future.

Determine design and implementation methods for asynchronous events

Consider this:

Two serial ports are open in the same process and the select function is being called on both FID for the two serial ports from one thread.

What if two reads are requested with different timeouts?

What if a read for serial port 1 is called with a timeout of 20 secs and 2 secs later a read with a timeout of 10 secs is called on the second serial port?

Major decisions:

One select "server" using libev style event handling (how does this work anyways?) OR using a separate thread and select call for each serial port.

Do either of these methods effect a future implementation in kqueue or epoll or Windows?

Other considerations:

  • Support for handshaking line events.
  • Canceling timed events.

Less Dependencies?

Can this library have less dependencies?

I would love a cross-platform library thats just a bunch of c or c++ code that I can dump into my existing code and then have serial communication - just like that.

This library I wont even try because of all the dependencies - seems like a hazzle to ask users to install all that.

Serial::available() not const

Is there any reason for Serial::available() method not being defined as const?

when in do this:

    class SerialTransport
    {
         public:
            ...
            size_t bytesAvailable() const;
            ...
     };

    size_t SerialTransport::bytesAvailable() const
    {
         return serial_port_.available();
    }

i get the error:
(in clang) member function 'available' not viable: 'this' argument has type 'const serial::Serial'

(in gcc) error: passing 'const serial::Serial' as 'this' argument of 'std::size_t serial::Serial::available' discards qualifiers [-fpermissive]
return serial_port_.available();

but if i define Serial::available() const in serial.cc, serial.h, also in the impl, it compiles.

IO Exception (14)

Hello!

I use your library to connect to dynamixel servos (http://www.robotis.com/xe/). I downloaded serial library and used it in my project about half a year ago. Today I have decided to update serial library. My code stopped working with following output: "IO Exception (14): Неправильный адрес, file /home/dmitry/software/serial/src/impl/unix.cc, line 235.". In English it means: "IO Exception (14): Incorrect address, file /home/dmitry/software/serial/src/impl/unix.cc, line 235.".

Here is a piece of code were the problem is:

    try {
        m_port->setPort(portName);
        serial::Timeout timeout = serial::Timeout::simpleTimeout(answerTimeout);
        m_port->setTimeout(timeout);
        m_port->setBaudrate(baudRate);
        m_port->setBytesize(serial::eightbits);
        m_port->setFlowcontrol(serial::flowcontrol_none);
        m_port->setParity(serial::parity_none);
        m_port->setStopbits(serial::stopbits_one);
        m_port->open(); // This method always prints specified message. No exceptions are generated.
    }
    catch(const std::exception& e) {
        std::cerr << e.what( ) << std::endl;
    }
    catch(...) {
        std::cerr << "unknown exception" << std::endl;
    }

    bool portState = m_port->isOpen(); // This method always returns false.

"portName" is set to correct value. Port is available for reading, writing and opening. "baudRate" is set to 1000000.

Here you can see the whole project: https://github.com/wicron/vdyna. This part of code is written in v_dynamixel_controller.cpp.

I use OpenSuse 11.4 x64.

Can't read a single line

My board is spitting out lines separated by "\r\n" at an arbitrary refresh rate x Hz.

I can't seem to read data line by line and flush() doesn't work.

Any idea how to use it?

serial_example.cc Command Arguments

Hello,

What could be a valid value argument for the serial port in order to run the example?
I tried COM1,COM2,etc and keep receiving the following error:
"unhandled exception: I/O Exception:specified port, port_name, doesn't exist."

Any ideas?

Style Checker Crashes on OS X with Python 3.1.3

When I run make check-styles I get this error on OS X with Python 3.1.3:

Python 3.1.3 (r313:86834, Jul  7 2011, 18:01:03) 
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin

Darwin Arepa.local 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun  7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386

Error:

find . | grep "\.h" | xargs python tools/cpplint.py --filter=-build/include
  File "tools/cpplint.py", line 1115
    if u'\ufffd' in line:
               ^
SyntaxError: invalid syntax
make: *** [check-styles] Error 1

I think changing my default python will fix this, but I would like to have it work on Python3 too.

Reduce CPU usage for multi-byte reads

The way read/select are implemented in unix.cc means that block reads are typically still pulling data a few bytes at a time. This can consume a lot of CPU for reads of 20+ consecutive bytes.

One of our customers has handled this by adding a lowlevel_read method, which gives the user a direct line to the underlying read() method: https://github.com/cedricpradalier/serial/blob/master/src/impl/unix.cc#L421

Another alternative would be to introduce a usleep between the select and read calls. If you know how many bytes are expected and the baud rate, you can compute how long of a pause will allow the entire message to arrive. I don't know how well aligned such functionality would be with the design goals of Serial, but it's something to consider.

As it stands, we have a sensor which mostly saturates a 115kbps serial line, and its Serial-based driver is still taking more CPU than we'd like.

Better Tests

The current tests are very basic. Given that a major feature of this library is timing control, there could be tests which set specific timeout configurations of the read and write timeouts and feed bytes in particular ways to trigger or not-trigger those timeouts. Each one could run nnn trials, to increase the likelihood of hitting weird bugs with timer wraparounds, etc.

Also, since we're talking a lot about what's efficient or not efficient, there could also be some tests which mimic real-world usages, things like "read 10000 bytes of data which arrive one byte at a time", "read 12-byte chunks of data which arrives 24 bytes every 10ms", "read \n-terminated ascii strings at 5Hz", etc. These tests could use clock() to measure approximate CPU usage, and be checked against set ceilings to catch regressions (or improvements) when changes are made.

Problem with setting timout

Hello,

I am having a problem setting the timeout. I am using ROS Hydro. I've catkin installed serial, and used rosbuild to build serial_utils. In my program I have the line

this->serial_port_->setTimeout(10);

When I try to run this I get the error

no matching function for call to 'serial::Serial::setTimeout(Int)'

When I tried changing the line to

this->serial_port_->setTimeout(10,10,10,10,10);

This gives me

  ../lib/libax2550.so: undefined reference to serial::Serial::setBytesize(serial::bytesize_t)'
  ../lib/libax2550.so: undefined reference to `serial::Serial::setBaudrate(unsigned int)'
  ../lib/libax2550.so: undefined reference to `serial::Serial::setTimeout(serial::Timeout&)'
  ../lib/libax2550.so: undefined reference to `serial::utils::SerialListener::SerialListener(unsigned long)'
  ../lib/libax2550.so: undefined reference to `serial::Serial::Serial(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int, serial::Timeout, serial::bytesize_t, serial::parity_t, serial::stopbits_t, serial::flowcontrol_t)'
  ../lib/libax2550.so: undefined reference to `serial::utils::SerialListener::startListening(serial::Serial&)'
  ../lib/libax2550.so: undefined reference to `serial::Serial::open()'
  ../lib/libax2550.so: undefined reference to `serial::Serial::write(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
  ../lib/libax2550.so: undefined reference to `serial::utils::SerialListener::~SerialListener()'
  ../lib/libax2550.so: undefined reference to `serial::Serial::setPort(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
  ../lib/libax2550.so: undefined reference to `serial::utils::SerialListener::createBufferedFilter(boost::function<bool (std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, unsigned long)'
  ../lib/libax2550.so: undefined reference to `serial::utils::SerialListener::stopListening()'
  ../lib/libax2550.so: undefined reference to `serial::Serial::setStopbits(serial::stopbits_t)'
  ../lib/libax2550.so: undefined reference to `serial::Serial::setParity(serial::parity_t)'
  ../lib/libax2550.so: undefined reference to `serial::utils::SerialListener::createFilter(boost::function<bool (std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::function<void (std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>)'

Purpose of read_cache_ member variable?

Not in use anywhere in the current/boostless implementation. Suggestion is for one of the following resolutions:

  • Remove the unused member, or
  • Make the read functions return data from the cache while there is cached data to return. In addition, create a putBack(std::string) method which allows the return of unconsumed data (for example, from an unbounded read() call) to the cache for future reads.

The second option does leave open the possibility of including a lazy readline() implementation in the library down the road, without requiring a wrapper class.

Compile fails on OSX ... can't find library rt

Looking at your CMakeLists.txt I don't think you want to add rt unless you are linux. I get the following error when it tries to build:

[kevin@tardis serial]$ make
cd build && cmake -DCMAKE_INSTALL_PREFIX=/tmp/usr/local ..
-- The C compiler identification is Clang 4.1.0
-- The CXX compiler identification is Clang 4.1.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Using CATKIN_DEVEL_PREFIX: /Users/kevin/tmp/serial/build/devel
-- Using CMAKE_PREFIX_PATH: /opt/ros/groovy
-- This workspace overlays: /opt/ros/groovy
-- Found PythonInterp: /usr/bin/python (found version "2.7.2") 
-- Found PY_em: /Library/Python/2.7/site-packages/em.pyc  
-- Found gtest: gtests will be built
-- catkin 0.5.52
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/kevin/tmp/serial/build
cd build && make
Scanning dependencies of target serial
[ 33%] Building CXX object CMakeFiles/serial.dir/src/serial.cc.o
[ 66%] Building CXX object CMakeFiles/serial.dir/src/impl/unix.cc.o
Linking CXX shared library devel/lib/libserial.dylib
ld: library not found for -lrt
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [devel/lib/libserial.dylib] Error 1
make[2]: *** [CMakeFiles/serial.dir/all] Error 2
make[1]: *** [all] Error 2
make: *** [serial] Error 2

You need to change CMakeLists.txt where you add library rt:

 if (UNIX AND NOT APPLE)
    target_link_libraries(${PROJECT_NAME} rt)
endif()

Here is the diff:

[kevin@tardis serial]$ git diff
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7ea1c80..216bc04 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -37,7 +37,7 @@ endif()
 add_library(${PROJECT_NAME}
     ${serial_SRCS}
 )
-if (UNIX)
+if (UNIX AND NOT APPLE)
     target_link_libraries(${PROJECT_NAME} rt)
 endif()

Specified port, COMX, does not exist (Windows)

Just an FYI. There seems to be some port number, beyond which the Serial constructor throws a IO Exception on Windows. When my device was enumerated at COM20 (with -e in test_serial), trying to connect to it throws. When I changed to COM2 it worked as expected. I have had this problem with Windows software before so I knew to try that...I can't remember the root cause.

C:\Users\AndersonM\Documents\Visual Studio 2013\Projects\wjwwood-serial-6e47bdd\
visual_studio\Debug>test_serial.exe -e
(COM20, USB Serial Port (COM20), FTDIBUS\COMPORT&VID_0403&PID_6001)

C:\Users\AndersonM\Documents\Visual Studio 2013\Projects\wjwwood-serial-6e47bdd\
visual_studio\Debug>test_serial.exe "COM20" 57600
Unhandled Exception: IO Exception: Specified port, COM20, does not exist., file
c:\users\andersonm\documents\visual studio 2013\projects\wjwwood-serial-6e47bdd\
src\impl\win.cc, line 71.

Compile serial_example.cc

Hello all,

I am trying to install serial 1.1.0 http://wjwwood.io/serial/doc/1.1.0/index.html in order to compile serial_example.cc but I am not sure if the process that I follow is correct.

Up to now I have performed the following steps:

  1. Downloaded and installed Visual C++
  2. Downloaded and installed cmake-2.8.12.1-win32-x86.exe from http://www.cmake.org/cmake/resources/software.html
  3. Downloaded cmake-2.8.12.1.zip from http://www.cmake.org/cmake/resources/software.html
  4. Created a folder in C:\Konst\cmake-2.8.12.1 and unzipped cmake-2.8.12.1.zip
  5. Opened CMake (cmake-gui) and selected Where is the source code:C:\Konst\cmake-2.8.12.1 and Where to build the binaries:C:\Konst\build
  6. Clicked on Configure and then Generate.
  7. Downloaded and unzipped wjwwood-serial-15d37ac from https://github.com/wjwwood/serial/releases
  8. Opened CMake (cmake-gui) and selected Where is the source code:C:\Konst\wjwwood-serial-15d37ac and Where to build the binaries:C:\Konst\build serial
  9. I receive the following error:
    "CMake Error at CMakeLists.txt:5 (find_package):
    By not providing "Findcatkin.cmake" in CMAKE_MODULE_PATH this project has
    asked CMake to find a package configuration file provided by "catkin", but
    CMake did not find one.

Could not find a package configuration file provided by "catkin" with any
of the following names:

catkinConfig.cmake
catkin-config.cmake

Add the installation prefix of "catkin" to CMAKE_PREFIX_PATH or set
"catkin_DIR" to a directory containing one of the above files. If "catkin"
provides a separate development package or SDK, be sure it has been
installed."

What am I doing wrong? Is there another way to install serial?
configure_cmake
configure_serial

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.