Qt Serial Port de Lecture de données de manière cohérente

Je suis d'envoi (par écrit) les octets à un périphérique via mon port série. Je suis l'aide de la QSerialPort (http://qt-project.org/wiki/QtSerialPort) module d'instancier périphérique d'e /s de soutien. Lorsque j'envoie des messages à mes INSTEON modem (série), à la lecture de mon message, l'appareil envoie une copie de mon message + 0x06 (accusé de réception de l'Octet), suivie par un message d'état.

J'ai testé mon message à l'aide de DockLight (http://www.docklight.de/). J'ai envoyer le message suivant à la requête de l'état de l'appareil:

    02 62 1D E9 4B 05 19 00

À l'aide de Docklight, je reçois la réponse:

    02 62 1D E9 4B 05 19 00 06 02 50 20 CB CF 1E DA F7 21 00 FF

L'a retourné le message indique exactement ce que je m'attends à ce que l'appareil est en marche. Si elle est désactivée, le modem serait de les envoyer en arrière 0x00 dans le dernier octet de la position si l'appareil a été éteint. Maintenant, mon problème - je ne dois pas avoir ma fonction correctement configuré afin d'envoyer et de recevoir la réponse d'octets. J'ai essayé beaucoup de différents exemples et des configurations, je suis actuellement en utilisant les éléments suivants:

De configuration connexions signal-slot:

QObject::connect(&thread, SIGNAL(sendResponse(QByteArray)), 
    this, SLOT(handleResponse(QByteArray)));
QObject::connect(&thread, SIGNAL(error(QString)), 
    this, SLOT(processError(QString)));
QObject::connect(&thread, SIGNAL(timeout(QString)), 
    this, SLOT(processTimeout(QString)));

Fonction utilisée pour parcourir QList de périphériques. Si l'appareil est de type désiré ("Lumière"), alors nous le format de l'ID de l'appareil à la destination de l'QByteArray structure du message. Passer message à fil pour l'envoi. (Sujet modifié à partir de QSerialPort BlockingMaster exemple.

void Device::currentStatus(QList<Device *> * deviceList){
    QString devID, updateQry;
    int devStatus, updateStatus;
    updateStatus=0;
    QSqlQuery query;
    for(int i=0; i<deviceList->size(); i++){
        if(deviceList->at(i)->type == "Light"){
            devStatus = deviceList->at(i)->status;
            devID = deviceList->at(i)->deviceID;
            QByteArray msg;
            bool msgStatus;
            msg.resize(8);

            msg[0] = 0x02;
            msg[1] = 0x62;
            msg[2] = 0x00;
            msg[3] = 0x00;
            msg[4] = 0x00;
            msg[5] = 0x05;
            msg[6] = 0x19;
            msg[7] = 0x00;
            msg.replace(2, 3, QByteArray::fromHex( devID.toLocal8Bit() ) );
            qDebug() << "Has device " << deviceList->at(i)->name << "Changed?";
            //send(msg,&msgStatus, &updateStatus);
            //msg.clear();
            thread.setupPort("COM3",500,msg);
            if(devStatus!=updateStatus){
                qDebug() << deviceList->at(i)->name << " is now: " << updateStatus;
                updateStatus = !updateStatus;
            }
        }
    }
}

SetupThread fonction utilisée pour définir les variables de thread et exécute (pistes) thread.

void serialThread::setupPort(const QString &portName, int waitTimeout, const QByteArray &msg){
    qDebug() << "Send Message " << msg.toHex();
    QMutexLocker locker(&mutex);
    this->portName = portName;
    this->waitTimeout = waitTimeout;
    this->msg = msg;
    if(!isRunning())
        start();
    else
        cond.wakeOne();
}

Run Fonction Manche envoi et la réception de

void serialThread::run(){
bool currentPortNameChanged = false;
qDebug() << "Thread executed";
mutex.lock();
QString currentPortName;
if(currentPortName != portName){
currentPortName = portName;
currentPortNameChanged = true;
}
int currentWaitTimeout = waitTimeout;
QByteArray sendMsg = msg;
mutex.unlock();
QSerialPort serial;
while(!quit){
if(currentPortNameChanged){
serial.close();
serial.setPortName("COM3");
if (!serial.open(QIODevice::ReadWrite)) {
emit error(tr("Can't open %1, error code %2")
.arg(portName).arg(serial.error()));
return;
}
if (!serial.setBaudRate(QSerialPort::Baud19200)) {
emit error(tr("Can't set baud rate 9600 baud to port %1, error code %2")
.arg(portName).arg(serial.error()));
return;
}
if (!serial.setDataBits(QSerialPort::Data8)) {
emit error(tr("Can't set 8 data bits to port %1, error code %2")
.arg(portName).arg(serial.error()));
return;
}
if (!serial.setParity(QSerialPort::NoParity)) {
emit error(tr("Can't set no patity to port %1, error code %2")
.arg(portName).arg(serial.error()));
return;
}
if (!serial.setStopBits(QSerialPort::OneStop)) {
emit error(tr("Can't set 1 stop bit to port %1, error code %2")
.arg(portName).arg(serial.error()));
return;
}
if (!serial.setFlowControl(QSerialPort::NoFlowControl)) {
emit error(tr("Can't set no flow control to port %1, error code %2")
.arg(portName).arg(serial.error()));
return;
}
}
//write request
serial.write(msg);
if (serial.waitForBytesWritten(waitTimeout)) {
//! [8] //! [10]
//read response
if (serial.waitForReadyRead(currentWaitTimeout)) {
QByteArray responseData = serial.readAll();
while (serial.waitForReadyRead(10)){
responseData += serial.readAll();
}
QByteArray response = responseData;
//! [12]
emit this->sendResponse(response);
//! [10] //! [11] //! [12]
} else {
emit this->timeout(tr("Wait read response timeout %1")
.arg(QTime::currentTime().toString()));
}
//! [9] //! [11]
} else {
emit timeout(tr("Wait write request timeout %1")
.arg(QTime::currentTime().toString()));
}
mutex.lock();
cond.wait(&mutex);
if (currentPortName != portName) {
currentPortName = portName;
currentPortNameChanged = true;
} else {
currentPortNameChanged = false;
}
currentWaitTimeout = waitTimeout;
sendMsg = msg;
mutex.unlock();
}
serial.close();
}

handleResponse de fonction, LOGEMENT qui reçoit le signal de réponse

void Device::handleResponse(const QByteArray &msg){
qDebug() << "Read: " << msg.toHex();
}

- Je recevoir la sortie suivante:

Has device  "Living Room Light" Changed? 
Send Message  "02621de94b051900" 
Has device  "Bedroom Light" Changed? 
Send Message  "026220cbcf051900" 
Thread executed 
Read:  "026220cbcf05190006" 
Polling for changes... 
Has device  "Living Room Light" Changed? 
Send Message  "02621de94b051900" 
Has device  "Bedroom Light" Changed? 
Send Message  "026220cbcf051900" 
Read:  "025020cbcf1edaf721000002621de94b05190006" 
Polling for changes... 
Has device  "Living Room Light" Changed? 
Send Message  "02621de94b051900" 
Has device  "Bedroom Light" Changed? 
Send Message  "026220cbcf051900" 
Read:  "02501de94b1edaf72100ff02621de94b05190006" 

De deux questions.

  1. Je n'ai jamais reçu aucune réponse concernant le deuxième dispositif (Chambre à coucher de la Lumière), c'est le message qui est envoyé à la seconde. Il semble que l'envoi est bloqué, comment voulez-vous recommander je format mon envoi afin que je vous envoie après la réception de la réponse de la première à envoyer? Il est à seulement 1 port COM qui peut être utilisé pour envoyer/recevoir. Je crois que je dois Envoyer un message à l'Appareil 1, le Dispositif de réception 1 réponse, Envoyer à l'Appareil 2, le Dispositif de réception 2. Pourrais-je voir un énorme embouteillage avec un grand nombre d'appareils et en utilisant les conditions d'attente, c'est à dire. attendez que l'appareil 1 processus de communication avant la fin de l'exécution de comm processus pour appareil 2?

  2. La première lecture contient le cas échéant le 1er semestre de la recevoir. Read: "026220cbcf05190006" La deuxième recevez contient le 2ème semestre de la 1ère réponse, suivi par le 1er semestre de la deuxième réponse: Lire 2 - Read: "025020cbcf1edaf721000002621de94b05190006" approprié réponse complète est 02621DE94B05190006 025020CBCF1EDAF72100FF
    (note 20CBCF est le Dispositif 2 de l'ID dans la réponse complète exemple)

Ce que des corrections doivent être apportées à la façon dont je suis la réception de données sur le port série?
Merci!!!!

InformationsquelleAutor Alex Hendren | 2013-02-27