2024年4月19日发(作者:)

锂电池化成系统曲线的绘制与开发

摘 要:阐述了运用VC++6.0对锂电池化成远程控制系统软件中

历史曲线绘制的开发方法及思路,并介绍了有关数据库的设计方法。

采用双缓冲的绘图方式,提高绘图过程中响应速度以及解决了绘图过

程中屏幕闪烁的问题。同时还介绍了如何使用鼠标跟随、键盘跟踪的

方法精确显示曲线上的每一点。对于选择参量多、记录时间较长时,

如果需要观察数据的局部变化趋势,可采用曲线放大功能,使观察数

据变得方便简洁。

关键词:双缓冲;鼠标跟随;键盘跟踪;坐标转换;曲线放大;

MFC绘图

0 引言

数据存储和数据曲线的实现是开发监控软件的重要环节,数据存

储方式的设计对程序的通用性及运行效率具有显著影响,数据曲线包

括实时曲线和历史曲线,实时曲线反映的是监控参数的当前值及变化

趋势,是当前工作状态的直观描述,历史曲线是对存储于数据库中的

历史数据进行图形显示以反映系统在过去一段时间内监测数据的变

化趋势,在研究系统以前工作状态和进行系统故障诊断时具有重要的

作用。在数据判读软件中数据的曲线复现功能应用较广。曲线显示直

观、生动,在时间轴上具有很强的可比性。数据判读时可以使用这项

功能进行设备工作周期判断。在选择参量多,记录时间较长时,如果

需要观察数据的局部变化趋势可以采用曲线放大功能,还应实现坐标

值的重画以配合区域的调整,观察数据变得方便简洁。本文将详细介

绍VC++6.0 环境下实现数据库读取历史数据、历史曲线的绘制方法、

鼠标跟随、键盘跟踪、以及曲线局部放大功能的方法。

1 历史曲线开发要求

历史曲线反映的是过去一段时间内某个或者多个检测点的变

化趋势,并供工艺人员分析工艺流程的稳定性和故障原因,设计时考

虑了以下几个原则:①必须显示对应每一个工位上电池所有的历史数

据;②时间坐标必须根据实际采样点的个数来确定,并以此确定时间

刻度;③当同时显示多根曲线时,注明各自对应的颜色来标识该曲线;

④必须有游标来显示坐标图里的数据采集时间和数据的大小;⑤对于

每一条曲线都具有键盘微调的功能;⑥对于每一个转折点处的曲线具

有放大的功能。

2 关键技术

在绘制历史数据曲线以前,我们需要从设备中获取电池化成过

程中的各项数据,比如:电流,电压,容量以及温度。当我们获得数

据后需要将数据存储到一定的容器中以供绘制曲线的使用,在这里我

们采用SQL Server数据库进行数据的存储,从而达到海量数据的存

储功能。它采用静态结果设计和动态行为设计(应用设计)分离的设计

方式,其中数据库结构设计包括数据需求分析、概念设计、逻辑设计、

物理设计等;数据库动态行为设计包括功能需求分析、功能设计、事

务设计、程序说明、应用程序的设计、调试、运行等。同时它取代文

本文件的存储方式,解决了响应速度过低以及存储容量过少的问

题.

绘制曲线采用双缓冲的绘图模式,双缓冲使用内存缓冲区来解

决由多重绘制操作造成的闪烁问题,当启用双缓冲时,所有绘制操作

首先呈现到内存缓冲区,而不是屏幕上的绘图图面。所有绘制操作完

成后,内存缓冲区直接复制到与其关联的绘图图面。因为在屏幕上只

执行一个图形操作,所以消除了由复杂绘制操作造成的图像闪烁。另

外相比传统的绘图方式,双缓冲绘图模式克服了绘图效率过低的弊

端。

3 详细设计

3.1 读取电池化成过程中的历史数据

数据库访问技术采用微软公司最新的数据库访问技术

ADO(ActiveX Data Objects),ADO是建立旨在OLEDB之上的高层数

据库访问技术,它封装了OLEDB所提供的借口,使用户能够编写应

用程序以通过OLEDB提供者访问和数据库服务器中的数据,由于它

基于组件对象模型,占用内存少,具有易于使用、占用内存少,访问

速度快的特点,得到了大范围的应用。对于本系统,预编译器命令

#import加载在StdAfx.h的头文件中,

#import "C:Program FilesCommon

no_namespace "

rename("EOF","adoEOF")rename("BOF","adoBOF")

导入ADO DLL,进行预编译,产生头文件.tlb 和.dll之后,

* *App::InitInstance()初始化COM环境::CoInitialize(NULL),并进

行连接.然后可以根据输入的查询电池工位号进行数据查询,完成所

有的ADO活动后,还必须在* *App::INitInstance()里关闭初始化COM

环境::CoUninitialize()。

3.2 双缓冲绘制曲线

在绘制曲线时,我们创建一个基于CView的类,在OnDraw(CDC*

pDC)中绘制曲线,当绘制的曲线数据量很大时,绘图可能需要几秒

钟甚至更长的时间,而且有时还会出现闪烁现象,为了解决这些问题,

本文采用双缓冲技术来绘图。

双缓冲即在内存中创建一个与屏幕绘图区域一致的对象,先将

图形绘制到内存中的这个对象上,再一次性将这个对象上的图形拷贝

到屏幕上,这样能大大加快绘图的速度。双缓冲实现过程如下:①在

内存中创建与画布一致的缓冲区;②在缓冲区画图;③将缓冲区位图

拷贝到当前画布上;④释放内存缓冲区。我们可以先在内存中作图,

然后用此函数将做好的图复制到前台,同时禁止背景刷新,这样就消

除了闪烁,实现的程序如下:

OnDraw(CDC *pDC)

CDC MemDC;//首先定义一个显示设备对象

CBitmap MemBitmap;//定义一个位图对象

CompatibleDC(NULL); //建立与屏幕显示兼容的

内存显示设备

Mem Compatible Bitmap(pDC,nWidth,nHeight); //

建立一个与屏幕显示兼容的位图

Cbitmap *pOldBit= Object (& Mem Bitmap); //将

位图选入到内存显示设备中

lidRect(0,0,nWidth,nHeight,RGB(255,255,255)); //

先用背景色将位图清除干净

//绘图

(……);

(……);

pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY); //将

内存中的图拷贝到屏幕上进行显示

//绘图完成后的清理

Object(pOldBit);

Object();

DC();

}

3.3 鼠标跟随

由于绘制的曲线数据量偏大,为了满足客户可以随时看到采样

过程中的数据,因此我们做了鼠标跟随功能。在OnMouseMove(UINT

nFlags,CPoint point) 消息响应函数中,鼠标移动时,不断更新移动中

鼠标的位置,同时将point赋值给全局变量m_mousepoint,同时不断

地更新视图调用Invalidate()函数,在OnDraw(CDC *pDC)中计算此点

的逻辑坐标DPtoLP(),并查询相应的历史数据,画出鼠标跟随光标,

(m_mousepoint.x,m_top);//m_top为绘制波形矩

形框的顶端

(m_mousepoint.x,m_bottom);//m_bottom)为绘制波

形矩形框的底端

此后显示该采样时刻的数据,流程图如下:

图1 鼠标跟随流程

3.4 键盘跟踪

当数据量偏大,我们操作鼠标不容易精确跟随窗口中的每一

个采样点的值时,我们可以采用键盘操作的方式进行微调,进而使曲

线上的每一个点能够准确的呈现在用户面前。在OnKeyDown(UINT

nChar,UINT nRepCnt,UINT nFlags) 消息响应函数中,我们捕获键盘

按下的消息,

if (nChar==VK_DOWN||nChar==VK_PRIOR)//查看此时刻采

样点的前一个采样数据,并将此信息传递给OnDraw(CDC *pDC)中进

行响应

if (nChar==VK_UP||nChar==VK_NEXT)//查看此时刻采样点的

下一个采样数据,并将此信息传递给OnDraw(CDC *pDC)中进行响应

获取了键盘消息之后将消息传递给OnDraw(CDC *pDC)函数,进

行鼠标跟随光标的重绘以及显示相应点的历史数据值。其流程图如下

所示:

3.5 曲线的局部放大功能

曲线显示直观、生动,在时间轴上具有很强的可比性,数据判

读软件在数据判读时可以使用这项功能进行设备工作周期判读,在选

择变量多、记录时间较长时,如果需要观察数据的局部变化趋势,可

以采用曲线放大功能,还应该事先坐标值的重画以配合区域的调整,

观察数据变得方便简洁。

图2 键盘操作流程

3.5.1 曲线放大的原理介绍

绘制曲线的基本原则如下首先要为曲线建立两个坐标轴,其次

要将参数映射成坐标系上的点,最后将点依次相连形成曲线。对于数

据复现曲线来说X 轴(横轴)一般为时间(s) 起始和终止点为所选中数

据段的开始和结尾,Y 轴(纵轴)的零点和极点为所选曲线的最小值和

最大值。具体的实现方法如下:

Y 轴:确定鼠标的起始点(m_startpoint)和终止点(m_endpoint)后,

为Y 轴设立放大系数(ymagnify)以及最大和最小值

ymagnify=()/(m_endpoint.y-m_startpoint.y);

rect为放大前的矩形框,为放大前矩形框的底端,

为放大前矩形框的顶端.

Y轴的最大值和最小值计算方法:

最大值=m_startpoint.y/()*yscale;

最小值=m_endpoint.y/()*yscale;yscale为窗口带单位的

坐标高度。

X 轴:同样为X 轴设立放大系数,其计算公式如下

xmagnify=()/(m_endpoint.x-m_startpoint.x);

,分别为放大前矩形框的右端和左端。

X轴的最大值和最小值计算方法:

最大值=m_startpoint.x/()*xscale;

最小值=m_endpoint/()*xscale;xscale为窗口带单位的坐

标宽度

坐标变化:设转换前波形中某点的坐标为(oldx,oldy),则

newx=(oldx-X轴最小值)/(X轴最大值-X轴最小值)*窗口的屏幕宽度;

newy=(oldy-Y轴最小值)/(Y轴最大值-Y轴最小值)*窗口的屏幕高度;

3.5.2 设计算法的流程图

3.5.3 功能演示

实际应用中,曲线输出以后选择放大曲线功能左键按下点为

m_startpoint,到达指定的区域后左键弹起,点为m_endpoint ,在选定区

域后系统自动进行全部曲线与坐标轴的重绘。

4 结束语

该功能模块主要完成了在工业监控软件中,需要实时查看在

过程反应当中不同时刻的数据,通过曲线取代报表的形式呈现给现场

操作人员,让他们能够及时发现存在问题的设备,从而大大提高他们

的工作效率。本文的重难点是曲线放大过程中参数的修改,只要参数

修改得正确完成预定的功能就较为简单,在确定位置时,为了多次放

大在每次起始与结尾的位置都使用数组进行保留,将获得的数据写入

数组尾部,其次是要注意数值与比例系数放大系数之间的关系,尤其

是纵坐标的变化。通过实际应用表明该方法确实简洁方便,实用性强。

参考文献:

[1] 邱仲潘,柯渝,谢燕华.Visual C++6从入门到精通[M].北

京:电子工业出版社,2005.

[2] 候俊杰.深入浅出MFC(第2版)[M].武汉:华中科技大

学出版社,2005.

[3] 辛长安,王彦国.Visual C++权威剖析——MFC的原理、机

制与开发实例[M].北京:清华大学出版社,2008.