基于opencv的图像分析串口发送,单片机接收,输出脉冲继而控制步进电机转动
mainwindow.h#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include #include #include #include #include "imagebuffer.h"#include "wlinkusbcamera.h"using namespace cv;
#includenamespace Ui
{
class MainWindow;}
class MainWindow
:
public QMainWindow{
Q_OBJECTpublic:
explicit MainWindow(QWidget
*parent
=
0);
~MainWindow();
void Init()
;
void PidControl(
int,
int,
int,
int);
void sendSerialPortData(
long ,
char,
long );
void handleSerialError(QSerialPort::SerialPortError
error,
bool &);
private slots:
void on_clearButton_clicked();
void on_sendButton_clicked();
void on_openButton_clicked();
void Read_Data();
void slot1();
void on_PidChange_valueChanged(
int value);
void on_PidChange_sliderReleased();
void on_PidChange_sliderPressed();
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
private:
Ui::MainWindow
*ui;
QSerialPort
*serial;
WLinkUsbCamera
*tab
;
QTimer
*timer;
int LastError;
//Error[-1]上一次 int PrevError;
//Error[-2]上两次 int Output;};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"#include "ui_mainwindow.h"#include #include "opencv2highguihighgui.hpp"#include #includeMainWindow::MainWindow(
QWidget *parent)
:
QMainWindow(parent),
ui(
new Ui::
MainWindow),
LastError(
0),
PrevError(
0),
Output(
0){
ui->setupUi(
this);
Init();
qDebug()<<
"sioflong"<<
sizeof(
long)<<
sizeof(
int)<<
sizeof(
char);
//查找可用的串口 foreach(
const QSerialPortInfo &info,
QSerialPortInfo::availablePorts())
{
QSerialPort serial;
serial.setPort(info);
if(serial.
open(
QIODevice::
ReadWrite))
{
ui->
PortBox->addItem(serial.portName());
serial.
close();
}
}
//设置波特率下拉菜单默认显示第三项 ui->
BaudBox->setCurrentIndex(
3);
//关闭发送按钮的使能 ui->
sendButton->setEnabled(
false);
ui->
groupBox_2->setEnabled(
false);
qDebug()<
"Interface settings successful!");}MainWindow::~MainWindow(){ delete ui; delete tab;}void MainWindow::Init(){ tab = new WLinkUsbCamera() ; tab->start(); timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this,SLOT(slot1())); timer->start(60);}void MainWindow::handleSerialError(QSerialPort::SerialPortError error,bool &TxEnTemp){ if (error == QSerialPort::ResourceError) { QMessageBox::critical(this, tr("Error"), "串口连接中断,请检查是否正确连接!"); // QMessageBox::critical(this, tr("Error"), com->errorString()); // CloseSerialPort(); }else { TxEnTemp=true; }}void MainWindow::slot1(){ if(ImageBuffer::Instance()->getSizeOfBuf()>0) { DStruct *temp=new DStruct; Mat img; Point pointbuf(0,0); int PointChange=0; int dec; bool ok; QString str; int SetKp=30,SetKi=0,SetKd=0; str = ui->SetKpUi->text(); dec = str.toInt(&ok, 10); SetKp=dec; str = ui->SetKiUi->text(); dec = str.toInt(&ok, 10); SetKi=dec; str = ui->SetKdUi->text(); dec = str.toInt(&ok, 10); SetKd=dec; temp=ImageBuffer::Instance()->getFrame(); img=temp->data; pointbuf=temp->currentpoint; PointChange=temp->displacement; img.col(pointbuf.x).setTo(cv::Scalar(244)); img.row(pointbuf.y).setTo(cv::Scalar(244)); imshow("pid2",img); qDebug()<<"PointChange"< PidControl(PointChange,SetKp,SetKi,SetKd); }}void MainWindow::PidControl(int iError,int kp,int ki ,int kd){//△u(k)=u(k)-u(k-1)=Kp△e(k)+Kie(k)+Kd[△e(k)-△e(k-1)]//式中△e(k)= e(k)¬-e(k-1)int P,I,D;long PulseNumBuf=0;char CwCcwBuf=0;long rateBuf=0;// iError; //iError[o]当前误差P=kp*(iError-LastError);I=ki*iError;D=kd*(iError-LastError)-kd*(LastError-PrevError);Output+=P+I+D;LastError=iError;PrevError=LastError;qDebug()<<"[Kp,Ki,Kd]"<<"["<","<","<"]"<<"output"<<Output;if(iError>0){ CwCcwBuf=0x01;}else{ CwCcwBuf=0x11;}PulseNumBuf=Output;if(ui->openButton->text()==tr("关闭串口")){ bool TxEn=false; QSerialPort::SerialPortError error=serial->error(); handleSerialError(error,TxEn); if(TxEn) { sendSerialPortData(PulseNumBuf,CwCcwBuf,rateBuf); }}}//清空接受窗口void MainWindow::on_clearButton_clicked(){ ui->textEdit->clear(); cv::Mat img=cv::imread("C:/Users/Administrator/Desktop/SerialPort/SerialPort/SerialPort/earth.jpg",1); qDebug()<data ; qDebug()<cols <rows ; cv::imshow("MyWindow", img);}//发送数据void MainWindow::on_sendButton_clicked(){ serial->write(ui->textEdit_2->toPlainText().toLatin1());}void MainWindow::sendSerialPortData(long PulseNumTemp,char CwCcwTemp,long rateTemp){ QByteArray Bin_Order; //帧头 Bin_Order.append(0x55);//1// bool ok ;//正转0x11 “01”,反转0x01 “11” ,停止0xx0; Bin_Order.append(CwCcwTemp);//2/*//频率个数 Bin_Order.append(0x80);//3 Bin_Order.append(0x0c);//4 Bin_Order.append((char)0x0);//5 Bin_Order.append((char)0x0);//6*/ //频率个数 char buf=0; buf=PulseNumTemp|buf; Bin_Order.append(buf);//3 buf=0; buf=PulseNumTemp>>8|buf; Bin_Order.append(buf);//4 buf=0; buf=PulseNumTemp>>16|buf;; Bin_Order.append(buf);//5 buf=0; buf=PulseNumTemp>>24|buf; Bin_Order.append(buf);//6//脉冲频率/* Bin_Order.append(0xd0);//7 Bin_Order.append(0x07);//8 Bin_Order.append((char)0x0);//9 Bin_Order.append((char)0x0);//10*/ buf=rateTemp|buf; Bin_Order.append(buf);//3 buf=0; buf=rateTemp>>8|buf; Bin_Order.append(buf);//4 buf=0; buf=rateTemp>>16|buf;; Bin_Order.append(buf);//5 buf=0; buf=rateTemp>>24|buf; Bin_Order.append(buf);//6//帧尾 //“aa” Bin_Order.append(0xaa);//11 serial->write(Bin_Order); //55 11 b8 0b 00 00 d0 07 00 00 aa}//读取接收到的数据void MainWindow::Read_Data(){ QByteArray buf; buf = serial->readAll(); if(!buf.isEmpty()) { QString str = ui->textEdit->toPlainText(); str+=tr(buf); ui->textEdit->clear(); ui->textEdit->append(str); } buf.clear();}void MainWindow::on_openButton_clicked(){ if(ui->openButton->text()==tr("打开串口")) { serial = new QSerialPort; //设置串口名 serial->setPortName(ui->PortBox->currentText()); //打开串口 serial->open(QIODevice::ReadWrite); //设置波特率 serial->setBaudRate(ui->BaudBox->currentText().toInt()); //设置数据位数 switch(ui->BitNumBox->currentIndex()) { case 8: serial->setDataBits(QSerialPort::Data8); break; default: break; } //设置奇偶校验 switch(ui->ParityBox->currentIndex()) { case 0: serial->setParity(QSerialPort::NoParity); break; default: break; } //设置停止位 switch(ui->StopBox->currentIndex()) { case 1: serial->setStopBits(QSerialPort::OneStop); break; case 2: serial->setStopBits(QSerialPort::TwoStop); break; default: break; } //设置流控制 serial->setFlowControl(QSerialPort::NoFlowControl); //关闭设置菜单使能 ui->PortBox->setEnabled(false); ui->BaudBox->setEnabled(false); ui->BitNumBox->setEnabled(false); ui->ParityBox->setEnabled(false); ui->StopBox->setEnabled(false); ui->openButton->setText(tr("关闭串口")); ui->sendButton->setEnabled(true); ui->groupBox_2->setEnabled(true); //连接信号槽 QObject::connect(serial, &QSerialPort::readyRead, this, &MainWindow::Read_Data); } else { //关闭串口 serial->clear(); serial->close(); serial->deleteLater(); //恢复设置使能 ui->PortBox->setEnabled(true); ui->BaudBox->setEnabled(true); ui->BitNumBox->setEnabled(true); ui->ParityBox->setEnabled(true); ui->StopBox->setEnabled(true); ui->openButton->setText(tr("打开串口")); ui->sendButton->setEnabled(false); ui->groupBox_2->setEnabled(false); }}void MainWindow::on_PidChange_valueChanged(int value){ ui->SetPidV->setText(QString::number(value));}void MainWindow::on_PidChange_sliderReleased(){ int dec=ui->PidChange->value(); if(ui->KpChoose->isChecked()) { ui->SetKpUi->setText(QString::number(dec)); } if(ui->KiChoose->isChecked()) { ui->SetKiUi->setText(QString::number(dec)); } if(ui->KdChoose->isChecked()) { ui->SetKdUi->setText(QString::number(dec)); } qDebug()<<"ui->PidChange->"<<ui->SetKpUi->text();}void MainWindow::on_PidChange_sliderPressed(){ if(ui->KpChoose->isChecked()) { QString str = ui->SetKpUi->text(); bool ok; int dec = str.toInt(&ok, 10); ui->PidChange->setValue(dec); ui->PidChange->setMinimum(dec-100); ui->PidChange->setMaximum(dec+100); } if(ui->KiChoose->isChecked()) { QString str = ui->SetKiUi->text(); bool ok; int dec = str.toInt(&ok, 10); ui->PidChange->setValue(dec); ui->PidChange->setMinimum(dec-100); ui->PidChange->setMaximum(dec+100); } if(ui->KdChoose->isChecked()) { QString str = ui->SetKdUi->text(); bool ok; int dec = str.toInt(&ok, 10); ui->PidChange->setValue(dec); ui->PidChange->setMinimum(dec-1000); ui->PidChange->setMaximum(dec+1000); }}void MainWindow::on_pushButton_clicked(){ sendSerialPortData(3200,0x11,2000);}void MainWindow::on_pushButton_2_clicked(){ sendSerialPortData(3200,0x01,2000);}void MainWindow::on_pushButton_3_clicked(){ sendSerialPortData(3200,0x00,2000);}
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮