本文共 10232 字,大约阅读时间需要 34 分钟。
#ifndef ZIOMODULE_H #define ZIOMODULE_H #include <QObject> #include <QDebug> #include <QSerialPort> #include <QSerialPortInfo> #define ZDebugInfo 1 #define ADDR_DEST 0x01 const uchar zresponse_failed[]={0xA3,0x0D,0x0A,}; const uchar zcmd_output1_open[]={0x3A,0x88,ADDR_DEST,0x01,0x00,0x0D,0x0A}; const uchar zcmd_output1_close[]={0x3A,0x88,ADDR_DEST,0x01,0xFF,0x0D,0x0A}; const uchar zcmd_output2_open[]={0x3A,0x88,ADDR_DEST,0x02,0x00,0x0D,0x0A}; const uchar zcmd_output2_close[]={0x3A,0x88,ADDR_DEST,0x02,0xFF,0x0D,0x0A}; const uchar zcmd_output3_open[]={0x3A,0x88,ADDR_DEST,0x03,0x00,0x0D,0x0A}; const uchar zcmd_output3_close[]={0x3A,0x88,ADDR_DEST,0x03,0xFF,0x0D,0x0A}; const uchar zcmd_output4_open[]={0x3A,0x88,ADDR_DEST,0x04,0x00,0x0D,0x0A}; const uchar zcmd_output4_close[]={0x3A,0x88,ADDR_DEST,0x04,0xFF,0x0D,0x0A}; const uchar zresponse_output_open_close[]={0xA3,ADDR_DEST,0x00,0xFF,0x0D,0x0A}; //get all relays status. const uchar zcmd_get_all_relay_status[]={0x3A,0x99,ADDR_DEST,0x00,0x0D,0x0A}; const uchar zresponse_all_relay_status[]={0xA3,ADDR_DEST,0xFF,0xFF,0xFF,0xFF,0x0D,0x0A}; //get all input status. const uchar zcmd_get_all_inputs_status[]={0x3A,0x98,ADDR_DEST,0x00,0x0D,0x0A}; const uchar zresponse_all_inputs_status[]={0xA5,ADDR_DEST,0xFF,0xFF,0xFF,0xFF,0x0D,0x0A}; class ZIOModule : public QObject { Q_OBJECT public: typedef enum { OutputPort1=1, OutputPort2=2, OutputPort3=3, OutputPort4=4, }ZOutputPort; //portName: ttyUSB0. //responseTimeout: the wait time for the device response. explicit ZIOModule(QString portName,qint32 responseTimeOut=2000,QObject *parent = 0); ~ZIOModule(); //execute serial port initial operations. bool ZDoInit(); //do some clean work here. void ZCleanUp(); //set output status of specified port. bool ZSetOutputPort(ZOutputPort port,bool bOpen); //get all output port status. qint32 ZGetOutputPortsStatus(qint32 *status); //get all input port status. qint32 ZGetInputPortsStatus(qint32 *status); signals: public slots: private: qint32 ZWriteData(const uchar *cmd,quint32 len); bool ZVerifyResponseForOutputOpenClose(qint32 index,bool bOpen); private: QSerialPort *m_serialPort; qint32 m_responseTimeout; }; #endif // ZIOMODULE_H#include "ziomodule.h"
ZIOModule::ZIOModule(QString portName,qint32 responseTimeOut,QObject *parent) : QObject(parent) { this->m_serialPort=new QSerialPort(portName); this->m_responseTimeout=responseTimeOut; } ZIOModule::~ZIOModule() { delete this->m_serialPort; } bool ZIOModule::ZDoInit() { this->m_serialPort->setBaudRate(QSerialPort::Baud9600); this->m_serialPort->setDataBits(QSerialPort::Data8); this->m_serialPort->setStopBits(QSerialPort::OneStop); this->m_serialPort->setParity(QSerialPort::NoParity); this->m_serialPort->setFlowControl(QSerialPort::NoFlowControl); this->m_serialPort->setReadBufferSize(1024); if(!this->m_serialPort->open(QIODevice::ReadWrite)) { #ifdef ZDebugInfo qDebug()<<"error:"<<this->m_serialPort->errorString(); qDebug()<<"available ports are:"; foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) { qDebug()<<info.portName(); } #endif return false; } //clear input buffer before. (void)this->m_serialPort->readAll(); return true; } void ZIOModule::ZCleanUp() { this->m_serialPort->flush(); this->m_serialPort->close(); } qint32 ZIOModule::ZWriteData(const uchar *cmd,quint32 len) { qint32 tWrites=-1; if(this->m_serialPort && this->m_serialPort->isOpen()) { QByteArray tSendBuffer((char*)cmd,len); tWrites=this->m_serialPort->write(tSendBuffer); this->m_serialPort->waitForBytesWritten(100); } return tWrites; } //set output status of specified port. bool ZIOModule::ZSetOutputPort(ZOutputPort port,bool bOpen) { qint32 portIndex; switch(port) { case ZIOModule::OutputPort1: if(bOpen) { this->ZWriteData(zcmd_output1_open,sizeof(zcmd_output1_open)); }else{ this->ZWriteData(zcmd_output1_close,sizeof(zcmd_output1_close)); } portIndex=1; break; case ZIOModule::OutputPort2: if(bOpen) { this->ZWriteData(zcmd_output2_open,sizeof(zcmd_output2_open)); }else{ this->ZWriteData(zcmd_output2_close,sizeof(zcmd_output2_close)); } portIndex=2; break; case ZIOModule::OutputPort3: if(bOpen) { this->ZWriteData(zcmd_output3_open,sizeof(zcmd_output3_open)); }else{ this->ZWriteData(zcmd_output3_close,sizeof(zcmd_output3_close)); } portIndex=3; break; case ZIOModule::OutputPort4: if(bOpen) { this->ZWriteData(zcmd_output4_open,sizeof(zcmd_output4_open)); }else{ this->ZWriteData(zcmd_output4_close,sizeof(zcmd_output4_close)); } portIndex=4; break; default: #ifdef ZDebugInfo qDebug()<<"error:invalid output port index!"; #endif return false; } return this->ZVerifyResponseForOutputOpenClose(portIndex,bOpen); } bool ZIOModule::ZVerifyResponseForOutputOpenClose(qint32 index,bool bOpen) { Q_UNUSED(index); Q_UNUSED(bOpen); //here we use sync mode to wait device's response. //wait for device response. qint32 tWaitTimeout=0; while(this->m_serialPort->bytesAvailable()<6) { this->m_serialPort->waitForReadyRead(1000); if(++tWaitTimeout>=3) { #ifdef ZDebugInfo qDebug()<<"error:device no response,timeout."; #endif return false; } } QByteArray tRecvBuffer=this->m_serialPort->readAll(); if(tRecvBuffer.count()!=sizeof(zresponse_output_open_close) && tRecvBuffer.count()!=sizeof(zresponse_failed)) { #ifdef ZDebugInfo qDebug()<<"error:invalid response!"; qDebug("success:%d,failed:%d,now is %d.\n",sizeof(zresponse_output_open_close),sizeof(zresponse_failed),tRecvBuffer.count()); #endif return false; } if(tRecvBuffer==QByteArray((const char*)zresponse_failed,sizeof(zresponse_failed))) { #ifdef ZDebugInfo qDebug()<<"error:device execute command failed!"; #endif return false; } //{0xA3,ADDR_DEST,0x00,0xFF,0x0D,0x0A}; //verify the response byte by byte. qint32 tPrefix=(qint32)tRecvBuffer.at(0)&0xFF; qint32 tAddr=(qint32)tRecvBuffer.at(1)&0xFF; qint32 tSuffix1=(qint32)tRecvBuffer.at(tRecvBuffer.count()-2)&0xFF; qint32 tSuffix2=(qint32)tRecvBuffer.at(tRecvBuffer.count()-1)&0xFF; if(0xA3!=tPrefix || ADDR_DEST!=tAddr || 0x0D!=tSuffix1 || 0x0A!=tSuffix2) { #ifdef ZDebugInfo qDebug()<<"error:specified byte is not right!"; #endif return false; } return true; } //get all output ports status. qint32 ZIOModule::ZGetOutputPortsStatus(qint32 *status) { qint32 ret; ret=this->ZWriteData(zcmd_get_all_relay_status,sizeof(zcmd_get_all_relay_status)); if(ret!=sizeof(zcmd_get_all_relay_status)) { #ifdef ZDebugInfo qDebug()<<"error:write data failed!"; #endif return -1; } if(!this->m_serialPort->waitForReadyRead(this->m_responseTimeout)) { #ifdef ZDebugInfo qDebug()<<"error:wait for response timeout!"; #endif return -1; } QByteArray tRecvBuffer=this->m_serialPort->readAll(); if(tRecvBuffer.count()!=sizeof(zresponse_all_relay_status) && tRecvBuffer.count()!=sizeof(zresponse_failed)) { #ifdef ZDebugInfo qDebug()<<"error:invalid response!"; #endif return -1; } if(tRecvBuffer==QByteArray((const char*)zresponse_failed,sizeof(zresponse_failed))) { #ifdef ZDebugInfo qDebug()<<"error:device execute command failed!"; #endif return -1; } //{0xA3,ADDR_DEST,0xFF,0xFF,0xFF,0xFF,0x0D,0x0A}; //verify byte by byte. qint32 tPrefix=(qint32)tRecvBuffer.at(0)&0xFF; qint32 tAddr=(qint32)tRecvBuffer.at(1)&0xFF; qint32 tSuffix1=(qint32)tRecvBuffer.at(tRecvBuffer.count()-2)&0xFF; qint32 tSuffix2=(qint32)tRecvBuffer.at(tRecvBuffer.count()-1)&0xFF; if(0xA3!=tPrefix || ADDR_DEST!=tAddr || 0x0D!=tSuffix1 || 0x0A!=tSuffix2) { #ifdef ZDebugInfo qDebug()<<"error:specified byte is not right!"; #endif return -1; } //combine bytes. *status=(qint32)tRecvBuffer.at(2)<<24|(qint32)tRecvBuffer.at(3)<<16|(qint32)tRecvBuffer.at(4)<<8|(qint32)tRecvBuffer.at(5)<<0; return 0; } //get all input port status. qint32 ZIOModule::ZGetInputPortsStatus(qint32 *status) { qint32 ret; ret=this->ZWriteData(zcmd_get_all_inputs_status,sizeof(zcmd_get_all_inputs_status)); if(ret!=sizeof(zcmd_get_all_inputs_status)) { #ifdef ZDebugInfo qDebug()<<"error:write data failed!"; #endif return -1; } qint32 waitTimeout=0; while(this->m_serialPort->bytesAvailable()<8) { this->m_serialPort->waitForReadyRead(1000); if(++waitTimeout>5) { #ifdef ZDebugInfo qDebug("error:device no response!"); #endif return -1; } } QByteArray tRecvBuffer=this->m_serialPort->readAll(); if(tRecvBuffer.count()!=sizeof(zresponse_all_inputs_status) && tRecvBuffer.count()!=sizeof(zresponse_failed)) { #ifdef ZDebugInfo qDebug()<<"error:invalid response!"; #endif return -1; } if(tRecvBuffer==QByteArray((const char*)zresponse_failed,sizeof(zresponse_failed))) { #ifdef ZDebugInfo qDebug()<<"error:device execute command failed!"; #endif return -1; } //{0xA5,ADDR_DEST,0xFF,0xFF,0xFF,0xFF,0x0D,0x0A}; //verify byte by byte. qint32 tPrefix=(qint32)tRecvBuffer.at(0)&0xFF; qint32 tAddr=(qint32)tRecvBuffer.at(1)&0xFF; qint32 tSuffix1=(qint32)tRecvBuffer.at(tRecvBuffer.count()-2)&0xFF; qint32 tSuffix2=(qint32)tRecvBuffer.at(tRecvBuffer.count()-1)&0xFF; if(0xA5!=tPrefix || ADDR_DEST!=tAddr || 0x0D!=tSuffix1 || 0x0A!=tSuffix2) { #ifdef ZDebugInfo qDebug()<<"error:specified byte is not right!"; #endif return -1; } //combine bytes. *status=(qint32)tRecvBuffer.at(2)<<24|(qint32)tRecvBuffer.at(3)<<16|(qint32)tRecvBuffer.at(4)<<8|(qint32)tRecvBuffer.at(5)<<0; return 0; } #include <QCoreApplication> #include <QThread> #include <ziomodule.h> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); bool bRet; qint32 tInportStatus; ZIOModule ioModule("ttyUSB0"); if(!ioModule.ZDoInit()) { qDebug()<<"initial failed!"; return -1; } #if 1 while(1) { ioModule.ZGetInputPortsStatus(&tInportStatus); QThread::sleep(1); qDebug("InputPort:0x%x\n",tInportStatus); } #endif #if 1 while(1) { bRet=ioModule.ZSetOutputPort(ZIOModule::OutputPort1,true); QThread::sleep(1); bRet=ioModule.ZSetOutputPort(ZIOModule::OutputPort2,true); QThread::sleep(1); bRet=ioModule.ZSetOutputPort(ZIOModule::OutputPort3,true); QThread::sleep(1); bRet=ioModule.ZSetOutputPort(ZIOModule::OutputPort4,true); QThread::sleep(5); bRet=ioModule.ZSetOutputPort(ZIOModule::OutputPort1,false); QThread::sleep(1); bRet=ioModule.ZSetOutputPort(ZIOModule::OutputPort2,false); QThread::sleep(1); bRet=ioModule.ZSetOutputPort(ZIOModule::OutputPort3,false); QThread::sleep(1); bRet=ioModule.ZSetOutputPort(ZIOModule::OutputPort4,false); QThread::sleep(5); } #endif //ioModule.ZCleanUp(); return a.exec(); }转载地址:http://oczji.baihongyu.com/