2015年1月30日 星期五

動態呼叫方法參數說明

前一篇文章已經有說明子程式的執行方式(動、靜態呼叫與裝載)。
本篇將進一步的說明動態裝載與呼叫時,會用到的 Open VI Reference元件。
 Option:
1          0x0(預設值):只能只用 call by reference
2          0x08:可使用於一般執行或同行(reentrant)執行,只能使用於run vi property 執行。如果要用於同步執行,參數不需增加0x40,只需要將被呼叫的背景程式的VI Properties設定視窗,依需求要設定為 Shared clone reentrant executionPreallocated clone reentrant execution。這邊需注意的是左圖中的Wait Until Done需設定為False,主程式才能呼叫多次背景程式,不然會在第一次呼叫時就暫停執行,並等待背景程式執行完畢。



3          0x40:啟用同步執行VI,並共享data。執行方式分為 call by reference start asynchronous call
3.1         Call by reference:下圖使用Parallel For Loop Iterations,由於是同步執行,所以此處的error cluster 不需要使用 shift register


3.2         Start asynchronous call:透過 start asynchronous call 執行的可建立背景程式,並依照是否讀取背景程式的輸出來設定Open VI Reference option值。
3.2.1   如果不需要讀取背景程式的輸出值,則option設定如下圖左方,0x80為不需讀取背景程式輸出值的設定碼。右圖為被呼叫的背景程式的VI Properties設定視窗,依需求要設定為 Shared clone reentrant executionPreallocated clone reentrant execution


3.2.2   如果需讀取背景程式的輸出值,則option設定如下圖左方,0x100為需讀取背景程式輸出值的設定碼。右圖為被呼叫的背景程式的VI Properties設定視窗,須設定為 Shared clone reentrant executionPreallocated clone reentrant execution


4          0x80:並且不需要管理其運行的背景程式,不讀取背景程式的輸出數據。只能用 Start Asynchronous Call執行
5          0x100:只能用 Start Asynchronous Call執行。並且透過Wait On Asynchronous Call讀取背景程式的輸出數據。

參考程式: labview\examples\viserver\AsynchronousCallByReference\TCPDateServerUsingStartAsynchronousCall.llb
labview\examples\viserver\AsynchronousCallByReference
labview\examples\viserver\AsynchronousCallByReference
labview\examples\viserver\AsynchronousCallByReference
labview\examples\Application Control\VI Server\Asynchronous Call By Reference\ Benchmarking Asynchronous Calls

XControl的運作流程與相關說明

最近在練習寫XControl,參考了網路上的文章
我都照著他的說明做。
最後將產生的XControl放置前面板時,正常來說只有是當顯示元件並且是run的狀態下才無法點選。
但不知道為何我編寫的XControl不管設置為控制元件還是顯示元件都無法點選。
所以後來我就了解一下XControl的運行流程。最後會說明我編寫的XControl的問題在哪!
XControl的運作流程:
下圖是說明前面板還有XControl元件的VI開啟時(只有開啟VI!還沒有Run),實際XControl內部的運行流程。不管你是否有改變XControl為控制元件或顯示元件。都會觸發Display State Change Event!


下圖是說明前面板還有XControl元件的VI運行停止時,實際XControl內部的運行流程。


後來我發現在XControlFacade內部如果你把XControl元件設定為顯示元件,則在呼叫XControl元件的VI內,不管你把他設定為控制元件還是顯示元件,都無法點選。

目前我還是有個問題無法解決,就是參考的那網頁把XControl的控制與顯示元件的預設顏色都是紅色。
但我把控制跟顯示的預設顏色設定為不一樣。就會發現一個問題。就是XControl無法依照我在含有XControlVI內設定XControl為控制或是顯示的元件,來變更預設的顏色。
我知道與Convert State For Save.VI有關但是我不知道怎樣的狀態下才會觸發這個VI,目前還在研究中….


2015年1月29日 星期四

執行檔與編譯環境下的路徑呼叫差異

程式當中常需要載入設定檔或是輸出報表,常常在程式編寫、測試時沒有問題。但將程式編譯成執行檔後,卻又無法正常的載入或輸出檔案。
一般來說比較常見的是因為呼叫的路徑錯誤,所以找不到檔案。
通常我們都使用Current’s VI Path Node取得主程式的路徑所存在的資料夾路徑。
如下圖,可以看到在程式編輯執行時,可以得到主程式所存在的資料夾路徑。


下圖是編譯成執行檔後的運行,原本的程式碼所取得的並不是主程式所存在的資料夾路徑。因為原本程式碼編譯成執行檔後,原本主程式VI包覆在執行檔的裡面,透過原本的Current’s VI Path Node 呼叫就可以看出多了一層。



這裡提出三個方法來完成不論是程式編輯或是編譯成執行檔皆可取得同樣的路徑。
1.          By Property Node
2.          By Conditional Disable Structure
3.          By Application Directory Node




2015年1月20日 星期二

事件(Event Structure)觸發說明

事件(Event Structure)觸發方式:
1.      normal event: 一般用來接收人機介面上的動作,while structure 內部不用放置延遲元件(WaitWait until next ms multiple)。圖中箭頭為timeout設定,預設為-1也就是沒有timeout


2.      call by value(signal) property node:上一個方法僅能觸發人機介面上的操作,但實際運作中並不一定每次的觸發都是因為人機介面操作所觸發的。如下圖,如果點選start按鈕後就會觸發將下面的迴圈產生的隨機數值加總,此外,如果沒有點選start按鈕,則透過圖中紅圈的value(Signal) property node,每產生二十個隨機數值觸發加總的事件(event)
PS:不管value(signal) 輸入何值,只要呼叫到該node 都會觸發event事件。


操作說明:在要觸發的按鍵上按右鍵,如圖可選出value(signaling)  property node


3.      dynamic event:雖然說盡量不要在subVI內放置event structure,但是如果一定要放的話,就可以透過此方法來執行。另外,這方法還可以完成程式執行的狀態下改變同一動作觸發狀態(#1) 的功能。


操作說明:
1.          event structure 上按右鍵點選show dynamic event terminals


2.          然後event structure左邊會出現一個雷達的圖樣,在上面點選右鍵,就會有相關的元件。



4.      user event(#2): 此方法的適用於原本event structure沒有定義的觸發動作與多迴圈的架構,如圖中LOOP2如果發生錯誤就會停止迴圈,並且LOOP1event structure會觸發自訂的user event 跳出錯誤顯示視窗後停止LOOP1迴圈,避免LOOP2錯誤發生時,無法停止LOOP1的問題。
圖中左邊的紅圈可自訂要傳輸的資料格式,設定好後可以在event structure中觸發user event時,輸出(圖中右邊的紅圈)




參考程式:
#1. \National Instruments\LabVIEW 2014\examples\Dialog and User Interface\Events\Dynamic Event Generation.vi

#2. \National Instruments\LabVIEW 2014\examples\Dialog and User Interface\Events\User Event Generation.vi

2015年1月16日 星期五

動態與靜態運行子程式說明

本篇要來介紹子程式載入與呼叫的方式,分別有分為靜態與動態,說明如下:

靜態裝載(static load):只要程式碼一開啟,即裝載進記憶體(不一定是程式執行的狀態下,編譯程式的狀態也會)
動態裝載(dynamic load):程式執行時,才裝載進記憶體

靜態呼叫(static call):呼叫的SubVI路徑只能於程式編譯時,做設定
動態呼叫(dynamic call):呼叫的SubVI路徑可以於程式執行的時候再設定

1.靜態裝載&靜態呼叫:

Load with callers:caller VI load後也一併load subVI(不用等到程式執行時)



2.動態裝載&靜態呼叫:

2.1 Reload for each call:

caller VI 運行並每次呼叫 SubVI時都會重新load(實際上是如果subVI沒有在記憶體內就會reload。故此選項也不保證運行完後SubVI會保留在記憶體內)



2.2 Load and retain on first call:

caller VI運行時第一次呼叫SubVI時,subVI才會Load,並存在記憶體內。



3.動態裝載&動態呼叫:

3.1 藉由invoke node 呼叫(call by vi method):

此種方法可以建立不影響主程式運行流程的背景程式但有個缺點就是要輸入跟輸出SubVI的資料很麻煩!!!

  

3.2 藉由reference呼叫(call by ref):

無法建立背景程式,主程式中如果透過該方式呼叫SubVI,則一定執行完SubVI的程式後,才可以繼續執行主程式



LabVIEW2011之後的版本,新增了

3.3 Start Asynchronous Call Node:

這個元件有很多功能,之後再另外開一篇文章來介紹。這篇只講其中一個,就是可以有(call by vi method)的優點,可以建立背景程式,並且又可以像(call by ref),有簡單的方式可以輸入跟輸出資料,設定的重點是圖中圈起來的地方必須設定為0x80