'QSerial without QThreads
I create a "server" lib with a Qt GUI.
I don't and can't use QThreads because this is supposed to be as independent from Qt as possible, and because I have other threads already working like a Ethernet part.
The thread ExternalRs232Thread() is lauched by the public function RunExternalRs232()
RunExternalRs232() opens the serial port, returns -1 if can't open serial, and if is ok runs the function ExternalRs232Thread() in a detached thread.
Initially, I have tried to run this with Serialib, but this never works properly with the Qt project. So I decided to give QSerialPort a try like this:
Server.h
#ifndef SERVER_H
#define SERVER_H
#include <iostream>
#include <winsock2.h>
#include <windows.h>
#include <thread>
#include <unordered_map>
#include <unordered_set>
#include <sstream>
#include <time.h>
#include <chrono>
#include <mutex>
#include <QObject>
#include "libs/json.hpp"
#include <QtSerialPort>
#include "hdlccsvparser.h"
using namespace std;
using json = nlohmann::json;
using std::chrono::milliseconds;
using std::chrono::duration_cast;
using std::chrono::seconds;
using std::chrono::system_clock;
struct Contact {
int port; //udp port of te contact
time_t time; //last communication date ( is still active ? )
};
class Server : public QObject
{
Q_OBJECT
public:
Server();
virtual ~Server();
[...]
//return 0 if sucess , 1 port is not usabe, 2 port already in use
int RunExternalRs232(string PortCom, unsigned int baudrate);
int StopExternalRs232(string PortCom);
[...]
//clean exit
void ExitServer();
signals:
[...]
private:
[...]
// External ThreadS and exiting loop of threadS in set (if key d'ont exist anymore, exit loop)
mutex mtxExternalRs232;
unordered_set<string> ExternalRs232PortActiveList;
void ExternalRs232Thread(QSerialPort* Rs232Connection, string port);
[...]
};
#endif // SERVER_H
Server.cpp
#include "Server/Server.h"
#include <winsock2.h>
/* Public Part*/
[...]
int Server::RunExternalRs232(string PortCom, unsigned int baudrate){
//PortCom = (char *)"COM1";
//baudrate = 9600;
QSerialPort Rs232Connection;
// Connection to serial port
// COMxx
Rs232Connection.setPortName(QString::fromStdString(PortCom));
Rs232Connection.setBaudRate(baudrate);
Rs232Connection.setDataBits(QSerialPort::Data8);
Rs232Connection.setParity(QSerialPort::NoParity);
Rs232Connection.setStopBits(QSerialPort::OneStop);
Rs232Connection.setFlowControl(QSerialPort::NoFlowControl);
int i = Rs232Connection.open(QIODevice::ReadWrite);
// If connection fails, errorOpening != 1
if(i != 1){
return i;
}
mtxExternalRs232.lock();
ExternalRs232PortActiveList.insert(PortCom);
mtxExternalRs232.unlock();
cout << "External Rs232 starting on " << PortCom << endl;
stringstream sstmp;
sstmp << PortCom;
emit LogMessage(QString::fromStdString("External Rs232 starting on " + sstmp.str()),0);
std::thread thServer(&Server::ExternalRs232Thread,this,&Rs232Connection,PortCom);
thServer.detach();
return 0;
}
int Server::StopExternalRs232(string PortCom){
PortCom = "COM1";
mtxExternalRs232.lock();
/*
if(ExternalRs232PortActiveList.count(PortCom) != 1){ //???
//port not in use
cerr << "close Failed Rs232 " << PortCom << endl;
mtxExternalRs232.unlock();
return 1;
}*/
cout << "close External Rs232 " << PortCom << endl;
ExternalRs232PortActiveList.erase(PortCom);
mtxExternalRs232.unlock();
return 0;
mtxExternalRs232.lock();
cout << ExternalRs232PortActiveList.count(PortCom) << " here " << endl;
mtxExternalRs232.unlock();
}
[...]
/* Private Part */
/* Thread part */
[...]
void Server::ExternalRs232Thread(QSerialPort * Rs232Connection, string port){
//char/binary read on rs232
char tmp;
//if rs232 has data
bool res = false;
stringstream message;
Rs232Connection->write("H");
mtxExternalRs232.lock();
int iscount = ExternalRs232PortActiveList.count(port);
mtxExternalRs232.unlock();
while(iscount == 1){
res = false;
if(!Rs232Connection->waitForReadyRead(300)){
//no data skipp
} else {
QByteArray datas = Rs232Connection->readAll();
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
string tmp = codec->toUnicode(datas).toStdString();
cout << tmp << endl;
}
mtxExternalRs232.lock();
iscount = ExternalRs232PortActiveList.count(port);
mtxExternalRs232.unlock();
}
Rs232Connection->flush();
Rs232Connection->close();
}
[...]
/* functions part */
[...]
Server::Server(){
//init winsock
if(WSAStartup(MAKEWORD(2,2),&wsa) != 0){
cerr << "Could not init winsock2 : " << WSAGetLastError();
}
//creating a socket
if((s = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET){
cerr << "Could not create a socket : " << WSAGetLastError();
}
}
Server::~Server(){
//dtor
}
at the end, I get
QObject::startTimer: Timers can only be used with threads started with QThreads
So how is possible to run Serial Rs232 without using QThreads?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
