我从Arduino微控制器向运行Qt的PC发送几KB数据。
Arduino测量来自PC的命令数据,然后像这样发送数据:
void loop(){
// I wait for trigger signal from PC, then begin data acquisition
// Data are acquired from a sensor, typically few thousand 16-bit values
// 1 kHz sampling rate, store data on SRAM chip
// Code below transfers data to PC
for(unsigned int i=0;i<datalength;i++){
// Get data from SRAM
msb=SPI.transfer(0x00);
lsb=SPI.transfer(0x00);
// Serial write
Serial.write(msb);
Serial.write(lsb);
}
Serial.flush();
} // Loop over
Qt正在接收如下数据:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
if(microcontroller_is_available){
// open and configure serialport
microcontroller->setPortName(microcontroller_port_name);
microcontroller->open(QSerialPort::ReadWrite);
microcontroller->setBaudRate(QSerialPort::Baud115200);
microcontroller->setDataBits(QSerialPort::Data8);
microcontroller->setParity(QSerialPort::NoParity);
microcontroller->setStopBits(QSerialPort::OneStop);
microcontroller->setFlowControl(QSerialPort::NoFlowControl);
}
connect(microcontroller, &QSerialPort::readyRead, this, &MainWindow::readData);
}
void MainWindow::readData() // Read in serial data bytes
{
serialData += microcontroller->readAll();
if(serialData.length()==2*datalength){
// Once all serial data received
// Do something, like save data to file, plot or process
}
}
现在上面的代码工作得很好,但偶尔(假设每隔几百次采集一次,所以不到1%的时间)并不是所有的数据都会被Qt和我的{{{上面的函数是悬挂的。我必须重置程序。所以我的问题是:如何使数据传输更可靠并避免丢失字节?
仅供参考:我知道存在一个Arduino堆栈交换。我不是在那里张贴,因为这似乎是一个与Qt相关的问题而不是Arduino。
答案 0 :(得分:2)
我没有太多关注它,但似乎问题可能与这一行有关:
if(serialData.length()==2*datalength)
所以,如果你有一些额外的数据,你就放弃了整个事情?不能保证数据最终会到达整齐的离散块。
如果长度大于或等于,则应读入数据,读取指定长度并保留剩余数据,因为它是下一个块的一部分。
它还可以解释为什么你的函数会挂起 - 如果你碰巧超过2*datalength
,那么这个条件永远不会成真。
但即使你解决这个问题,实施也有点幼稚,而不是可以被认为是全面的。还有其他一些可能出错的地方,你需要有更多的描述性数据块,以便你可以找出出了什么问题以及如何解决它或者跳过错误而不用挥动扳手可以这么说。
答案 1 :(得分:0)
我建议的一些事情是将数据包装在信封中。每次要发送数据时,都要添加标题字符(例如&#39; H&#39;例如)和签名(&#39; S&#39;可能?)。在接收部分检查您的消息的第一个和最后一个字符并确保它应该是什么。这将消除噪音和非完整数据。