• 基于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:http://arduino.cc/

  • 相关阅读:
    php源码学习——开篇
    springMvc入门一
    spring 整合 servlet
    java jar包下载地址
    java spring学习
    Servlet 学习
    JRE_HOME environment variable is not defined correctly This environment variableis needed to run this program
    java JBDC操作
    Java 自定义异常
    JAVA的日期类DATE
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3097988.html
Copyright © 2020-2023  润新知