I'm developing an app with Qt and I have to read frames and check each byte to see if its values are correct.
QSerialPort serial;
QByteArray data = serial.readAll();
I well receive bytes but I don't know how to check if they are well equal to my hex values. I'd like to do something like this:
if (data[0] == 0x02) {
// my code
}
My question will probably be stupid for most of you but I don't find any answer :(
Related
How does one check for specific values in a QByteArray?
Something like this:
QByteArray example;
//...
example = file.readAll();//fill with data from a file
//...
if(example.mid(0, 2) == 0x0a00)
//do something
The above doesn't work.
I CAN do this but I am currently fixing performance issues so I'd rather not have to convert it to a QString:
QByteArray example;
//...
example = file.readAll();//fill with data from a file
//...
if(example.mid(0, 2).toHex() == "0a00")
//do something
What's the fastest way to check the bytes in a QByteArray based on their hex representation?
You can compare simply like this.
if(example.mid(0, 2) == "\x0a\x00")
Edited:
This is not working. Check below comment.
I'm a beginner in Qt. Now I want to use Qt5 to send a 9-byte command through uart.
Here is my command:
FFFFFF5550464DAA0E
I want to transfer my command to a Qstring object. When I write my code like this, it tells me the const is too big.
QString str=0xFFFFFF5550464DAA0E;
So I choose an array like this, but it still doesn't work.
char cmd[9]={0xFF,0xFF,0xFF,0x55,0x50,0x46,0x4D,0xAA,0x0E};
for(int i=0;i<9;i++)
{
QString str=cmd[i];
QByteArray outData=str.toLatin1();
int size=outData.size();
outData=myHelper::HexStrToByteArray(str);
size=outData.size();
myCom->write(outData);
}
I also try this which failes again
char cmd[9]={0xFF,0xFF,0xFF,0x55,0x50,0x46,0x4D,0xAA,0x0E};
QString str=cmd;
QByteArray outData=str.toLatin1();
int size=outData.size();
outData=myHelper::HexStrToByteArray(str);
size=outData.size();
myCom->write(outData);
So could anyone tell me how to do this ?
This line of code:
QString str=0xFFFFFF5550464DAA0E;
0xFFFFFF5550464DAA0E is not a string. You're trying to assign a very big constant (9 bytes) number to a string. Note that 0xFF is not a string but a character with ASCII code 0xFF. With your second attempt you're on the right way:
char cmd[9]={0xFF,0xFF,0xFF,0x55,0x50,0x46,0x4D,0xAA,0x0E};
Now you have two options; it depends on what you have to send, 9 bytes or a longer string with that commands represented as a hex string and encoded as ASCII. First case is easier, drop all your code:
QByteArray outData = QByteArray(cmd, sizeof(cmd));
myCom->write(outData);
With this code you won't send a string to your device but 9 bytes (0xFF...0x0E). If you have to send a string then you can do what paxdiablo suggested:
QByteArray outData = QByteArray("\xFF\xFF\xFF\x55\x50\x46\x4D\xAA\x0E", 9);
myCom->write(outData);
Or:
QByteArray outData = QString("0xFF0xFF0xFF0x550x500x460x4D0xAA0x0E")
.toLatin1();
myCom->write(outData);
Or in alternative you can do this:
char cmd[9]={0xFF,0xFF,0xFF,0x55,0x50,0x46,0x4D,0xAA,0x0E};
QByteArray outData = QByteArray(cmd, sizeof(cmd)).toHex();
myCom->write(outData);
Which one is right for you? Well you should clarify your context...
You don't need to mess about with strings and conversions. You can just make the QByteArray directly from the data itself, with a simple one-liner:
QbyteArray data("\xFF\xFF\xFF\x55\x50\x46\x4D\xAA\x0E", 9);
Following that, the statement:
myCom->write(data);
will then output the nine bytes as specified in the string.
I have this simple code that use QtSerialPort:
char foo[] = {130,50,'\0'};
serial->write(foo);
The result on my serial is {2, 50}. I think that che biggest number that I can send is 128 (char go from -128 to 128). Where is the manner for send number from 0 to 255? I try to use unsigned char but the method "write" don't work with it. The same problem also appear with QByteArray.
Thankyou all.
The QIODevice interface has the default char for sending which may be compiler dependent. See the documentation for details.
qint64 QIODevice::write(const char * data, qint64 maxSize)
Writes at most maxSize bytes of data from data to the device. Returns the number of bytes that were actually written, or -1 if an error occurred.
However, you should not be concerned much if you take the data properly on the other hand. you can still send the greater than 128 values through as signed, but they will come across as negative values, for instance 0xFF will be -1.
If you take the same logic in the reverse order on the receiving end, there should be no problems about it.
However, this does not seem to relate to your issue because you do not get the corresponding negative value for 130, but you get it chopped at 7 bits. Make sure you connection is 8 data bit.
You can set that explicitly after opening the port with this code:
QSerialPort serialPort;
QString serialPortName = "foo";
serialPort.setPortName(serialPortName);
if (!serialPort.open(QIODevice::WriteOnly)) {
standardOutput << QObject::tr("Failed to open port %1, error: %2").arg(serialPortName).arg(serialPort.errorString()) << endl;
return 1;
}
if (!serialPort.setDataBits(QSerialPort::Data8)) {
standardOutput << QObject::tr("Failed to set 8 data bits for port %1, error: %2").arg(serialPortName).arg(serialPort.errorString()) << endl;
return 1;
}
// Other setup code here
char foo[] = {130,50,'\0'};
serialPort.write(foo);
Make sure you've set the serial port to send 8 bits, using QSerialPort::DataBits
The fact that '130' is coming as '2' implies that the most significant bit is being truncated.
I'm trying to use QSerialPort class to reading and writing to serial port.
Right now i'm using virtual comports implemented by eltima driver.
I can successfully send bytes like this:
QSerialPortInfo info = QSerialPortInfo("COM30");
QSerialPort serial;
serial.setPort(info);
serial.setBaudRate(57600);
serial.open(QIODevice::ReadWrite);
char arr[] = {0xAA, 0xBB, 0xCC, 0xDD};
serial.write(arr, 4);
I'm trying reading like this (I want to read just a single byte; this code is called by timer, if data is ready to be read):
virtual uint8_t getByte(void)
{
char arr[2] = {0};
int8_t err = qPort.read(arr, 1);
DEBUG_ASSERT(err != -1);
if(! isNewByte() )
{
onReceiveFinished();
}
return arr[0];
}
If I send to a virtual port (i.e. to my program) any value less then 128, I get it right (as debugger is showing). However, if I try to send 128 or more, I get value-128 o_o (if I send 153 - I get 25. Not -25 or 103).
That seems like something really odd to me.
Can anyone see where is the mistake?
My mistake was really stupid. QSerialPort is set to 7 databits by default (which seems not very practical, actually), so every received byte had its MSB cut off (like substracting 128).
Still, oddly enough, sending worked fine.
Not. You wrong do setBaudRate(). It need to do after the port is opening.
I am a beginner with C++ and Qt. The data sent is a string of ASCII characters ex:"jdlsfjffjf: XX" where I would like to extract the number XX. I know I should possibly use indexof to point to it but not sure how. Any direction? Here's the server side code that receives, displays and writes. I get the correct numbers in the application but gibberish characters in the file I'm writing to.
void Receiver::processPendingDatagrams()
{
while (udpSocket->hasPendingDatagrams()) {
QByteArray datagram; //array of bytes
datagram.resize(udpSocket->pendingDatagramSize()); //size it depending on sent data
udpSocket->readDatagram(datagram.data(), datagram.size()); //read all
statusLabel->setText(tr("%1 C").arg(datagram.data()));
//writing stream to file
bool ok;
QFile file("file.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
out << datagram.toInt(&ok, 10 );
}
int num = datagram.right(datagram.size() - datagram.indexOf(':') - 1).toInt();