LabVIEW及Labwindows/CVI如何在波形图上显示时间和日期
江南拱桥夜
2024年06月15日 12:30

在LabVIEW及Labwindows/CVI中我们分析或采集的数据通常都是时间的函数。例如,我们可能希望知道在一天中温度随着时间的变化,或者是变化的波形在时间轴上绘出之后的样子。

LabVIEW及Labwindows/CVI中有一些特殊的数据类型可以用来帮助一般的用户来以曲线的形式分析或展示这些数据。这些特殊的数据类型就是时标(Time Stamp)、波形(Waveform)。而在Labwindows/CVI中,没有提供时标控件,因此只能通过插入ActiveX控件实现相似功能。我们就在本文中主要介绍时标(Time Stamp)。

时标这个数据类型用来存储绝对日期/时间值,比如数据采集的时间。它的精度非常高,不论是对于计数秒的整数部分还是分数部分都有19位的精度。

虽然我们可通过将一个数值控件的显示方式设定为日期/时间来存储与显示时标值,不过数值控件保存的是相对值,而时标控件保存的则是绝对值。

在LabVIEW中,我们可以使用Get Date/Time In Seconds函数来获取当前的时标值。一个时标控件如下图所示:

时标是一个高精度保存绝对时间的手段,而时标控件则可以用来查看与修改时标的值。时标控件可以在Controls控件面板的Modern>>Numeric子面板中找到。

通过点击你要修改的时标控件左侧的上下箭头就可以对该时标的值进行增减操作。或者是通过键盘直接键入数值来取代时标的当前值。也可以在时标控件上点击鼠标右键,并在右键菜单中选择Data Operations>>Set Time to Now将时标的值设置为当前的日期与时间。

不过我们还有一个更有趣的修改时标的方法,那就是点击时标控件右侧的日期/时间浏览按钮。在点击该按钮之后,就会弹出下面的日期与时间设置对话框。从这个对话框,我们能够轻松的用这个日历式的界面来修改时标的日期与时间值。

这个对话框也可以在时标控件上点击鼠标右键,在右键菜单中Data Operations>>Set Time and Data菜单项打开这个对话框。对于没有日期/时间浏览按钮的时标常量以及指示器类型的控件,使用这个右键菜单是最合适的方式。

在LabVIEW及Labwindows/CVI都可以采用插入ActiveX控件实现类似功能,效果如下:

LabVIEW在波形图上显示时间和日期

1.   将波形图横坐标显示格式改为绝对时间格式,如下图:

2.   对数据格式进行变换,表示横坐标的数据转换成时标(Time Stamp),纵坐标数据转换成非字符串类型,如浮点数

3.   对数据进行捆绑,然后显示在波形图控件上,部分代码如下:

4.   显示效果如下:

Labwindows/CVI在波形图上显示时间和日期

1. 将波形图横坐标显示格式改为绝对时间格式,如下图:

2.对数据格式进行变换,表示横坐标的数据转换成int64_t,纵坐标数据转换成非字符串类型,如浮点数,部分代码如下:

……

strncpy (NIAN, &timevalue[0], 4);

             strncpy (YUE, &timevalue[5], 2);

                          strncpy (RI, &timevalue[8], 2);

                          strncpy (SHI, &timevalue[11], 2);

                          strncpy (FEN, &timevalue[14], 2);

                          strncpy (MIAO, &timevalue[17], 2);

                          

                          Scan (NIAN, "%s>%d", &nian);

                          Scan (YUE, "%s>%d", &yue);

                          Scan (RI, "%s>%d", &ri);

                          Scan (SHI, "%s>%d", &shi);

                          Scan (FEN, "%s>%d", &fen);

                          Scan (MIAO, "%s>%f", &miao);

                          Scan (datavalue, "%s>%f", &data);

                          

                          info.tm_year = nian - 1900;

            info.tm_mon =yue-1;

            in fo.tm_mday = ri;

             info.tm_hour = shi;

             info.tm_min = fen;

             info.tm_sec = miao;

             info.tm_isdst = -1;

ret = mktime(&info)+28800;//格林威治时间换算成北京时间,差8小时

……

3.通过PlotXY函数将图像绘制在Graph控件上

PlotXY函数:绘制数组x相对于另一数组y的曲线图。

函数原型: int PlotXY (int Panel_Handle, int Control_ID, void *X_Array, void *Y_Array, size_t Number_of_Points, int X_Data_Type, int Y_Data_Type, int Plot_Style, int Point_Style, int Line_Style, int Point_Frequency, int Color);

X_Array:沿着x轴绘图的数组变量。

Y_Array:沿着y轴绘图的数组变量。

X_Data_Type:x轴数据类型。

Y_Data_Type:y轴数据类型。

4 显示效果如下:

Labwindows/CVI中时间范围选择部分代码:

……

//起始时间设置

           //设置TimerPicker控件的显示格式

                    MSComCtl2_IDTPickerSetFormat (objecthandle1, NULL, MSComCtl2Const_dtpLongDate);

                    MSComCtl2_IDTPickerSetFormat (objecthandle2, NULL, MSComCtl2Const_dtpTime);

                   

                    //获得当前日期

                    MSComCtl2_IDTPickerGetDay (objecthandle1, NULL, &pvday);

                    

                    //获得当前月份

                    MSComCtl2_IDTPickerGetMonth (objecthandle1, NULL, &pvmonth);

                    

                    //获得当前年份

                    MSComCtl2_IDTPickerGetYear (objecthandle1, NULL, &pvyear);

                    

                    //获得当前的年月日,实际为一个8字节的实型数据,整数部分为年月日,小数部分为时间

                    //该日期是1900-01-01开始计时

                 MSComCtl2_IDTPickerGetValue (objecthandle1, NULL, &pvdatevalue);

                    //获得当前小时

                    MSComCtl2_IDTPickerGetHour (objecthandle2, NULL, &pvhour);

                    //获得当前分钟

                    MSComCtl2_IDTPickerGetMinute (objecthandle2, NULL, &pvminute);

                    //获得当前秒数

                  MSComCtl2_IDTPickerGetSecond (objecthandle2, NULL, &pvsecond);

                    

                    //将VARIANT型数年月日据转换为short型

                    CA_VariantGetShort (&pvyear, &yearvalue);

                    CA_VariantGetShort (&pvmonth, &monthvalue);

                    CA_VariantGetShort (&pvday, &dayvalue);

                    CA_VariantGetShort (&pvhour, &hourvalue);

                   CA_VariantGetShort (&pvminute, &minutevalue);

                    CA_VariantGetShort (&pvsecond, &secondvalue);

                    

                    sprintf (date, "%d-%02d-%02d %02d:%02d:%02d", yearvalue,monthvalue,dayvalue,hourvalue,minutevalue,secondvalue);         

           //终止时间设定

           //设置TimerPicker控件的显示格式

                    MSComCtl2_IDTPickerSetFormat (objecthandle3, NULL, MSComCtl2Const_dtpLongDate);

                    MSComCtl2_IDTPickerSetFormat (objecthandle4, NULL, MSComCtl2Const_dtpTime);

                    

                    //获得当前日期

                    MSComCtl2_IDTPickerGetDay (objecthandle3, NULL, &pvday1);   

                    //获得当前月份

                    MSComCtl2_IDTPickerGetMonth (objecthandle3, NULL, &pvmonth1);

                    //获得当前年份

                    MSComCtl2_IDTPickerGetYear (objecthandle3, NULL, &pvyear1);

      //获得当前的年月日,实际为一个8字节的实型数据,整数部分为年月日,小数部分为时间

                    //该日期是1899-12-31开始计时

               MSComCtl2_IDTPickerGetValue (objecthandle3, NULL, &pvdatevalue1);

                    //获得当前小时

                    MSComCtl2_IDTPickerGetHour (objecthandle4, NULL, &pvhour1);

                    //获得当前分钟

                 MSComCtl2_IDTPickerGetMinute (objecthandle4, NULL, &pvminute1);

                    //获得当前秒数

             MSComCtl2_IDTPickerGetSecond (objecthandle4, NULL, &pvsecond1);   

                   //将VARIANT型数年月日据转换为short型

                    CA_VariantGetShort (&pvyear1, &yearvalue1);

                    CA_VariantGetShort (&pvmonth1, &monthvalue1);

                    CA_VariantGetShort (&pvday1, &dayvalue1);

                    CA_VariantGetShort (&pvhour1, &hourvalue1);

                    CA_VariantGetShort (&pvminute1, &minutevalue1);

                    CA_VariantGetShort (&pvsecond1, &secondvalue1);

                    

                    sprintf (date1, "%d-%02d-%02d %02d:%02d:%02d", yearvalue1,monthvalue1,dayvalue1,hourvalue1,minutevalue1,secondvalue1);

……

通过以上程序可以看到,在LabVIEW及Labwindows/CVI中都可以显示带时间的非均匀的数据。