閱讀126 返回首頁    go windows


基於Arduino+LabVIEW的多路數據采集係統

摘要: 針對低速、低成本、快速搭建的特點,采用Arduino與LabVIEW來實現低成本上下位機數據采集係統。Arduino作為下位機,負責A/D轉換以及數據傳輸;LabVIEW編寫的數據采集軟件作為上位機;上下位機利用RS-232串行接口實現通訊。

     【注】一般認為上位機為主機,下位機為從機,上位機領導下位機按照上位機的意願為上位機服務;同時下位機也可以主動向上位機發出請求,上位機響應下位機並配合完成某個請求。

      數據采集,是指從傳感器和其它待測設備等模擬和數字被測單元中自動采集信息的過程。相應能夠完成數據采集的係統被稱為數據采集係統。

      數據采集係統的任務,就是采集傳感器輸出的模擬信號轉換成計算機能識別的信號,並送入計算機,然後將計算得到的數據進行顯示或打印,以便實現對某些物理量的監測,其中一些數據還將被生產過程中的計算機控製係統用來控製某些物理量。 【文獻1】

一、Arduino下位機部分

      數據采集係統中的Arduino下位機部分采用Arduino Leonardo實驗板,如圖1所示。

圖1 Arduino Leonardo控製板

      Arduino下位機部分需要完成兩個功能:數據采集和數據傳輸,Arduino Leonardo控製板通過串口接受上位機命令,完成相應的數據采集,並將數據回傳至上位機。

      數據采集分為模擬量采集和數字量采集,設置采集路數各為2路,分別采用Arduino UNO上具有模擬量輸入的管腳A0、A1和具有數字量輸入的管腳2、3來實現。模擬量采用接至GND、3.3V和5V來實現不同電壓值,數字量采用接至5V和GND實現高電平與低電平。【注】

    【注】如果有電位器,可以用來測量分壓值。由於手頭沒有電位器,我這裏隻是簡單的實現。

Arduino Leonardo代碼清單:

1 #define A0_COMMAND  0x10   //A0采集命令字
2 #define A1_COMMAND  0x11   //A1采集命令字
3 #define D0_COMMAND  0x20   //D0采集命令字
4 #define D1_COMMAND  0x21   //D1采集命令字
1 byte comdata[3]={0};      //定義數組數據,存放串口接收數據
1 int LED = 13;             //定義LED連接的管腳
1 int A0_mark=0;            //定義A0的標誌位
2 int A1_mark=0;            //定義A1的標誌位
3 int D0_mark=0;            //定義D0的標誌位
4 int D1_mark=0;            //定義D1的標誌位
1 int AD_Value=0;          //AD轉換後的數字量
2 float float_AD_Value;    //數字量換算成浮點電壓量
3 int D_Value=0;           //數字量測量的數據
1 void receive_data(void);      //接受串口數據
2 void test_data(void);         //測試串口數據是否正確,並更新數據
3 void do_command(void);        //執行更新的數據
1 void setup()
2 {
3   Serial.begin(9600);     
4   pinMode(LED, OUTPUT);
5 }
1 void loop()
2 {
3   while (Serial.available() > 0)   //不斷檢測串口是否有數據
4    {
5         receive_data();            //接受串口數據
6         test_data();               //測試數據是否正確並更新標誌位
7         do_command();              //執行更新的數據
8    }
9 }
01 void receive_data(void)      
02 {
03    int i ;
04    for(i=0;i<3;i++)
05    {
06       comdata[i] =Serial.read();
07       //延時一會,讓串口緩存準備好下一個字節,不延時可能會導致數據丟失,
08        delay(2);
09    }
10 }
01 void test_data(void)
02 {
03   if(comdata[0] == 0x55)            //0x55和0xAA均為判斷是否為有效命令
04    {
05      if(comdata[1] == 0xAA)
06      {
07         if(comdata[2] == A0_COMMAND)
08           {  
09               A0_mark=2;                //A0更新位置位 
10           }
11         if(comdata[2] == A1_COMMAND)
12           {
13               A1_mark=2;                //A1更新位置位
14           }
15         if(comdata[2] == D0_COMMAND)
16           {  
17               D0_mark=2;                //D0更新位置位 
18           }
19         if(comdata[2] == D1_COMMAND)
20           {
21               D1_mark=2;               //D1更新位置位
22           }
23       }
24    }
25 }
01 void do_command(void)
02 {
03   if(A0_mark==2)
04   {
05     A0_mark=0;                                 //複位A0更新位
06     digitalWrite(LED, HIGH);                   //打開LED燈
07     AD_Value = analogRead(A0);                 //讀取A0電壓值
08     float_AD_Value=(float)AD_Value/1023*5.00;  //換算為浮點電壓值
09     Serial.println(float_AD_Value,2);          //保留兩位小數發送數據
10     delay(500);
11     digitalWrite(LED, LOW);                     //關閉LED燈
12   }
13   if(A1_mark==2)
14  
15   {
16     A1_mark=0;                                 //複位A1更新位
17     digitalWrite(LED, HIGH);                   //打開LED燈
18     AD_Value = analogRead(A1);                 //讀取A1電壓值
19     float_AD_Value=(float)AD_Value/1023*5.00;  //換算為浮點電壓值
20     Serial.println(float_AD_Value,2);          //保留兩位小數發送數據
21     delay(500);
22     digitalWrite(LED, LOW);                     //關閉LED燈
23   }
24   if(D0_mark==2)
25   {
26     D0_mark=0;                                 //複位D0更新位
27     digitalWrite(LED, HIGH);                   //打開LED燈
28     D_Value = digitalRead(2);                  //讀取D2數字量
29     Serial.println(D_Value);                  //發送數字量測量數據
30     delay(500);
31     digitalWrite(LED, LOW);                     //關閉LED燈
32   }
33   if(D1_mark==2)
34   {
35     D1_mark=0;                                  //複位D1更新位
36     digitalWrite(LED, HIGH);                    //打開LED燈
37     D_Value = digitalRead(3);                   //讀取D1數字量
38     Serial.println(D_Value);                   //發送數據量測量數據
39     delay(500);
40     digitalWrite(LED, LOW);                      //關閉LED燈
41   }
42 }


二、LabVIEW上位機部分

      串口讀寫的程序框圖如圖2所示。首先,對選擇的通道的串口進行配置,然後串口寫入所需要測量的通道號,等待100ms,從串口中讀取Arduino下位機返回數據,最後對數據進行適當的轉換並顯示出來。                                                   

圖2 LabVIEW串口通訊最小部分

    LabVIEW上位機前麵板設計如圖3所示。

圖3 LabVIEW上位機前麵板

      LabVIEW上位機程序框圖如圖4和圖5所示,由於有2路模擬量和2路數字量,此處僅給出一路模擬量和一路數字量的程序框圖。不同通道的模擬量或數字量的發送數據幀中,通道號不同;數字量與模擬量采集的發送數據幀中,命令號不同。發送數據幀中,具體的命令號和通道可以自己定義,不過需要上下位機的對應起來。

圖4 模擬量采集程序框圖

圖5 數字量采集程序框圖

三、實驗與演示

      通過將模擬量輸入A0依次接入GND、3.3V和5V,然後點擊“測量”按鈕,觀察麵板上的儀表盤和數顯框中數值的變化。

      通過將數字量輸入2依次接入GND和5V,然後點擊“測量”按鈕,觀察麵板上的LED燈的變化,LED亮代表高電平、LED滅代表低電平。 

      視頻貼不進來,就留個鏈接吧。

四、總結

      在傳感器等領域經常需要用到數據采集的功能,此應用實現了命令發送與數據回傳功能,可以在此基礎上擴展功能,對相關傳感器的數據采集有一定的參考價值。

參考文獻:

文獻1:基於單片機的數據采集係統的控製器設計

文獻2:https://arduino.cc/

最後更新:2017-04-03 18:52:01

  上一篇:go Mybatis調用Oracle中的存儲過程和function
  下一篇:go 你不能不知道中國最神秘的10個部門