QSerialPort problem (between windows and linux)
-
Hi. I,m new in Qt . i try to write a serial port application to communicate from serial port between windows and linux system.
void SerialPort::openSerialPort() { if(portToUse.isNull() || !portToUse.isValid()) { qDebug() << "port is not valid:" << portToUse.portName(); return; } // Enumerate the serial port // Open it if it isn't busy qDebug()<<"Port Name " << portToUse.portName(); serial->setPortName(portToUse.portName()); serial->setTextModeEnabled(true); serial->setBaudRate(QSerialPort::Baud19200); serial->setDataBits(QSerialPort::Data8); serial->setParity(QSerialPort::NoParity); serial->setStopBits(QSerialPort::OneStop); serial->setFlowControl(QSerialPort::NoFlowControl); if (serial->open(QIODevice::ReadWrite)) { qDebug() << "Connected to" << portToUse.description() << "on" << portToUse.portName(); } else { qCritical() << "Serial Port error:" << serial->errorString(); qDebug() << tr("Open error"); } } void SerialPort::closeSerialPort() { serial->close(); qDebug() << tr("Disconnected"); } void SerialPort::writeData(const QByteArray &data) { serial->write(data); }
and this is abstaction of my code.
when data write from a linux system and recive from another linux system every thing is ok , but when recive with windows data is not correct.any body can tell me what is the problem?
-
@iRenji said in QSerialPort problem (between windows and linux):
any body can tell me what is the problem?
Probably endianness.
Do not use the raw
serial->write
( andserial->read
) use QDataStream.void SerialPort::writeData(const QByteArray &data) { QDataStream stream(serial); stream << data; }
-
Maybe reason is in:
serial->setTextModeEnabled(true);
Currently, the QSP does not support QIODevice::OpenMode::Text flag, which adds when you call this method. QSP works only in binary mode.
-
@VRonin said in QSerialPort problem (between windows and linux):
Probably endianness.
Windows is little-endian, linux is (often) big-endian.
QDataStream is safe to use as it always use big-endian (unless you force it otherwise).
So bottom line, your possible solutions:
- Use QDataStream both for reading and writing
- force an endianness convention manually.
- you can detect what your platform is using with (C code from source, can be converted to constexpr in C++11)
int is_big_endian() { union { uint32_t i; char c[4]; } bint = {0x01020304}; return bint.c[0] == 1; }
-
I use the serial ports from GNU/Linux, OSX, and Windows to talk to each other and the other devices. You shouldn't have issues specific to GNU/Linux.
Are you actually writing binary versions of numbers through serial? If not, then endianness shouldn't be an issue. If you write "1.2345\r\n" that is what you will get at the other end (6 bytes + <cr> + <lf>). It will be treated as text.
Maybe there is a problem with your USB/Serial device. Maybe try a baud rate of something slow like 1200 baud. Some of them are not very reliable.
Maybe when sending text you are sending the unicode version unintentionally. Something like ' 0x00 0x65 0x00 0x66 0x00 0x67' instead of '0x65 0x66 0x67'. Both are for the text 'ABC' but the first one is unicode or two bytes for each character. I don't know what it would look like at the receiving end but very likely it will just show blocks for every other character (?).
-
I would test with a linux serial program and a window ditto to check that
it will send as expected. If you are using USB serial on windows or any such difference
its good to verify that it work as expected. -
@iRenji
ok super.Now try
http://doc.qt.io/qt-5/qtserialport-terminal-example.html
in both ends.Then we know if its Qt related or simply something in your app.