LabwindowsCVI 波形显示介绍及事例

       波形相对于数值而言,其更能直观描述数值的大小及变化趋势,有利于工程师排查问题,标定最优参数。本章将介绍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模式:

 

 

  • 4
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值