當(dāng)前位置: 首頁(yè) > 工業(yè)電氣產(chǎn)品 > 端子與連接器 > 線路板連接器 > FFC連接器
發(fā)布日期:2022-04-25 點(diǎn)擊率:74
關(guān)鍵詞:正運(yùn)動(dòng)技術(shù),機(jī)器視覺(jué),運(yùn)動(dòng)控制
摘要:QT是目前眾多軟件開(kāi)發(fā)工程師使用的C++應(yīng)用程序開(kāi)發(fā)框架。QT具有完整的GUI圖形庫(kù),界面控件的樣式和布局可直接通過(guò)控件屬性進(jìn)行設(shè)置,簡(jiǎn)化了代碼的使用。對(duì)于需要人機(jī)界面操作的機(jī)器視覺(jué)程序而言,QT強(qiáng)大的界面設(shè)計(jì)功能很大程度地減少了視覺(jué)軟件開(kāi)發(fā)工程師設(shè)計(jì)操作界面的開(kāi)發(fā)難度。正運(yùn)動(dòng)技術(shù)VPLC系列控制器可搭載Linux系統(tǒng),且支持QT調(diào)用正運(yùn)動(dòng)軟件的ZBasic指令。
QT是目前眾多軟件開(kāi)發(fā)工程師使用的C++應(yīng)用程序開(kāi)發(fā)框架。QT具有完整的GUI圖形庫(kù),界面控件的樣式和布局可直接通過(guò)控件屬性進(jìn)行設(shè)置,簡(jiǎn)化了代碼的使用。對(duì)于需要人機(jī)界面操作的機(jī)器視覺(jué)程序而言,QT強(qiáng)大的界面設(shè)計(jì)功能很大程度地減少了視覺(jué)軟件開(kāi)發(fā)工程師設(shè)計(jì)操作界面的開(kāi)發(fā)難度。正運(yùn)動(dòng)技術(shù)VPLC系列控制器可搭載Linux系統(tǒng),且支持QT調(diào)用正運(yùn)動(dòng)軟件的ZBasic指令。
本節(jié)課程我們將和大家一起分享ZBasic結(jié)合QT實(shí)現(xiàn)圖像采集功能的方法。
一認(rèn)識(shí)QT
Qt是一個(gè)1991年由Qt Company開(kāi)發(fā)的跨平臺(tái)C++圖形用戶界面應(yīng)用程序開(kāi)發(fā)框架。它既可以開(kāi)發(fā)GUI程序,也可用于開(kāi)發(fā)非GUI程序,比如控制臺(tái)工具和服務(wù)器。Qt是面向?qū)ο蟮目蚣埽褂锰厥獾拇a生成擴(kuò)展(稱為元對(duì)象編譯器“meta Object Compiler, moc”)以及一些宏,Qt很容易擴(kuò)展,并且允許真正地組件編程。
二ZBasic and QT
正運(yùn)動(dòng)技術(shù)將ZDevelop軟件主要使用的ZBasic語(yǔ)言封裝成C++動(dòng)態(tài)鏈接庫(kù),QT可以通過(guò)調(diào)用動(dòng)態(tài)庫(kù)的形式調(diào)用ZBasic指令。
三軟件實(shí)現(xiàn)
(一)準(zhǔn)備
(二)實(shí)例演示
1.打開(kāi)QTCreator軟件,新建QT項(xiàng)目:點(diǎn)擊“New Project”→項(xiàng)目選擇“Application”→選擇“QT Widgets Application”→點(diǎn)擊“Choose...”按鈕進(jìn)入下一步→輸入項(xiàng)目名稱“ZVision_QT_1”,選擇項(xiàng)目存儲(chǔ)的路徑(路徑不能包含中文),點(diǎn)擊“下一步”按鈕→默認(rèn)選擇“下一步”,最后點(diǎn)擊“完成”按鈕,完成項(xiàng)目的建立。
2.添加庫(kù)相關(guān)文件:將相關(guān)庫(kù)文件拷貝到項(xiàng)目所在文件夾下→鼠標(biāo)左鍵點(diǎn)擊項(xiàng)目名稱,再點(diǎn)擊鼠標(biāo)右鍵彈出快捷菜單,選擇“添加現(xiàn)有文件”→依次將“zaux.h”文件、“zmotion.h”文件、“zaux.cpp”文件添加到項(xiàng)目→雙擊“.pro”文件,手動(dòng)添加動(dòng)態(tài)鏈接庫(kù)代碼“win32: LIBS += -L$$PWD/ -lzmotion”→在“mainwindow.cpp”文件中定義調(diào)用庫(kù)相關(guān)頭文件,即添加代碼:#include “zmotion.h”和#include “zaux.h”。
3.在mainwindow.cpp文件中定義程序中使用到的全局變量。
ZMC_HANDLE g_handle;//控制器句柄
int Times=0;
uint8 zv0_pBuff[400*300*2]={0};//鎖存0緩存大小
int ContinuousGetImgFlag=0; //連續(xù)采集標(biāo)志
4.設(shè)計(jì)UI界面。
5.添加界面初始化代碼。
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->ZV0->setText("");//清空字體
ui->ZV0->setStyleSheet("QLabel{background-color:rgb(0, 0, 100);}"); //設(shè)置樣式表
ui->Exposurevalue->setText("5000");
}
6.添加【掃描控制器IP】槽函數(shù):選擇【掃描控制器IP】按鈕,右擊彈出快捷菜單欄,選擇“轉(zhuǎn)到槽”選項(xiàng)→彈出“轉(zhuǎn)到槽”窗口,選擇對(duì)應(yīng)的信號(hào)源“clicked()”,點(diǎn)擊“OK”確認(rèn),即可完成槽函數(shù)的定義和聲明→在槽函數(shù)的聲明函數(shù)中添加函數(shù)實(shí)現(xiàn)的具體代碼內(nèi)容。
//掃描控制器IP
void MainWindow::on_Scan_Control_IP_clicked()
{
char buffer[10240];
int32 iresult;
const char *ipaddress;
iresult = ZMC_SearchEth(buffer, 10230, 100);//掃描控制器IP,返回錯(cuò)誤碼信息
if(ERR_OK != iresult)
{
return ; //錯(cuò)誤
//將掃描到的所有IP地址進(jìn)行分割,并按照IP地址格式顯示在下拉列表中
int ipos =0;
const char * pstring;
pstring = buffer;
for(int j= 0; j< 100;j++) //最多100個(gè)IP列表
{
char buffer2[256];
buffer2[0] = '?';
while(' ' == pstring[0])
{
pstring++;
}
ipos = sscanf(pstring , "%s", &buffer2);
if(EOF == ipos)
{
break;
}
//跳過(guò)字符
while((' ' != pstring[0]) && (' ' != pstring[0]) && ('?' != pstring[0]))
{
pstring++;
}
if(0 == strcmp(buffer2, ipaddress))
{
return ;
}
ui->ComboBoxIP->addItem(buffer2);
}
}
7.添加【連接】槽函數(shù):選擇【連接】按鈕,右擊彈出快捷菜單欄,選擇“轉(zhuǎn)到槽”選項(xiàng)→彈出“轉(zhuǎn)到槽”窗口,選擇對(duì)應(yīng)的信號(hào)源“clicked()”,點(diǎn)擊“OK”確認(rèn),即可完成槽函數(shù)的定義和聲明→在槽函數(shù)的聲明函數(shù)中添加函數(shù)實(shí)現(xiàn)的具體代碼內(nèi)容。
//連接控制器
void MainWindow::on_link_Control_clicked()
{
//get ip from current list
int32 iresult;//錯(cuò)誤碼
int nIndex = 0;
char * tmp_buff = new char[16];
char str1[64];
QString str;
str = ui->ComboBoxIP->currentText();//獲取IP列表里的IP地址數(shù)據(jù)
qDebug()<<"current ip"<<str;//打印當(dāng)前選擇的IP地址數(shù)據(jù)
QByteArray ba = str.toLatin1();//將IP的字符串格式轉(zhuǎn)到char * 格式
tmp_buff = ba.data();
if(0 != g_handle)//如果控制器句柄不為0
{
ZAux_Close(g_handle);//關(guān)閉控制器鏈接
}
iresult=ZAux_OpenEth(tmp_buff,&g_handle);//根據(jù)獲取的IP地址與控制器建立鏈接,返回錯(cuò)誤碼
if (iresult==0)
{
sprintf(str1, "控制器連接成功,當(dāng)前IP:%s", tmp_buff);
setWindowTitle(str1);
qDebug()<<"link Success! ip:"<<tmp_buff;
}
else
{
qDebug()<<"link Fail!";
setWindowTitle("控制器已斷開(kāi)");
}
}
8.添加【斷開(kāi)】槽函數(shù):選擇【斷開(kāi)】按鈕,右擊彈出快捷菜單欄,選擇“轉(zhuǎn)到槽”選項(xiàng)→彈出“轉(zhuǎn)到槽”窗口,選擇對(duì)應(yīng)的信號(hào)源“clicked()”,點(diǎn)擊“OK”確認(rèn),即可完成槽函數(shù)的定義和聲明→在槽函數(shù)的聲明函數(shù)中添加函數(shù)實(shí)現(xiàn)的具體代碼內(nèi)容。
//斷開(kāi)連接控制器
void MainWindow::on_Disconnect_clicked()
{
if(0 != g_handle)
{
ZAux_Close(g_handle);//關(guān)閉控制器鏈接
g_handle = NULL;//清空句柄
setWindowTitle("控制器已斷開(kāi)");
}
}
9.添加【掃描相機(jī)】槽函數(shù):選擇【掃描相機(jī)】按鈕,右擊彈出快捷菜單欄,選擇“轉(zhuǎn)到槽”選項(xiàng)→彈出“轉(zhuǎn)到槽”窗口,選擇對(duì)應(yīng)的信號(hào)源“clicked()”,點(diǎn)擊“OK”確認(rèn),即可完成槽函數(shù)的定義和聲明→在槽函數(shù)的聲明函數(shù)中添加函數(shù)實(shí)現(xiàn)的具體代碼內(nèi)容。
//掃描相機(jī)
void MainWindow::on_Scan_Camera_clicked()
{
float CamNum=0;
int32 iresult;//錯(cuò)誤碼
QString str;
char buffer[2048];
iresult=ZAux_RunTask(g_handle,0,"cam_scan_all()");//運(yùn)行控制器里面指定的SUB
if (iresult==0)
{
qDebug()<<"run cam_scan_all() success";
}
else
{
qDebug()<<"run cam_scan_all() fail !!"<<iresult;
}
ZAux_Direct_GetTable(g_handle,0,1,&CamNum);//讀取控制器table變量
str = QString("掃描到的相機(jī)個(gè)數(shù):%1").arg(CamNum);
ui->CamNum->setText(str);//顯示掃描到的相機(jī)數(shù)量
}
10.添加【采集圖像】槽函數(shù):選擇【采集圖像】按鈕,右擊彈出快捷菜單欄,選擇“轉(zhuǎn)到槽”選項(xiàng)→彈出“轉(zhuǎn)到槽”窗口,選擇對(duì)應(yīng)的信號(hào)源“clicked()”,點(diǎn)擊“OK”確認(rèn),即可完成槽函數(shù)的定義和聲明→在槽函數(shù)的聲明函數(shù)中添加函數(shù)實(shí)現(xiàn)的具體代碼內(nèi)容(此前需要在頭文件中定義使用到的QPixmap fPixmap 變量)。
//單次采集
void MainWindow::on_Camera_Grab_clicked()
{
int32 iresult;//錯(cuò)誤碼
iresult=ZAux_RunTask(g_handle,0,"btn_grab()");//運(yùn)行控制器里面指定的SUB
if (iresult==0)
{
qDebug()<<"run btn_grab() success";
}
else
{
qDebug()<<"run btn_grab() fail !!"<<iresult;
}
ZV0_Show();//將控制器獲取到的圖像轉(zhuǎn)換成Qt可顯示的圖片格式,并顯示圖像
}
//將獲取到的圖像顯示到ZV0控件中
void MainWindow::ZV0_Show()
{
int latin=0,buffsize=400*300*2;
int width, height,bite,WrTimes;
int flag=1, count=0;
//獲取zvlatch的信息
ZMC_ZVLatinImgGetInfo(g_handle, latin, &width, &height, &bite, &WrTimes);//獲取圖像信息
if(WrTimes==0)
{
return;//時(shí)間沒(méi)有改變退出函數(shù)
}
//獲取到的鎖存0的緩存數(shù)據(jù)
buffsize = width*height*2;
ZMC_ZVLatinImgGet(g_handle, latin, &width, &height, &bite, zv0_pBuff, buffsize);//獲取圖像數(shù)據(jù)
//將獲取到的鎖存0的緩存數(shù)據(jù)在qt中顯示出來(lái)
QImage Image((uchar *)zv0_pBuff,width, height,QImage::Format_RGB555);
Image = Image.mirrored(false,true);
QPixmap Pixmap = QPixmap:: fromImage (Image);
fPixmap = Pixmap.scaled(width, height);
ui->ZV0->clear();
ui->ZV0->setPixmap(fPixmap);
}
11.添加顯示函數(shù)ZV0_Show()的定義和聲明函數(shù)。
private slots:
void on_Scan_Control_IP_clicked();
void on_link_Control_clicked();
void on_Disconnect_clicked();
void on_Scan_Camera_clicked();
void on_Camera_Grab_clicked();
void on_Contiue_Grab_clicked();
void on_Stop_Grab_clicked();
void on_Set_Exposure_clicked();
void ZV0_Show(); //鎖存0顯示
//將獲取到的圖像顯示到ZV0控件中
void MainWindow::ZV0_Show()
{
int latin=0,buffsize=400*300*2;
int width, height,bite,WrTimes;
int count=0;
int flag=0;
ZMC_ZVLatinImgGetInfo(g_handle, latin, &width, &height, &bite, &WrTimes);
qDebug()<<WrTimes;
if(Times == WrTimes)
{
return;//時(shí)間沒(méi)有改變退出函數(shù)
}
else
{
Times = WrTimes;
}
QThread::msleep(100);
while(0 == flag)//等待
{
ZAux_Direct_GetVariableInt(g_handle,"CamGetPhotoFlag",&flag);
QThread::msleep(10);
count++;
if(1000 < count)//等待時(shí)間大于10s
{
break;//退出循環(huán)
}
}
flag=0;
//獲取zvlatch的信息
ZAux_Direct_SetVariableInt(g_handle,"CamGetPhotoFlag",flag);
//獲取到的鎖存0的緩存數(shù)據(jù)
buffsize = width*height*2;
ZMC_ZVLatinImgGet(g_handle, latin, &width, &height, &bite, zv0_pBuff, buffsize);//獲取圖像數(shù)據(jù)
//將獲取到的鎖存0的緩存數(shù)據(jù)在qt中顯示出來(lái)
flag=1;
//獲取zvlatch的信息
ZAux_Direct_SetVariableInt(g_handle,"CamGetPhotoFlag",flag);
QImage Image((uchar *)zv0_pBuff,width, height,QImage::Format_RGB555);
Image = Image.mirrored(false,true);
QPixmap Pixmap = QPixmap:: fromImage (Image);
fPixmap = Pixmap.scaled(width, height);
ui->ZV0->clear();
ui->ZV0->setPixmap(fPixmap);
}
12.添加【連續(xù)采集】槽函數(shù):選擇【連續(xù)采集】按鈕,右擊彈出快捷菜單欄,選擇“轉(zhuǎn)到槽”選項(xiàng)→彈出“轉(zhuǎn)到槽”窗口,選擇對(duì)應(yīng)的信號(hào)源“clicked()”,點(diǎn)擊“OK”確認(rèn),即可完成槽函數(shù)的定義和聲明→在槽函數(shù)的聲明函數(shù)中添加函數(shù)實(shí)現(xiàn)的具體代碼內(nèi)容。
//連續(xù)采集
void MainWindow::on_Contiue_Grab_clicked()
{
int32 iresult;//錯(cuò)誤碼
iresult=ZAux_RunTask(g_handle,0,"btn_cgrab()");//運(yùn)行控制器里面指定的SUB
if (iresult==0)
{
qDebug()<<"run btn_cgrab() success";
}
else
{
qDebug()<<"run btn_cgrab() fail !!"<<iresult;
}
ContinuousGetImgFlag=1;//連續(xù)采集標(biāo)志置1
}
13.添加定時(shí)刷新函數(shù):在“mainwindow.h”文件中添加包含QTimer定時(shí)器的類型庫(kù),并定義“QTimer UpZV_0”定時(shí)器變量→在界面初始化函數(shù)中添加定時(shí)器觸發(fā)條件和信號(hào)與槽連接函數(shù)→添加定時(shí)采集圖像的定義和聲明函數(shù),并在聲明函數(shù)中添加具體的實(shí)現(xiàn)代碼內(nèi)容。
#include
#include
void ZV0_Show(); //鎖存0顯示
void UpZV_0show();
private:
Ui::MainWindow *ui;
QPixmap fPixmap;
QTimer UpZV_0;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->ZV0->setText(""); //清空字體
ui->ZV0->setStyleSheet("QLabel{background-color:rgb(0, 0, 100);}"); //設(shè)置樣式表
ui->Exposurevalue->setText("5000");
UpZV_0.start(20);//200ms定時(shí)判斷采集并顯示圖像
connect(&UpZV_0, SIGNAL(timeout()), this, SLOT(UpZV_0show()));
}
//定時(shí)器開(kāi)啟連續(xù)采集
void MainWindow::UpZV_0show()
{
if(1 == ContinuousGetImgFlag)
{
ZV0_Show();
}
}
14.添加【停止采集】槽函數(shù):選擇【停止采集】按鈕,右擊彈出快捷菜單欄,選擇“轉(zhuǎn)到槽”選項(xiàng)→彈出“轉(zhuǎn)到槽”窗口,選擇對(duì)應(yīng)的信號(hào)源“clicked()”,點(diǎn)擊“OK”確認(rèn),即可完成槽函數(shù)的定義和聲明→在槽函數(shù)的聲明函數(shù)中添加函數(shù)實(shí)現(xiàn)的具體代碼內(nèi)容。
//停止采集
void MainWindow::on_Stop_Grab_clicked()
{
int32 iresult;//錯(cuò)誤碼
iresult=ZAux_RunTask(g_handle,0,"btn_stopCgrab()");//運(yùn)行控制器里面指定的SUB
if (iresult==0)
{
qDebug()<<"run btn_stopCgrab() success";
}
else
{
qDebug()<<"run btn_stopCgrab() fail !!"<<iresult;
}
ContinuousGetImgFlag=0;//連續(xù)采集標(biāo)志置0
}
15.添加【設(shè)置】槽函數(shù):選擇【設(shè)置】按鈕,右擊彈出快捷菜單欄,選擇“轉(zhuǎn)到槽”選項(xiàng)→彈出“轉(zhuǎn)到槽”窗口,選擇對(duì)應(yīng)的信號(hào)源“clicked()”,點(diǎn)擊“OK”確認(rèn),即可完成槽函數(shù)的定義和聲明→在槽函數(shù)的聲明函數(shù)中添加函數(shù)實(shí)現(xiàn)的具體代碼內(nèi)容。
//設(shè)置曝光時(shí)間
void MainWindow::on_Set_Exposure_clicked()
{
int32 iresult;//錯(cuò)誤碼
QString str_tmp;
float Exposurevalue;
str_tmp = ui->Exposurevalue->text();//獲取QLineEdit控件顯示的曝光值
Exposurevalue = str_tmp.toFloat();//字符串轉(zhuǎn)成浮點(diǎn)數(shù)
ZAux_Direct_SetTable(g_handle,1,1,&Exposurevalue);//設(shè)置控制器的table變量
iresult=ZAux_RunTask(g_handle,0,"Camera_Exposure()");//運(yùn)行控制器里面指定的SUB
if (iresult==0)
{
qDebug()<<"run Camera_Exposure() success";
}
else
{
qDebug()<<"run Camera_Exposure() fail !!"<<iresult;
}
}
16.查看運(yùn)行效果:將控制器接入電源,使用網(wǎng)線將控制器與PC連接,將相機(jī)通電并接入控制器→使用ZDevelop軟件打開(kāi)ZBasic指令編寫包含采集函數(shù)的項(xiàng)目文件,將該項(xiàng)目下載到控制器→運(yùn)行QT程序,并連接到控制器,進(jìn)行對(duì)應(yīng)采集操作。
完整代碼獲取地址
▼
本次,正運(yùn)動(dòng)技術(shù)ZBasic結(jié)合Qt實(shí)現(xiàn)機(jī)器視覺(jué)圖像采集,就分享到這里。
更多精彩內(nèi)容請(qǐng)關(guān)注“正運(yùn)動(dòng)小助手”公眾號(hào),需要相關(guān)開(kāi)發(fā)環(huán)境與例程代碼,請(qǐng)咨詢正運(yùn)動(dòng)技術(shù)銷售工程師:400-089-8936。
本文由正運(yùn)動(dòng)技術(shù)原創(chuàng),歡迎大家轉(zhuǎn)載,共同學(xué)習(xí),一起提高中國(guó)智能制造水平。文章版權(quán)歸正運(yùn)動(dòng)技術(shù)所有,如有轉(zhuǎn)載請(qǐng)注明文章來(lái)源。
下一篇: PLC、DCS、FCS三大控