QSerialPort problem. readyRead and bytesWritten have not been emitted
-
Hello!
I work with a note dispenser, which is connected to my computer through COM.
COM board manufacturer: MosChip Semiconductor Technology Ltd.Port settings by default:
RS232
BaudRate:9600
DataBits:8
Parity:None
StopBits:1
FlowControl:NoneProtocol is simple. Program sends strictly defined command, and then should get an answer.
Example:
- Command 0×30,0×33,0×30,0×0D means reset device.
- Answer should be (if command was executed successfully): 00000010190502018979301900338.
That is as a literal string. Of course, raw hex result can be obtained by translating every char into hex number.
However, I can’t get any answer from the device.
Manufacturer of note dispenser also provides test program, to use device.
That program works fine.Below is the link on a log of PortMon. Test program from the development dispenser kit.
So, as we can see:
- Basic setup of COM port is different from default settings:
StopBits: 1 Parity: EVEN WordLength: 7
EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13
Shake:0 Replace:80000000 XonLimit:409 XoffLimit:410
RI:-1 RM:0 RC:0 WM:0 WC:0
Mask: RXCHAR CTS DSR RLSD BRK ERR RING-
Initialization of COM is repeated 4 times.
-
Windows messages IOCTL_SERIAL_SET_WAIT_MASK IOCTL_SERIAL_WAIT_ON_MASK.
I disassembled that program by using AidaPro and there was 4 thread in a process. So, maybe 4 times initialization means 4 threads?
Anyway, it seems that test program using async read/write operations.I use that example: https://qt.gitorious.org/qt/qtserialport/source/dda7449d18cf8aaa542f869dcaea28634d21ecb0:examples/serialport/creaderasync
Also, beware of waitForReadyRead: https://bugreports.qt-project.org/browse/QTBUG-33987
Qt version:4.8.2.
Below is my code:
@
#include <QtCore/QCoreApplication>
#include <QtCore/QtGlobal>
#include <QObject>
#include <QString>
#include <QByteArray>
#include "qserialport.h"
#include <QDebug>QT_USE_NAMESPACE
class ComPort : public QObject
{
Q_OBJECT
public:
ComPort(QObject *parent = 0);
~ComPort();
private slots:
void ReadBytes();
void WrittenBytes(qint64 bytes);
public:
void WriteData(const QByteArray & Data);
private:
QSerialPort serial;
};#include "main.moc"
ComPort::ComPort(QObject *parent) : QObject(parent)
{
serial.setPortName(QString("COM22"));
if (serial.open(QIODevice::ReadWrite))
{
serial.setBaudRate(QSerialPort::Baud9600);
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::NoParity);
serial.setStopBits(QSerialPort::OneStop);
serial.setFlowControl(QSerialPort::NoFlowControl);
connect(&serial, SIGNAL(readyRead()), this, SLOT(ReadBytes()));
connect(&serial, SIGNAL(bytesWritten(qint64)), this, SLOT(WrittenBytes(qint64)));
}
else
{
serial.close();
qDebug() << "Error opening COM port";
}
}ComPort::~ComPort()
{
serial.close();
}void ComPort::ReadBytes()
{
qDebug() << "Signal readyRead is emitted and caught successfull:";
QByteArray data = serial.readAll();
qDebug() << data;
}void ComPort::WrittenBytes(qint64 bytes)
{
qDebug() << "Signal bytesWritten is emitted and caught successfull:" << bytes;
}void ComPort::WriteData(const QByteArray & Data)
{
if(serial.write(Data)==-1)
qDebug() << "Error in writing";
else
qDebug() << "Writing is successfull";
}int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
ComPort CP;
QByteArray Data;
Data.push_back(0x30);
Data.push_back(0x33);
Data.push_back(0x30);
Data.push_back(0x0D);
CP.WriteData(Data);
return a.exec();
}@The only string that i managed to get on console is: “Writing is successfull”. No readyRead or bytesWritten signals.
And the link on produced result sniffed by PortMon:
So it stucks after successfull writing.
What I’m doing wrong?
Thanks -
-
Do you use the QtSerialPort sources from Git? In case no - please try download, compile and use them.
-
Can you provide VID/PID of your "MosChip Semiconductor Technology Ltd" board?
UPD: The board - it is an PCI/express board?
-
-
i experienced the same problem as you.
http://qt-project.org/forums/viewthread/35719/
[quote author="kuzulis" date="1386326287"]Nobody guarantees that you will receive at once all package of data (1 byte? 15 bytes? 1000 bytes? 100000 bytes?).
It is necessary to do waiting of expected number of bytes, like:
@
...
for (;;) {
bool ret = serial.waitForReadyRead(500); // wait at least one byte available
if (ret) {qint64 bav = serial.bytesAvailable(); if (bav < expected) continue; QByteArray recvData = serial.read(expected); // do something } else { // error or timeout, no more bytes received // do something }
}
...
@But in any case is better to use the async approach instead of sync.[/quote]
-
2 Elias,
I don't trust that there are no messages except "Writing is successfull", at least should be also and "Signal bytesWritten is emitted and caught successfull: 4" because I see from your log this:
bq. IRP_MJ_WRITE PCISerial0 SUCCESS Length 4: 030.
i.e. all 4 bytes has been transferred.
Maybe problem because need to configure serial port as:
9600 baud + even parity + 7 data bit + 1 stop bit..
You can try use any terminal application (also from the QtSerialPort) to check it, just send "030." sequence and wait result.
-
bq. 1. Do you use the QtSerialPort sources from Git? In case no – please try download, compile and use them.
Yes, I use Git version.
bq. 2. Can you provide VID/PID of your “MosChip Semiconductor Technology Ltd” board?
I get VID/PID by using QSerialPortInfo. Is that a correct way?
Result is: VID - 9710. PID - 9865.bq. UPD: The board – it is an PCI/express board?
Yes. PCI Express.
bq. I don’t trust that there are no messages except “Writing is successfull”, at least should be also and “Signal bytesWritten is emitted and caught successfull: 4” because I see from your log this:
bq. IRP_MJ_WRITE PCISerial0 SUCCESS Length 4: 030.
bq. i.e. all 4 bytes has been transferred.
Yeah, I agree with you, that its strange, but really it is. I can't also catch the signal bytesWritten, not only readyRead.
bq. Maybe problem because need to configure serial port as:
bq. 9600 baud + even parity + 7 data bit + 1 stop bit..
I tried, but unfortunately, thats didnt help.
bq. You can try use any terminal application (also from the QtSerialPort) to check it, just send “030.” sequence and wait result.
I try to do it, and everything is fine. From HyperTerminal data has been sent and received successfully.
-
Hmmm.. Then you can try modify the QtSerialPort sources and add the "SetupComm()":http://msdn.microsoft.com/en-us/library/windows/desktop/aa363439(v=vs.85).aspx function after CreateFile() because from the your log I see this;
bq. IOCTL_SERIAL_SET_QUEUE_SIZE PCISerial0 SUCCESS InSize: 4096 OutSize: 4096
So, maybe it is the reason?
UPD: or instead of modify of the sources, you can get the serial port handle QSerialPort::handle() and call SetupComm() for this handle after QSerialPort::open().