IO-Warrior 40 unter VB.Net - Kuriosum mit Read-Report switch

Dies ist das deutsche Forum für alle Themen um den IO-Warrior. Beiträge bitte nur in Deutsch.

Moderator: Guido Körber

Post Reply
Leasimo
Posts: 9
Joined: Mon Jan 13, 2014 10:37 pm

IO-Warrior 40 unter VB.Net - Kuriosum mit Read-Report switch

Post by Leasimo »

Guten Abend, wahrscheinlich liegt es schon an der Uhrzeit, dass ich selber keine Antwort für das folgende "Problem" habe:

An meinem IOW-40 habe ich eine 8x8 switch matrix angeschlossen. Durch die Überprüfung mit SimpleHIDWrite weiß ich auch, dass ich die Schalter und Taster alle richtig angeschlossen habe:
WR 18 01 00 00 00 00 00 00
WR 19 00 00 00 00 00 00 00
RD 1A 00 0C 01 40 00 00 00
RD 19 00 00 00 FF 00 00 00

Die Werte in Zeile 3 und 4 entsprechen den tatsächlichen Schalterstellungen.

Mein Kuriosum ist nun, dass ich den folgenden Code in VB.Net wie beschrieben aufbauen muss, um auch die richtige Reihenfolge des Ergebnis in meinem in VB.net geschriebenen Programm zu erzielen:

'......
'liest zuerst die Reihen Y4...Y7 aus:
data(0) = &H19
Result = IowKitRead(iowHandles(x), IOW_PIPE_SPECIAL_MODE, data(0), 8)
If Result <> 8 Then
MsgBox("Irgendwas ist schiefgegangen beim Lesen des zweiten Reports mit Report-ID $1A")
End If
TextBox1.Text = "Y4: (Bin)" & CBinS8(data(1)) & " -> (Hex)" & Hex(data(1)) & vbNewLine & _
"Y5: (Bin)" & CBinS8(data(2)) & " -> (Hex)" & Hex(data(2)) & vbNewLine & _
"Y6: (Bin)" & CBinS8(data(3)) & " -> (Hex)" & Hex(data(3)) & vbNewLine & _
"Y7: (Bin)" & CBinS8(data(4)) & " -> (Hex)" & Hex(data(4)) & vbNewLine

'liest dann erst die Reihen Y0...Y3 aus:
data(0) = &H1A
Result = IowKitRead(iowHandles(x), IOW_PIPE_SPECIAL_MODE, data(0), 8)
If Result <> 8 Then
MsgBox("Irgendwas ist schiefgegangen beim Lesen des ersten Reports mit Report-ID $19")
End If
TextBox2.Text = "Y0: (Bin)" & CBinS8(data(1)) & " -> (Hex)" & Hex(data(1)) & vbNewLine & _
"Y1: (Bin)" & CBinS8(data(2)) & " -> (Hex)" & Hex(data(2)) & vbNewLine & _
"Y2: (Bin)" & CBinS8(data(3)) & " -> (Hex)" & Hex(data(3)) & vbNewLine & _
"Y3: (Bin)" & CBinS8(data(4)) & " -> (Hex)" & Hex(data(4)) & vbNewLine
'....
Das Ergebnis ist optisch dann in Textbox1:
Y4: (Bin)00000000 -> (Hex)0
Y5: (Bin)00001100 -> (Hex)C
Y6: (Bin)00000001 -> (Hex)1
Y7: (Bin)01000000 -> (Hex)40

sowie in Textbox2:
Y0: (Bin)00000000 -> (Hex)0
Y1: (Bin)00000000 -> (Hex)0
Y2: (Bin)00000000 -> (Hex)0
Y3: (Bin)11111111 -> (Hex)FF

Ich muss also mit Report-ID $19 Y4...Y7 abholen bzw. mit Report-ID $1A Y0...Y3. Laut Datenblatt ist es genau anders herum (was ja auch durch SimpleHIDWrite bestätigt wird

Wo liegt denn hier mein Denkfehler? Danke für die Info schon mal im Voraus
Guido Körber
Site Admin
Posts: 2856
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Re: IO-Warrior 40 unter VB.Net - Kuriosum mit Read-Report sw

Post by Guido Körber »

Na schauen Sie doch mal nach wie die ReportIDs aussehen die empfangen werden, dann erklärt sich das ganz schnell.

Tip: Die Zuweisung der gewünschten ReportID in data(0) hat auf das nachfolgende iowKitRead keinen Einfluss.
Leasimo
Posts: 9
Joined: Mon Jan 13, 2014 10:37 pm

Re: IO-Warrior 40 unter VB.Net - Kuriosum mit Read-Report sw

Post by Leasimo »

ok - mit Ihrer Hilfe meine ich verstanden zu haben, dass beim IowKitRead keine Report-ID definiert werden muss bzw. darf. Ausprobiert habe ich dass dann zunächst, indem ich eine MsgBox erstellt habe, die mir ALLE Bits (einschliesslich Bit0 = Report-ID) zurückliest. Auch daraus habe ich nun gelernt.

Nun ergeben sich (leider) weitere Fragen:

1. Ich beobachte, dass grundsätzlich erst der Report mit der $1A und dann $19 zurückgegeben wird. Ist meine Beobachtung korrekt (im Datenblatt wird mir eine andere Reihenfolge suggeriert)?

2. Wenn ich einmal den switchmatrixmode enabled habe, muss ich dies z.B. im Rahmen eines Timers nicht mehr wiederholen, richtig?
Mein Programm habe ich umgestrickt und rufe nun folgende Routine im 50ms-Takt mit einem Timer auf:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Public Sub Lese_SwitchMatrix(ByVal iow_winhandler As Integer)


'Block 1 - fordert direkt den Status der Schalter-Matrix an:
data(0) = &H19
data(1) = &H0

Result = IowKitWrite(iow_winhandler, IOW_PIPE_SPECIAL_MODE, data(0), 8)
If Result <> 8 Then
MsgBox("Irgendwas ist schiefgegangen beim Anfordern der Daten")
End If

'Block 2 - liest zuerst die Reihen Y4...Y7 aus:
Result = IowKitRead(iow_winhandler, IOW_PIPE_SPECIAL_MODE, data(0), 8)
If Result <> 8 Then
MsgBox("Irgendwas ist schiefgegangen beim Lesen des Reports mit Report-ID $1A" & vbLf & "Result: " & Result)
Else
Me.Label1.Text = DateAndTime.TimeString & " / " & CInt(Int((100 * Rnd()) + 1))
End If

TextBox1.Text = _
"Y4: (Bin)" & CBinS8(data(1)) & " -> (Hex)" & Hex(data(1)) & vbNewLine & _
"Y5: (Bin)" & CBinS8(data(2)) & " -> (Hex)" & Hex(data(2)) & vbNewLine & _
"Y6: (Bin)" & CBinS8(data(3)) & " -> (Hex)" & Hex(data(3)) & vbNewLine & _
"Y7: (Bin)" & CBinS8(data(4)) & " -> (Hex)" & Hex(data(4)) & vbNewLine

'Block 3 - liest dann erst die Reihen Y0...Y3 aus (warum auch immer diese Reihenfolge, im Datenblatt wird unter 5.10.7 eine andere Reihenfolge suggeriert
Result = IowKitRead(iow_winhandler, IOW_PIPE_SPECIAL_MODE, data(0), 8)
If Result <> 8 Then
MsgBox("Irgendwas ist schiefgegangen beim Lesen des Reports mit Report-ID $19" & vbLf & "Result: " & Result)
End If

TextBox1.Text = _
"Y0: (Bin)" & CBinS8(data(1)) & " -> (Hex)" & Hex(data(1)) & vbNewLine & _
"Y1: (Bin)" & CBinS8(data(2)) & " -> (Hex)" & Hex(data(2)) & vbNewLine & _
"Y2: (Bin)" & CBinS8(data(3)) & " -> (Hex)" & Hex(data(3)) & vbNewLine & _
"Y3: (Bin)" & CBinS8(data(4)) & " -> (Hex)" & Hex(data(4)) & vbNewLine & TextBox1.Text

End Sub
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

3. Wenn ich beispielsweise 8 Schalter (hängen alle an y3) annähernd gleichzeitig umschalte(oder relativ flott hintereinander umschalte, z.B. binnen 0,5 sec), kann ich im Textfeld beobachten, wie erst innerhalb der nächsten 2-3 Sekunden nach und nach die Bits kippen. Manchmal "verschluckt" sich auch der IOW, und statt unter Y3 werden die Daten dann auf beispielsweise Y6 ausgegeben. Ich habe den Eindruck, dass ganze ist sehr träge (was vermutlich nicht am IOW liegt...)Was mache ich denn da noch falsch?

Danke für Ihre Unterstützung, Gruß Dirk Kaben
Guido Körber
Site Admin
Posts: 2856
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Re: IO-Warrior 40 unter VB.Net - Kuriosum mit Read-Report sw

Post by Guido Körber »

Bei IowKitRead KANN keine ReportID spezifiziert werden, die Funktion liefert einfach den nächsten verfügbaren Report, entweder aus dem Puffer des Systems, oder indem auf den nächsten gewartet wird, wenn der Puffer leer ist.

Die Matrixfunktion muss nur ein mal eingeschaltet werden und sendet dann automatisch Daten wenn sich der Status ändert. Die Abfrage mittels Report $19 ist nur notwendig, wenn man den aktuellen Status auslesen will ohne auf eine Statusänderung zu warten.

50 ms sind eine ungeeignete Zeit, da der IOW alle 8 ms ein Datenpaket schicken kann. Werden mehrere Schalter fast gleichzeitig betätigt, dann ist damit zu rechnen, dass etliche Datenpakete hintereinander kommen. Wenn nur alle 50 ms gelesen wird kann es zu einem Überlauf des Puffers führen, da der IOW die Daten sendet unabhängig davon, ob Ihr Programm die abnimmt. Das dürfte dann das Nachziehen verursachen.

Das Datenblatt macht keine Aussage über die Reihenfolge der Datenpakete. Der Ansatz davon aus zu gehen zu wissen welches Datenpakt ankommt ist falsch, insbesondere da durchaus mal ein Paket verpasst werden kann weil der Puffer im System überläuft. Bei jedem eintreffenden Report muss geprüft werden welcher denn da angekommen ist. Das ist dafür verantwortlich, dass die Tasten auf falschen Positionen erscheinen.
Leasimo
Posts: 9
Joined: Mon Jan 13, 2014 10:37 pm

Re: IO-Warrior 40 unter VB.Net - Kuriosum mit Read-Report sw

Post by Leasimo »

ok, danke für die weiteren Informationen, jetzt ist mir wieder einiges klarer geworden. Ich habe meinen Code wie folgt umgestrickt, und zudem das Timeout des IOW auf 10ms sowie meinen Timer in VB.Net für den im Folgenden aufgeführten Code auch auf 10ms gesetzt. Jetzt kommen alle Schalter knackig zackig ohne für mich erkennbare Verzögerung oder Verschlucken an:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Public Sub Lese_SwitchMatrix(ByVal iow_winhandler As Integer)

Dim Report_Teil1, Report_Teil2 As String
Report_Teil1 = ""
Report_Teil2 = ""

'fordert jetzt den Status der Schalter-Matrix an:
data(0) = &H19
data(1) = &H0

Result = IowKitWrite(iow_winhandler, IOW_PIPE_SPECIAL_MODE, data(0), 8)
If Result <> 8 Then
Me.Label1.Text = DateAndTime.TimeString & " / " & "Daten auslesen nicht möglich"
Else
Me.Label1.Text = DateAndTime.TimeString
End If

'Da man nicht genau weiß, in welcher Reihenfolge die Reports für $19 bzw. $1A kommen,
'wird in einer Schleife solange ausgelesen, bis der Puffer des IO-Warriors leer ist.
Do While Result = 8 '8 gilt nur für den IOW-40, bei anderen IOW ist das entsprechend zu ändern !
Result = IowKitRead(iow_winhandler, IOW_PIPE_SPECIAL_MODE, data(0), 8)

Select Case data(0)
Case &H19
Report_Teil1 = _
"D0: (Bin)" & CBinS8(data(0)) & " -> (Hex)" & Hex(data(0)) & vbNewLine & _
"Y0: (Bin)" & CBinS8(data(1)) & " -> (Hex)" & Hex(data(1)) & vbNewLine & _
"Y1: (Bin)" & CBinS8(data(2)) & " -> (Hex)" & Hex(data(2)) & vbNewLine & _
"Y2: (Bin)" & CBinS8(data(3)) & " -> (Hex)" & Hex(data(3)) & vbNewLine & _
"Y3: (Bin)" & CBinS8(data(4)) & " -> (Hex)" & Hex(data(4)) & vbNewLine
Case &H1A
Report_Teil2 = _
"D0: (Bin)" & CBinS8(data(0)) & " -> (Hex)" & Hex(data(0)) & vbNewLine & _
"Y4: (Bin)" & CBinS8(data(1)) & " -> (Hex)" & Hex(data(1)) & vbNewLine & _
"Y5: (Bin)" & CBinS8(data(2)) & " -> (Hex)" & Hex(data(2)) & vbNewLine & _
"Y6: (Bin)" & CBinS8(data(3)) & " -> (Hex)" & Hex(data(3)) & vbNewLine & _
"Y7: (Bin)" & CBinS8(data(4)) & " -> (Hex)" & Hex(data(4)) & vbNewLine
Case Else
MsgBox("unbekannter Report") 'kann eigentlich nicht vorkommen ;-)
End Select
Loop
TextBox1.Text = Report_Teil1 & Report_Teil2
End Sub
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Ich werde eventuell nochmal mit den Zeiten für das IOW-Read-Timeout und dem Timer(in VB.Net) "Spielen", um ein eventuell auftretendes Prellen eines Schalters oder Tasters zu eliminieren. Bisher habe ich aber dieses Problem (noch) nicht, so dass mein Code für meine Belange zur Zeit einwandfrei funktioniert

Danke nochmal für die Tipps, ich bin jetzt meinem (VB.Net)Projekt wieder einen für mich entscheidenen Schritt weiter gekommen,

Dirk Kaben
Guido Körber
Site Admin
Posts: 2856
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Re: IO-Warrior 40 unter VB.Net - Kuriosum mit Read-Report sw

Post by Guido Körber »

Prellen wird nicht auftreten, der IO-Warrior hat eine Debounce Funktion in der Matrixfunktion. Andernfalls würden die Datenpakete überhand nehmen mit ca. 3-5 pro Tastenbetätigung.
Post Reply