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 }
-
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.
-
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 theQThread
instance was created in).
In any case, listen to @Wieland - you're doing it wrong. :)