QByteArray read only 4 Byte from Arduino



  • Hello Forum,

    i have a problem with my code. I send from Arduino a float (4 Byte) over Serial to my Software.
    I become the 4 Byte not clean.
    This is the code:

    @if(serial.bytesAvailable() == 4 ||serial.waitForReadyRead(10))
    {
    QByteArray reading = serial.readAll();
    serial.write(reading);@

    And later i convert it to float:

    @char *data = reading.data();
    float tempUmgewandelt = (float)data;
    QString temperatur = QString::number(tempUmgewandelt);@

    But the qDebug give me some other Bytes. The Arduino send a const float:

    @"ff?A"
    "27.8"@

    The first is the float as to Byte and the other is the convert Bytes to float:
    And usually the reading process isn´t clean:

    @"ff?"
    "A"
    "ff?A" @

    Can anybody help me with this problem?

    Sorry for my bad english.

    Bye

    Alex from Germany


  • Moderators

    Use .toFloat() instead of your custom conversion:
    @
    float tempUmgewandelt = reading.toFloat();
    @

    Your logic is a bit strange. Why are you checking whether there are 4 bytes, but then proceed to read all data? You should read only 4 bytes if that is what you expect to be there.

    Then, why do you immediately send that data back to the board with write()?

    In general, to avoid data fragmentation problems, people use established protocols to send the data (for example, it is trivial to see if an XML document has been fully retrieved, and to glue different packets together if not), or at least use some kind of synchronization byte to make sure the communication works smoothly.



  • Hello,

    i have test this code:

    @if(serial.bytesAvailable() >= 4 || serial.waitForReadyRead(10))
    {
    QByteArray reading = serial.read(4);
    qDebug() << reading;
    qDebug() << reading.size();@

    the "4" from read is the size from 4 byte. is this correct?
    The Debug give me some information:

    @4
    "27.8"
    QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
    QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
    QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
    "ff"
    2
    "?A"
    2
    "ff?A"
    4
    "27.8"
    QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
    QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
    QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
    "f"
    1
    "f?A"
    3
    "ff?A"
    4
    "27.8"
    QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
    QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
    QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.
    "f"
    1
    "f?A"
    3 @


  • Moderators

    It is indeed correct. But it can't read 4 bytes if only 2 are available, right?



  • That is correct. But i send from Arduino 4 Bytes to the Serial port. But how must i do read the 4 Byte´s?


  • Moderators

    I think "serial.waitForReadyRead(10)" is causing you to read the packets too soon. But it might be that there are also some problems where sending, some additional buffering, etc. That is why it is always good to add some kind of packet glueing and checking mechanism, even in very simple systems.



  • When i delete the "serial.waitForReadyRead(10)" instruction the if do nothing. How can i send or do a checking mechanism?



  • I have change my if and this works better:

    @if(serial.bytesAvailable() >= 4 || (serial.waitForReadyRead(10) && serial.size() == 4))
    {
    QByteArray reading = serial.read(4);@

    When i send more data´s over the serial port. how must change the code?
    For example i send from arduino following data´s:

    Temp1
    23.4
    Temp2
    45
    Temp3
    12.5

    My if take every 4 byte and change it into a float. What must i do when i send more datas?



  • [quote author="nickvan86" date="1404856945"]What must i do when i send more datas?[/quote]
    Use "readyRead":http://qt-project.org/doc/qt-5/qiodevice.html#readyRead signal.
    Also take a look to "examples":http://qt-project.org/doc/qt-5/qtserialport-terminal-example.html



  • Hello,

    bq. Also take a look to examples [qt-project.org]

    I have check the example Terminal. When i send "27.0000" and "Hallo" the terminal show the right data, but when i Debug the readFunction i become this:

    @"27.0000HALLO"
    "27.00"
    "00HALLO"
    "27.0000HALLO"
    "27."
    "0000HALLO"
    "27.0000HAL"
    "LO"
    "2"
    "7.0000HALLO"
    "27.0000H"
    "ALLO"@

    The Terminal puts it together and than is the right order.
    I must show how solve this problem.
    But thanks for the tipp.

    Bye Alex



  • bq. I have check the example Terminal. When i send “27.0000” and “Hallo”

    The serial port reads your data stream by a some chunks. Size of those chunks can be randomly, depends on state of Windows (Linux, etc) scheduler and so on...

    The qDebug() to end of each message adds the \n\r symbols, but the Terminal do not adds any additional symbols.

    Thus, the qDebug() print out a received data (chunks of data) on the new line.

    bq. I must show how solve this problem.

    This is not a problem.



  • I recommend to use the RS232-Protocol and use STX and EOT to define data packets.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.