目前有两种读取串口的代码实现,分别如下所示,第一种实现起来较为简单,复制下面的代码编译就能使用。第二种方法需要安装依赖项,具体步骤后面详细介绍。
方法一:
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
int set_interface_attribs(int fd, int speed)
{
struct termios tty;
if (tcgetattr(fd, &tty) < 0) {
printf("Error from tcgetattr: %s\n", strerror(errno));
return -1;
}
cfsetospeed(&tty, (speed_t)speed);
cfsetispeed(&tty, (speed_t)speed);
tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; /* 8-bit characters */
tty.c_cflag &= ~PARENB; /* no parity bit */
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */
/* setup for non-canonical mode */
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
tty.c_oflag &= ~OPOST;
/* fetch bytes as they become available */
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 1;
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
printf("Error from tcsetattr: %s\n", strerror(errno));
return -1;
}
return 0;
}
void set_mincount(int fd, int mcount)
{
struct termios tty;
if (tcgetattr(fd, &tty) < 0) {
printf("Error tcgetattr: %s\n", strerror(errno));
return;
}
tty.c_cc[VMIN] = mcount ? 1 : 0;
tty.c_cc[VTIME] = 5; /* half second timer */
if (tcsetattr(fd, TCSANOW, &tty) < 0)
printf("Error tcsetattr: %s\n", strerror(errno));
}
int main()
{
char *portname = "/dev/ttyUSB0";
int fd;
int wlen;
fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0) {
printf("Error opening %s: %s\n", portname, strerror(errno));
return -1;
}
/*baudrate 115200, 8 bits, no parity, 1 stop bit */
set_interface_attribs(fd, B115200);
//set_mincount(fd, 0); /* set to pure timed read */
/* simple output */
wlen = write(fd, "Hello!\n", 7);
if (wlen != 7) {
printf("Error from write: %d, %d\n", wlen, errno);
}
tcdrain(fd); /* delay for output */
/* simple noncanonical input */
do {
unsigned char buf[80];
int rdlen;
rdlen = read(fd, buf, sizeof(buf) - 1);
if (rdlen > 0) {
cout<<buf<<endl;
} else if (rdlen < 0) {
printf("Error from read: %d: %s\n", rdlen, strerror(errno));
}
/* repeat read to get full message */
} while (1);
}
方法二:
1.在如下github网址中拉去代码。
https://github.com/wjwwood/serial/releases
2.按照如下方法添加更新库
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu quantal main" > /etc/apt/sources.list.d/ros-latest.list'
wget http://packages.ros.org/ros.key -O - | sudo apt-key add -
sudo apt-get update
3.安装依赖项
sudo apt-get install cmake python-catkin-pkg python-empy python-nose python-setuptools libgtest-dev build-essential
4.安装catkin_pkg
登录https://github.com/ros-infrastructure/catkin_pkg/releases下载最新版本,在文件夹下。
sudo make install
5.打开第一步中拉取的代码文件夹
sudo make install
6.简单代码例程
通过串口读取NMEA的GPS协议
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <iostream>
#include <string>
#include <regex>
#include <regex.h>
#include <assert.h>
#include "gps2local.h"
#include "serial/serial.h"
#include <fstream>
#include <vector>
#include <boost/algorithm/string.hpp>
using namespace boost;
int fd;//the serial
using namespace std;
void serial_rec(void) //get serial data and change to xy and 2-5 11-12
{
/*open the serial and config*/
serial::Serial my_serial("/dev/ttyUSB0", 115200, serial::Timeout::simpleTimeout(1000));
cout << "Is the serial port open?";
if(my_serial.isOpen())
cout << " Yes." << endl;
else
cout << " No." << endl;
my_serial.flushInput();
/*open the serial and config*/
/*log*/
ofstream serf;
ofstream findf;
serf.open("buf.txt");
findf.open("gga.txt");
/*log*/
const int buf_size = 9999;
/*find gpgga*/
int iret;
//char resultfirst[256];
char* resultfirst;
/*find gpgga*/
/**/
size_t read_size = buf_size;
int counter = 0;
int nmatch = 0;
// string line_info;
while(1) {
//puts("Here");
//printf("Round %d\n", counter);
string line_info;
size_t ret = 0;
try{
ret = my_serial.readline(line_info, read_size);
}
catch(...){
printf("Something Weird...\n");
return ;
}
if (ret > 10) {
//strcpy(buf,line_info.c_str());
//iret = find_first(buf,pattern,resultfirst);
iret = -1;
try{
//iret = find_first(line_info.c_str(), pattern, resultfirst);
iret = (line_info.substr(0, 6) == "$GPGGA") ? 0: -1;
if (iret == 0){
resultfirst = (char*)line_info.c_str();
}
}
catch(...){
printf("err1\n");
return;
}
try{
if(iret == 0) {
nmatch++;
double lat, lon;
int status, nsati;
int success = sscanf(resultfirst,
"$GPGGA,%*f,%lf,N,%lf,E,%d,%d",
&lat, &lon, &status, &nsati);
findf<<"num"<<counter<<endl;
findf<<resultfirst<<endl;
//cout << counter <<"/" << nmatch <<"\tRead "<< line_info.size()<<": " <<line_info;
printf("%d/%d\tRead %d: %s", counter, nmatch, line_info.size(), line_info.c_str());
if (success == 4){
lat = int(lat/100)+(lat-int(lat/100)*100)/60.0;
lon = int(lon/100)+(lon-int(lon/100)*100)/60.0;
printf("\tlat=%.8f, lon=%.8f, status=%d, nsati=%d\n", lat, lon, status, nsati);
}
else{
printf("success-%d\n", success);
}
}
serf<<"num"<<counter<<":"<<line_info.size()<<endl;
serf<<line_info<<endl;
}
catch(...){
printf("err2 at round %d\n", counter);
return ;
}
}
counter++;
}
}
int main()
{
serial_rec();
return 0;
}