目录
一、QT读取串口数据
二、解析数据
目标:
使用QT,读取gps模块的串口数据,并解析其中的经纬高数据,然后进行处理
一、QT读取串口数据
变量定义
QSerialPort *serial;
QSerialPortInfo SerialPortInfo;
QByteArray lineData;
串口初始化
//初始化串口
void serialPort::initSerialPort() {serial = new QSerialPort;QList<QSerialPortInfo> listCom;//获取串口列表listCom = QSerialPortInfo::availablePorts();for (int i = 0; i < listCom.size(); i++)qDebug() << "串口名称:" << listCom[i].portName();//打印串口信息foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())//搜索串口,获取串口列表{if (info.portName() == "COM3") {//在串口列表中查找//此处使用的是判断串口描述说明相同SerialPortInfo = info;//储存串口信息serial->setPort(info);//设置串口break;//找到所需要的串口信息,退出循环}//使用if语句判断是否所需串口}if (SerialPortInfo.portName() == "COM3") {qDebug() << "所需串口已找到,具体信息如下:";qDebug() << "Name : " << SerialPortInfo.portName();//串口名称,比如com3qDebug() << "Description : " << SerialPortInfo.description();//串口描述说明qDebug() << "Manufacturer: " << SerialPortInfo.manufacturer();qDebug() << "Serial Number: " << SerialPortInfo.serialNumber();//串口号qDebug() << "System Location: " << SerialPortInfo.systemLocation();//系统位置}else {qDebug() << "串口信息未找到,请检查设备是否连接";}serial->setBaudRate(QSerialPort::Baud9600);//设置串口波特率(9600)serial->setDataBits(QSerialPort::Data8);//设置数据位(8)serial->setParity(QSerialPort::NoParity); //设置奇偶校检(无)serial->setStopBits(QSerialPort::OneStop);//设置停止位(一位)serial->setFlowControl(QSerialPort::NoFlowControl);//设置流控制(无)serial->open(QIODevice::ReadOnly);//打开串口,并设置串口为只读模式if (serial->isOpen())qDebug() << "串口已经打开";connect(serial, SIGNAL(readyRead()), this, SLOT(slot_read_from_port()));
}
二、解析数据
因为串口每次读取不定长的字符,因此需要对每一条GPS数据进行拼接,遇到回车符\n拼接结束,进行解析。
void serialPort::slot_read_from_port() {QByteArray byteArray = serial->readAll();lineData.append(byteArray);if (lineData.contains('\n'))//只有等到\n的时候才能进入{QString lineQstring = QString::fromLocal8Bit(lineData);qDebug() << "lineQstring: " << lineQstring;QString parseName = "GNGGA";//解析GPGGA数据if (lineQstring.contains(parseName)) { //如果解析北斗数据,换为 BDGGA 格洛纳斯:GLGGA//qDebug()<<"parse data: " << lineQstring;//通过逗号分割数据QList<QString>d = lineQstring.split(',');/*(1)UTC时间,格式为hhmmss.ss;(2)纬度,格式为ddmm.mmmmm(度分格式);(3)纬度半球,N或S(北纬或南纬);(4)经度,格式为dddmm.mmmmm(度分格式);(5)经度半球,E或W(东经或西经);(9) 海拔高度(-9999.9~99999.9)*///时间转为秒_flyData.time = d[1].mid(0, 2).toInt() * 60 * 60 + d[1].mid(2, 2).toInt() * 60 + d[1].mid(4, 2).toInt();//纬度if (d[3] == "N") {_flyData.lat = parseLngLat(d[2].toDouble());}else if (d[3] == "S") {_flyData.lat = -parseLngLat(d[2].toDouble());}//经度if (d[5] == "E") {_flyData.lng = parseLngLat(d[4].toDouble());}else if (d[5] == "W") {_flyData.lng = -parseLngLat(d[4].toDouble());}//高度_flyData.alt = d[9].toDouble();//qDebug() << d[1] << " " << _flyData.lng << " " << _flyData.lat << " " << _flyData.alt;}lineData.clear();}}//解析经纬度至小数
double serialPort::parseLngLat(double LL) { //例如:4546.40891 //度int d = int(LL / 100);int m = int(LL - d * 100);double s = ((LL - d * 100) - m) * 60;//组合为小数return (d + m / 60.0 + s / 3600.0);
}