赞
踩
波形相对于数值而言,其更能直观描述数值的大小及变化趋势,有利于工程师排查问题,标定最优参数。本章将介绍LabwindowsCVI对波形控件的支持。LabwindowsCVI共支持3种Graph控件,分别为Graph、Strip Chart、Digital Graph控件。
Graph控件:
Graph控件比较适合于一次画许多数据的曲线,不是很适合连续往曲线上继续添加波形(需要自己写额外的代码将波形接续上),其可添加光标进行数据测量,并可以将曲线以坐标轴的方式进行放大和缩小。
Strip Chart控件:
Strip Chart控件比较适合多条曲线的连续绘图,可以显示或隐藏每条波形数据,但不可以添加光标测量数据。Strip Chart有3种波形显示模式,分别是SWEEP、CONTINUOUS、BLOCK,读者可以在随后的测试程序中体验这3种模式的区别。
Digital Graph:
Digital Graph适合数字电平信号的绘图。
本章主要介绍Strip Chart控件的使用,其主要API如下所示:
PlotStripChart:
PlotStripChart用于往Strip Chart控件上添加波形数据,其函数原型如下所示:
int PlotStripChart (int panelHandle, int controlID, void *yArray, size_t numberOfPoints, int startingIndex, int skipCount, int yDataType);
其中panelHandle为控件所在的panel,controlID为Strip Chart控件的ID,yArray为添加的数据波形,numberOfPoints为添加数据的大小,startingIndex为yArray第一个数据的索引,skipCount为忽略数据的计数,yDataType为添加数据的格式。
SetTraceAttribute:
SetTraceAttribute用于设置波形的属性,其函数原型如下所示:
int SetTraceAttribute (int panelHandle, int controlID, int traceNumber, int traceAttribute, int attributeValue);
其中panelHandle为控件所在的panel,controlID为Strip Chart控件的ID,traceNumber为要设置的波形索引,traceAttribute为要设置的属性名称,attributeValue为属性值。
SetAxisRange:
SetAxisRange用于设置波形显示窗口的坐标大小,其函数原型如下所示:
int SetAxisRange (int panelHandle, int controlID, int xAxisScaling, double xminXinit, double xmaxXinc, int yAxisScaling, double ymin, double ymax);
其中panelHandle为控件所在的panel,controlID为Strip Chart控件的ID,xAxisScaling为X轴缩放模式的选择,xminXinit对Strip Chart控件为X轴的初始值,xmaxXinc对Strip Chart控件为每添加一个数据点,X轴增加的值,yAxisScaling为Y轴缩放模式的选择,ymin为Y轴的最小值,ymax为Y轴的最大值。
项目实践:
新建一个LabwindowsCVI工程,往主面板添加一个Strip Chart控件,编写程序使该控件能显示两条随机数据的波形,其工程代码如下所示:
#include <windows.h>
#include "toolbox.h"
#include <utility.h>
#include <ansi_c.h>
#include <cvirte.h>
#include <userint.h>
#include "GraphTest.h"
static int panelHandle;
CmtThreadFunctionID backgroundThreadFunctionID;
volatile int AppRunningFlag = 0;
CmtThreadPoolHandle threadPoolHandle;
char errorStringBuffer[256];
int CVICALLBACK BackgroundThreadFunction (void *functionData);
int CreateBackgroundThread(void)
{
int ret = -1;
ret = CmtNewThreadPool (1, &threadPoolHandle);
if(ret < 0)
{
CmtGetErrorMessage(ret,errorStringBuffer);
printf("%s\r\n",errorStringBuffer);
}
else
{
ret = CmtScheduleThreadPoolFunctionAdv(threadPoolHandle,BackgroundThreadFunction,NULL,THREAD_PRIORITY_HIGHEST,NULL,EVENT_TP_THREAD_FUNCTION_END,NULL,RUN_IN_SCHEDULED_THREAD,&backgroundThreadFunctionID);
if(ret < 0)
{
CmtGetErrorMessage(ret,errorStringBuffer);
printf("%s\r\n",errorStringBuffer);
}
}
return ret;
}
int QuitBackgroundThread(void)
{
CmtWaitForThreadPoolFunctionCompletion(threadPoolHandle,backgroundThreadFunctionID,OPT_TP_PROCESS_EVENTS_WHILE_WAITING);
return 0;
}
int QueryTickPeriod(LARGE_INTEGER *begin,LARGE_INTEGER *end,LONGLONG tick)
{
if(end->QuadPart >= begin->QuadPart)
{
if((end->QuadPart - begin->QuadPart) >= tick)
{
return 1;
}
else
{
return 0;
}
}
else
{
if((0xFFFFFFFFFFFFFFFF - begin->QuadPart + end->QuadPart) >= tick)
{
return 1;
}
else
{
return 0;
}
}
}
void Task1ms(void)
{
static int cnt =0;
if(cnt >= 1000)
{
printf("1s count\r\n");
cnt = 0;
}
else
{
cnt ++;
}
}
double yData[3*100];
int CVICALLBACK BackgroundThreadFunction (void *functionData)
{
LARGE_INTEGER begin, end, ticksPerSecond;
LONGLONG tickPeriod;
AppRunningFlag = 1;
QueryPerformanceFrequency (&ticksPerSecond);
tickPeriod = ticksPerSecond.QuadPart/10;//可修改tick的周期值
while(AppRunningFlag)
{
QueryPerformanceCounter (&begin);
QueryPerformanceCounter (&end);
while(QueryTickPeriod(&begin,&end,tickPeriod) == 0)
{
QueryPerformanceCounter (&end);
}
yData[0] = 10.0 + Random(-5.0,5.0);
yData[1] = 50.0 + Random(-5.0,5.0);
yData[2] = 80.0 + Random(-5.0,5.0);
PlotStripChart(panelHandle,PANEL_STRIPCHART,yData,3,0,0,VAL_DOUBLE);
}
return 0;
}
void InitStripChartControl(void)
{
SetCtrlAttribute(panelHandle,PANEL_STRIPCHART,ATTR_POINTS_PER_SCREEN,100); //设置每屏数据显示的数目
SetCtrlAttribute (panelHandle, PANEL_STRIPCHART, ATTR_SCROLL_MODE, VAL_BLOCK); //设置Strip Chart显示模式
SetCtrlAttribute (panelHandle, PANEL_STRIPCHART, ATTR_NUM_TRACES, 2);//设置显示的波形数目
SetTraceAttribute (panelHandle, PANEL_STRIPCHART, 1, ATTR_TRACE_COLOR, VAL_RED);//设置波形颜色
SetTraceAttribute (panelHandle, PANEL_STRIPCHART, 2, ATTR_TRACE_COLOR, VAL_GREEN);
SetTraceAttribute (panelHandle, PANEL_STRIPCHART, 1, ATTR_TRACE_VISIBLE, 1);//设置波形是否可见
SetTraceAttribute (panelHandle, PANEL_STRIPCHART, 2, ATTR_TRACE_VISIBLE, 1);
SetTraceAttribute (panelHandle, PANEL_STRIPCHART, 1, ATTR_TRACE_LG_VISIBLE, 1);//设置波形说明是否可见
SetTraceAttribute (panelHandle, PANEL_STRIPCHART, 2, ATTR_TRACE_LG_VISIBLE, 1);
SetTraceAttribute (panelHandle, PANEL_STRIPCHART, 1, ATTR_TRACE_LG_TEXT,"Line1");//设置波形说明字符
SetTraceAttribute (panelHandle, PANEL_STRIPCHART, 2, ATTR_TRACE_LG_TEXT,"Line2");
}
int main (int argc, char *argv[])
{
if (InitCVIRTE (0, argv, 0) == 0)
return -1; /* out of memory */
if ((panelHandle = LoadPanel (0, "GraphTest.uir", PANEL)) < 0)
return -1;
DisplayPanel (panelHandle);
InitStripChartControl();
CreateBackgroundThread();
RunUserInterface ();
QuitBackgroundThread();
DiscardPanel (panelHandle);
return 0;
}
int CVICALLBACK quit (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_COMMIT:
QuitUserInterface(0);
AppRunningFlag = 0;
break;
}
return 0;
}
int CVICALLBACK AppSetLineDisplay (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
int onOffFlag = 0;
GetCtrlVal(panel,control,&onOffFlag);
switch (event)
{
case EVENT_COMMIT:
switch(control)
{
case PANEL_LINE1_ONOFF:
SetTraceAttribute (panelHandle,PANEL_STRIPCHART, 1, ATTR_TRACE_VISIBLE, onOffFlag);
break;
case PANEL_LINE2_ONOFF:
SetTraceAttribute (panelHandle,PANEL_STRIPCHART, 2, ATTR_TRACE_VISIBLE, onOffFlag);
break;
}
break;
}
return 0;
}
int CVICALLBACK AppSetAxisValue (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
int xsize = 0;
double ymax =0.0;
double ymin = 0.0;
switch (event)
{
case EVENT_COMMIT:
switch(control)
{
case PANEL_Y_MAX:
GetCtrlVal(panel,PANEL_Y_MAX,&ymax);
GetCtrlVal(panel,PANEL_Y_MIN,&ymin);
SetAxisRange(panelHandle,PANEL_STRIPCHART,VAL_NO_CHANGE,0,0,VAL_MANUAL,ymin,ymax);
break;
case PANEL_Y_MIN:
GetCtrlVal(panel,PANEL_Y_MAX,&ymax);
GetCtrlVal(panel,PANEL_Y_MIN,&ymin);
SetAxisRange(panelHandle,PANEL_STRIPCHART,VAL_NO_CHANGE,0,0,VAL_MANUAL,ymin,ymax);
break;
case PANEL_X_SIZE:
GetCtrlVal(panel,PANEL_X_SIZE,&xsize);
SetCtrlAttribute(panelHandle,PANEL_STRIPCHART,ATTR_POINTS_PER_SCREEN,xsize);
break;
}
break;
}
return 0;
}
int CVICALLBACK AppSetMode (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
int modeValue = 0;
switch (event)
{
case EVENT_COMMIT:
GetCtrlVal(panel,control,&modeValue);
if(modeValue == 0)
{
SetCtrlAttribute (panelHandle, PANEL_STRIPCHART, ATTR_SCROLL_MODE, VAL_SWEEP);
}
else if(modeValue == 1)
{
SetCtrlAttribute (panelHandle, PANEL_STRIPCHART, ATTR_SCROLL_MODE, VAL_CONTINUOUS);
}
else if(modeValue == 2)
{
SetCtrlAttribute (panelHandle, PANEL_STRIPCHART, ATTR_SCROLL_MODE, VAL_BLOCK);
}
break;
}
return 0;
}
项目效果:
运行该工程程序,可以看到,Strip Chart控件实时显示2条随机数据的波形,如下图所示:
单击Line1显示或Line2显示,可以看到Line1或Line2隐藏或显示,比如去掉Line1显示,Line1就不显示了,如下图所示:
可修改Y轴的最大值、最小值和X轴大小,如下所示:
可以修改Strip Chart控件波形显示模式,如下所示:
Block模式:
Sweep模式:
Continuous模式:
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。