Function step by setp



  • Hi,

    I use serial port to do something.

    When I write :

    void MainWindow::mouve()
    {
        stepX->moveR(1000);
        stepX->moveR(-200);
        stepX->moveR(1000);
        stepX->moveR(-20000);
        stepX->moveR(100);
    }
    
    void StepperMotor::moveR(int step)
    {
        QTimer t;
        t.setInterval(10000);
        int posReach = send(GAP,1,0,0) + step;
        send(MVP, 1, step, 0);
        t.start();
        while (posReach != send(GAP,1,0,0,false) && t.remainingTime()>0);
    }
    

    mouve is connected to button when I clik on it, funcitons are done setp by setp
    stepX->moveR(-200); wait the end of stepX->moveR(1000);

    The problem is th GUI Freez ... so I do this :

    void MainWindow::mouveandwait() // connected to my button
    {
        qDebug() << "Main Thread" << this->thread()->currentThread();
        QtConcurrent::run(this, &MainWindow::mouveth);
    }
    
    void MainWindow::mouveth()
    {
        qDebug() <<"start" <<QTime::currentTime() << this->thread()->currentThread();
        stepX->moveR(1000);
        stepX->moveR(-200);
        stepX->moveR(1000);
        stepX->moveR(-20000);
        stepX->moveR(100);
        qDebug() <<"end" <<QTime::currentTime();
    }
    

    but now all function are executed
    stepX->moveR(1000);
    stepX->moveR(-200);
    stepX->moveR(1000);
    stepX->moveR(-20000);
    stepX->moveR(100);

    without waiting the end of previous.

    All "stepX->mouveR" are in the same thread, diffrent of Main thread

    Someone can help to do this step by setp?

    I use some mutex but nothing change.


  • Qt Champions 2016

    @Franckynos said:
    Hi
    the
    while (posReach != send(GAP,1,0,0,false) && t.remainingTime()>0);

    is the reason GUI is hanging. U kill the message pump.

    Im wondering what "send(GAP,1,0,0,false)" is.

    Its that sending over serial?
    If yes , You should look into signals as it can tell you when finished sending etc and you could design this step by step
    in a way not using a loop.

    So each step would send signal when finished and the slot would then start the next step.
    Of Course if "send" is something completely different that serial port then might not be possible :)



  • For more detail,

    int StepperMotor::send(int commande, int param, int value, int motor_bank, bool verbose)
    {
        SendCmd(hRS232, 1, commande, param, motor_bank, value);
        while(GetResult(hRS232, &Address, &Status, &Value)==TMCL_RESULT_NOT_READY && abs(GetTickCount()-Timeout)<1000);
    }
    

    and SendCmd & GetResult are api window not Qt, because with Qt, the responding time is to long

    void StepperMotor::SendCmd(HANDLE Handle, UCHAR Address, UCHAR Command, UCHAR Type, UCHAR Motor, INT Value)
    {
        UCHAR TxBuffer[9];
        DWORD BytesWritten;
        int i;
    
        TxBuffer[0]=Address;
        TxBuffer[1]=Command;
        TxBuffer[2]=Type;
        TxBuffer[3]=Motor;
        TxBuffer[4]=Value >> 24;
        TxBuffer[5]=Value >> 16;
        TxBuffer[6]=Value >> 8;
        TxBuffer[7]=Value & 0xff;
        TxBuffer[8]=0;
        for(i=0; i<8; i++)
            TxBuffer[8]+=TxBuffer[i];
    
        //Send the datagram
        WriteFile(Handle, TxBuffer, 9, &BytesWritten, NULL);
    }
    
    UCHAR StepperMotor::GetResult(HANDLE Handle, UCHAR *Address, UCHAR *Status, int *Value)
    {
        UCHAR RxBuffer[9], Checksum;
        DWORD Errors, BytesRead;
        COMSTAT ComStat;
        int i;
    
        //Check if enough bytes can be read
        ClearCommError(Handle, &Errors, &ComStat);
        if(ComStat.cbInQue>8)
        {
            //Receive
            ReadFile(Handle, RxBuffer, 9, &BytesRead, NULL);
    
            Checksum=0;
            for(i=0; i<8; i++)
                Checksum+=RxBuffer[i];
    
            if(Checksum!=RxBuffer[8]) return TMCL_RESULT_CHECKSUM_ERROR;
    
            *Address=RxBuffer[0];
            *Status=RxBuffer[2];
            *Value=(RxBuffer[4] << 24) | (RxBuffer[5] << 16) | (RxBuffer[6] << 8) | RxBuffer[7];
        } else return TMCL_RESULT_NOT_READY;
    
        return TMCL_RESULT_OK;
    }
    

    When I put this code :

    void MainWindow::mouveth()
    {
        qDebug() <<"start" <<QTime::currentTime() << this->thread()->currentThread();
        stepX->moveR(1000);
        stepX->moveR(-200);
        stepX->moveR(1000);
        stepX->moveR(-20000);
        stepX->moveR(100);
        qDebug() <<"end" <<QTime::currentTime();
    }
    

    In a Thread (QtConcurrent) all function are done without waiting the previous. How can I wait in thread ?

    Thx for reply


  • Qt Champions 2016

    hi
    if look at the sample
    http://doc.qt.io/qt-5/qtconcurrent-progressdialog-example.html

    you can see how to use futureWatcher
    QObject::connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset()));
    to be notified when a thread is finished.

    I think you should use this method to run a step and when it signal Finished, you run next step and so on.

    I do not know a way to make it pause in each
    when you run them all in one thread at once.
    Maybe other will :)

    Hope it help


Log in to reply
 

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