Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ QSerialPort-等待来自发送方的全部数据_C++_Qt_Serial Port_Qthread - Fatal编程技术网

C++ QSerialPort-等待来自发送方的全部数据

C++ QSerialPort-等待来自发送方的全部数据,c++,qt,serial-port,qthread,C++,Qt,Serial Port,Qthread,我用的是串行设备。 QSerialPort位于单独的线程中。 线程的创建方式如下: QThread* serialthread = new QThread; Serial* serial = new Serial(); serial->moveToThread(serialthread); 当数据可用时,我的线程辅助进程中会发出此信号: void Serial::process() { serialport = new QSerialPort();

我用的是串行设备。 QSerialPort位于单独的线程中。 线程的创建方式如下:

QThread* serialthread = new QThread;
Serial*  serial = new Serial();
serial->moveToThread(serialthread);
当数据可用时,我的线程辅助进程中会发出此信号:

    void Serial::process()
    {
        serialport = new QSerialPort();
        connect(this->serialport,SIGNAL(readyRead()),this,SLOT(readyToRead()));
    }
    void Serial::readyToRead()
    {
        emit SIG_dataAvailable(this->read());
    }
这是一个读取数据并检查数据是否正确的函数-我的串行设备上的第二个字节表示数据包的剩余部分有多长

QByteArray Serial::read() const
{
    QByteArray receivedData;
    int length;
    receivedData = serialport->readAll();
    length = receivedData[1];
    if(length != receivedData.length() - 1)
    {
        qDebug() << "protocol error.";
        return NULL;
    }
    return receivedData;
}
QByteArray串行::read()常量
{
QByteArray接收数据;
整数长度;
receivedData=serialport->readAll();
长度=接收数据[1];
if(长度!=receivedData.length()-1)
{

qDebug()绝对不能保证一次获得完整的数据。你可以用一些方法解决这个问题

1) 如果您有固定大小的软件包,您可以执行以下操作:

void foo::onSerialRead()
{
    //! Is there whole datagram appears?
    if (m_serial->bytesAvailable() < ::package_size) {
        //! If not, waiting for other bytes
        return;
    }

    //! Read fixed size datagram.
    QByteArray package = m_serial->read(::package_size);
    //! And notify about it.
    emit packageReady(package);
}
void foo::onSerialRead()
{
    static QByteArray package;
    static bool isHeaderRead = false;
    static quint8 startByte = 0;
    static quint8 dataSize = 0;

    //! Is there whole header appears?
    if (m_serial->bytesAvailable() < ::header_size) {
        //! If not, waiting for other bytes
        return;
    }

    if (!isHeaderRead) {
    //! Read fixed size header.
        package.append(m_serial->read(::header_size));
        QDataStream out(&package);

        out >> startByte;

    //! Check is it actually beginning of our package?
        if (Q_UNLIKELY(startByte != ::protocol_start_byte)) {
            return;
        }
        out >> dataSize;
        isHeaderRead = true;
    }

    //! Check is there whole package available?
    if (Q_LIKELY(dataSize > m_serial->bytesAvailable())) {
        //! If not, waiting for other bytes.
        return;
    }
    //! Read rest.
    package.append(m_serial->read(dataSize));
    //! And notify about it.
    emit packageReady(package);
    package.clear();
    isHeaderRead = false;
}
void foo::onSerialRead()
{
//!是否显示整个数据报?
如果(m_序列->字节可用()<::包大小){
//!如果没有,请等待其他字节
返回;
}
//!读取固定大小的数据报。
QByteArray package=m_serial->read(::package_size);
//!并通知我。
发射包就绪(包);
}
2) 如果您的包大小可能不同。那么您必须在包中包含“hader”。此标头应至少包含“开始”字节和数据大小(在您的情况下为第二个字节)。标头的大小应固定。然后您可以执行以下操作:

void foo::onSerialRead()
{
    //! Is there whole datagram appears?
    if (m_serial->bytesAvailable() < ::package_size) {
        //! If not, waiting for other bytes
        return;
    }

    //! Read fixed size datagram.
    QByteArray package = m_serial->read(::package_size);
    //! And notify about it.
    emit packageReady(package);
}
void foo::onSerialRead()
{
    static QByteArray package;
    static bool isHeaderRead = false;
    static quint8 startByte = 0;
    static quint8 dataSize = 0;

    //! Is there whole header appears?
    if (m_serial->bytesAvailable() < ::header_size) {
        //! If not, waiting for other bytes
        return;
    }

    if (!isHeaderRead) {
    //! Read fixed size header.
        package.append(m_serial->read(::header_size));
        QDataStream out(&package);

        out >> startByte;

    //! Check is it actually beginning of our package?
        if (Q_UNLIKELY(startByte != ::protocol_start_byte)) {
            return;
        }
        out >> dataSize;
        isHeaderRead = true;
    }

    //! Check is there whole package available?
    if (Q_LIKELY(dataSize > m_serial->bytesAvailable())) {
        //! If not, waiting for other bytes.
        return;
    }
    //! Read rest.
    package.append(m_serial->read(dataSize));
    //! And notify about it.
    emit packageReady(package);
    package.clear();
    isHeaderRead = false;
}
void foo::onSerialRead()
{
静态QByteArray包;
静态bool-ishaderread=false;
静态五分之八起始字节=0;
静态quint8数据大小=0;
//!是否显示整个标题?
如果(m_序列->字节可用()<::页眉大小){
//!如果没有,请等待其他字节
返回;
}
如果(!isHeaderRead){
//!读取固定大小的标题。
package.append(m_serial->read(::header_size));
Qdata数据流输出(和包);
out>>startByte;
//!这是我们包裹的开始吗?
如果(Q_不太可能(开始字节!=::协议_开始字节)){
返回;
}
输出>>数据大小;
ISHEADREAD=真;
}
//!检查是否有完整的包装?
如果(很可能是(数据大小>串行->字节可用()){
//!如果没有,请等待其他字节。
返回;
}
//!阅读其余部分。
package.append(m_serial->read(dataSize));
//!并通知我。
发射包就绪(包);
package.clear();
ISHEADREAD=错误;
}

把你的QSerial放到不同的线程中是毫无意义的。

绝对没有保证你可以一次获得整个数据。你可以用一些方法解决这个问题

1) 如果您有固定大小的软件包,您可以执行以下操作:

void foo::onSerialRead()
{
    //! Is there whole datagram appears?
    if (m_serial->bytesAvailable() < ::package_size) {
        //! If not, waiting for other bytes
        return;
    }

    //! Read fixed size datagram.
    QByteArray package = m_serial->read(::package_size);
    //! And notify about it.
    emit packageReady(package);
}
void foo::onSerialRead()
{
    static QByteArray package;
    static bool isHeaderRead = false;
    static quint8 startByte = 0;
    static quint8 dataSize = 0;

    //! Is there whole header appears?
    if (m_serial->bytesAvailable() < ::header_size) {
        //! If not, waiting for other bytes
        return;
    }

    if (!isHeaderRead) {
    //! Read fixed size header.
        package.append(m_serial->read(::header_size));
        QDataStream out(&package);

        out >> startByte;

    //! Check is it actually beginning of our package?
        if (Q_UNLIKELY(startByte != ::protocol_start_byte)) {
            return;
        }
        out >> dataSize;
        isHeaderRead = true;
    }

    //! Check is there whole package available?
    if (Q_LIKELY(dataSize > m_serial->bytesAvailable())) {
        //! If not, waiting for other bytes.
        return;
    }
    //! Read rest.
    package.append(m_serial->read(dataSize));
    //! And notify about it.
    emit packageReady(package);
    package.clear();
    isHeaderRead = false;
}
void foo::onSerialRead()
{
//!是否显示整个数据报?
如果(m_序列->字节可用()<::包大小){
//!如果没有,请等待其他字节
返回;
}
//!读取固定大小的数据报。
QByteArray package=m_serial->read(::package_size);
//!并通知我。
发射包就绪(包);
}
2) 如果您的包大小可能不同。那么您必须在包中包含“hader”。此标头应至少包含“开始”字节和数据大小(在您的情况下为第二个字节)。标头的大小应固定。然后您可以执行以下操作:

void foo::onSerialRead()
{
    //! Is there whole datagram appears?
    if (m_serial->bytesAvailable() < ::package_size) {
        //! If not, waiting for other bytes
        return;
    }

    //! Read fixed size datagram.
    QByteArray package = m_serial->read(::package_size);
    //! And notify about it.
    emit packageReady(package);
}
void foo::onSerialRead()
{
    static QByteArray package;
    static bool isHeaderRead = false;
    static quint8 startByte = 0;
    static quint8 dataSize = 0;

    //! Is there whole header appears?
    if (m_serial->bytesAvailable() < ::header_size) {
        //! If not, waiting for other bytes
        return;
    }

    if (!isHeaderRead) {
    //! Read fixed size header.
        package.append(m_serial->read(::header_size));
        QDataStream out(&package);

        out >> startByte;

    //! Check is it actually beginning of our package?
        if (Q_UNLIKELY(startByte != ::protocol_start_byte)) {
            return;
        }
        out >> dataSize;
        isHeaderRead = true;
    }

    //! Check is there whole package available?
    if (Q_LIKELY(dataSize > m_serial->bytesAvailable())) {
        //! If not, waiting for other bytes.
        return;
    }
    //! Read rest.
    package.append(m_serial->read(dataSize));
    //! And notify about it.
    emit packageReady(package);
    package.clear();
    isHeaderRead = false;
}
void foo::onSerialRead()
{
静态QByteArray包;
静态bool-ishaderread=false;
静态五分之八起始字节=0;
静态quint8数据大小=0;
//!是否显示整个标题?
如果(m_序列->字节可用()<::页眉大小){
//!如果没有,请等待其他字节
返回;
}
如果(!isHeaderRead){
//!读取固定大小的标题。
package.append(m_serial->read(::header_size));
Qdata数据流输出(和包);
out>>startByte;
//!这是我们包裹的开始吗?
如果(Q_不太可能(开始字节!=::协议_开始字节)){
返回;
}
输出>>数据大小;
ISHEADREAD=真;
}
//!检查是否有完整的包装?
如果(很可能是(数据大小>串行->字节可用()){
//!如果没有,请等待其他字节。
返回;
}
//!阅读其余部分。
package.append(m_serial->read(dataSize));
//!并通知我。
发出packageReady(包装);
package.clear();
ISHEADREAD=错误;
}

把你的QSerial放到不同的线程中是绝对没有意义的。

我把m QSerial放到不同的线程中,因为我想实时监控汽车ECU。我在主窗口过程中尝试过,gui非常滞后。我想,这是因为你在“阻塞”(非异步)中使用QSerialPort而冻结了曼纳。这就是为什么它冻结的原因。我把Qserial放在不同的线程中,因为我想实时监控汽车ECU。我在主窗口过程中尝试过,gui非常滞后。我想,它冻结是因为你在“阻塞”(非异步)曼纳中使用QSerialPort。这就是为什么它冻结的原因