QT之问题解决记录1:上下位机通信中断而不自知
问题背景
在工业控制系统中,上下位机通过串口通信是一种常见的架构模式。下位机(通常是嵌入式设备)按照预定协议发送数据,上位机(通常是PC端应用程序)接收并解析这些数据,然后在用户界面上进行显示。
问题描述
在实际开发中,我发现了一个潜在的问题:当上下位机之间的通信意外中断时,上位机界面无法及时察觉这一情况。这意味着:
用户界面显示的数据可能长时间保持不变
系统无法及时报警或采取恢复措施
操作人员可能误认为系统仍在正常运行
解决方案
为了解决这个问题,我们设计了一个简单而有效的通信状态监测机制:
状态指示灯:在用户界面上添加一个通信状态指示灯
定时检测:使用QT的定时器功能,每5秒检查一次串口缓冲区
状态判定:
如果检测周期内收到数据,指示灯显示绿色(通信正常)
如果检测周期内未收到数据,指示灯显示红色(通信中断)
代码实现
//头文件中
extern void setLED(QLabel* label, qint16 color, qint16 size); // 具体实现见博文【QT界面LED指示灯-绘制一个LED灯】private slots:void serialPort_readyRead();void get_serial_data();
private:Ui::MainWindow *ui;QSerialPort *serial;QTimer *serial_timer;QTimer *serial_status_timer;//构造函数中
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ //串口serial = new QSerialPort(this); connect(serial, &QSerialPort::readyRead, this, &MainWindow::serialPort_readyRead);//初始化串口定时器serial_timer = new QTimer(this); connect(serial_timer, SIGNAL(timeout()), this, SLOT(get_serial_data()));//初始化用于检测无线串口状态的定时器serial_status_timer = new QTimer(this);connect(serial_status_timer, &QTimer::timeout, this, [this](){setLED(ui->label_led4_1, 1, 16); //无线指示灯红});
}void MainWindow::serialPort_readyRead()
{serial_timer->start(60);QByteArray data = serial->readAll();serial_buffer.append(data);// 重置无线状态定时器serial_status_timer->stop();serial_status_timer->start(5000); // 5秒后触发超时setLED(ui->label_led4_1, 2, 16); // 无线指示灯绿
}void MainWindow:: get_serial_data()
{serial_timer->stop();qDebug()<<"串口接收数据serial_buffer:"<<serial_buffer;// 重置无线状态定时器serial_status_timer->stop();serial_status_timer->start(5000); // 5秒后触发超时setLED(ui->label_led4_1, 2, 16); //无线指示灯绿// 处理数据包...
}