Congratulations to our 2022 Qt Champions!

[Resolved] Best approach for serial port

  • Hi, i'm using qexteserial port to managed a serial port, in this case the library is not the focus. The problem is the approach.
    At the moment i have a class serialport, where i've basic command to write on serial, and i've a class Test that have custom function that create message and send to serial port by write() function of serial class.
    I have a slot connect to readyRead() of the serial class. The problem is send every 100ms a message and get a response, and send other message. What's can be the best approach? I read more document online, some said use thread, some exclude thread approach.
    So i want write here a good knowhow of write a particular class to write/read data from serial.

    The requisite are:

    • Always read() data when they are avaiable

    If i'm in a write function that split data by packets and send, if bytearrived() i can read that only when return to the main event loop(). Or i have to create a time delay(50) between each packet and use processEvent();

    • A method to send data without lock

    I don't know if i can read/write at the same time, i think i can't so i have to manage this problem.

  • I'm not sure I fully understood your post, but from what you wrote:

    • You normally don't have to worry about reading/writing at the same time. If you don't create any thread, you will not "be" in your reception slot at the same time as writing.
    • Your slot connected to the dataReady() signal will effectively be triggered only when returning to the main event loop if you are writing, as you said, which is usually not a problem, as long as you don't need to be highly reactive.

    If that doesn't answer your question please try rephrasing it.

  • The problem is when using Xon/Xoff software, if i'm using a function to send packet and i get xon, i can get this only when i return to main loop, and in the same time i send packet and lost theme!

  • Didn't you meant "Xoff" ? Then yes, you have to handle this signal as fast as possible. The easiest is to have a single method to send the data, and stop it regularly.

    To do so, create a "sendData" method, which writes 10 bytes (for exemple) from all the data it have to send, and then, if it have to send more data, call itself again asynchronously.

    Here is a simplified exemple:
    m_pExtSerial->write(m_pData, 10);
    // then remove 10 bytes from your data queue and update the number of bytes to send

    if (m_nDataBytesToSend > 0)
    QTimer::singleShot(0, this, SLOT(sendData()));

    This way, each 10bytes sent, you will re-enter the main event loop and so enter your "dataAvailable" slot if any. If not, sendData will immediately resume. And if no more data has to be sent, sendData will stop calling itself. Just be careful not to call sendData while not finished sending (use a flag or something else).

  • Mmm singleShot is interesting, but if i call singleShot with 0, and byteArrived() what 'slot' is the first called?

  • The first queued, the first processed !

  • I'm writing code but i'm use a variable QTimer with setSingleShoot(), becouse the static function create everytimes the connect and this consume time!

  • Yes you're right. Same behavior anyway.

  • Method works perfect. Thanks.

Log in to reply