QSerialPort unvollständige Antwort nach Anfrage
-
Hallo zusammen,
ich bin momentan etwas verzweifelt um habe mich hier angemeldet, in der Hoffnung Hilfe zu finden.
Ich arbeite gerade an einem Projekt, bei dem ich zum ersten Mal "QSerialPort" verwende. Ich möchte über eine RS232-Schnittstelle die Temperatursensoren eines Ofens abfragen. Laut Bedienungsanleitung des Ofens muss ich dazu zunächst eine Anfrage an den Ofen senden, dann antwortet der Ofen mit den gewünschten Daten. Ich verwende dazu unten dargestellten Code. Über die Funktion "ask_for_temperatures()" schicke ich die Anfrage. Über das "readyRead()"-Signal wird "receive_message()" ausgelöst und schreib die Antwort des Ofens in "m_received_message". Nach Anleitung des Ofens wird jede Antwort mit einem Carriage Return abgeschlossen, sodass ich über ein if-Anweiseung prüfen kann, ob die Antwort komplett ist. "ask-for-temperatures()" Löse ich mit einem QTimer alle 8000ms um eine Aktualisierung der Temperatur zu bekommen.
Mein Problem ist nun: Die ersten 3-4 Mal funktioniert die Kommunikation mit dem Ofen wunderbar und ich bekomme die erwartete Antwort vom Ofen. Ab dem 4. oder 5. Mal bekomme ich dann aber keine korrekte Antwort mehr. Es kommen nur noch Bruchstücke einer Antwort an und auch unwerwartete Zeichen. Ich verstehe nicht warum, insbesondere da die Kommunikation zunächst funktionert.
Weiterhin ist es für mich verwunderlich, dass die Kommunikation an einem 2. baugleichen Ofen problemlos klappt. Ein Problem mit dem Ofen selbst würde ich aber auch ausschließen, da eine ältere Software (welche ich ersetzen möchte, Quellcode unbekannt) mit dem Ofen normal kommuniziert.
Hat irgendjemand eine Idee, was ich optimieren könnte? Die Einstellungen (BaudRate,DataBits usw.) habe ich direkt aus der Bedienungsanleitung des Ofens übernommen. Schonmal vielen Dank fürs Lesen und eventuelle Unterstützung.rs232::rs232() { rs232_ofen->setPortName("COM5"); rs232_ofen->setBaudRate(QSerialPort::Baud57600); rs232_ofen->setDataBits(QSerialPort::Data8); rs232_ofen->setParity(QSerialPort::NoParity); rs232_ofen->setStopBits(QSerialPort::OneStop); rs232_ofen->setFlowControl(QSerialPort::NoFlowControl); rs232_ofen->open(QSerialPort::ReadWrite); connect(rs232_ofen, SIGNAL(readyRead()), this, SLOT(receive_message())); } bool rs232::ask_for_temperatures() { if(rs232_ofen->isOpen()){ m_received_message.clear(); QByteArray message = "?:3010:00::c2\r"; rs232_ofen->write(message); return true; } return false; } bool rs232::receive_message() { m_received_message += rs232_ofen->readAll(); if(m_received_message.contains("\r")){ qDebug()<<m_received_message; //über qDebug kann ich die Antwort direkt ablesen. evaluate_answer(); emit message_received(); return true; } return false; }
-
Hi
Ich würde mit einem Tool wie Wireshark überprüfen, was tatsächlich gesendet wird.
-
Hi @tobaias neben das was @mrjj gesagt hat,
kannst du deine Debug-Ausgabe hier posten, sodass man sehen kann, was du mit ungewöhnlichen Zeichen und unvollständigen Nachrichten meinst.
Weil eigentlich sollte es zumindest keine Unvollständigen Nachrichten geben, da man sieht, dass du den Fall eine unvollständigen Nachricht eigentlich abfängst!
Das gesagt, warum hat dein slot new bool Returnwert ? Das ist verwunderlich und könnte ein design problem sein 😉
Kannst auch mal diesen Ansatz versuchen:
void rs232::onReadyReayd() { if(rs232_ofen->canReadLine()) { QByteArray lineBa = rs232_ofen->readLine(); qDebug() << "new Line" << lineBa << lineBa.toHex(' '); } }
-
Danke für die ersten Antworten. Bool als return ist nicht sinnvoll, richtig. Ich wollte damit ursprünglich abfangen, ob eine Nachricht vollständig ist oder nicht bis ich gemerkt habe, dass das gar nicht so funktioniert. Danach kam erst das "emit" hinzu.
Hier die Ausgabe, zusätzlich mit zeitstempel und einem qDebug() in "ask_for_temerature()". Weiterhin habe ich das qDebug für die Antwort vor die if-schleife gezogen damit man sehen kann, wie häufig der Slot ausgelöst wird bzw. In welchen Abschnitten nicht Antwort empfangen wird.
Hier das Ergebnis, die eigentliche Antwort beginnt mit dem "!":05.09.2020-14:15:55;ask for temp 05.09.2020-14:15:55;! 05.09.2020-14:15:55;!:3010:1f:+125.00;+125.00;+125.00;+127.51:b6 > korrekte Antwort 05.09.2020-14:16:03;ask for temp 05.09.2020-14:16:03;!:3010 05.09.2020-14:16:03;!:3010:1f:+125.00;+125.00;+125.00;+127.51:b6 > korrekte Antwort 05.09.2020-14:16:11;ask for temp 05.09.2020-14:16:11;!:30 05.09.2020-14:16:11;!:3010:02:?2:d3 > Antwort unvollständig, “?” nicht erwartet 05.09.2020-14:16:19;ask for temp 05.09.2020-14:16:19;!:301 05.09.2020-14:16:19;!:3010:1f:+125.00;+125.00;+125.00;+127.53:b4 > korrekte Antwort 05.09.2020-14:16:27;ask for temp 05.09.2020-14:16:27;!:0 05.09.2020-14:16:27;!:010::02:?2:da > Antwort unvollständig, “?” nicht erwartet 05.09.2020-14:16:35;ask for temp 05.09.2020-14:16:35;! 05.09.2020-14:16:35;!:0:0::02:?2:d1 > Antwort unvollständig, “?” nicht erwartet 05.09.2020-14:16:43;ask for temp 05.09.2020-14:16:43;!:0 05.09.2020-14:16:43;!:010::02:?2:da > Antwort unvollständig, “?” nicht erwartet 05.09.2020-14:16:51;ask for temp 05.09.2020-14:16:51;!: 05.09.2020-14:16:51;!:10:0:02:?2:da > Antwort unvollständig, “?” nicht erwartet 05.09.2020-14:16:59;ask for temp 05.09.2020-14:17:07;ask for temp 05.09.2020-14:17:07;!: 05.09.2020-14:17:07;!:0c?::02:?2:87 > Antwort unvollständig, “?” nicht erwartet
Ich habe jetzt auch mal den Ansatz mit readLine() ausprobiert. Allerdings bekomme ich dann gar keine Antwort....