|
在大型的工业现场控制中,一般用DCS(集散控制系统)来实现过程控制。在DCS中,实时曲线可显示该控制点的当前趋势,以监测该点在现场工况变化的情况下的控制稳定性,历史曲线可观察过去一段时间内某一点的变化趋势,并供工艺人员分析工艺流程的稳定性和故障原因。然而在小型的工业控制中,由于控制规模小,控制回路少,因此可用PC机就能完成整个过程控制,在实时曲线和历史曲线方面,可用VB4.0就能实现,并可与大型的DCS相媲美。 [实时曲线] 实时曲线反映的是现场数据的实时性和当前趋势,因此在实现时需显示曲线的动态变化,参考DCS,当前点在曲线的最右端显示,而整个曲线动态地向左移动。
具体实现如下: 1、选择需要显示的窗体Form1,加入图片框Picture1,根据实际需要设置图片的大小并移到合适的位置,并在图片的外面画好量程----时间坐标系; 2、在全局模块中定义位块传输API函数BitBlt()和全局变量: DeclareFunctionBitBltLib"GDI32"(ByValhDestDCASLong,ByValXAsLong,ByValYAsLong,ByValnWidthAsLong,ByValnHeightAsLong,ByValhSrcDCAsLong,ByValxSrcAsLong,ByValySrcAsLong,ByValDrawStyleAsLong)AsLong GobalSAsLong`量程 GobalLAsLong`上一次的纵坐标值 GobalTAsInteger`上一次时间值(分) 3、PrivateSubForm1_Load() Picture1.AutoRedraw=False`曲线不重画 Picture1.ScaleMode=3`以象素方式(Pixel) L=-1`设置初值 S=400 T=-1 EndSub 4、根据现场数据采集的采样频率,设置定时器Timer1的定时值,曲线移动就 在 Timer1实现: PrivateSubTimer1_Time() DimwAsLong,hAsLong,y1AsLong,DataAsLong DimhBmpAshDC,ShowModeAsLong,iiAsLong,t1AsInteger w=Picture1.Width h=Picture1.Height hBmp=Picture1.hDC ShowMode=&HCC0020`ROP模式(复制) Data=Get_RealDatabase()`从实时数据库取当前监控值 y1=(S-Data)/S*h`根据量程转变成具体坐标 ii=BitBlt(hBmp,0,0,w-1,h,hBmp,1,0,ShowMode)`整个曲线右移一个像素点 Picture1.Line(w-1,y)-(w,y1),RGB(0,255,0) y=y1 t1=Val(Mid$(Time$,3,2)) IfT<>t1Then`在曲线下方显示时间(用分表示) Picture1.CurrentX=w-16 Picture1.CurrentY=h-8 Picture1.PrintMid$(Time$,1,5) T=t1 EndIf EndSub [历史曲线] 历史曲线反映的是过去一段时间内某个监测点的变化趋势,其曲线走向是从左向右方向发展的,与实时曲线走向正好相反。由于历史数据库保存的时间长,一般为一个月、三个月或者更长,因此其数据量特别大,在实现时只能显示其中的一段曲线,而不能在图片上一次画好,否则其显示速度将非常慢。
具体实现如下: 1、 在窗体Form2中加入图片框Picture2,在图片框的下方加入四个按钮,分别为曲线右移4小时按钮Command1、曲线右移8小时按钮Command2、曲线左移4小时按钮Command3和曲线左移8小时按钮Command4。 2、设历史曲线一分钟存储一个数据,并设一个像素点画一小段直线,因此对于8小时的曲线,图片的宽度为480Pixel,而对于4个小时的曲线,则两个像素点画一小段直线,具体设置如下: Picture2.ScaleMode=3:Picture2.AutoRedraw=False Picture2.Width=480:Picture2.Height=120 3、在窗体级变量中定义以下变量: DimSAsLong`被测点的量程 DimFileNoAsLong`历史数据库的记录号 DimHtimeAsDate`被测点对应的历史时间 4、PrivateSubForm2_Load() t$=FileDateTime("C:\HDB\HistoryData.dat")`获得历史数据库存储时间 Htime=TimeValue(Mid$(t$,Len(t$)-8,8)) Open"C:\HDB\HistoryData.dat"ForRandomAs#1Len=4 `打开历史数据库, 每个记录存放一个单精度数 S=400`设置量程 EndSub 5、PrivateSubCommand1_Click() `曲线右移4个小时 DimwAsLong.HAsLong,IAsLong,jAsLong Dimy1AsLong,y2AsLong,yAsSingle Picture2.Picture=LoadPicture("")`清曲线 w=Picture2.Width h=Picture2.Height Picture2.Line(0,0)-(w-1,h-20-1),RGB(127,127,127),B`用灰色在图片上 画网格 ForI=1To4 Picture2.Line(0,I*20)-(w-1,I*20),RGB(127,127,127) NextI ForI=1To7 Picture2.Line(I*60,0)-(I*60,h-20-1),RGB(127,127,127) NextI y1=-1 I=0 j=0 DoWhileNotEOF(#1)ANDI<w Get#1,y y2=(S-y)/S*h`根据量程转换为具体坐标值 Ify1<>-1Then Picture2.Line(I,y1)-(I 2,y2),RGB(0,255,0)`用绿色画曲线 I=I 2 y1=y2 EndIF j=j 1 Ifj=60Then'显示时间(用小时显示) Htime=TimeValue(Htime) TimeValue("01:00:00") j=0 Picture2.CurrentX=I-10 Picture2.CurrentY=h-20 Picture2.PrintHour(Htime) EndIf EndDo FileNo=Seek(#1)`获得历史数据库的记录号 EndSub 6、PrivateSubCommand3_Click() `曲线左移4个小时 DimwAsLong.HAsLong,IAsLong,jAsLong Dimy1AsLong,y2AsLong,yAsSingle Picture2.Picture=LoadPicture("")`清曲线 w=Picture2.Width h=Picture2.Height Picture2.Line(0,0)-(w-1,h-20-1),RGB(127,127,127),B`用灰色在图片上 画网格 ForI=1To4 Picture2.Line(0,I*20)-(w-1,I*20),RGB(127,127,127) NextI ForI=1To7 Picture2.Line(I*60,0)-(I*60,h-20-1),RGB(127,127,127) NextI y1=-1 I=0 j=0 IfFileNo>240Then`记录指针往前移240个记录 FileNo=FileNo-240 Seek#1,FileNo Htime=TimeValue(Htime)-TimeValue("04:00:00")`时间左移4个小时 EndIf DoWhileNotEOF(#1)ANDI<w Get#1,y y2=(S-y)/S*h Ify1<>-1Then Picture2.Line(I,y1)-(I 2,y2),RGB(0,255,0)`用绿色画曲线 I=I 2 y1=y2 EndIF j=j 1 Ifj=60Then'显示时间(用小时显示) Htime=TimeValue(Htime) TimeValue("01:00:00") j=0 Picture2.CurrentX=I-10 Picture2.CurrentY=h-20 Picture2.PrintHour(Htime) EndIf EndDo FileNo=Seek(#1)`获得历史数据库的记录号 EndSub 至于曲线左移8小时和右移8小时,可以参考上述的方法,在画两点之间的直线时,以一个像素点为一小段直线,这里不一一举例。->
|
| |
|