本文共 8119 字,大约阅读时间需要 27 分钟。
#ifndef ZIOMODULE_H #define ZIOMODULE_H #include <QObject> #include <QDebug> #include <QSerialPort> #include <QSerialPortInfo> #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); if(!this->m_serialPort->open(QIODevice::ReadWrite)) { qDebug()<<"error:"<<this->m_serialPort->errorString(); qDebug()<<"available ports are:"; foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) { qDebug()<<info.portName(); } return false; } 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(1000); } 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: qDebug()<<"error:invalid output port index!"; return false; } return this->ZVerifyResponseForOutputOpenClose(portIndex,bOpen); } bool ZIOModule::ZVerifyResponseForOutputOpenClose(qint32 index,bool bOpen) { qint32 portIndex=index; //here we use sync mode to wait device's response. if(!this->m_serialPort->waitForReadyRead(this->m_responseTimeout)) { qDebug()<<"error:wait for response timeout!"; return false; } QByteArray tRecvBuffer=this->m_serialPort->readAll(); if(tRecvBuffer.count()!=sizeof(zresponse_output_open_close) && tRecvBuffer.count()!=sizeof(zresponse_failed)) { qDebug()<<"error:invalid response!"; return false; } if(tRecvBuffer==QByteArray((const char*)zresponse_failed,sizeof(zresponse_failed))) { qDebug()<<"error:device execute command failed!"; return false; } //{0xA3,ADDR_DEST,0x00,0xFF,0x0D,0x0A}; //verify the response byte by byte. if(0xA3!=(uchar)tRecvBuffer.at(0) || ADDR_DEST!=(uchar)tRecvBuffer.at(1) || portIndex!=(uchar)tRecvBuffer.at(2) || 0x0D!=(uchar)tRecvBuffer.at(tRecvBuffer.count()-2) || 0x0A!=(uchar)tRecvBuffer.count()-1) { qDebug()<<"error:specified byte is not right!"; return false; } if(bOpen && 0x00!=(uchar)tRecvBuffer.at(3)) { qDebug()<<"open failed"; return false; }else if(!bOpen && 0xFF!=(uchar)(tRecvBuffer.at(3))) { qDebug()<<"close failed!"; 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)) { qDebug()<<"error:write data failed!"; return -1; } if(!this->m_serialPort->waitForReadyRead(this->m_responseTimeout)) { qDebug()<<"error:wait for response timeout!"; return -1; } QByteArray tRecvBuffer=this->m_serialPort->readAll(); if(tRecvBuffer.count()!=sizeof(zresponse_all_relay_status) && tRecvBuffer.count()!=sizeof(zresponse_failed)) { qDebug()<<"error:invalid response!"; return -1; } if(tRecvBuffer==QByteArray((const char*)zresponse_failed,sizeof(zresponse_failed))) { qDebug()<<"error:device execute command failed!"; return -1; } //{0xA3,ADDR_DEST,0xFF,0xFF,0xFF,0xFF,0x0D,0x0A}; //verify byte by byte. if(0xA3!=(uchar)tRecvBuffer.at(0) || ADDR_DEST!=(uchar)tRecvBuffer.at(1) || 0x0D!=(uchar)tRecvBuffer.at(tRecvBuffer.count()-2) || 0x0A!=(uchar)tRecvBuffer.count()-1) { qDebug()<<"error:specified byte is not right!"; 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)) { qDebug()<<"error:write data failed!"; return -1; } if(!this->m_serialPort->waitForReadyRead(this->m_responseTimeout)) { qDebug()<<"error:wait for response timeout!"; return -1; } QByteArray tRecvBuffer=this->m_serialPort->readAll(); if(tRecvBuffer.count()!=sizeof(zresponse_all_inputs_status) && tRecvBuffer.count()!=sizeof(zresponse_failed)) { qDebug()<<"error:invalid response!"; return -1; } if(tRecvBuffer==QByteArray((const char*)zresponse_failed,sizeof(zresponse_failed))) { qDebug()<<"error:device execute command failed!"; return -1; } //{0xA5,ADDR_DEST,0xFF,0xFF,0xFF,0xFF,0x0D,0x0A}; //verify byte by byte. if(0xA5!=(uchar)tRecvBuffer.at(0) || ADDR_DEST!=(uchar)tRecvBuffer.at(1) || 0x0D!=(uchar)tRecvBuffer.at(tRecvBuffer.count()-2) || 0x0A!=(uchar)tRecvBuffer.count()-1) { qDebug()<<"error:specified byte is not right!"; 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; }转载地址:http://nczji.baihongyu.com/