您的位置:首页 > 编程语言 > Qt开发

QT项目笔记

2015-06-03 20:45 381 查看
最近在做基于QT的烟箱分类计数系统,一共四个串口,其中三个串口接收扫描头发送过来的条码数据,剩下一个串口发送确认信号(确认有烟箱,升降机中的托盘会触发扫描头发送数据)。

四个串口开四个独立的线程读取数据,通过继承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_H
serialthread.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
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: