GPS模块运用: GPS轨迹记录

一、软件与硬件环境介绍

GPS模块型号:  中科微电子ATGM336H-5N 系列模块

该系列模块支持多种卫星导航系统,包括中国的 BDS(北斗卫星导航系统),美国的 GPS,俄罗斯的 GLONASS,欧盟的 GALILEO,日本的 QZSS以及卫星增强系统 SBAS(WAAS,EGNOS,GAGAN,MSAS)。

软件开发环境: win10 + Qt5.12.6

二、软件功能介绍

大致的功能部分介绍:

1. 解析GPS模块接收的数据,得到经纬度和速度。

2. 上电配置GPS模式为车载模式、并配置GPS只输出GNVTG(地面速度)、GNRMC(推荐定位)语句。

3. 解析的数据会上传到自己的服务器,完成GPS数据保存分析,并调用百度地图完成轨迹绘制。 

4. 串口数据接收部分放在子线程,将解析的数据保存到全局类中,全局类里加了读写锁,防止多线程读写全局变量出现问题。数据显示部分和上传部分放在主UI线程里,使用定时器2秒调用一次。

5. 支持断网数据缓存,如果网络不好导致数据没有上传成功,程序里使用队列缓存上传的数据,最大缓存300条数据,差不多10分钟的数据,有网络时再一次性上传到服务器。

三、软件运行效果

四、核心代码

4.1  uart_code.h

#ifndef UART_CODE_H
#define UART_CODE_H
#include <QSerialPort>
#include <QObject>
#include <QThread>
#include <QDebug>
#include <QString>
#include "config.h"
class OBD_Data
{
public:
      QString V; //电瓶电压
      QString R; //转速
      QString S; //速度
      QString P; //绝对气门开度
      QString O; //发动机负荷
      QString C; //冷却液温度
      QString L; //油量
      QString M; //此次行程米
      QString F; //此次油耗L
      QString XM; //瞬时油耗、百公里油耗
      QString T; //运行时间
      //QString E; //发动机状态 0熄火 1点火 2自动启动
      QString A; //急加速次数
      QString B; //急刹车次数
      QString D; //故障码个数
      QString GX;//X
      QString GY;//Y
      QString GZ;//Z
      QString data;
};

class GPS_Data
{
private:
    double lat; //纬度
    double lng; //经度
    QString speed; //速度
    QReadWriteLock lock; //读写锁
    QString save_src_data; //原始数据
public:
    QString Data;
    QQueue<QString> queue; //缓存数据的队列
    bool gps_push_stat=0;  //GPS向服务器上传的状态

    //构造函数
    GPS_Data()
    {
        lat=0.0;
        lng=0.0;
        speed="0";
        save_src_data="";
    }
    //读取纬度
    double get_lat(void)
    {
        lock.lockForRead();
        double tmp_lat=lat;
        lock.unlock();
        return  tmp_lat;
    }
    //设置纬度
    void set_lat(double tmp_lat)
    {
        lock.lockForWrite();
        lat=tmp_lat;
        lock.unlock();
    }
    //读取经度
    double get_lng(void)
    {
        lock.lockForRead();
        double tmp_lng=lng;
        lock.unlock();
        return  tmp_lng;
    }
    //设置经度
    void set_lng(double tmp_lng)
    {
        lock.lockForWrite();
        lng=tmp_lng;
        lock.unlock();
    }
    //读取速度
    QString get_speed(void)
    {
        lock.lockForRead();
        QString tmp_speed=speed;
        lock.unlock();
        return  tmp_speed;
    }
    //设置速度
    void set_speed(QString tmp_speed)
    {
        lock.lockForWrite();
        speed=tmp_speed;
        lock.unlock();
    }
    //读取原始数据
    QString get_src_data(void)
    {
        lock.lockForRead();
        QString tmp_speed=save_src_data;
        lock.unlock();
        return  tmp_speed;
    }
    //设置原始数据
    void set_src_data(QString tmp_save_src_data)
    {
        lock.lockForWrite();
        save_src_data+=tmp_save_src_data;
        if(save_src_data>1024)save_src_data.clear();
        lock.unlock();
    }
    //清除原始数据
    void set_src_clear(void)
    {
        lock.lockForWrite();
        save_src_data.clear();
        lock.unlock();
    }

#if 0
    //向队列里插入一条数据
    void write_queue(QString str)
    {
        lock.lockForWrite();
        queue.enqueue(str);
        if(queue.size()>300) //最大缓存300个数据
        {
            queue.clear();
        }
        lock.unlock();
    }

    //返回队列里的一条数据
    QString read_queue()
    {
        QString data="";
        lock.lockForWrite();
        //判断队列是否为空,有数据才取
        if(!queue.isEmpty())
        {
            data=queue.dequeue();
        }
        lock.unlock();
        return data;
    }
#endif
};

class UART_ReadWriteThread:public QObject
{
    Q_OBJECT
public:
    QByteArray byte_all;
    UART_ReadWriteThread(QObject* parent=nullptr):QObject(parent){}
    ~UART_ReadWriteThread();
    //成员变量
    QSerialPort *UART_Config=nullptr; //串口---数据接收串口
    int GPS_GetData(const char *gps_src,const char *find_head,char *buff,int cnt);
    int GPS_GetCheckSum(const char *src_str,const char *find_str);
public slots:
    void UART_ReadUasrtData(void);
    void run();
    void Open_UART(void);
    void Close_UART(void);
    void UART_Send(QString text);
signals:
    void LogSend(QString text);
    void SendUartState(qint8 state);  //发送串口状态   true 表示连接 否则表示断开
};
#endif // UART_CODE_H

4.2 uart_code.cpp

#include "uart_code.h"
#include "config.h"

QString current_SerialPort="";  //当前串口端口号
qint32 current_SerialBaudRate=0; //当前波特率

class OBD_Data obd_data;
class GPS_Data gps_data;

UART_ReadWriteThread::~UART_ReadWriteThread()
{

}

void UART_ReadWriteThread::run()
{
    //串口配置
    if(UART_Config)
    {
        UART_Config->close();
        delete UART_Config;
        UART_Config=nullptr;
    }
    UART_Config =new QSerialPort;
    //打开串口设备
    Open_UART();
}


//当串口打不开的时候,间隔一段时间再次重新测试
void UART_ReadWriteThread::Open_UART(void)
{
    //配置串口属性
    UART_Config->setBaudRate(current_SerialBaudRate);              //默认波特率
    UART_Config->setDataBits(QSerialPort::Data8);  //数据位
    UART_Config->setParity(QSerialPort::NoParity); //奇偶校验
    UART_Config->setStopBits(QSerialPort::OneStop);//停止位
    UART_Config->setFlowControl(QSerialPort::NoFlowControl); //流控开关
    UART_Config->setPortName(current_SerialPort);    //COM的名称

    //1 数据传输串口连接 2 数据传输串口断开
    if(!(UART_Config->open(QIODevice::ReadWrite)))      //打开的属性权限
    {
        LogSend("数据传输串口打开失败.\n");
        SendUartState(2); //发送信号 通知状态改变
    }
    else
    {
        LogSend("数据传输串口打开成功.\n");
        SendUartState(1); //发送信号 通知状态改变

        //配置GPS
        UART_Config->write("$CCRMO,GGA,3,1*3F\r\n"); //关闭全部语句输出
        QThread::msleep(20);
        UART_Config->write("$CCRMO,RMC,2,1*23\r\n");  //打开RMC语句输出
        QThread::msleep(20);
        UART_Config->write("$CCRMO,VTG,2,1*3A\r\n"); //打开VTG语句输出
        QThread::msleep(20);
        UART_Config->write("$PCAS11,3*1E\r\n"); //设置GPS模块为车载模式
        QThread::msleep(20);

        //关联数据读信号
        connect(UART_Config,SIGNAL(readyRead()),this,SLOT(UART_ReadUasrtData()),Qt::QueuedConnection);
    }
}


//读取串口数据
void UART_ReadWriteThread::UART_ReadUasrtData()
{
    int cnt;
    QString byte;
    /*读取串口缓冲区所有的数据*/
    byte=UART_Config->readAll();
    LogSend("---接收的原始数据帧---\n");
    LogSend(byte);
    LogSend("---原始数据帧结束---\n");
    //qDebug()<<"byte="<<byte;
    /*读取串口缓冲区所有的数据*/
    gps_data.Data+=byte;

    //完整的1帧VTG--RMC数据在109字节左右
    //if(gps_data.Data.size()>=200)
    //为了避免接收出错,这里判断4个\r\n也就是接收2帧数据再解析
    if(gps_data.Data.count("\r\n")>=4 && gps_data.Data.count("$GNRMC")>=1 && gps_data.Data.count("$GNVTG")>=1)
    {
        LogSend("---正在分析的数据---\n");
        LogSend(gps_data.Data);
        LogSend("---分析结束---\n");
       // qDebug()<<"gps_data.Data="<<gps_data.Data;
        //保存原始数据
        gps_data.set_src_data(gps_data.Data);
        char *gps_p;
        char gps_tmp_buff[50];
        char gps_src_buff[200];
        gps_p=gps_data.Data.toLocal8Bit().data();
        //拷贝数据
        strncpy(gps_src_buff,gps_p,sizeof(gps_src_buff));

        //计算$GNRMC校验和
        if(GPS_GetCheckSum(gps_src_buff,"$GNRMC")==0)
        {
            //qDebug()<<"$GNRMC 校验和计算成功.\n";
            LogSend("$GNRMC 校验和计算成功\n");
            //提取定位状态数据
            cnt=GPS_GetData(gps_src_buff,"$GNRMC",gps_tmp_buff,2);

            //判断定位数据是否有效
            if(gps_tmp_buff[0]=='A')
            {
                SendUartState(3); //发送信号 通知状态改变  定位成功
                //qDebug()<<"定位成功.";
                //提取纬度
                memset(gps_tmp_buff,0,sizeof(gps_tmp_buff));
                GPS_GetData(gps_src_buff,"$GNRMC",gps_tmp_buff,3);
                QString lat=gps_tmp_buff;  //得到纬度
                //提取经度
                memset(gps_tmp_buff,0,sizeof(gps_tmp_buff));
                GPS_GetData(gps_src_buff,"$GNRMC",gps_tmp_buff,5);
                QString lng=gps_tmp_buff;  //得到经度

               //qDebug()<<"当前纬度:"<<lat;
               //qDebug()<<"当前经度:"<<lng;

                unsigned int int_data;
                double s_Longitude,s_latitude;

                //转换纬度
                s_latitude=lat.toDouble();
                s_latitude=s_latitude/100;
                int_data=s_latitude;//得到纬度整数部分
                s_latitude=s_latitude-int_data;//得到纬度小数部分
                s_latitude=(s_latitude)*100;
                gps_data.set_lat(int_data+(s_latitude/60.0)); //得到转换后的值

                //转换经度
                s_Longitude=lng.toDouble();
                s_Longitude=s_Longitude/100;
                int_data=s_Longitude;//得到经度整数部分
                s_Longitude=s_Longitude-int_data; //得到经度小数部分
                s_Longitude=s_Longitude*100;

                //gai guo le
                gps_data.set_lng(int_data+(s_Longitude/60.0));
            }
            else
            {
                SendUartState(4); //发送信号 通知状态改变  定位失败
                //GPS经纬度置0
                gps_data.set_lat(0.0);
                gps_data.set_lng(0.0);
            }
        }
        else
        {
            //GPS经纬度置0
            gps_data.set_lat(0.0);
            gps_data.set_lng(0.0);
        }

        //计算GNVTG校验和
        if(GPS_GetCheckSum(gps_src_buff,"$GNVTG")==0)
        {
            LogSend("$GNVTG 校验和计算成功\n");
            //提取速度
            memset(gps_tmp_buff,0,sizeof(gps_tmp_buff));
            GPS_GetData(gps_src_buff,"$GNVTG",gps_tmp_buff,7);
           // qDebug()<<"当前速度:"<<gps_tmp_buff;
            gps_data.set_speed(gps_tmp_buff);
        }
        else
        {
            gps_data.set_speed("0");//当前速度置0
        }
        //清空数据
        gps_data.Data.clear();
    }
}


//关闭串口
//1 数据传输串口连接 2 数据传输串口断开
void UART_ReadWriteThread::Close_UART(void)
{
    SendUartState(2); //发送信号 通知状态改变
    if(UART_Config->isOpen())
    {
       UART_Config->close();
    }
}

//发送数据
void UART_ReadWriteThread::UART_Send(QString text)
{
   //qDebug()<<text;
    //如果串口处于打开状态就发送数据
    if(UART_Config->isOpen())
    {
        QByteArray byte=text.toLocal8Bit();
        UART_Config->write(byte);
    }
}

/*
函数功能: 根据逗号位置提取数据
函数参数:
char *gps_src GPS源字符串地址
char *buff 存放提取的数据
char *find_head 查找的GPS数据头  例如:$GNVTG
int cnt  逗号的偏移量
返回值:提取的字节数。
*/
int UART_ReadWriteThread::GPS_GetData(const char *gps_src,const char *find_head,char *buff,int cnt)
{
    const char *p;
    int number=0; //提取的数量
    int a=0;
    p=strstr(gps_src,find_head);
    if(p!=nullptr)
    {
        //查找逗号的位置
        while(*p!='\0')
        {
            if(*p==',')a++; //记录逗号的数量
            if(a==cnt)break; //逗号找成功了
            p++;
        }
        p++; //跨过当前逗号
        //提取数据
        while(*p!='\0')
        {
            if(*p==',')break; //遇到逗号停止提取数据
            buff[number]=*p;
            p++;
            number++;
        }
        buff[number]='\0';
    }
    return number;
}

/*
 * 计算GPS数据指定数据的校验和
 * char *src_str GPS源字符串
 * char *find_str GPS数据头  例如:$GNVTG
 * 返回值: -1表示失败  0表示成功
*/
int UART_ReadWriteThread::GPS_GetCheckSum(const char *src_str,const char *find_str)
{
    const char *tmp_p;
    /*1. 开始解析数据*/
    tmp_p=strstr(src_str,find_str);
    if(tmp_p!=nullptr)
    {
        unsigned char data=0;
        tmp_p++;
        //计算校验和
        while(*tmp_p!='*' && *tmp_p!='\0')
        {
            data^=*tmp_p;
            tmp_p++;
        }
        QString sum_str=QString::number(data,16);
        QString sum_val;
        //提取校验和
        sum_val[0]=*(tmp_p+1);
        sum_val[1]=*(tmp_p+2);

       // qDebug()<<"sum_val:"<<sum_val;
       // qDebug()<<"sum_str:"<<sum_str;

        //判断校验和,不区分大小写
        if(sum_str.compare(sum_val,Qt::CaseInsensitive)==0)
        {
            return 0; //校验正确
        }
    }
    return -1;
}

4.3 widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    this->setWindowTitle("GPS数据解析工具");
    GetDeviceList();

    //串口初始化
    //连接串口的日志信息
    connect(&uart_WorkClass,SIGNAL(LogSend(QString)),this,SLOT(Log_Text_Display(QString)));
    connect(&uart_WorkClass,SIGNAL(SendUartState(qint8)),this,SLOT(UART_State_Display(qint8)));

    //连接串口初始化函数
    connect(this,SIGNAL(Start_Uart_Read()),&uart_WorkClass,SLOT(run()));
    //连接串口发送函数
    connect(this,SIGNAL(Uart_SendData(QString)),&uart_WorkClass,SLOT(UART_Send(QString)));
    //将串口工作对象移动到子线程里工作
    uart_WorkClass.moveToThread(&uart_Workthread);

    //连接服务器
    TCP_ConnectServer(RECV_SERVER_CMD_IP,RECV_SERVER_CMD_PROT);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::GetDeviceList()
{
    ui->comboBox->clear();
    //获取系统串口设备
    usart_device_list=QSerialPortInfo::availablePorts();
    /*打印出支持的串口名称*/
    for(int i=0;i<usart_device_list.count();i++)
    {
        ui->comboBox->addItem(usart_device_list.at(i).portName());
    }
}

void Widget::on_pushButton_2_clicked()
{
    GetDeviceList();
}

void Widget::on_pushButton_clicked()
{
    current_SerialPort=ui->comboBox->currentText();  //当前串口端口号
    current_SerialBaudRate=ui->comboBox_baud->currentText().toInt(); //当前波特率

    if(ui->pushButton->text()=="打开串口")
    {
        if(current_SerialPort.isEmpty()||current_SerialBaudRate<=0)
        {
            QMessageBox::information(this,"提示","请先选择串口COM和波特率\n在菜单栏的设置页面找到串口设置按钮.",
            QMessageBox::Ok,QMessageBox::Ok);
        }
        else
        {
            ui->pushButton->setText("关闭串口");
            uart_Workthread.start(); //启动串口线程
            Start_Uart_Read(); //发送信号启动串口工作
        }
    }
    else
    {
        uart_WorkClass.Close_UART(); //关闭串口
        uart_Workthread.quit(); //退出线程
        uart_Workthread.wait(); //等待线程退出
        ui->pushButton->setText("打开串口");
    }
}

/*日志显示*/
void Widget::Log_Text_Display(QString text)
{
    QPlainTextEdit *plainTextEdit_log=ui->plainTextEdit;
    //设置光标到文本末尾
    plainTextEdit_log->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
    //当文本数量超出一定范围就清除
    if(plainTextEdit_log->toPlainText().size()>4096)
    {
        plainTextEdit_log->clear();
    }
    plainTextEdit_log->insertPlainText(text);
    //移动滚动条到底部
    QScrollBar *scrollbar = plainTextEdit_log->verticalScrollBar();
    if(scrollbar)
    {
        scrollbar->setSliderPosition(scrollbar->maximum());
    }
}

/*日志显示*/
void Widget::Log_Text_Display2(QString text)
{
    QPlainTextEdit *plainTextEdit_log=ui->plainTextEdit2;
    //设置光标到文本末尾
    plainTextEdit_log->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
    //当文本数量超出一定范围就清除
    if(plainTextEdit_log->toPlainText().size()>4096)
    {
        plainTextEdit_log->clear();
    }
    plainTextEdit_log->insertPlainText(text);
    //移动滚动条到底部
    QScrollBar *scrollbar = plainTextEdit_log->verticalScrollBar();
    if(scrollbar)
    {
        scrollbar->setSliderPosition(scrollbar->maximum());
    }
}

//串口状态显示
//1 数据传输串口连接 2 数据传输串口断开
void Widget::UART_State_Display(qint8 state)
{
   if(state==1)
   {
       connect_state=state;
       Log_Text_Display("串口连接\n");
   }
   if(state==2)
   {
       connect_state=state;
       Log_Text_Display("串口断开\n");
   }
   if(state==3)  //GPS定位成功
   {
       ui->label_gps_stat->setText("GPS定位状态: 定位成功");
   }
   if(state==4)  //GPS定位失败
   {
       ui->label_gps_stat->setText("GPS定位状态: 正在定位中..请稍等");
   }
}

//发送数据
void Widget::on_pushButton_send_data_clicked()
{
    QString text=ui->lineEdit_send_data->text();
    if(ui->checkBox->isChecked())
    {
        text+="\r\n";
        Uart_SendData(text);
    }
    else
    {
        Uart_SendData(text);
    }
}

void Widget::on_pushButton_mode_set_clicked()
{
     Uart_SendData("$PCAS11,3*1E\r\n");
}

void Widget::on_pushButton_open_all_clicked()
{
    Uart_SendData("$CCRMO,GGA,4,1*38\r\n");
}

void Widget::on_pushButton_close_all_clicked()
{

    Uart_SendData("$CCRMO,GGA,3,1*3F\r\n");
}

void Widget::on_pushButton_open_rmc_clicked()
{

    Uart_SendData("$CCRMO,RMC,2,1*23\r\n");
}

void Widget::on_pushButton_open_vtg_clicked()
{
     Uart_SendData("$CCRMO,VTG,2,1*3A\r\n");
}


//客户端模式:响应连接上服务器之后的操作
void Widget::LocalTcpClientConnectedSlot()
{
    //身份验证
    QString cmd=tr("token=%1&devId=%2\r\n").arg(TOKEN).arg(DeviceID);
    LocalTcpClientSocket->write(cmd.toLatin1().data());
    Log_Text_Display("命令长连接:连接上服务器.\n");
    ui->label_server_connect->setText("服务器连接状态:连接");
}

//客户端模式:断开服务器
void Widget::LocalTcpClientDisconnectedSlot()
{
    Log_Text_Display("命令长连接:服务器断开.----------------->\n");
    ui->label_server_connect->setText("服务器连接状态:断开");
}

//客户端模式:读取服务器发过来的数据
void Widget::LocalTcpClientReadDtatSlot()
{
    //读取数据
   QString array=LocalTcpClientSocket->readAll();
   qDebug()<<"服务器反馈:"<<array;
   //判断服务器是否收到数据
   if(array.contains("ok\r\n", Qt::CaseInsensitive))
   {
       qDebug()<<"发送成功.";
       gps_data.gps_push_stat=1; //1表示收到数据
   }
}

//创建客户端,连接至服务器
void Widget::TCP_ConnectServer(QString Ipaddr,quint16  prot)
{
    if(LocalTcpClientSocket==nullptr)
    {
        /*1. 创建本地客户端TCP套接字*/
        LocalTcpClientSocket = new QTcpSocket;
        /*2. 设置服务器IP地址*/
        QHostAddress FarServerAddr(Ipaddr);
        /*3. 连接客户端的信号槽*/
        connect(LocalTcpClientSocket,SIGNAL(connected()),this,SLOT(LocalTcpClientConnectedSlot()));
        connect(LocalTcpClientSocket,SIGNAL(disconnected()),this,SLOT(LocalTcpClientDisconnectedSlot()));
        connect(LocalTcpClientSocket,SIGNAL(readyRead()),this,SLOT(LocalTcpClientReadDtatSlot()));
        /*4. 尝试连接服务器主机*/
        LocalTcpClientSocket->connectToHost(FarServerAddr,prot);
        /*5. 检测服务器是否断开,并发送心跳包*/
        timer_check_connect=new QTimer;
        connect(timer_check_connect,SIGNAL(timeout()),this,SLOT(check_connect()));
        timer_check_connect->start(2000);
    }
}

//上传数据给服务器
void Widget::check_connect()
{
    //组合GPS与OBD数据的并返回
    QString requestUrl=obd_gps_update();

    //判断是否需要上传服数据到服务器
    if(!ui->checkBox_push_server->isChecked())
    {
        return;
    }

    //判断该客户端是否已经断开
    if(LocalTcpClientSocket->socketDescriptor()==-1)
    {
        Log_Text_Display("服务器已经断开,正在尝试连接服务器主机.\n");
        /*4. 尝试连接服务器主机*/
        LocalTcpClientSocket->connectToHost(QHostAddress(RECV_SERVER_CMD_IP),RECV_SERVER_CMD_PROT);
        //QThread::sleep(10); //等待10秒

        //服务器断开的情况下就缓存数据到队列
        if(gps_data.queue.size()>300) //最大缓存300个数据
        {
            gps_data.queue.clear();
        }
        gps_data.queue.enqueue(requestUrl); //向队列插入数据
        qDebug()<<"正在缓存数据到队列-断开:"<<gps_data.queue.size();
    }
    else
    {
        //上一次数据没有发送成功,就将数据缓存起来
        if(gps_data.gps_push_stat==0) //1表示服务器已经收到车载主机发送的数据  0表示没有
        {
            //服务器断开的情况下就缓存数据到队列
            if(gps_data.queue.size()>300) //最大缓存300个数据
            {
                gps_data.queue.clear();
            }
            gps_data.queue.enqueue(requestUrl); //向队列插入数据
            qDebug()<<"正在缓存数据到队列-没有发送成功:"<<gps_data.queue.size();
        }
        else
        {
            //如果数据向服务器发送成功了那么就将队列里的数据一次性发送给服务器
            //判断队列是否为空,有数据才取
            for(int i=0;i<gps_data.queue.size();i++)
            {
                LocalTcpClientSocket->write(gps_data.queue.dequeue().toLatin1());
                qDebug()<<"正在发送队列数据:"<<i;
            }
        }

        //每次发送之前将状态清0,如果发送成功了服务器会将这个状态值给1
        gps_data.gps_push_stat=0; //清0
        //发送一次当前的数据
        LocalTcpClientSocket->write(requestUrl.toLatin1());
    }
}

//定时向服务器上报OBD与GPS信息
QString Widget::obd_gps_update()
{
    //服务器请求地址
    QString requestUrl="";
    requestUrl+=tr("devId=%1&").arg(DeviceID);//车载主机设备编号

    //判断OBD是否采集到数据,采集到就使用OBD,没有就使用GPS的速度
    if(obd_data.S.toInt()>0)
    {
        requestUrl+=tr("speed=%1&").arg(obd_data.S);//车速
    }
    else
    {
        requestUrl+=tr("speed=%1&").arg(gps_data.get_speed());//车速
    }

    requestUrl+=tr("ym=%1&").arg(obd_data.XM);//油门
    requestUrl+=tr("xc=%1&").arg(obd_data.M);//行程
    requestUrl+=tr("temperature=%1&").arg(obd_data.C);//温度
    requestUrl+=tr("rotationRate=%1&").arg(obd_data.R);//转速。单位(转)
    requestUrl+=tr("xc=%1&").arg(obd_data.B);//刹车
    requestUrl+=tr("dw=%1&").arg(1);//档位
    requestUrl+=tr("kt=%1&").arg(0);//空调状态  0-未开启, 1开启。不知道就是0
    requestUrl+=tr("errorcode=%1&").arg(obd_data.D);
    requestUrl+=tr("lat=%1&").arg(gps_data.get_lat(),0,'g',13);//纬度
    requestUrl+=tr("lng=%1&").arg(gps_data.get_lng(),0,'g',13);//经度

    //GPS与OBD的原始数据
    QString gps_text=gps_data.get_src_data();
    gps_data.set_src_clear();
    gps_text=gps_text.remove("\n");
    gps_text=gps_text.remove("\r");
    requestUrl+=tr("gpsplain=%1&").arg(gps_text);//GPS原始数据
    requestUrl+=tr("obdplain=%1&").arg("");//OBD原始数据

    //获取当前时间
    QString qStr="";
    QDateTime dateTime(QDateTime::currentDateTime());
    qStr=dateTime.toString("yyyy-MM-dd hh:mm:ss");

    requestUrl+=tr("datetime=%1\r\n").arg(qStr);//当前时间


    //本地显示
    QString text="GPS:";
    text+=tr("纬度=%1,").arg(gps_data.get_lat(),0,'g',13); //纬度
    text+=tr("经度=%1,").arg(gps_data.get_lng(),0,'g',13); //经度
    text+=tr("速度=%1Km/h\n").arg(gps_data.get_speed());//速度
    Log_Text_Display2(text);

    QPalette pe;
    pe.setColor(QPalette::WindowText,Qt::red);
    ui->label_lat_lng_display->setPalette(pe);
    ui->label_lat_lng_display->setText(text);

    text+=tr("原始数据:%1\n").arg(gps_text);//原始数据
    Log_Text_Display2(text);

    return requestUrl;
}

//退出事件
void Widget::closeEvent(QCloseEvent *event)
{
    uart_WorkClass.Close_UART(); //关闭串口
    uart_Workthread.quit(); //退出线程
    uart_Workthread.wait(); //等待线程退出
}

下面公众号有全套的单片机、QT、C++、C语言、物联网相关的教程,欢迎关注:

猜你喜欢

转载自blog.csdn.net/xiaolong1126626497/article/details/108104933
GPS