繁体   English   中英

无法将简单的读/写串行端口代码从boost :: asio :: serial_port迁移到QSerialPort

[英]Unable to migrate simple read/write serial port code from boost::asio::serial_port to QSerialPort

我需要一段非常简单的代码来连接串行端口(已连接家用设备的端口),向其中写入一些数据,然后读取答复。 写入的数据会打开设备上的LED指示灯(这样可以很容易地查看设备是否实际接收到PC发送的数据)

我有它与boost/asio一起工作,需要将其移植到QSerialPort 使用QSerialPort ,我可以连接,发送数据(并且我知道它已发送,因为LED亮了),但是却无法接收任何数据。

这是boost asio代码的工作原理:

#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/serial_port_base.hpp>
#include <boost/thread.hpp>

static std::vector<char> sReceived;
void readThread( boost::asio::serial_port* port )
{
    try
    {
        char read;
        while ( boost::asio::read( *port, boost::asio::buffer(&read,1) ) == 1 )
            sReceived.push_back( read );
    }
    catch (...)
    {
        // connection most likely closed
    }
}

int main( int argc, char* argv[] )
{
    int res = 1;
    if ( argc != 2 )
    {
        std::cout << "Specify COM port name as first and unic parameter" << std::endl;
    }
    else
    {
        try
        {
            std::string portName = argv[1];

            boost::asio::io_service ioservice;
            boost::asio::serial_port port( ioservice );

            port.open( portName );
            port.set_option( boost::asio::serial_port_base::baud_rate( 921600 ) );
            port.set_option( boost::asio::serial_port_base::parity( boost::asio::serial_port_base::parity::none ) );
            port.set_option( boost::asio::serial_port_base::stop_bits( boost::asio::serial_port_base::stop_bits::one ) );
            port.set_option( boost::asio::serial_port_base::character_size( 8 ) );
            port.set_option( 
                boost::asio::serial_port_base::flow_control( 
                    boost::asio::serial_port_base::flow_control::hardware ) );

            if ( port.is_open() )
            {
                boost::thread thrd( readThread, &port );

                static const size_t requestMessageSize = 10;
                unsigned char request[requestMessageSize] = { 0x01, 0x00, 0x07, 0x01, 0x01, 0x00, 0x00, 0xBE, 0x0B, 0x00 };
                if ( boost::asio::write( port,
                                         boost::asio::buffer(request,requestMessageSize) ) == requestMessageSize )
                {
                    boost::this_thread::sleep( boost::posix_time::milliseconds( 1000 ) );

                    if ( !sReceived.empty() )
                    {
                        std::cout << "Received:" << std::hex;
                        for ( size_t i = 0; i != sReceived.size(); ++i )
                        {
                            std::cout << " 0x" << static_cast<int>( sReceived[i] );
                        }
                        std::cout << std::endl;
                        std::cout << "Could open port, send and receive data" << std::endl;
                        res = 0;
                    }
                    else
                    {
                        std::cout << "Could open port, send data, but did not received any reply" << std::endl;
                    }
                }
                else
                {
                    std::cout << "Could not send data" << std::endl;
                }

                port.close();
            }
            else
            {
                std::cout << "Could not open connection with " << portName << std::endl;
            }
        }
        catch (...)
        {
            std::cout << "Exception raised by boost asio" << std::endl;
        }
    }

    return res;
}

这是Qt代码(不起作用):

#include <QApplication>
#include <QThread>
#include <QMessageBox>
#include <QtSerialPort/QSerialPort>

#include <sstream>

int main( int argc, char* argv[] )
{
    QApplication app(argc, argv);

    int res = 1;
    if ( argc != 2 )
    {
        QMessageBox::critical( NULL, "Invalid argument", "Specify COM port name as first and unic parameter" );
    }
    else
    {
        QString portName = argv[1];

        QSerialPort port( portName );

        if ( port.open( QSerialPort::ReadWrite ) )
        {
            if ( port.setBaudRate( 921600 ) &&
                 port.setFlowControl( QSerialPort::HardwareControl ) &&
                 port.setStopBits( QSerialPort::OneStop ) &&
                 port.setParity( QSerialPort::NoParity ) &&
                 port.setDataBits( QSerialPort::Data8 ) )
            {
                static const size_t requestMessageSize = 10;
                char request[requestMessageSize] = { 0x01, 0x00, 0x07, 0x01, 0x01, 0x00, 0x00, 0xBE, 0x0B, 0x00 };
                if ( port.write( request, requestMessageSize ) == requestMessageSize )
                {
                    QThread::sleep( 1 );

                    QByteArray reply = port.readAll();

                    if ( !reply.isEmpty() )
                    {
                        std::stringstream str;
                        str << "Received:" << std::hex;
                        for ( size_t i = 0; i != reply.size(); ++i )
                        {
                            str << " 0x" << static_cast<int>( reply.at(i) );
                        }
                        str << std::endl;
                        str << "Could open port, send and receive data" << std::endl;
                        QMessageBox::information( NULL, "OK", str.str().c_str() );
                        res = 0;
                    }
                    else
                    {
                        QMessageBox::critical( NULL, "Error", "Could open port, send data, but did not received any reply" );
                    }
                }
                else
                {
                    QMessageBox::critical( NULL, "Error", "Unable to send request to port" );
                }
            }
            else
            {
                QMessageBox::critical( NULL, "Error", "Unable to configure port" );
            }
            port.close();
        }
        else
        {
            QMessageBox::critical( NULL, "Unable to connect", QString("Could not open connection with %1").arg( portName ) );
        }
    }

    return res;
}

当我运行两个代码时都使用了作为参数传递的良好端口名:

  • boost的一个使LED点亮并报告已Received: 0x.....Could open port, send and receive data
  • Qt的一个指示灯点亮,但报告Could open port, send data, but did not received any reply

我的QSerialPort代码有什么问题? 为什么它可以发送数据但不能接收任何数据?

在读取某些内容之前, port.readAll()不会阻塞,实际上,直到返回事件循环或执行waitForReadyRead来接收数据并执行waitForBytesWritten来写出缓冲区之前,才发送或读取任何数据

所以将Thread::sleep(1)替换为port.waitForBytesWritten(1000);port.waitForReadyRead(1000);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM