QSerialPort reset
-
Hallo zusammen,
ich habe ein Problem mit QSerialPort und der Kommunikation über eine RS232-Schnittstelle. Qt-Version 5.12.8 und Windows 10.
Auf dem System, wo das Programm laufen soll, läuft normalerweise eine Software (Programmiert mit LABVIEW) welche dieselbe RS232-Schnittstelle nutzt, mit der ich auch arbeiten möchte. Ich schließe also die Labview-Software und starte mein eigenes Tool. In meinem Tool habe ich einen Button welchen den "write"-Befehl der QSerialPort-Klasse ausführt und eine Nachricht sendet. Über das ReadyRead-Signal empfange ich direkt folgende Antwort vom anderen Gerät und lasse sie in einem Textfeld darstellen. Das Senden und Empfangen funktioniert leider nicht zuverlässig: Manchmal bekomme ich die erwarteten Antworten und manchmal bekomme ich Antworten, welche auf eine falsche Anfrage hinweisen.
Ich habe dann also meine Anfrage mit dem Terminalprogramm HTerm getestet. Die Schnittstelle habe ich in HTerm genauso konfiguriert wie in Qt. Die Anfrage und Antwort mit HTerm klappt problemlos. Ich schließe HTerm nun wieder und teste erneut mein (unverändertes!) Qt-Tool. Und plötzlich klappt es problemlos. Dieses Verhalten lässt sich zuverlässig reproduzieren:
Lief die Labview-Software vorher, gibt es Probleme - lief HTerm vorher, klappt auch danach das Qt-Tool fehlerfrei.
Daher meine Frage: Kann ich in Qt irgendwie die Schnittstelle "resetten"? Ich verstehe nicht, welche Einstellung durch die Labview-Software plötzlich falsch ist. Eigentlich konfiguriere ich mit Qt die Schnittstelle neu.
Hier mein überschaubarer Quelltext:#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); connect(rs232_ofen, SIGNAL(readyRead()), this, SLOT(receive())); } MainWindow::~MainWindow() { if(rs232_ofen->isOpen()){ rs232_ofen->close(); } delete ui; } void MainWindow::receive() { received_message += rs232_ofen->readAll(); ui->textBrowser->append("Received: " + received_message); } void MainWindow::on_pushButton_writeToPort_clicked() { received_message.clear(); QByteArray message = "?:3010:00::c2\r"; ui->textBrowser->append("send: " + message); rs232_ofen->write(message); } void MainWindow::on_pushButton_setPort_clicked() { if(rs232_ofen->isOpen()){ rs232_ofen->close(); } rs232_ofen->setPortName("COM5"); ui->textBrowser->append(rs232_ofen->portName()); 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); ui->textBrowser->append("isopen?: " + QString::number(rs232_ofen->isOpen())); }
-
Hallo
Es ist nicht klar was rs232_ofen ist.
Deine receive() wird durch ein Signal ausgelöst. Du kannst nicht garantieren, dass bei er Ausführun von receive schon alle Zeichen zu empfangen sind. Weiterhin muss nicht immer ein readyRead ausgelöst werden, wenn du es vielleicht erwartest. Solange du in der receive routine bist, kannst du eventuell das Signal verpassen, da es soweit ich weiss dann nicht generiert wird. -
@koahnig richtig, ich hab den Header vergessen. Werd ich morgen nachreichen. Aber da steht drin:
QSerialPort *rs232_ofen = new QSerialPort();Zum Zweiten: richtig, aber die Antwort wird Stück für Stück zusammengebaut... das geht schon, und die Antworten sind auch ALLE inklusive prüfsumme und korrekt. Das Senden macht Probleme, so dass das Gerät, welches angesprochen wird, eine Antwort schickt, welche besagt, dass die Anfrage nicht verstanden wurde.
Zur Erinnerung: das Tool funktioniert. Es ist eben nur abhängig davon, welches Programm vorher geöffnet war und die Schnittstelle geöffnet hatte. Und das verstehe ich nicht.