Problem with second thread



  • Hello folks, I have a program with a thread to read the serial port with the windows api. The problem is that I need write data too, and the program stops on the event "wait for data in serial port "; I think that the solution could be, another thread to write the data... but qt, do not allow me to create a second thread, in the same way as the first

    Qt creator get me the next errors, after adding "send *snd;" in sport.h:

    Documents\Gui6_exp\sport.h:23: error: C2143: syntax error : missing ';' before ''
    Documents\Gui6_exp\sport.h:23: error: C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    Documents\Gui6_exp\sport.h:23: error: C2143: syntax error : missing ';' before '
    '
    Documents\Gui6_exp\sport.h:23: error: C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    and much more...

    I have not idea over QSerial port, but if it can solve simultaneously read and write ASCII strings in an overloaded serial pore, would be a pleasure to learn. Any suggestions on how to fix the second thread or how to use QSerialPort, will be welcome. Thank you very much in advance

    Here comes the second thread (the thread that fails):

    #ifndef SEND_H
    #define SEND_H
    #include <QThread>
    #include <QObject>
    class send : public QThread
    {
        Q_OBJECT
    public:
        send(QObject *parent);
    private:
       void run();
    };
    
    #endif // SEND_H
    //****************************************
    #include "send.h"
    
    send::send(QObject *parent) : QThread(parent)
    {
    
    }
    //**************************************************************
    void send::run(){
    
    
    }
    
    

    first thread

    #ifndef SPORT_H
    #define SPORT_H
    #include <QDebug>
    #include <Windows.h>
    
    #define maxComPort  26
    #define minComPort  0
    #define baudRate CBR_19200
    #define maxSB   256
    #define askId       "cb?"
    #define iDBoard     "cbr"
    #include <QThread>
    #include <string.h>
    #include <send.h>
    
    class sport : public QThread
    {
        Q_OBJECT
    public:
        sport(QObject *parent);
        void makeCnx();
        bool exit = false;
        send *snd;
    
    public slots:
        void updateMsg(QString newMsg);
    
    signals:
        void received(QString rcv);
        void conInf(QString cnxInfo);
    
    
    private:
        void run();
        char *read();
        void write(char *outBuffer);
    
        char vacio[1];
        QString conMsgs,qWriteBuf;    //connection messages (error or success)
        char readBuffer[maxSB];
        HANDLE hComm;   //-------------------------
        char port2Config[16];
        BOOL status;
        DWORD dwEventMask;  //event mask to trigger
        DWORD nBytesRead;
    
    };
    
    #endif // SPORT_H
    //*********************************************************
    #include "sport.h"
    #include<iostream>
    using namespace std;
    //sssssssssssssssssssssssssssssssssssssssssssssss
    void sport::updateMsg(QString newMsg){  //write here
        newMsg = newMsg + '\0';
        qWriteBuf = newMsg;
        qDebug() << "nMsgOut" << newMsg;
    }
    
    //ssssssssssssssssssssssssssssssssssssssssssssEND
    sport::sport(QObject *parent) : QThread(parent)
    {
       /// if (makeCnx()) run(); //das ist nicht klug
    
    }
    //************************************************
    void sport::run(){
        makeCnx();
        snd = new send(this);
        char *rcv = new char[maxSB];
        qWriteBuf = "";
        while(!exit){
    
            if (qWriteBuf != "" ){
    
                string sWB = qWriteBuf.toStdString().c_str();
                char cWB[maxSB];
                qint8 in = 0;
                while(in < sWB.size()){
                    cWB[in] = sWB[in];
                    in++;
                }
                cWB[in] = '\0';
                write(cWB);
                qWriteBuf = "";
            }
    
            *rcv = '\0';
    
           // status = SetCommMask(hComm, EV_RXCHAR); //Configure Windows to Monitor the serial device for Character Reception
           // qDebug() << "wait: " << WaitCommEvent(hComm, &dwEventMask, NULL); //Wait for
    
    
            rcv = read();
            if (*rcv != '\0') {
                QString qRcv(rcv);
                emit received(qRcv);
            }
        }
    }
    //************************************************
    void sport::write(char *outBuffer){
      //  qDebug() << "El punto de escritura: "<< outBuffer;
             DWORD  dNoOfBytesWritten = 0;          // No of bytes written to the port
        /*
         DWORD  dNoOFBytestoWrite;              // No of bytes to write into the port
    
    
        ClearCommError(hComm, &dNoOfBytesWritten, NULL);
       dNoOfBytesWritten = 0;
       dNoOFBytestoWrite = sizeof(outBuffer); // Calculating the no of bytes to write into the port
       qDebug() << "outBuffer:" << outBuffer << " lenght" << strlen(outBuffer);     //<---- OJOOO, AUGEENNN write in Port
       qDebug() << "outBuffer[0]" << outBuffer[0];
       WriteFile(hComm,               // Handle to the Serialport
                 &outBuffer,            // Data to be written to the port
                 dNoOFBytestoWrite,   // No of bytes to write into the port
                 &dNoOfBytesWritten,  // No of bytes written to the port
                 NULL);
    
       qDebug() << "outBuffer:" << outBuffer << " lenght" << strlen(outBuffer);     //<---- OJOOO, AUGEENNN write in Port
    */
       char aux;
       for(qint8 i= 0; i < strlen(outBuffer);i++) {
           aux = outBuffer[i];
           cerr << aux;
           WriteFile(hComm,               // Handle to the Serialport
                     reinterpret_cast<LPCVOID>(&aux),            // Data to be written to the port
                     1,   // No of bytes to write into the port
                     &dNoOfBytesWritten,  // No of bytes written to the port
                     NULL);
    
    
       }
    
    // ClearCommError(hComm, &dNoOfBytesWritten, NULL);
    /* for(qint8 i= 0; i > strlen(outBuffer);i++){
    
       aux =
       WriteFile(hComm,               // Handle to the Serialport
                 aux,            // Data to be written to the port
                 1,   // No of bytes to write into the port
                 &dNoOfBytesWritten,  // No of bytes written to the port
                 NULL);
        }
    */
    }
    //************************************************
    char* sport::read(){
     /*   ReadFile(hComm, &readBuffer, maxSB, &nBytesRead, NULL);
        readBuffer[nBytesRead] = '\0';*/
    
        char in = '\0';
        static qint8 i;
        i = 0;
        while(in != '\n'){
            ReadFile(hComm, &in, 1, &nBytesRead, NULL); // nBytesRead //num bytes readed
            if (in == 32 || in == '+' || in == '\n' || in == '.' ||(in >= '0' && in <= '9') ||
                    (in >= 'A' && in <= 'Z') || (in >= 'a' && in <= 'z')){
                readBuffer[i] = in;
                i++;
    
            }
            else {
              strcpy(vacio,"\0");
              return vacio;
            }
        }//von while
    
        readBuffer[i] = '\0';
        qDebug() << "ReadBuffer: " << readBuffer;
        return readBuffer; //<--- Ojooo, Augeenn
    }
    
    //************************************************
    void sport::makeCnx(){
    
        for (int nP = minComPort; nP < maxComPort; nP++){ //find the port
    
            conMsgs.clear();   //clear connection messages
    
            sprintf(port2Config, "\\\\.\\COM%d",nP);
            hComm = CreateFileA(port2Config,                  // Name of the Port to be Opened
                                GENERIC_READ | GENERIC_WRITE, // Read/Write Access
                                0,                            // No Sharing, ports cant be shared
                                NULL,                         // No Security
                                OPEN_EXISTING,                // Open existing port only
                                0,                            // Non Overlapped I/O
                                NULL);                        // Null for Comm Devices
    
            if (hComm == INVALID_HANDLE_VALUE) {
                qDebug() << "Error " << port2Config << " can't be opened";
                emit conInf("Port not\n connected");
                CloseHandle(hComm);//Closing the Serial Port
                continue;
            }
                else qDebug() << port2Config << " openned" ;
    
            /*------------------------------- Setting the Parameters for the SerialPort ------------------------------*/
    
            DCB dcbSerialParams = { 0 };                         // Initializing DCB structure
            dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
    
            status = GetCommState(hComm, &dcbSerialParams);      //retreives  the current settings
    
            if (status == FALSE) {
                qDebug() << " Error! in GetCommState()";
                emit conInf("Port not\n connected");
                CloseHandle(hComm);//Closing the Serial Port //@@@ get the port and retry?
                continue;
            }
    
    
            dcbSerialParams.BaudRate = baudRate;      // Setting BaudRate = 9600
            dcbSerialParams.ByteSize = 8;             // Setting ByteSize = 8
            dcbSerialParams.StopBits = ONESTOPBIT;    // Setting StopBits = 1
            dcbSerialParams.Parity = NOPARITY;        // Setting Parity = None
    
            status = SetCommState(hComm, &dcbSerialParams);  //Configuring the port according to settings in DCB
    
                if (status == FALSE) qDebug() << " Error! in Setting DCB Structure";
                    else qDebug() << "DCB OK";
    
            /*------------------------------------ Setting Timeouts --------------------------------------------------*/
    
              COMMTIMEOUTS timeouts = { 0 };
              timeouts.ReadIntervalTimeout         = 100;
              timeouts.ReadTotalTimeoutConstant    = 100;
              timeouts.ReadTotalTimeoutMultiplier  = 10;
              timeouts.WriteTotalTimeoutConstant   = 100;
              timeouts.WriteTotalTimeoutMultiplier = 10;
    
                if (!SetCommTimeouts(hComm, &timeouts)) qDebug() << "Error! in Setting Time Outs";
                    else qDebug() << "\n\n    Setting Serial Port Timeouts Successfull";
    
            /**************************************************************************************************/
                /*--- write ---*/
                char writeBuffer[] = askId;
                /*sendMSG(request);*/
                DWORD  dNoOFBytestoWrite;              // No of bytes to write into the port
                 DWORD  dNoOfBytesWritten = 0;          // No of bytes written to the port
    
               dNoOfBytesWritten = 0;
               dNoOFBytestoWrite = sizeof(writeBuffer); // Calculating the no of bytes to write into the port
    
               status = WriteFile(hComm,               // Handle to the Serialport
                                  writeBuffer,            // Data to be written to the port
                                  dNoOFBytestoWrite,   // No of bytes to write into the port
                                  &dNoOfBytesWritten,  // No of bytes written to the port
                                  NULL);
    
               if (status == TRUE) qDebug() << "written " << writeBuffer;
               else qDebug() << "Error Writting";
    
                /*------------------------------------ Setting Receive Mask ----------------------------------------------*/
    
                status = SetCommMask(hComm, EV_RXCHAR); //Configure Windows to Monitor the serial device for Character Reception
    
                if (status == FALSE) qDebug() << "Error! in Setting CommMask";
                else qDebug() << "Setting CommMask successfull";
    
    
               /*------------------------------------ Setting WaitComm() Event   ----------------------------------------*/
                status = WaitCommEvent(hComm, &dwEventMask, NULL); //Wait for the character to be received
                qDebug() << "Waiting for Data Reception";
    
                /*-------------------------- Program will Wait here till a Character is received ------------------------*/
    
    
                if (status == FALSE) qDebug() << "Error! in Setting WaitCommEvent()";
                    else{ //If  WaitCommEvent()==True Read the RXed data using ReadFile();
    
                     /*  char tempChar;
                        int i = 0;
                          do{
                            status = ReadFile(hComm, &tempChar, sizeof(tempChar), &nBytesRead, NULL);
                            readBuffer[i] = tempChar;
                            i++;
                         }while (nBytesRead > 0);
                        readBuffer[i] = '\0';*/
    
                        status = ReadFile(hComm, &readBuffer, maxSB, &nBytesRead, NULL);
                        readBuffer[nBytesRead-1] = '\0';
    
                        if (!strncmp(readBuffer,iDBoard,3)) {qDebug() << "Success on Port: " <<
                            port2Config << " " << readBuffer << " " << strlen(readBuffer);
                            // emit conInf("Connected On: \n" + QString(port2Config)); //Conectado en
                        }
                        return;
                    }//from else
                 //   CloseHandle(hComm);//Closing the Serial Port
        }//end port find
    
    }
    

  • Moderators

    Hi! This isn't an answer to your question, I just want to tell you "you're holding it wrong". Please read this blog post.



  • Thank you very much Wieland, i will take a look...


  • Qt Champions 2016

    @yczo

    You can't have slots executed in a thread without an event loop when the triggering signals are not emitted from the same thread. Also giving a slot to a QThread object will cause that function to be executed in the main thread (or rather the thread the QThread instance was created in).
    In any case, listen to @Wieland - you're doing it wrong. :)



  • Thread problem solved. Thank you very much


Log in to reply
 

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