Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Syncrhonize slot() calls



  • Hi,

    Im using QSerialPort to communicate with an hardware platform Im developing and for each packet sent I wait for an ACK.
    Whenever the value of a QSpinBox is changed a new packet is sent to the platform. Im doing this with a queue in between, so I can be sure only one packet is sent at a time and that I wait for the corresponding ACK. So I have one class that is responsible to insert packets into that queue, emiting packetReady(), signal, and then in the other class I have the slot slotPacketReady where Im doing this:

    @void Connection::slotFrameReady()
    {
    while(packetsToSend()->count() > 0)
    {
    QByteArray packet = packetsToSend()->dequeue();
    qDebug() << "SENDING...";
    sendPacket(packet);
    waitForACK();
    }
    }@

    However, if the QSpinBox's value changes too fast, and as far as I can understand, the slotPacketReady() is called multiple times NOT waiting for the ACK of the previously sent packet.

    =========

    SENDING... // here I wait until I get the ACK
    sendPacket
    waitForACK
    ACK id 17 code 58 type 1
    acknowledged! "id:17 type:1 code:58"
    elapsed time: 92

    SENDING... // then I scroll the mouse wheel fast so the QSpinBox's value changes fast
    sendPacket
    waitForACK

    SENDING...
    sendPacket
    waitForACK

    SENDING...
    sendPacket
    waitForACK

    // Communication gets scrambled because the embedded buffer of the platform gets full and data is lost...

    =========

    So my question is: how can I avoid the slotPacketReady() being called multiple times? Actually I want this behavior: "call the slot only if it's not already running (while(packetsToSend()->count() > 0)".



  • I see at least two solutions:

    1. Block your spinbox for the time of sending (I understand that waitForACK processes the events and this way you get redundand events)
    2. Synchronise your 'in between' buffer to be read after ACK response received, not for every spinbox event. But here you probably need to run another thread which reads/sends your data.

Log in to reply