welche programmiersprache/readimmediate mit vb6 geht nicht
Moderator: Guido Körber
-
- Posts: 55
- Joined: Thu Apr 15, 2004 11:23 pm
- Contact:
welche programmiersprache/readimmediate mit vb6 geht nicht
hey!
ich habe den iow 40 bisher mit vb6 betrieben, bin aber auf das problem der blockierenden lesezugriffe (oder wie das heisst) gestossen.
ich hatte schon seit längerem die idee, eine neue programmiersprache zu lernen, und fand da visual c++.net interessant. ist es möglich, den iow40 damit anzusteuern? wäre da das problem der blockierung gelöst?
es wäre echt hilfreich, hier etwas orientierung zu haben
thx!!
ich habe den iow 40 bisher mit vb6 betrieben, bin aber auf das problem der blockierenden lesezugriffe (oder wie das heisst) gestossen.
ich hatte schon seit längerem die idee, eine neue programmiersprache zu lernen, und fand da visual c++.net interessant. ist es möglich, den iow40 damit anzusteuern? wäre da das problem der blockierung gelöst?
es wäre echt hilfreich, hier etwas orientierung zu haben
thx!!
Last edited by formatc1702 on Tue Mar 22, 2005 12:58 am, edited 1 time in total.
-
- Posts: 55
- Joined: Thu Apr 15, 2004 11:23 pm
- Contact:
hey!
ja das mit readimmediate hatte ich schonmal probiert, aber da ist manchmall irgendwie alles schiefgegengen. wenn man schnell hintereinander mehrere pins verändert hat und dann auf den ursprungszustand gesetzt hat (ich habs mit schaltern gemacht), dann kam plötzlich ein anderer wert raus...
falls jemand einen fertigen vb code mit readimmediate hat wäre ich sehr dankbar, da ich da selber nicht zurechtkomme
ja das mit readimmediate hatte ich schonmal probiert, aber da ist manchmall irgendwie alles schiefgegengen. wenn man schnell hintereinander mehrere pins verändert hat und dann auf den ursprungszustand gesetzt hat (ich habs mit schaltern gemacht), dann kam plötzlich ein anderer wert raus...
falls jemand einen fertigen vb code mit readimmediate hat wäre ich sehr dankbar, da ich da selber nicht zurechtkomme
Die Funktion IowKitReadImmediate finde ich auch ein wenig verwirrend (mit VB). Problem scheint zu sein, das es hierfür kein Sample gibt.
War mehrfach zu lesen das ReadImmediate True zurückgibt wenn am Interface 0 neue Daten anliegen.
Das konnte ich leider mit VB nicht nachvollziehen. Der Long-Wert den die Funktion zurückgibt entspricht dem Zustand der Pins. Jedenfalls Werte ich einiger Taster mittels dieser Rückgabe aus und das klappt auch wunderbar.
Falls das falsch sein sollte: wie wendet man diese Function richtig an?
War mehrfach zu lesen das ReadImmediate True zurückgibt wenn am Interface 0 neue Daten anliegen.
Das konnte ich leider mit VB nicht nachvollziehen. Der Long-Wert den die Funktion zurückgibt entspricht dem Zustand der Pins. Jedenfalls Werte ich einiger Taster mittels dieser Rückgabe aus und das klappt auch wunderbar.
Falls das falsch sein sollte: wie wendet man diese Function richtig an?
-
- Posts: 55
- Joined: Thu Apr 15, 2004 11:23 pm
- Contact:
Klar poste ich gerne einen Beispielcode mit meiner Lösung.
Ich bin mir zwar nicht sicher ob die Funktion im Sinne der Erfinder benutzt wird, es ist aber die einzige Lösung die ich gefunden habe. Mir ist nicht ganz klar wo genau ich ein True finde wenn neue Daten anliegen (und wie neue Daten definiert sind).
Api-Funnktions Deklaration
In einer Timerprocedur:
Bisher hat das immer ganz gut geklappt auf diesem Wege.
Edit: Ich werte die ByRef übergebene Long-Variable aus (im ersten Posting hatte ich was von Rückgabewert geschrieben).
Ich bin mir zwar nicht sicher ob die Funktion im Sinne der Erfinder benutzt wird, es ist aber die einzige Lösung die ich gefunden habe. Mir ist nicht ganz klar wo genau ich ein True finde wenn neue Daten anliegen (und wie neue Daten definiert sind).
Api-Funnktions Deklaration
Code: Select all
Private Declare Sub CopyMemory Lib "kernel32" Alias _
"RtlMoveMemory" (Destination As Any, Source As Any, _
ByVal Length As Long)
Code: Select all
Dim lng_res As Long
Dim lng_buffer As Long
Dim i As Integer
Dim by_arr(3) As Byte
lng_res = IowKitReadImmediate(iowHandle, lng_buffer)
CopyMemory by_arr(0), lng_buffer, 4&
Debug.Print
For i = 0 To 3: Debug.Print CStr(i) & ": " & Hex(by_arr(i)): Next i
Debug.Print Hex(lng_res)
Edit: Ich werte die ByRef übergebene Long-Variable aus (im ersten Posting hatte ich was von Rückgabewert geschrieben).
-
- Posts: 543
- Joined: Mon Dec 01, 2003 6:09 pm
...und wenn jetzt lng_res nicht 0 (= False) ist, dann gab es neue Daten.
Das Basismissverstaendnis ist wohl die Darstellung von True und False in VB und anderen Programmiersprachen.
In VB ist es -1 und 0, waehrend C ungleich 0 und 0 verwendet. Delphi beutzt 1 und 0, kann aber auch mit LongBool wie C arbeiten.
Das Basismissverstaendnis ist wohl die Darstellung von True und False in VB und anderen Programmiersprachen.
In VB ist es -1 und 0, waehrend C ungleich 0 und 0 verwendet. Delphi beutzt 1 und 0, kann aber auch mit LongBool wie C arbeiten.
-
- Posts: 55
- Joined: Thu Apr 15, 2004 11:23 pm
- Contact:
hey!
ja der code klappt jetzt auch ganz gut, nur eine sache ist noch komisch:
ich habe den iow40, und da ist ja neben dem chip ein taster. wenn ich den drücke/loslasse ändert sich der wert aber nicht! er ist an p 0.0 angeschlossen, und da sitzt nix anderes dran. ich dachte das könnte am lcd teil liegen, aber auch ohne es funzt es nicht...
2. frage: ich habe mir den wert von lng_res ausgeben lassen, und konnte aber nicht feststellen, dass da ein besonderer wert rauskommt, wenn sich nicts verändert hat, geschweige denn -1, was ja bei longs überhaupt nicht geht oder
ich dachte mir man könnte so etwas realisieren (noch ganz abstrakt gedacht):
ich weiss aber nicht ob das zu viel systemressourcen schlucken würde. jedoch hätte ich hier nicht das problem mit dem timer, dass sehr kurze änderungen nicht bemerkt werden (schnelles drücken der tasten)
was meint ihr dazu? lohnt es sich, es so zu machen oder wat?
ich finde immer noch die delphi hacker hier im forum sollten eine dll schreiben, die in vb6 funzt und einen EVENT hat, der eintritt, wenn neue daten da sind
, etwas ganz einach handhabbares
wäre cool wenn das einer machen könnte
ja der code klappt jetzt auch ganz gut, nur eine sache ist noch komisch:
ich habe den iow40, und da ist ja neben dem chip ein taster. wenn ich den drücke/loslasse ändert sich der wert aber nicht! er ist an p 0.0 angeschlossen, und da sitzt nix anderes dran. ich dachte das könnte am lcd teil liegen, aber auch ohne es funzt es nicht...
2. frage: ich habe mir den wert von lng_res ausgeben lassen, und konnte aber nicht feststellen, dass da ein besonderer wert rauskommt, wenn sich nicts verändert hat, geschweige denn -1, was ja bei longs überhaupt nicht geht oder
ich dachte mir man könnte so etwas realisieren (noch ganz abstrakt gedacht):
Code: Select all
do while not varProgBeenden ' die variable setze ich am ende =true
newValue=ausgelesenerWert
if oldValue<>newValue then ' nur print wenn neuer wert da ist
debug.print newValue
oldValue=newValue
end if
loop
was meint ihr dazu? lohnt es sich, es so zu machen oder wat?
ich finde immer noch die delphi hacker hier im forum sollten eine dll schreiben, die in vb6 funzt und einen EVENT hat, der eintritt, wenn neue daten da sind
Code: Select all
Sub iowNewValue(iowHandle as long, newData as long)
wäre cool wenn das einer machen könnte
Hallo
"Neue Daten" sollten ja vorliegen wenn ein IowKitRead durchgeführt wurde und der Zustand der Pins sich danach ändert (oder seh ich da was falsch).?
Das funktioniert aber leider nicht. Ein IOWKitRead führt sogar dazu das man IowKitReadImmediate nicht mehr richtig benutzen kann.
Kleines Beispiel (Form mit 2 Command Buttons)
Code ausführen und
- Command2-Klick für IOWKitRead.(Daten sollten nun neu sein)
- Command1- Klick für IowKitReadImmediate.
lng_res liefert nun immer 1. Die ByRef übergebene Variable lng_buffer hat den Wert 0.
Nun kann man sich an dem kleinen Taster neben dem Chip richtig verausgaben - ein IowKitReadImmediate liefert immer das obige Ergebnis. IOWKitRead bleibt hängen, weil anscheinend doch keine neuen Daten anliegen.
@formatc
Evtl. nicht sauber gelötet oder ein IOWKitRead gemacht (s.o.)? Taste länger drücken?
Um Verwirrungen vorzubeugen: Auch in VB hat der Datentyp Long einen negativen Wertebereich.
Warum keinen Timer? Der vbTimer ist zwar nicht sonderlich genau, hat als kleinste Aufösung aber 1ms. Wenn ich mich nicht täusche ist der IOW langsamer.
mfg FlitzPin
sowas in der Richtung dachte ich mir ja. Leider hat lng_res nie den Wert 0....und wenn jetzt lng_res nicht 0 (= False) ist, dann gab es neue Daten.
"Neue Daten" sollten ja vorliegen wenn ein IowKitRead durchgeführt wurde und der Zustand der Pins sich danach ändert (oder seh ich da was falsch).?
Das funktioniert aber leider nicht. Ein IOWKitRead führt sogar dazu das man IowKitReadImmediate nicht mehr richtig benutzen kann.
Kleines Beispiel (Form mit 2 Command Buttons)
Code: Select all
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias _
"RtlMoveMemory" (Destination As Any, Source As Any, _
ByVal Length As Long)
Dim iowHandle As Long
Private Sub Command1_Click()
Dim lng_res As Long
Dim lng_buffer As Long
Dim i As Integer
Dim by_arr(3) As Byte
lng_res = IowKitReadImmediate(iowHandle, lng_buffer)
CopyMemory by_arr(0), lng_buffer, 4&
Debug.Print
For i = 0 To 3: Debug.Print CStr(i) & ": " & Hex(by_arr(i)): Next i
Debug.Print lng_res,
If lng_res <> 0 Then Debug.Print "Neue Daten !!"; Else Debug.Print ; "Keine neuen Daten"
End Sub
Private Sub Command2_Click()
Dim res As Long
Dim data(4)
' Perform a read
' Don't forget that we read report ID too
' So we have 5 bytes buffer
' Turn off all LEDs
' Unmask all input lines
' first byte is report ID
data(0) = &O0
' first report byte
data(1) = &HFF
' second report byte
data(2) = &HFF
' third report byte
data(3) = &HFF
' fourth report byte
data(4) = &HFF
' Write to IO-Warrior
Dim nWritten As Long
nWritten = IowKitWrite(iowHandle, 0, data(0), 5)
' Handle error
If (nWritten <> 5) Then
' You can use GetLastError() to get error code
MsgBox "Can not set input mask!", 0, "Error"
Exit Sub
End If
' After this write, all input lines are unmasked
' Set caption
' Read from IO-Warrior
res = IowKitRead(iowHandle, 0, data(0), 5)
' Check results
If (res <> 5) Then
Debug.Print "error"
Else
' Convert and set data
Debug.Print Hex$(data(1))
Debug.Print Hex$(data(2))
Debug.Print Hex$(data(3))
Debug.Print Hex$(data(4))
Debug.Print "Read from IOW complete"
End If
End Sub
Private Sub Form_Load()
iowHandle = IowKitOpenDevice()
End Sub
- Command2-Klick für IOWKitRead.(Daten sollten nun neu sein)
- Command1- Klick für IowKitReadImmediate.
lng_res liefert nun immer 1. Die ByRef übergebene Variable lng_buffer hat den Wert 0.
Nun kann man sich an dem kleinen Taster neben dem Chip richtig verausgaben - ein IowKitReadImmediate liefert immer das obige Ergebnis. IOWKitRead bleibt hängen, weil anscheinend doch keine neuen Daten anliegen.
@formatc
Sollte mit und ohne LCD klappen, da ja das Interface 0 abgefragt wird. Gedrückt ist arr(0)=&hFE, nicht gedrückt arr(0)=&hFF.ich habe den iow40, und da ist ja neben dem chip ein taster. wenn ich den drücke/loslasse ändert sich der wert aber nicht! er ist an p 0.0 angeschlossen, und da sitzt nix anderes dran. ich dachte das könnte am lcd teil liegen, aber auch ohne es funzt es nicht...
Evtl. nicht sauber gelötet oder ein IOWKitRead gemacht (s.o.)? Taste länger drücken?
Um Verwirrungen vorzubeugen: Auch in VB hat der Datentyp Long einen negativen Wertebereich.
Warum keinen Timer? Der vbTimer ist zwar nicht sonderlich genau, hat als kleinste Aufösung aber 1ms. Wenn ich mich nicht täusche ist der IOW langsamer.
mfg FlitzPin
-
- Posts: 55
- Joined: Thu Apr 15, 2004 11:23 pm
- Contact:
hey!
den code muss ich noch ausprobieren, melde mich dann wieder
{edit}: hmm da kommt immer 1 raus egal ob ich command2 drücke oder nicht.
der richtige wert, der ausgelesen sollte ist bei mir im moment:
FF FF FF 7F
mit iowkit read gehts auch, es blockiert halt.
in deinem code steht erst:
FF FF FF 7F , das stimmt auch, aber leider ändert sich der wert für p0 nicht, egal welchen port ich auf masse setze. alle anderen ports gehen
danach steht noch
bei lng_res stehen die werte ja genau umgekehrt, erst p3 und am ende p0, also sollte 7FFFFFFF erscheinen, bei mir steht da aber 7FFFFF01 wo kommt die 07 her?
diese fehler treten nur mit readimmediate auf, mit iowkitread geht alles, wenn auch blockierend. jetzt muss man nur noch das beste aus beiden welten vereinen (also richtige werte ohne zu blockieren)
ist der fehler jetzt beim iowarrior, bei dir oder bei mir????
tja gelötet ist alles ordentlich, und manchmal passiert es auch bei längerem drücken. iowkitread habe ich in meinen letzten experimenten ganz vermieden...Evtl. nicht sauber gelötet oder ein IOWKitRead gemacht (s.o.)? Taste länger drücken?
hmm was verbraucht denn mehr ressourcen? eine endlosschleife mit do...loop oder ein timer mit 1ms... ich habe gelesen dass die eigentliche geschwindigkeit nicht unter 55ms kommen kann. im prinzip ist die geschwindigkeit kein grosses problem, es ist nur eine frage der performance-einbussen.Warum keinen Timer? Der vbTimer ist zwar nicht sonderlich genau, hat als kleinste Aufösung aber 1ms. Wenn ich mich nicht täusche ist der IOW langsamer.
den code muss ich noch ausprobieren, melde mich dann wieder
{edit}: hmm da kommt immer 1 raus egal ob ich command2 drücke oder nicht.
der richtige wert, der ausgelesen sollte ist bei mir im moment:
FF FF FF 7F
mit iowkit read gehts auch, es blockiert halt.
in deinem code steht erst:
Code: Select all
For i = 0 To 3: Debug.Print CStr(i) & ": " & Hex(by_arr(i)): Next i
danach steht noch
Code: Select all
Debug.Print Hex(lng_res)
diese fehler treten nur mit readimmediate auf, mit iowkitread geht alles, wenn auch blockierend. jetzt muss man nur noch das beste aus beiden welten vereinen (also richtige werte ohne zu blockieren)
ist der fehler jetzt beim iowarrior, bei dir oder bei mir????
IowKitReadImmediate muss natürlich ausgeführt werden wenn der Taster gedrückt ist. Wenn es nur manchmal klappt, einfach mal den Taster durchmessen. Bei mir klappt das gut.tja gelötet ist alles ordentlich, und manchmal passiert es auch bei längerem drücken
Zu dem Ergebnis bin ich auch gekommen. ;)iowkitread habe ich in meinen letzten experimenten ganz vermieden...
Gute Frage. Zumindest wenn in dem Do Loop noch DoEvents und Sleep vorkommen. Die Unterschiede sind aber nicht allzu gross. Sprich: Auf meinem alten K6-III kann ich kaum einen Ressourcenverauch erkennen.hmm was verbraucht denn mehr ressourcen? eine endlosschleife mit do...loop oder ein timer mit 1ms
Noch eine andere Idee auf die Du mich gebracht hast: Mithilfe der API- Funktion SetTimer in einem VB-Klassenmodul IowKitReadImmediate ausführen. Dort dann mittels der Daten in lng_buffer bestimmen ob diese Daten neu sind. Wenn ja, dann ein Event auslösen.
Vor dem Programmstart einmal kurz den USB-Stecker ziehen.....hmm da kommt immer 1 raus egal ob ich command2 drücke oder nicht
bei lng_res stehen die werte ja genau umgekehrt, erst p3 und am ende p0, also sollte 7FFFFFFF erscheinen, bei mir steht da aber 7FFFFF01 wo kommt die 07 her?
Wenn lng_Res <> 0 ist, sollten theoretisch neue Daten vorliegen.
Da ich das nicht nachvollziehen kann, werte ich nur lng_buffer aus und ignoriere die Daten in lng_res fleissig.
-
- Posts: 55
- Joined: Thu Apr 15, 2004 11:23 pm
- Contact:
hey!
ich bin irgendwie ziemlich verwirrt, was read und readimmediate angeht. ich hab kein plan mehr, was by_arr(x), lng_buffer und lng_res machen, ich blick einfach nicht mehr durch.
was ich geil fände wäre eine dll, die read und write funktionen, sowie lcd usw. ganz einfach verwaltet, ohne viele variablen und sowas. also muss ich das ganze zeug mal wirklich kapieren und dann setze ich mich vielleicht mal dran.
wenn ich es schaffe, read und readimmediate zu kapieren und da was schreibe, sag ich hier bescheid, kann aber noch ne weile dauern
{edit}: hab was zu klassenmodulen gefunden und festgestellt, das die ja in der dll sind wenn man ein dll projekt startet und hab nun ne frage: angenommen ich lese mit einer methode der dll normal mit iowkitread. blockiert dann nur die dll oder das ganze programm? dann mach ich vielleicht eine dll zum lesen (die dann ruhig blockieren darf) und eine zum schreiben und lcd-zeug machen. ist zwar vielleicht nicht besonders elegant aber wenns funktioniert?
mit der api-function timeSetEvent könnte man das teil abfragen, und in der api-guide steht:
ich hoffe, ihr könnt meinem gedankengang noch halbwegs folgen
von klassenmodulen habe ich so gut wie null ahnung, ich weiss nich was die bringen, wann/wie man sie einsetzt und überhaupt...Noch eine andere Idee auf die Du mich gebracht hast: Mithilfe der API- Funktion SetTimer in einem VB-Klassenmodul IowKitReadImmediate ausführen. Dort dann mittels der Daten in lng_buffer bestimmen ob diese Daten neu sind. Wenn ja, dann ein Event auslösen.
auch keine so tolle lösung oder?Vor dem Programmstart einmal kurz den USB-Stecker ziehen.....
ich bin irgendwie ziemlich verwirrt, was read und readimmediate angeht. ich hab kein plan mehr, was by_arr(x), lng_buffer und lng_res machen, ich blick einfach nicht mehr durch.
was ich geil fände wäre eine dll, die read und write funktionen, sowie lcd usw. ganz einfach verwaltet, ohne viele variablen und sowas. also muss ich das ganze zeug mal wirklich kapieren und dann setze ich mich vielleicht mal dran.
wenn ich es schaffe, read und readimmediate zu kapieren und da was schreibe, sag ich hier bescheid, kann aber noch ne weile dauern
{edit}: hab was zu klassenmodulen gefunden und festgestellt, das die ja in der dll sind wenn man ein dll projekt startet und hab nun ne frage: angenommen ich lese mit einer methode der dll normal mit iowkitread. blockiert dann nur die dll oder das ganze programm? dann mach ich vielleicht eine dll zum lesen (die dann ruhig blockieren darf) und eine zum schreiben und lcd-zeug machen. ist zwar vielleicht nicht besonders elegant aber wenns funktioniert?
mit der api-function timeSetEvent könnte man das teil abfragen, und in der api-guide steht:
dann geht es doch im selben projekt oder der selben dll wie fürs schreiben, wenn man mit timeSetEvent blockierend liest..The timeSetEvent function starts a specified timer event. The multimedia timer runs in its own thread. After the event is activated, it calls the specified callback function or sets or pulses the specified event object.
ich hoffe, ihr könnt meinem gedankengang noch halbwegs folgen
-
- Posts: 55
- Joined: Thu Apr 15, 2004 11:23 pm
- Contact:
hey!
ich habe gerade ein experiment mit der timeSetEvent-api gemacht und es klappt (fast) alles. es ist eine modifizierte version von iowsample.vbp (aus der sdk), mit einem zusätzlichen button zum lesen. Es klappt auch wunderbar, bis auf:
> wenn man einen wert SCHREIBT, macht er das auch, aber in der iowkitread funktion steht ja erst, dass irgendwas geschrieben wird, und zwar FFFFFFFF. wenn man schreibt, ändert man ja die port-werte. dadurch wird iowkitread ausgefürht und es schreibt wieder den ausgangszustand.
wozu sind die write-commands im read-befehl eigentlich? kann man die weglassen? dann wär ja alles gut! würde die lcd funktion unter meinem aufbau leiden? (habe ich noch nicht probiert).
meinen sourcecode gibts hier:
http://home.arcor.de/formatc1702/misc/iowsamplenew.zip
schaut es euch mal an und sagt mir was ihr davon haltet. aus irgendeinem grund kollabiert ganz vb wenn man das programm schliesst ohne nach abschalten des auto-read modus noch einmal die port-werte zu ändern, da krieg ich aber noch was hin, im zweifelsfall einfach nochmal was auf die ports schreiben dann geht das schon
ich habe gerade ein experiment mit der timeSetEvent-api gemacht und es klappt (fast) alles. es ist eine modifizierte version von iowsample.vbp (aus der sdk), mit einem zusätzlichen button zum lesen. Es klappt auch wunderbar, bis auf:
> wenn man einen wert SCHREIBT, macht er das auch, aber in der iowkitread funktion steht ja erst, dass irgendwas geschrieben wird, und zwar FFFFFFFF. wenn man schreibt, ändert man ja die port-werte. dadurch wird iowkitread ausgefürht und es schreibt wieder den ausgangszustand.
wozu sind die write-commands im read-befehl eigentlich? kann man die weglassen? dann wär ja alles gut! würde die lcd funktion unter meinem aufbau leiden? (habe ich noch nicht probiert).
meinen sourcecode gibts hier:
http://home.arcor.de/formatc1702/misc/iowsamplenew.zip
schaut es euch mal an und sagt mir was ihr davon haltet. aus irgendeinem grund kollabiert ganz vb wenn man das programm schliesst ohne nach abschalten des auto-read modus noch einmal die port-werte zu ändern, da krieg ich aber noch was hin, im zweifelsfall einfach nochmal was auf die ports schreiben dann geht das schon
hi
Dein Soucecode schau ich mir mal an. Mit der von Dir verwendeten Api-Funktion hatte ich bisher auch noch keinen Umgang.
Habe gestern auch nochmal geschaut wie man das mit der Klasse realisieren kann und es klappt soweit auch mit dem Event. Code poste ich morgen
Sollte auch nur bei diesem Beispiel so sein. Um aufzuzeigen das die Aufrufe den IOW durcheinanderbringen. Ansonsten gehts auch ohne wenn man nur mit readimmediate arbeitet.Quote:
Vor dem Programmstart einmal kurz den USB-Stecker ziehen.....
auch keine so tolle lösung oder?
Kenn ich sowas. Ich mach dann immer die Kaffeemaschine an. ;)ich bin irgendwie ziemlich verwirrt, was read und readimmediate angeht. ich hab kein plan mehr, was by_arr(x), lng_buffer und lng_res machen, ich blick einfach nicht mehr durch.
Dein Soucecode schau ich mir mal an. Mit der von Dir verwendeten Api-Funktion hatte ich bisher auch noch keinen Umgang.
Habe gestern auch nochmal geschaut wie man das mit der Klasse realisieren kann und es klappt soweit auch mit dem Event. Code poste ich morgen
Die Api-Funktion ist nicht schlecht. Leider macht einem hier das Read auch wieder ein Strich durch die Rechnung. Solange Read hängt existiert auch der Thread - was in dem Fall ein Absturz beim Beenden zur Folge hat.
Hier ist mein Code.
Bedienen lässt sich das relativ einfach.
- Mit den Funktionen StartScan und StopScan (im Modul) startet, bzw. stoppt man den Timer.
- Sobald eine Zustandsänderung an den Pins vorliegt wird das Ereignis clsIOWRI_NewData ausgelöst. Die 4 Parameter (Byte) geben den Zustand der Ports wieder.
- Mit clsIOWRI.IgnorePort(x)=true/false kann man Einstellen ob eine Zustansänderung an Port X ignoriert werden soll. D.h. Es wird kein Ereignis ausgelöst.
- Über PortX=clsIOWRI.LastValue(X) kommt man an den letzten ausgelesenen Wert von Port Nr. X.
- Mittels der Public-deklarierten Variable hTimer kann man bestimmen ob der Timer läuft.
Hinweis: Das Programm in der Entwicklungsumgebung mit dem "schliessen-Kreuz" der Form beenden, damit StopScan ausgelöst wird und der Timer gekillt wird. Ansonsten Absturz.
Formular (Form1)
Modul:
clsIOWRI (Klassenmodul)
Leider kann man den die API-Timer-Procedur nicht in einer Klasse unterbringen. Deswegen der
Umweg über das Modul. clsIOWRI muss deshalb auch als Public deklariert sein (und das in einer Form wegen Withevents).
Kompiliert habe ich das nicht ausprobiert, aber in der IDE verbraucht es kaum Ressourcen.
Der Intervall steht übrigens auf 10 ms.
Bis die neue SDK fertig ist müssen wir uns halt mit dem gefrickel abfinden ;).
Nochmal ne Frage an die Experten: Was wäre den ein sinnvoller (minimaler) Intervall?
So long...
Hier ist mein Code.
Bedienen lässt sich das relativ einfach.
- Mit den Funktionen StartScan und StopScan (im Modul) startet, bzw. stoppt man den Timer.
- Sobald eine Zustandsänderung an den Pins vorliegt wird das Ereignis clsIOWRI_NewData ausgelöst. Die 4 Parameter (Byte) geben den Zustand der Ports wieder.
- Mit clsIOWRI.IgnorePort(x)=true/false kann man Einstellen ob eine Zustansänderung an Port X ignoriert werden soll. D.h. Es wird kein Ereignis ausgelöst.
- Über PortX=clsIOWRI.LastValue(X) kommt man an den letzten ausgelesenen Wert von Port Nr. X.
- Mittels der Public-deklarierten Variable hTimer kann man bestimmen ob der Timer läuft.
Hinweis: Das Programm in der Entwicklungsumgebung mit dem "schliessen-Kreuz" der Form beenden, damit StopScan ausgelöst wird und der Timer gekillt wird. Ansonsten Absturz.
Formular (Form1)
Code: Select all
Option Explicit
Public WithEvents clsIOWRI As clsIOWRI
Private Sub clsIOWRI_NewData(Port0 As Byte, Port1 As Byte, Port2 As Byte, Port3 As Byte)
Debug.Print Hex(Port0), Hex(Port1), Hex(Port2), Hex(Port3)
End Sub
Private Sub Form_Load()
IOWHandle = IowKitOpenDevice()
Set clsIOWRI = New clsIOWRI
clsIOWRI.IgnorePort(3) = True 'Wenn sich die Daten an Port3 ändern wird kein Ereignis ausgelöst
StartScan 'Startet den API-Timer
'X=clsIOWRI.OldValue (X)'Zum Bestimmen des letzten Wertes
End Sub
Private Sub Form_Unload(Cancel As Integer)
StopScan
IowKitCloseDevice (IOWHandle)
Set clsIOWRI = Nothing
End Sub
Code: Select all
Private Declare Function SetTimer Lib "user32" (ByVal hWnd As _
Long, ByVal nIDEvent As Long, ByVal uElapse As Long, _
ByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib "user32" (ByVal hWnd As _
Long, ByVal nIDEvent As Long) As Long
Public IOWHandle As Long
Public hTimer As Long 'Wenn hTimer <> 0 dann läuft der Scan
Public Sub TimerProc(ByVal hWnd&, ByVal Msg&, ByVal idEvent&, ByVal _
dwTime&)
Dim lng_buffer As Long
IowKitReadImmediate IOWHandle, lng_buffer
Form1.clsIOWRI.CheckData (lng_buffer)
End Sub
Public Sub StartScan()
hTimer = SetTimer(0, 0, 10, AddressOf TimerProc) '
End Sub
Public Sub StopScan()
Call KillTimer(0, hTimer)
hTimer = 0
End Sub
Code: Select all
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias _
"RtlMoveMemory" (Destination As Any, Source As Any, _
ByVal Length As Long)
Dim mbln_IngnorePort(3) As Boolean
Dim mbln_FirstRun As Boolean
Dim marr_byOldValue(3) As Byte
Public Event NewData(Port0 As Byte, Port1 As Byte, Port2 As Byte, Port3 As Byte)
Property Get LastValue(Port As Integer) As Byte
'Letzter Ausgelesener Wert auf PortX (ReadOnly)
If Port > 3 Or Port < 0 Then Exit Property
LastValue = marr_byOldValue(Port)
End Property
Property Let IgnorePort(Port As Long, IgnoreEnabled As Boolean)
'Neue Werte auf PortX ignorieren(=kein Ereignis auslösen bei ValueChange)
If Port > 3 Or Port < 0 Then Exit Property
mbln_IngnorePort(Port) = IgnoreEnabled
End Property
Property Get IgnorePort(Port As Long) As Boolean
'Neue Werte auf PortX ignorieren(=kein Ereignis auslösen bei ValueChange)
If Port > 3 Or Port < 0 Then Exit Property
IgnorePort = mbln_IngnorePort(Port)
End Property
Public Sub CheckData(data As Long)
Dim lng_buffer As Long
Dim i As Integer
Dim by_arr(3) As Byte
Dim bln_NewValue As Boolean
CopyMemory by_arr(0), data, 4&
'Auf neuen Wert prüfen
For i = 0 To 3
If mbln_IngnorePort(i) = False Then
If marr_byOldValue(i) <> by_arr(i) Then bln_NewValue = True
End If
Next i
'NewValue=OldValue
For i = 0 To 3: marr_byOldValue(i) = by_arr(i): Next i
'Prüfen ob erster Durchlauf
If mbln_FirstRun = True Then
mbln_FirstRun = False
Exit Sub
End If
'Wenn neue Daten -> Ereignis auslösen
If bln_NewValue = True Then
bln_NewValue = False
RaiseEvent NewData(by_arr(0), by_arr(1), by_arr(2), by_arr(3))
End If
End Sub
Private Sub Class_Initialize()
Dim i As Integer
For i = 0 To 3: mbln_IngnorePort(i) = False: Next i
mbln_FirstRun = True
End Sub
Umweg über das Modul. clsIOWRI muss deshalb auch als Public deklariert sein (und das in einer Form wegen Withevents).
Kompiliert habe ich das nicht ausprobiert, aber in der IDE verbraucht es kaum Ressourcen.
Der Intervall steht übrigens auf 10 ms.
Bis die neue SDK fertig ist müssen wir uns halt mit dem gefrickel abfinden ;).
Nochmal ne Frage an die Experten: Was wäre den ein sinnvoller (minimaler) Intervall?
So long...