作为一个非专业人员,开发一个测试系统时遇到了问题,请大家赐教!
本人是刚开始用vb.net,被搞的焦头烂额。请大家一定帮忙,回复请尽量清楚,因为我是菜鸟一个。
我在写一个自动数据采集数据,用的是NI的visa库。
具体工作流程如下:多数时间里,我每隔100ms读取设备1的数据并画图,这部分我是用timer实现的。
同时设备2会会每间隔一段时间发出一个触发信号,我希望捕捉这个触发信号并触发一个事件,在这个时间中读设备2的一些状态字,来确定是否继续读设备1。当遇到设备2产生特殊事件时,要及时停止程序。 现在问题是,设备2运转慢时,即设备2的触发信号间隔比较长时,我可以捕捉到设备2 的停止状态信号,但是,当设备2运转快时,好像就没办法捕捉到停止信号了。以下是代码。请帮我看看,该如何改进?
主程序中:
ZTsession是一个ni Visa 的设备对象。。。。
AddHandler ZTSession.ServiceRequest, AddressOf OnServiceRequest ‘安装事件触发
ZTSession.EnableEvent(MessageBasedSessionEventType.ServiceRequest, EventMechanism.Handler) ’触发使能
ScanStopFlag = 0
Timer1.Start() ‘设备1的读数与绘图程序使能
触发事件程序OnServiceRequest 如下:
Private Sub OnServiceRequest(ByVal sender As Object, ByVal e As MessageBasedSessionEventArgs)
Dim ZTRSQByte As Byte
Dim responsstring As String
'当设备2 有事件触发响应时,首先读取设备2 的状态字,并进行判断,遇到某些状态时,执行对应的处理,
'其中最主要的处理是停止Timer1的tick
'并使用全局变量ScanStopFlag 来记录是何种情况。
''但貌似当触发很快’‘时,timer会捕捉”停止状态“的变化,或者说不响应Call Clearstop_Rastscan()!
'但是,如果在每个Call Clearstop_Rastscan()前下断点,就能保证Call Clearstop_Rastscan()被执行,这说明设备2是送出了状态字的。只是因为线程的某些原因,无断点时,Call似乎被跳过了??
ZTRSQByte = ZTSession.ReadStatusByte() ’读设备2 状态字
If (ZTRSQByte And 64) = 0 Then Exit Sub
If ZTRSQByte And 128 Then
responsstring = ZTSession.ReadString(22)
End If
Select Case ZTRSQByte
Case Is = 80
ScanStopFlag = 2
Call Clearstop_Rastscan()
MsgBox("测试中止,结果未保存")
Case Is = 81
ScanStopFlag = 3
Call Clearstop_Rastscan()
MsgBox("可能测试中止,结果未保存")
Case Is = 82
ScanStopFlag = 4
Call Clearstop_Rastscan()
MsgBox("可能测试中止,结果未保存")
Case Is = 83
Case Is = 84
Case Is = 88
ScanStopFlag = 1
scan_suceed_Flag = True ‘ 正常的结束
Case Is = 92 '正常状态
AngleIncrease_i = AngleIncrease_i + 1
Case Is = 93
ScanStopFlag = 6
Case Is = 94
ScanStopFlag = 7
Case Is = 220 '另外一种正常状态
AngleIncrease_i = AngleIncrease_i + 1
End Select
End Sub
其中,需要停止时,调用的Clearstop_Rastscan()函数如下:
Private Sub Clearstop_Rastscan()
Dim toclear As Byte
Timer1.Stop() '停止计时器
’对设备的一些其他操作,略去。。。
mbSession.Clear()
mbSession.Dispose() ' 释放设备1
PictureBox1.Enabled = True
PictureBox2.Enabled = False
GroupBox8.Enabled = True
STOPFLAG = True
End Sub
Timer的函数如下:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Static finished As Boolean = True
Dim scanpoint As Integer
Dim RECval As Single
Dim realpart As Double, imgpart As Double
Dim scanstoppoint As Single
Dim Thisrunstop As Boolean = False, Unkownstop As Integer = 0
Dim nowP As Single
Dim i As Integer
Dim Ydata() As Single
Dim filepath As String
Dim ZTcondition(5) As Byte
Dim toclear As Byte
scanstoppoint = Val(Scanstop.Text)
If STOPFLAG Then ‘这是手动点击停止按键时的处理。
ZTSession.DisableEvent(MessageBasedSessionEventType.ServiceRequest, EventMechanism.Handler)
PictureBox1.Enabled = True
mbSession.Dispose()
PictureBox2.Enabled = False
GroupBox8.Enabled = True
Timer1.Stop()
MsgBox("测试被提前中止,请等待彻底停止")
ZTSession.Dispose()
Else
If finished Then '如果timer1的间隔内完成了读数画图
finished = False
scanpoint = Math.Abs((Scanstart.Text - Scanstop.Text) / Scanstep.Text) + 1
ReDim Ydata(scanpoint - 1)
Dim tempt As New Stopwatch
Dim weishu As Integer
Select Case scanpoint * 8
Case Is >= 100000
weishu = 6
Case Is >= 10000
weishu = 5
Case Is >= 1000
weishu = 4
Case Is >= 100
weishu = 3
Case Is >= 10
weishu = 2
Case Is >= 1
weishu = 1
End Select
Dim aaa(8 * scanpoint + weishu + 2) As Byte
TChart1.AutoRepaint = True
RadationPT.Clear() '清除当前数据
mbSession.Write(ReplaceCommonEscapeSequences("CALCulate:DATA? SDATA\n"))
tempt.Start()
aaa = mbSession.ReadByteArray(8 * scanpoint + weishu + 3)
Dim scanstartv As Single, scanstepv As Single
Dim tempx As Single
scanstartv = Scanstart.Text
scanstepv = Scanstep.Text * Math.Sign(Scanstop.Text - Scanstart.Text)
For i = 0 To (scanpoint - 1)
realpart = System.BitConverter.ToSingle(aaa, i * 8 + weishu + 2)
imgpart = System.BitConverter.ToSingle(aaa, i * 8 + weishu + 6)
RECval = realpart * realpart + imgpart * imgpart
RECval = 10 * Math.Log10(RECval)
Ydata(i) = RECval
Next
RadationPT.Add(Sectormod1_Xdata, Ydata) ' 执行到此处时,Tchart理应自动更新绘图了。
My.Application.DoEvents() ‘这里是使用的Tchart,此处等待是为了界面上更新绘图。
finished = True
End If
' 没有点停止!,确定设备2 的状态是否正常完成,如已经正常完成,也停止所有操作。
If scan_suceed_Flag Then
Timer1.Stop() '停时间触发
MsgBox("测试成功结束,结果已经存入文件")
’此处已经省略其他文件操作
STOPFLAG = True '停止计时器
PictureBox1.Enabled = True
ZTSession.DisableEvent(MessageBasedSessionEventType.ServiceRequest, EventMechanism.Handler)
'停止设备2的事件触发
ZTSession.Dispose()
mbSession.Dispose()
PictureBox2.Enabled = False
GroupBox8.Enabled = True
scan_suceed_Flag = False
End If
End If
End Sub
可能程序有点乱,希望大家能耐心帮我看看。。
重复一下我的问题,说白了,就是设备2的事件触发来的比较频繁时,不能正常的判断设备2 的状态,并响应 Clearstop_Rastscan()函数。。
------解决思路----------------------
看你的程序,首先并不知道是如何触发事件程序OnServiceRequest的,从表面看timer倒是定时触发的
------解决思路----------------------
是不是可以开多一个线程,将设备2的timmer的间隔足够短就可以了呢
------解决思路----------------------
你都没用线程,Timer还是在同一个线程里边,还是一步一步执行的。。。
也可以异步委托啊