我是编程新手,我自学。我写了一个应用程序来轮询控制单元的一些请求。我基本上不断地向控制单元发送各种读取命令并回读响应。我的程序工作,我成功发送命令并接收答案。但读取速度非常慢(我的代码中有100毫秒超时,以确保我得到完整的回复) 我有一个由C ++专业编码员编写的同一个控制单元的程序,在他的程序中,他每30毫秒轮询一次,我总是在那段时间内得到完整的答案。我有相同的设置57K波特8位1停止位和无奇偶校验。但是我的QT代码需要将近100毫秒才能收到答案。 在我的代码中,我读取前2个字节(第一个字节是消息标识符,第二个字节是消息长度的剩余部分)然后我在循环中读取,直到总消息长度等于消息长度字节+1(+ 1是包括第一个字节)。我很清楚为什么我的代码在QT中如此慢,因为我知道它知道硬件是限制因素。请求总是3个字节,回复从3到61个字节不等。请帮我指出我的错误。如果我删除超时我总是有短读。到目前为止,我也尝试过阅读(全部),但结果相同。 以下是我的代码摘录,我在其中阅读了回复。完整代码位于https://github.com/MarkusIppy/PowerTune
//Error handling
QTime startTime = QTime::currentTime();
int timeOut = 100; // timeout in milisec.
QByteArray recvData = m_serialport->read(2); // reading first two bytes of received message to determine lenght of ecpected message
int msgLen = recvData[1]; //Total message Lenght excluding the first byte
while ( recvData.size() <= (msgLen+1) )
{
if ( startTime.msecsTo(QTime::currentTime()) > timeOut ) break;
recvData += m_serialport->read(msgLen+1-recvData.size());
}
if (msgLen +1 == recvData.length()) //if the received data lenght equals the message lenght from lenght byte + identifier byte (correct message lenght received )
{
qDebug() << "Received data OK"<<msgLen +1;
if(requestIndex <= 61){requestIndex++;}
else{requestIndex = 58;}
readData(recvData);
}
else //if the lenght of the received message does not correspond with the expected lenght repeat the request
{
qDebug() << "Received data lenght NIO";
readData(recvData);
qDebug() << "Request Message again"<< requestIndex;
}
答案 0 :(得分:2)
对不起,我没有足够的时间来完成您的项目,而且从您提供的代码中我无法100%确定原因是什么。我最好的猜测是,在这种情况下,问题是您明确等待接收数据,并且事件处理以某种方式延迟或根本不发生。
无论如何,这里有一些建议:
我通过将bytesWritten(qint64 bytes)
和readyRead()
信号连接到我的程序的插槽来使用 QSerialPort ,让我们说on_bytesWritten(qint64 bytes)
和{{1 }}。然后我向目标设备发送请求,并在on_readyRead()
插槽中处理结果。使用每个发送命令,我启动 QTimer ,其on_readyRead()
信号连接到我的应用程序的timeout()
插槽。通过这种方式,我可以监控设备是否及时响应,以及在数据到达时立即生成数据。您也可以使用 QSerialPort 的on_timeout()
信号来检查传输是否存在问题。
答案 1 :(得分:1)
这是我到目前为止(只是发布我的cpp文件的重要部分) 这段代码现在几乎与我的消息模拟器完美配合。它现在按预期轮询,但超时总是在5秒后触发(我需要将其更改为仅在没有消息出现时触发)。我只能在下周的实际硬件端测试它。 这就是我到目前为止所做的:
void Serial::initSerialPort()
{
if (m_serialport)
delete m_serialport;
m_serialport = new SerialPort(this);
connect(this->m_serialport,SIGNAL(readyRead()),this,SLOT(readyToRead()));
connect(m_serialport, static_cast<void (QSerialPort::*) (QSerialPort::SerialPortError)>(&QSerialPort::error),
this, &Serial::handleError);
connect(&m_timer, &QTimer::timeout, this, &Serial::handleTimeout);
m_timer.start(5000);
}
void Serial::readyToRead()
{
if(ecu == 0)
{
m_readData.append(m_serialport->readAll());
Bytesexpected = m_readData[1]+1;
if (Bytesexpected == m_readData.size())
{
if(requestIndex <= 62){requestIndex++;}
else{requestIndex = 59;}
readData(m_readData); // message for processing
Serial::clear();
m_readData.clear();
}
//Timeout
if (!m_timer.isActive())
m_timer.start(5000);
}
}
void Serial::handleTimeout()
{
qDebug() << "Timeout";
//request Data Again
QString fileName = "Errors.txt";
QFile mFile(fileName);
if(!mFile.open(QFile::Append | QFile::Text)){
qDebug() << "Could not open file for writing";
}
QTextStream out(&mFile);
out << "Timeout Request Index " << int(requestIndex)<< " lenght received "<< int(m_readData.length())<< " Bytes "<< " Expected Bytes "<< int(Bytesexpected)<< " bytes " <<" Message "<< QByteArray(m_readData.toHex()) <<endl;
mFile.close();
Serial::clear();
m_readData.clear();
Serial::sendRequest(requestIndex);
}
void Serial::handleError(QSerialPort::SerialPortError serialPortError)
{
if (serialPortError == QSerialPort::ReadError) {
QString fileName = "Errors.txt";
QFile mFile(fileName);
if(!mFile.open(QFile::Append | QFile::Text)){
qDebug() << "Could not open file for writing";
}
QTextStream out(&mFile);
out << "Serial Error " << (m_serialport->errorString()) <<endl;
mFile.close();
qDebug() <<"Serialport Error" <<(m_serialport->errorString());
}
}
答案 2 :(得分:1)
稍微改变了我的代码,现在它在实际硬件上完美运行 以下是我准备阅读Slot:
void Serial::readyToRead()
{
qDebug() << "ready read";
if(ecu == 0)
{
m_readData.append(m_serialport->readAll());
Bytesexpected = m_readData[1]+1;
qDebug() << "readdata current" <<m_readData.toHex();
if (Bytesexpected == m_readData.size())
{
m_timer.stop();
if(requestIndex <= 62){requestIndex++;}
else{requestIndex = 59;}
readData(m_readData);
Serial::clear();
m_readData.clear();
Serial::sendRequest(requestIndex);
}
if (Bytesexpected != m_readData.size())
{
qDebug() << "starting timer";
m_timer.start(5000);
}
}