gpt4 book ai didi

c++ - 无法使用 QSerialPort 读取任何内容

转载 作者:行者123 更新时间:2023-11-28 05:08:20 26 4
gpt4 key购买 nike

我已经围绕 QSerialPort 创建了一个包装器库。我想与我的设备通信。首先,我向我的设备发送 list 命令,它应该返回该设备支持的命令列表。然而,在调试我的代码时,我观察到 list 命令正在发送到设备并且设备返回正确的响应(我使用串行流量嗅探器 Linux 工具进行调试)。但是,我没有从使用 QSerialPort 的设备获得任何响应(串行流量嗅探器工具已禁用)。多次测试后,我无法让它工作。

我的序列号.h:

class Serial : public Print {

public:
Serial();
explicit Serial(const char *dev_path);
~Serial();

int begin(unsigned long baudrate);
int begin(unsigned long baudrate, uint8_t cfg);
void end(void);

int available(void) const;
bool availableForWrite(void) const;
void flush(void);
bool isError(void) const;
void reset(void);

unsigned long write(uint8_t c);
unsigned long write(uint8_t *p_data, unsigned long maxSize);
int read(void);

void close();

QSerialPort &getPort()
{
return *_p_port;
}

public slots:
void readyBe(void);

private:
QSerialPort *_p_port;
unsigned long _baudrate;
};

我的序列号.cpp:

Serial::Serial()
{
_p_port = new QSerialPort();
if (_p_port == nullptr)
throw std::runtime_error("Can't allocate memory");
}

Serial::Serial(const char *dev_path)
{
_p_port = new QSerialPort(QString(dev_path), QApplication::instance());
if (_p_port == nullptr)
throw std::runtime_error("Can't allocate memory");
// _p_port->setPortName(QString(dev_path));
if (_p_port->open(QIODevice::ReadWrite) == false) {
throw std::runtime_error("Can't open the serial _p_port");
delete _p_port;
}
_p_port->setBaudRate(QSerialPort::Baud9600);
_p_port->setDataBits(QSerialPort::Data8);
_p_port->setParity(QSerialPort::NoParity);
_p_port->setStopBits(QSerialPort::OneStop);
_p_port->setFlowControl(QSerialPort::NoFlowControl);
}

Serial::~Serial()
{
if (_p_port != nullptr) {
end();
delete _p_port;
}
}

int Serial::begin(unsigned long baudrate)
{
if (_p_port->setBaudRate(baudrate, QSerialPort::AllDirections) == false)
return -1;
_baudrate = baudrate;
return 0;
}

void Serial::end()
{
if (_p_port->isOpen())
_p_port->close();
}

int Serial::available(void) const
{
int num_bytes = _p_port->bytesAvailable();
return num_bytes;
}

bool Serial::availableForWrite(void) const
{
if (_p_port->isWritable())
return true;
return false;
}

void Serial::flush()
{
_p_port->flush();
}

unsigned long Serial::write(uint8_t c)
{
if (_p_port->putChar(c))
return 1;
return 0;
}

unsigned long Serial::write(uint8_t *p_data, unsigned long maxSize)
{
return _p_port->write(reinterpret_cast<const char *>(p_data), (qint64)maxSize);
}

int Serial::read(void)
{
char c;
_p_port->getChar(&c);
return c;
}

void Serial::reset(void)
{
_p_port->clear(QSerialPort::AllDirections);
_p_port->clearError();
}

bool Serial::isError(void) const
{
if (_p_port->error() == QSerialPort::NoError)
return false;
return true;
}

还有我的 main.cpp:

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
// w.show();

Serial serial("ttyACM0");
if (serial.begin(115200))
std::cout << "Failed to set Baud rate" << std::endl;
std::cout << "Sending data" << std::endl;
// QObject::connect(&(serial.getPort()), SIGNAL(readyRead()), &serial, SLOT(readyBe()));
serial.print("list\r");
serial.flush();

while (true) {
while (true) {
while (serial.available() == 0) {
if (serial.isError()) {
std::cout << "Error" << std::endl;
// serial.reset();
}
}

char c = serial.read();
std::cout << c;
if (c == '\n')
break;
}
std::cout << std::endl;
}

return a.exec();

}

最佳答案

您几乎错过了这段代码运行所需的一切:事件循环。现实生活中的 I/O 是异步的。您不能只是从端口“读取”而没有一些方法在数据可用时得到通知,并且实际上让异步 I/O 请求得到处理。是的,有一些遗留 API 可以让您这样做,但它们大多会导致面条式代码、线程浪费和性能低下。

while (serial.available() == 0) 循环是空操作。它实际上没有让 available() 返回任何其他值。 available() 在内部所做的只是读取一个类的整数成员。您永远不会运行任何可以更新存储在该成员中的值的代码。即使您将其转换为 serial.waitForReadyRead(),它确实更新了可用字节数,您仍然没有旋转事件循环,因此您赢了' 能够处理超时,或对应用程序可能需要使用react的任何其他事件使用react。 QIODevice::waitForReadyRead 只是为了做一件事:当 readyRead 信号触发时返回。它不会处理任何其他事件,它是用于移植阻塞代码的拐杖,并不真正用于生产。

您应该将代码重新设计为异步代码并由来自 QSerialPort 的信号驱动。然后,工作将从 QCoreApplication::exec 内完成——您不会有自己的循环。这种控制反转对于让异步 I/O 正常工作至关重要。

参见例如this answer一个非常简单的异步方法示例,this answer一个更完整的。

关于c++ - 无法使用 QSerialPort 读取任何内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44090144/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com