C++ QSerialPort-等待来自发送方的全部数据
我用的是串行设备。 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();
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。这就是为什么它冻结的原因