QT项目笔记
2015-06-03 20:45
381 查看
最近在做基于QT的烟箱分类计数系统,一共四个串口,其中三个串口接收扫描头发送过来的条码数据,剩下一个串口发送确认信号(确认有烟箱,升降机中的托盘会触发扫描头发送数据)。
四个串口开四个独立的线程读取数据,通过继承QThread类,在run() 函数中定义自己封装的串口类对象(封装QSerialPort类),然后在run()函数中调用exec()函数,启动线程的事件循环。借助Qt的信号槽机制,将串口线程读取到的数据发送到主线程中作简单处理。
serialthread.h文件
分辨品牌的原理是:从扫描到的一号工程码中提取品牌码,查询数据库,得到平牌名。如果一号工程码没有扫描到,从扫描到的烟箱码中提取平牌码,然后和数据库中的对比。(当然如果都没有扫描到,当做未知品牌,基本不会出现。)
现场经过仔细的观察,发现出现混乱的原因是扫描头的安装位置引起前后两个箱子平牌A和品牌B离得太近,A箱子的条码扫描完成,但是确认信号还没发送过来,后边B箱子的一号工程码已经扫描了,这样就导致B箱子的一号工程码把A箱子的一号工程码给覆盖了。结果及时A箱子被当做B品牌计入了数据库,在每次处理完一个箱子之后,保存数据的变量清空,所以B箱子的确认信号过来时,只有烟箱码,没有一号工程码(一号工程码给A箱子使用了,这里假设没有C箱子的一号工程码来覆盖B箱子的一号工程码)。这样B品牌就被记了两次。
解决问题的方法有两点:
1、先判断烟箱码,如果烟箱码能够识别出品牌来,则不用管一号工程码,烟箱码总是实时的,是当前箱子的。
2、采用两个变量和comString1Tem和comString1Common来保存一号工程码,交替的保存。当有确认信号过来时,同样交替的来处理。
保存读取的串口数据代码:
交替处理串口的数据代码:
后来在观察的过程中,发现还是有错误,部分只有一号工程码的品牌错误,部分烟箱码和一号工程码不匹配(当然品牌能够正常识别),然后发现是由于干扰,发送一号工程码的串口多发送了一个数据,相当于在comString1Tem和comString1Common中,比如comString1Tem中保存了一个无效的数据,而正确的数据却在comString1Common中,这造成每次交替的处理一号工程码时,当前要处理的一号工程码对应的错乱,而且会一直这么错下去。
考虑到如果都能发送过来一号工程码和烟箱码,那么一号工程码和烟箱码必须匹配,通过是否匹配来纠错。
如果不匹配,读取一个新的一号工程码来处理。
四个串口开四个独立的线程读取数据,通过继承QThread类,在run() 函数中定义自己封装的串口类对象(封装QSerialPort类),然后在run()函数中调用exec()函数,启动线程的事件循环。借助Qt的信号槽机制,将串口线程读取到的数据发送到主线程中作简单处理。
serialthread.h文件
#ifndef SERIALTHREAD_H #define SERIALTHREAD_H #include "myserialport.h" #include <QString> #include <QThread> #include <QObject> class SerialThread : public QThread { Q_OBJECT public: explicit SerialThread(QString comName, qint32 baudrate,bool flag = true, QThread *parent = 0); ~SerialThread(); private: QString m_comName; //把串口名称作为成员,使每个串口打开都封装在一个线程当中 qint32 m_baudrate; bool codeFlag; protected: void run(); signals: void transCode(QString Code); //把读到的条码转发出去 }; #endif // SERIALTHREAD_Hserialthread.cpp文件
#include "serialthread.h" #include <QtSerialPort/QtSerialPort> #include "myserialport.h" SerialThread::SerialThread(QString comName, qint32 baudrate, bool flag, QThread *parent) : QThread(parent),m_comName(comName) { this->m_baudrate = baudrate; this->codeFlag = flag; } void SerialThread::run() { MySerialPort *thePort =new MySerialPort(m_comName, m_baudrate, this->codeFlag); connect(thePort, SIGNAL(sendCode(QString)), this, SIGNAL(transCode(QString))); this->exec(); delete thePort; } SerialThread::~SerialThread() { }到现场测试的时候,发现分类出现了混乱。把一个品牌的计入到另外品牌中。
分辨品牌的原理是:从扫描到的一号工程码中提取品牌码,查询数据库,得到平牌名。如果一号工程码没有扫描到,从扫描到的烟箱码中提取平牌码,然后和数据库中的对比。(当然如果都没有扫描到,当做未知品牌,基本不会出现。)
现场经过仔细的观察,发现出现混乱的原因是扫描头的安装位置引起前后两个箱子平牌A和品牌B离得太近,A箱子的条码扫描完成,但是确认信号还没发送过来,后边B箱子的一号工程码已经扫描了,这样就导致B箱子的一号工程码把A箱子的一号工程码给覆盖了。结果及时A箱子被当做B品牌计入了数据库,在每次处理完一个箱子之后,保存数据的变量清空,所以B箱子的确认信号过来时,只有烟箱码,没有一号工程码(一号工程码给A箱子使用了,这里假设没有C箱子的一号工程码来覆盖B箱子的一号工程码)。这样B品牌就被记了两次。
解决问题的方法有两点:
1、先判断烟箱码,如果烟箱码能够识别出品牌来,则不用管一号工程码,烟箱码总是实时的,是当前箱子的。
2、采用两个变量和comString1Tem和comString1Common来保存一号工程码,交替的保存。当有确认信号过来时,同样交替的来处理。
保存读取的串口数据代码:
void Widget::getReadDate1(QString transData)
if(this->readFlag) //交替存储
{
this->comString1Common = transData;
this->readFlag = false;
}
else //交替存储 防止覆盖
{
this->comString1Tem = transData;
this->readFlag = true;
}
}
交替处理串口的数据代码:
void Widget::getcomString1()
if(this->saveFlag) //交替读取两个储存
{
this->comString1 = comString1Common;
if(this->comString1.startsWith(QString("\x02\x5D"))) //一号工程码
{
this->proCodeFlag = true;
//***********************************
this->comString1.remove(0,6); //移除开始的6位
this->comString1.chop(1); //移除末尾的一位
this->proCode = comString1;
this->proBrandCode = this->proCode.left(6); //获取开始的6位
//*****************************************
}
this->comString1Common.clear();
this->saveFlag = false;
}
else
{
this->comString1 = comString1Tem;
if(this->comString1.startsWith(QString("\x02\x5D"))) //一号工程码
{
this->proCodeFlag = true;
//****************************************
this->comString1.remove(0,6); //移除开始的6位
this->comString1.chop(1); //移除末尾的一位
this->proCode = comString1;
this->proBrandCode = this->proCode.left(6); //获取开始的6位
//*****************************************
}
this->comString1Tem.clear();
this->saveFlag = true;
}
}
后来在观察的过程中,发现还是有错误,部分只有一号工程码的品牌错误,部分烟箱码和一号工程码不匹配(当然品牌能够正常识别),然后发现是由于干扰,发送一号工程码的串口多发送了一个数据,相当于在comString1Tem和comString1Common中,比如comString1Tem中保存了一个无效的数据,而正确的数据却在comString1Common中,这造成每次交替的处理一号工程码时,当前要处理的一号工程码对应的错乱,而且会一直这么错下去。
考虑到如果都能发送过来一号工程码和烟箱码,那么一号工程码和烟箱码必须匹配,通过是否匹配来纠错。
如果不匹配,读取一个新的一号工程码来处理。
if(boxCodeFlag && proCodeFlag) //此时扫到一号工程码和烟箱码 { //从烟箱码中提取出品牌码 this->boxCode = rawBoxCode.mid(1, 13); //丢掉起始和结束标志位 this->boxBrandCode = this->boxCode.right(6); if(this->proBrandCode != this->boxBrandCode) { this->getcomString1(); //使用下一个comstring1 }
相关文章推荐
- win7下配置OpenCV的Qt开发环境
- 大量的QT控件及示例发放
- qt字体设置
- Qt(2):MOC文件解析
- Ubuntu14.04 LTS安装 OpenCV-3.0.0-rc1 + QT5.4.1
- Tiny6410 && ubuntu 14.04 运行qt程序
- QTableWidget
- QML和C++混合编程--Qt声明式用户界面运行环境
- qt按键焦点切换
- Qt多线程学习:创建多线程
- 解决QT用着用着就不好使的问题
- opencv & qt study-(3)-图像的容器--Mat
- Qt5.3 for vs2013 中文乱码解决办法
- Ubuntu环境下Qt软件deb包制作
- 使用Qt5.4安装Netanim 3.106
- QT对话框中show和exec的区别
- Qt开发:打开外部程序
- ubuntu+QT+ OpenGL绘图
- Qt_5_4_1_MSVC2013_OpenGL和opencv2.10
- qt里面如何调用mplayer