文章目录
Qt中Qchart插件实现PMW3901迷你光流模块上位机
光流计介绍
首先PMW3901 是一款迷你光流模块具有一下特点:
- 体积小、重量轻 仅0.6g
- 精度高
- 价格便宜
- 串口通信
PMW3901淘宝一搜一大片。串口通信协议如下图:
上位机
上位机使用Qt中的Qchart插件实现,实时显示X轴和Y轴速度变化量和X轴Y轴位移(这是在调试飞机时添加的,可以用软件里一个宏USE_UAV
设置)。可以直观的看出速度的变化,方便调试。主界面如下:
Qchart使用方便一下代码是在窗口构造函数中添加的创建chart和坐标轴的函数:
m_chart = new QChart();
QChartView *chartView = new QChartView(m_chart);
chartView->setMinimumSize(800, 600);
m_chart->addSeries(m_seriesX); //一共添加四条曲线
m_chart->addSeries(m_seriesY);
m_chart->addSeries(m_distX);
m_chart->addSeries(m_distY);
axisX = new QValueAxis; //设置图标坐标和文字等
axisX->setRange(0, index_max);
axisX->setLabelFormat("%g");
axisX->setTitleText("sample");
axisY = new QValueAxis;
axisY->setRange(-indexY_range, indexY_range);
axisY->setTitleText("speed");
axis2Y = new QValueAxis();
axis2Y->setRange(-50,50);
axis2Y->setLabelFormat("%g");
axis2Y->setTitleText("distance");
axisY->setTickCount(11); //设置Y轴上的网格数,11代表10个空格
m_chart->setAxisX(axisX,m_seriesX);
m_chart->setAxisY(axisY,m_seriesX);
m_chart->setAxisX(axisX,m_seriesY);
m_chart->setAxisY(axisY,m_seriesY);
m_chart->addAxis(axis2Y,Qt::AlignRight);
m_chart->setAxisY(axis2Y,m_distX);
m_chart->setAxisY(axis2Y,m_distY);
m_chart->setAxisX(axisX,m_distX);
m_chart->setAxisX(axisX,m_distY);
m_chart->legend()->setVisible(true);
m_chart->legend()->setAlignment(Qt::AlignBottom);
m_chart->setTitle("Optcial Flow Data");
然后在串口接收函数里更新chart:
/*串口数据接收处理槽函数*/
void Widget::SerialReceive()
{
requestData = serial->readAll();
uint8_t head,tail,sum;
#define USE_UAV 0 //通过无人机发数据还是直接用光流计
#if USE_UAV
head = requestData[0];
tail = requestData[12];
flow_sum = requestData[10];
count++; /*统计帧率*/
if(index_x>index_max)
{
index_x=0;
m_seriesX->clear();
m_distX->clear();
}
if(index_y>index_max)
{
index_y=0;
m_seriesY->clear();
m_distY->clear();
}
if(head == 0xFE && tail ==0xAA) //根据协议解包
{
sum = requestData[2]+requestData[3]+requestData[4]+requestData[5]
+requestData[6]+requestData[7]+requestData[8]+requestData[9];
if(sum == flow_sum)
{
flow_SQUAL = requestData[11];
dist_x = (int16_t)(requestData[2]<<8 | requestData[3]);
dist_y = (int16_t)(requestData[4]<<8 | requestData[5]);
flow_x = (int16_t)(requestData[6]<<8 | requestData[7]);
flow_y = (int16_t)(requestData[8]<<8 | requestData[9]);
m_seriesX->append(index_x,flow_x); //在曲线最末端追加一个点
m_seriesY->append(index_y,flow_y);
m_distX->append(index_x,dist_x);
m_distY->append(index_y,dist_y);
index_x++;
index_y++;
sum_data++;
sum_label->setNum(sum_data);
}
}
// qDebug()<<"head:"<<head<<"tail:"<<tail<<"sum:"<<sum<<"SQUAL:"<<SQUAL;
// qDebug()<<"head:"<<head<<"tail:"<<tail<<"flow_sum:"<<flow_sum<<"sum:"<<sum;
qDebug()<<"head:"<<head<<"tail:"<<tail<<"flow_x:"<<flow_x<<"flow_y:"<<flow_y;
#else
head = requestData[0];
tail = requestData[8];
flow_sum = requestData[6];
count++; /*统计帧率*/
if(index_x>index_max)
{
index_x=0;
m_seriesX->clear();
}
if(index_y>index_max)
{
index_y=0;
m_seriesY->clear();
}
if(head == 0xFE && tail ==0xAA)
{
sum = requestData[2]+requestData[3]+requestData[4]+requestData[5];
if(sum == flow_sum)
{
flow_SQUAL = requestData[7];
flow_x = (int16_t)(requestData[3]<<8 | requestData[2]);
flow_y = (int16_t)(requestData[5]<<8 | requestData[4]);
m_seriesX->append(index_x++,flow_x);
m_seriesY->append(index_y++,flow_y);
sum_data++;
sum_label->setNum(sum_data);
}
}
// qDebug()<<"head:"<<head<<"tail:"<<tail<<"sum:"<<sum<<"SQUAL:"<<SQUAL;
// qDebug()<<"head:"<<head<<"tail:"<<tail<<"flow_sum:"<<flow_sum<<"sum:"<<sum;
qDebug()<<"head:"<<head<<"tail:"<<tail<<"flow_x:"<<flow_x<<"flow_y:"<<flow_y;
#endif
}