|
> はい。とりあえずインターフェースのを買いました。
> 確かに、インターフェースのはイベントがありまして、それを使用しようかと
> 考えました。ところが、純粋なデジタルI/OではなくFA用ネットワーク用で
> 同様に使用したいボードがありまして、それはイベントが無いんです。
> なので、インターフェースのも同様にスレッドでやりたいなって考えました。
型式は?
私はボードに関連してインターフェース社のサイトからGPC-2000を入手し
IFCDIOクラス(これを.NET用と言われると困る)を作り直して、使ってま
す。
レベル信号なので、その信号の立ち上がりエッジだけを監視すると言う事
ですが、高精度と言う意味合いであれば、ノイズって大丈夫?とお聞きし
たい。PLCとかの信号であれば、100msくらいの1ショット信号を監視し
て・・・みたいなこともできますが。
私の自作IFCDIOクラスの一部(スレッドのところ)を参考に載せておきま
す。ほかの部分との兼ね合いもありますが、流用して下さい。
(VB.NETです)
2種類のスレッドがありますが、何をどうしているのかは・・・
解読して(推測して)みて下さい。Win32 APIも使ってます。
因みに、TimerThreadの方は、ボードのタイマーイベントを使って機能する
コールバック的なスレッドとなってます。
#Region "Private Thread"
Private Sub MonitorThread(ByVal obj As Object)
Dim dwEventBuf As Integer
Dim Overlapped As OVERLAPPED
Dim bRet As Boolean
Dim iRet As Integer
Dim dtBuff() As Integer
Dim dtBit() As Boolean
Dim dtBak() As Boolean
Dim BitCount As Integer
bMonitorJob = True
BitCount = DirectCast(obj, Integer)
ReDim dtBuff(BitCount - 1)
ReDim dtBit(BitCount - 1)
ReDim dtBak(BitCount - 1)
For i As Integer = 0 To BitCount - 1
dtBak(i) = False
Next
Overlapped = New OVERLAPPED()
With Overlapped
.hEvent = CreateEvent(0, True, False, 0)
.Internal = 0
.InternalHigh = 0
.offset = 0
.OffsetHigh = 0
End With
RaiseEvent MonitorError(MONITOR_ERROR.MonitorStart)
While bMonitorJob
iRet = DioEventRequestPending(hDevice, &H10, dwEventBuf, Overlapped)
If iRet <> FBIDIO_ERROR_IO_PENDING Then
RaiseEvent MonitorError(MONITOR_ERROR.EventRequesError)
bMonitorJob = False
Exit While
End If
If bMonitorJob = False Then
Exit While
End If
iRet = WaitForSingleObject(Overlapped.hEvent, TimeoutInterval)
If iRet = 0 Then
iRet = DioInputPoint(hDevice, dtBuff, 1, BitCount)
If iRet <> 0 Then
RaiseEvent MonitorError(MONITOR_ERROR.InputPointError)
Else
For i As Integer = 0 To BitCount - 1
If dtBuff(i) <> 0 Then
dtBit(i) = True
dtNow(i) = True
Else
dtBit(i) = False
dtNow(i) = False
End If
Next
bRet = False
For i As Integer = 0 To BitCount - 1
If dtBit(i) <> dtBak(i) Then
bRet = True
End If
Next
If bRet Then
For i As Integer = 0 To BitCount - 1
dtBak(i) = dtBit(i)
Next
RaiseEvent ChangeBit(dtBit, BitCount)
End If
End If
Else
RaiseEvent MonitorError(MONITOR_ERROR.WaitError)
bMonitorJob = False
Exit While
End If
End While
iRet = DioSetIrqMask(hDevice, &H0)
If iRet <> 0 Then
RaiseEvent MonitorError(MONITOR_ERROR.MaskResetError)
End If
CloseHandle(Overlapped.hEvent)
RaiseEvent MonitorError(MONITOR_ERROR.MonitorStop)
End Sub
Private Sub TimerThread(ByVal obj As Object)
Dim dwEventBuf As Integer
Dim Overlapped As OVERLAPPED
Dim iRet As Integer
Dim dtBuff() As Integer
Dim dtBit() As Boolean
Dim BitCount As Integer
bTimerJob = True
BitCount = DirectCast(obj, Integer)
ReDim dtBuff(BitCount - 1)
ReDim dtBit(BitCount - 1)
Overlapped = New OVERLAPPED()
With Overlapped
.hEvent = CreateEvent(IntPtr.Zero, True, False, String.Empty)
.Internal = 0
.InternalHigh = 0
.offset = 0
.OffsetHigh = 0
End With
RaiseEvent MonitorError(MONITOR_ERROR.MonitorStart)
While bTimerJob
iRet = DioEventRequestPending(hDevice, &H10, dwEventBuf, Overlapped)
If iRet <> FBIDIO_ERROR_IO_PENDING Then
RaiseEvent MonitorError(MONITOR_ERROR.EventRequesError)
bTimerJob = False
Exit While
End If
If bTimerJob = False Then
Exit While
End If
iRet = WaitForSingleObject(Overlapped.hEvent, TimeoutInterval)
If iRet = 0 Then
iRet = DioInputPoint(hDevice, dtBuff, 1, BitCount)
If iRet <> 0 Then
RaiseEvent MonitorError(MONITOR_ERROR.InputPointError)
Else
For i As Integer = 0 To BitCount - 1
If dtBuff(i) <> 0 Then
dtBit(i) = True
dtNow(i) = True
Else
dtBit(i) = False
dtNow(i) = False
End If
Next
RaiseEvent TimerEvent(dtBit, BitCount)
End If
Else
RaiseEvent MonitorError(MONITOR_ERROR.WaitError)
bTimerJob = False
Exit While
End If
End While
iRet = DioSetIrqMask(hDevice, &H0)
If iRet <> 0 Then
RaiseEvent MonitorError(MONITOR_ERROR.MaskResetError)
End If
CloseHandle(Overlapped.hEvent)
Overlapped = Nothing
ReDim dtBit(-1)
ReDim dtBuff(-1)
RaiseEvent MonitorError(MONITOR_ERROR.MonitorStop)
End Sub
#End Region
以上。
|