widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QTimer>
#include<QMessageBox>
#include<QByteArray>
#include<QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void initSerialPort();
void initSerialPortCompass();
void initSocket();
private slots:
void on_pushButton_2_clicked(); //刷新串口按钮
void on_pushButton_gps_clicked();
void readComGps();//用于读取gps数据
void readComCompass();//用于读取罗盘消息
public:
//用于发送16进制的函数,(string转16进制)
void QStringtoHex(QByteArray& sendData,QString str);
char ConvertHexChar(char c);
void sendTcpAll();
private:
Ui::Widget *ui;
//和tcp有关的
private:
QTcpSocket* socket;
bool socketConnectedFlag;
//和串口有关的private
private:
QSerialPort mySerial;
QSerialPort *serialPortGps;//(实例化一个指向串口的指针,可以用于访问串口)
QSerialPort* serialPortCompass;
QTimer *timer;// 使用定时器进行周期读取gps串口数据
QTimer* timerCompass;
QTimer* timerAll;
QByteArray recvDataGps;
QByteArray recvDataCompass;
QByteArray recvAll;
int baseSizeGps;
int baseSizeCompass;
private slots:
void handleSerialError(QSerialPort::SerialPortError error);
void handleSerialErrorCompass(QSerialPort::SerialPortError error);
void on_pushButton_luopan_clicked();
void sendRequest();//向罗盘发送请求命令
void on_pushButton_clicked();
void reconnectTcp();
void warningTcp();
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
#include<unistd.h>
#include<windows.h>
using namespace std;
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::initSerialPort()
{
//对gps的串口进行初始化
if(ui->pushButton_gps->text() == "port_closed")
{
ui->pushButton_gps->setText("open");
serialPortGps = new QSerialPort(this);
serialPortGps->setPortName(ui->comboBox->currentText()); //设置串口
serialPortGps->setBaudRate(4800);
serialPortGps->setFlowControl(QSerialPort::NoFlowControl);
serialPortGps->setDataBits(QSerialPort::Data8);
serialPortGps->setParity(QSerialPort::NoParity);
serialPortGps->setStopBits(QSerialPort::OneStop);
serialPortGps->open(QIODevice::ReadWrite);//打开串口
ui->pushButton_gps->setStyleSheet("background-color:red");
timer = new QTimer(this);
connect(timer,&QTimer::timeout,this,&Widget::readComGps);
timer->start(500);//每500MS读一次
connect(serialPortGps,SIGNAL(errorOccurred(QSerialPort::SerialPortError)),this,SLOT(handleSerialError(QSerialPort::SerialPortError))); //连接打开的串口异常检测
}
else
{
ui->pushButton_gps->setStyleSheet("background-color:rgb(130,130,130)");
ui->pushButton_gps->setText("port_closed");
serialPortGps->close();
timer->stop();
}
}
void Widget::initSerialPortCompass()
{
//对罗盘的串口进行初始化
if(ui->pushButton_luopan->text() == "port_closed")
{
ui->pushButton_luopan->setText("open");
serialPortCompass = new QSerialPort(this);
serialPortCompass->setPortName(ui->comboBox_2->currentText()); //设置串口
serialPortCompass->setBaudRate(9600);
serialPortCompass->setFlowControl(QSerialPort::NoFlowControl);
serialPortCompass->setDataBits(QSerialPort::Data8);
serialPortCompass->setParity(QSerialPort::NoParity);
serialPortCompass->setStopBits(QSerialPort::OneStop);
serialPortCompass->open(QIODevice::ReadWrite);//打开串口
ui->pushButton_luopan->setStyleSheet("background-color:red");
timerCompass = new QTimer(this);
connect(timerCompass,&QTimer::timeout,this,&Widget::readComCompass);
connect(timerCompass,&QTimer::timeout,this,&Widget::sendRequest);
timerCompass->start(500);//每5MS读一次
connect(serialPortCompass,SIGNAL(errorOccurred(QSerialPort::SerialPortError)),this,SLOT(handleSerialError(QSerialPort::SerialPortError))); //连接打开的串口异常检测
}
else
{
ui->pushButton_luopan->setStyleSheet("background-color:rgb(130,130,130)");
ui->pushButton_luopan->setText("port_closed");
serialPortCompass->close();
timerCompass->stop();
}
}
void Widget::initSocket()
{
socket = new QTcpSocket(this);
QString ip = "127.0.0.1";
QString port = "45458";
socket->connectToHost(ip,port.toUInt());
connect(socket,&QTcpSocket::connected,this,[=]()
{
socketConnectedFlag = true;
});
connect(socket,&QTcpSocket::disconnected,this,&Widget::reconnectTcp);
connect(socket,&QTcpSocket::disconnected,this,&Widget::warningTcp);
}
void Widget::reconnectTcp()
{
QString ip = "127.0.0.1";
QString port = "45458";
socket->connectToHost(ip,port.toUInt());
}
void Widget::warningTcp()
{
QDialog* warnDialog = new QDialog;
warnDialog->setWindowTitle(tr("TCP disconnected"));
warnDialog->show();
}
void Widget::on_pushButton_2_clicked()//点击刷新串口按钮
{
//刷新串口
ui->comboBox->clear();
foreach( const QSerialPortInfo &Info,QSerialPortInfo::availablePorts())//读取串口信息
{
mySerial.setPort(Info);
ui->comboBox->addItem(Info.portName());
ui->comboBox_2->addItem(Info.portName());
}
}
void Widget::on_pushButton_gps_clicked()
{
initSerialPort();
}
void Widget::readComGps()
{
recvDataGps.append(serialPortGps->readAll());
int totolSize = recvDataGps.size();
baseSizeGps = 60;
if(totolSize<baseSizeGps)
{
return ;
}
//满足解析条件
else {
usleep(1000);
ui->textEdit->moveCursor(QTextCursor::End);
ui->textEdit->insertPlainText(recvDataGps.left(baseSizeGps));
recvDataGps = recvDataGps.right(totolSize-baseSizeGps);
totolSize = recvDataGps.size();
}
}
void Widget::readComCompass()
{
recvDataCompass.append(serialPortCompass->readAll());
int totolSize = recvDataCompass.size();
baseSizeCompass = 14;
if(totolSize<baseSizeCompass)
{
return ;
}
//满足解析条件
else {
usleep(1000);
QString tmpCompassStr(recvDataCompass.toHex());
ui->textEdit_2->moveCursor(QTextCursor::End);
ui->textEdit_2->insertPlainText(tmpCompassStr.left(baseSizeCompass));
recvDataCompass = recvDataCompass.right(totolSize-baseSizeCompass);
totolSize = recvDataCompass.size();
}
}
void Widget::handleSerialError(QSerialPort::SerialPortError error) //串口拔出检测
{
if (error == QSerialPort::ResourceError) {
serialPortGps->close();
QMessageBox::critical(this, tr("Error"), "串口连接中断,请检查是否正确连接!");
ui->pushButton_gps->setStyleSheet("background-color:rgb(130,130,130)");
ui->pushButton_gps->setText("port_close");
}
}
void Widget::handleSerialErrorCompass(QSerialPort::SerialPortError error)
{
if (error == QSerialPort::ResourceError) {
serialPortCompass->close();
QMessageBox::critical(this, tr("Error"), "串口连接中断,请检查是否正确连接!");
ui->pushButton_luopan->setStyleSheet("background-color:rgb(130,130,130)");
ui->pushButton_luopan->setText("port_close");
}
}
void Widget::on_pushButton_luopan_clicked()//点击罗盘那边的开启
{
initSerialPortCompass();
}
void Widget::sendRequest()
{
QString sendData("68 04 00 04 08");
QByteArray sendDataByte;
QStringtoHex(sendDataByte,sendData);
serialPortCompass->write(sendDataByte);
}
void Widget::QStringtoHex(QByteArray& sendData,QString str)
{
char hstr,lstr,hdata,ldata;
int len = str.length();
int sendnum = 0;
QByteArray temp;
temp.resize(len/2);//设置大小,len/2会大于实际16进制字符
//sendData.resize(len/2);
for(int i=0;i<len;)
{
//hstr = str[i].toAscii();
hstr = str[i].toLatin1();
if(hstr == ' ')
{
++i;
continue;
}
++i;
if(i >= len)
{
break;
}
lstr = str[i].toLatin1();
hdata = ConvertHexChar(hstr);
ldata = ConvertHexChar(lstr);
if(-1 == hdata || -1 == ldata)
{
break;
}
++i;
temp[sendnum] = hdata<<4|ldata;
sendnum++;
}
sendData.reserve(sendnum);
sendData = temp.left(sendnum);//去掉多余字符
}
char Widget::ConvertHexChar(char c)
{
if(c>='a'&&c<='f')
{
return c-'a'+10;
}
else if(c>='A'&&c<='F')
{
return c-'A'+10;
}
else if(c>='0'&&c<='9')
{
return c-'0';
}
else{
return -1;
}
}
#if 1
void Widget::sendTcpAll()
{
qDebug()<<"gps.size"<<recvDataGps.size();
qDebug()<<"compass.size"<<recvDataCompass.size();
#if 1
if(recvDataGps.size()==60&&recvDataCompass.size()==14)
{
qDebug()<<"yes";
recvAll.append(recvDataGps).append(recvDataCompass);
//socketwrite
//如果socket打开了
try
{
if(socketConnectedFlag==false)
throw runtime_error("socketflag false");
}
catch(runtime_error err)
{
qDebug()<<err.what();
}
socket->write(recvAll);
}
else {
qDebug()<<"nothing";
}
#endif
}
#endif
#if 0
自建结构体然后发送
#endif
//实现整合
void Widget::on_pushButton_clicked()
{
initSocket();
timerAll = new QTimer(this);
timerAll->start(5);
connect(timerAll,&QTimer::timeout,this,&Widget::sendTcpAll);
}