1
0
mirror of https://github.com/wjwwood/serial.git synced 2026-01-23 04:04:54 +08:00

Simple sync read working.

This commit is contained in:
William Woodall 2011-03-16 08:03:54 -05:00
parent ab455881b2
commit 7587b16fd0
7 changed files with 384 additions and 0 deletions

30
serial/CMakeLists.txt Normal file
View File

@ -0,0 +1,30 @@
cmake_minimum_required(VERSION 2.4.6)
include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
# Set the build type. Options are:
# Coverage : w/ debug symbols, w/o optimization, w/ code-coverage
# Debug : w/ debug symbols, w/o optimization
# Release : w/o debug symbols, w/ optimization
# RelWithDebInfo : w/ debug symbols, w/ optimization
# MinSizeRel : w/o debug symbols, w/ optimization, stripped binaries
#set(ROS_BUILD_TYPE RelWithDebInfo)
rosbuild_init()
#set the default path for built executables to the "bin" directory
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
#set the default path for built libraries to the "lib" directory
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
#uncomment if you have defined messages
#rosbuild_genmsg()
#uncomment if you have defined services
#rosbuild_gensrv()
#common commands for building c++ executables and libraries
rosbuild_add_library(${PROJECT_NAME} src/serial.cpp)
#target_link_libraries(${PROJECT_NAME} another_library)
rosbuild_add_boost_directories()
rosbuild_link_boost(${PROJECT_NAME} system filesystem thread)
rosbuild_add_executable(test_serial src/test_serial.cpp)
target_link_libraries(test_serial serial)

1
serial/Makefile Normal file
View File

@ -0,0 +1 @@
include $(shell rospack find mk)/cmake.mk

167
serial/include/serial.h Normal file
View File

@ -0,0 +1,167 @@
/**
* @file serial.h
* @author William Woodall <wjwwood@gmail.com>
* @version 0.1
*
* @section LICENSE
*
* The MIT License
*
* Copyright (c) 2011 William Woodall
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @section DESCRIPTION
*
* This provides a cross platform interface for interacting with Serial Ports.
*/
#ifndef SERIAL_H
#define SERIAL_H
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/asio/serial_port.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#define READ_BUFFER_SIZE 4
#define SERIAL_BUFFER_SIZE 1024
class Serial {
public:
/** Constructor, creates a SerialPortBoost object without opening a port. */
Serial();
/**
* Constructor, creates a SerialPortBoost object and opens the port.
*
* @param port A std::string containing the address of the serial port,
* which would be something like 'COM1' on Windows and '/dev/ttyS0'
* on Linux.
*
* @param baudrate An integer that represents the buadrate
*
* @param timeout A double that represents the time (in seconds) until a
* timeout on reads occur. Setting this to a negative number will
* silently disable the timeout on reads.
*/
Serial(std::string port, int baudrate = 9600, double timeout = -1.0);
// Serial(string port, int baudrate = 9600, int bytesize = EIGHTBITS, int parity = PARITY_NONE, int stopbits = STOPBITS_ONE, double timeout = -1.0, bool xonxoff = false, bool rtscts = false, double writeTimeout = -1.0, bool dsrdtr = false, double interCharTimeout = -1.0);
/** Destructor */
~Serial();
/** Opens the serial port as long as the portname is set and the port isn't alreay open. */
void open();
/** Closes the serial port and terminates threads. */
void close();
/** Read size bytes from the serial port.
* If a timeout is set it may return less characters than requested. With no timeout
* it will block until the requested number of bytes have been read.
*
* @param buffer A char[] of length >= the size parameter to hold incoming data.
*
* @param size An integer defining how many bytes to be read.
*
* @return An integer representing the number of bytes read.
*/
int read(char* buffer, int size = 1);
/** Read size bytes from the serial port.
* If a timeout is set it may return less characters than requested. With no timeout
* it will block until the requested number of bytes have been read.
*
* @param size An integer defining how many bytes to be read.
*
* @return A std::string containing the data read.
*/
std::string read(int size=1);
/** Write length bytes from buffer to the serial port.
*
* @param data A char[] with data to be written to the serial port.
*
* @param length An integer representing the number of bytes to be written.
*
* @return An integer representing the number of bytes written.
*/
int write(char data[], int length);
/** Write a string to the serial port.
*
* @param data A std::string to be written to the serial port. (must be null terminated)
*
* @return An integer representing the number of bytes written to the serial port.
*/
int write(std::string data);
/** Checks the number of bytes waiting in the buffer.
*
* @return An integer representing the number of bytes in the serial buffer.
*/
int inWaiting();
/** Flushes the write buffer, blocks untill all data has been written. */
void flush();
/** Sets the logic level of the RTS line.
*
* @param level The logic level to set the RTS to. Defaults to true.
*/
void setRTS(bool level = true);
/** Sets the logic level of the DTR line.
*
* @param level The logic level to set the DTR to. Defaults to true.
*/
void setDTR(bool level = true);
/** Gets the status of the CTS line.
*
* @return A boolean value that represents the current logic level of the CTS line.
*/
bool getCTS();
/** Gets the status of the DSR line.
*
* @return A boolean value that represents the current logic level of the DSR line.
*/
bool getDSR();
private:
boost::asio::io_service io_service;
boost::asio::serial_port *serial_port;
boost::thread * io_service_thread;
char read_buffer[READ_BUFFER_SIZE];
std::string port;
int baudrate;
double timeout;
};
#endif

26
serial/mainpage.dox Normal file
View File

@ -0,0 +1,26 @@
/**
\mainpage
\htmlinclude manifest.html
\b boostserial is ...
<!--
Provide an overview of your package.
-->
\section codeapi Code API
<!--
Provide links to specific auto-generated API documentation within your
package that is of particular interest to a reader. Doxygen will
document pretty much every part of your code, so do your best here to
point the reader to the actual API.
If your codebase is fairly large or has different sets of APIs, you
should use the doxygen 'group' tag to keep these APIs together. For
example, the roscpp documentation has 'libros' group.
-->
*/

15
serial/manifest.xml Normal file
View File

@ -0,0 +1,15 @@
<package>
<description brief="serial">
serial
</description>
<author>William Woodall</author>
<license>BSD</license>
<review status="unreviewed" notes=""/>
<url>http://ros.org/wiki/serial</url>
<depend package="roscpp"/>
</package>

95
serial/src/serial.cpp Normal file
View File

@ -0,0 +1,95 @@
#include "serial.h"
Serial::Serial() {
;
}
Serial::Serial(std::string port, int baudrate, double timeout) {
this->port = port;
this->baudrate = baudrate;
this->timeout = timeout;
this->open();
}
Serial::~Serial() {
;
}
void Serial::open() {
this->serial_port = new boost::asio::serial_port(this->io_service, this->port);
if(not serial_port->is_open()) {
std::cerr << "[AX2550] Failed to open serial port: " << this->port << std::endl;
return;
}
try {
this->serial_port->set_option(boost::asio::serial_port_base::baud_rate(this->baudrate));
// this->serial_port->set_option(
// boost::asio::serial_port_base::flow_control(
// boost::asio::serial_port_base::flow_control::none));
// this->serial_port->set_option(
// boost::asio::serial_port_base::parity(
// boost::asio::serial_port_base::parity::even));
// this->serial_port->set_option(
// boost::asio::serial_port_base::stop_bits(
// boost::asio::serial_port_base::stop_bits::one));
// this->serial_port->set_option(boost::asio::serial_port_base::character_size(7));
} catch(std::exception &e) {
std::cerr << "[AX2550] Error opening serial port: " << e.what() << std::endl;
try {
if(this->serial_port->is_open())
this->serial_port->close();
} catch(std::exception &e) {
std::cerr << "[AX2550] Error closing serial port: " << e.what() << std::endl;
}
this->serial_port = NULL;
}
}
void Serial::close() {
;
}
int Serial::read(char* buffer, int size) {
return this->serial_port->read_some(boost::asio::buffer(buffer, size));
}
std::string Serial::read(int size) {
char serial_buffer[size];
int number_read = this->serial_port->read_some(boost::asio::buffer(serial_buffer, size));
serial_buffer[number_read] = NULL;
return std::string(serial_buffer);
}
int Serial::write(char data[], int length) {
return -1;
}
int Serial::write(std::string data) {
return -1;
}
int Serial::inWaiting() {
return -1;
}
void Serial::flush() {
;
}
void Serial::setRTS(bool level) {
;
}
void Serial::setDTR(bool level) {
;
}
bool Serial::getCTS() {
return false;
}
bool Serial::getDSR() {
return false;
}

View File

@ -0,0 +1,50 @@
#include "ros/ros.h"
#include <string>
#include <iostream>
#include "serial.h"
Serial *serial;
std::string toHex(std::string input) {
std::stringstream ss;
for(int i = 0; i != input.length(); i++) {
char temp[4];
sprintf(temp, "%.2X", input[i]);
ss << " ";
if(input[i] == 0x0A)
ss << "LF";
else if(input[i] == 0x0D)
ss << "NL";
else
ss << input[i];
ss << " " << std::hex << temp;
}
return ss.str();
};
int main(int argc, char **argv)
{
ros::init(argc, argv, "serial_test_node");
ros::NodeHandle n;
std::string port("/dev/tty.usbserial-A900cfJA");
serial = new Serial(port);
ros::Rate loop_rate(10);
while (ros::ok()) {
std::string result = serial->read(1);
ROS_INFO("%d,%s", result.length(), toHex(result).c_str());
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}