Abfrage serielle Schnittstelle
Moderator: Moderatoren
- Rudolf
- Programmier-Gott
- Beiträge: 1418
- Registriert: Mo, 02. Jan 2006 23:03
- Wohnort: Salzburg/Österreich
- Kontaktdaten:
Abfrage serielle Schnittstelle
Hallo,
suche eine Lösung für das Einlesen von Daten über die serielle Schnittstelle und sofortige Auslösung eines Events o.ä. Ich muss für ein Bonierungssystem den Kellnerschlüssel seriell abfragen bzw. auf einen seriellen Kartenleser reagieren. Die Reaktion vom System sollte sehr schnell sein, daher müsste ich die Schnittstelle in einem anderen Thread ständig abfragen. Finde die Lösung aber nicht sehr elegant.
Ideal wäre ein AcitveX Control, welches eine Ereignis auslöst.
Hat jemand schon Erfahrung damit ?
Grüsse
Rudolf
suche eine Lösung für das Einlesen von Daten über die serielle Schnittstelle und sofortige Auslösung eines Events o.ä. Ich muss für ein Bonierungssystem den Kellnerschlüssel seriell abfragen bzw. auf einen seriellen Kartenleser reagieren. Die Reaktion vom System sollte sehr schnell sein, daher müsste ich die Schnittstelle in einem anderen Thread ständig abfragen. Finde die Lösung aber nicht sehr elegant.
Ideal wäre ein AcitveX Control, welches eine Ereignis auslöst.
Hat jemand schon Erfahrung damit ?
Grüsse
Rudolf
Rudolf Reinthaler
http://www.formcommander.net
http://www.formcommander.net
- andreas
- Der Entwickler von "Deep Thought"
- Beiträge: 1902
- Registriert: Mi, 28. Sep 2005 10:53
- Wohnort: Osnabrück
- Hat sich bedankt: 4 Mal
- Kontaktdaten:
Hallo Rudolf,
wir benutzen auch Serielle Schnittstellen mit XBase-Tools. Über Zugriff mit ActiveX kann ich nur sagen dass es irgendwelche Standartschnittstelle von Microsoft gibt. Versuchs mit Microsoft Communication Control, den du direkt mit XppFd einfügen kannst.
Ich glaube aber, dass ohne ständiges Abfragen nichts laufen wird.
wir benutzen auch Serielle Schnittstellen mit XBase-Tools. Über Zugriff mit ActiveX kann ich nur sagen dass es irgendwelche Standartschnittstelle von Microsoft gibt. Versuchs mit Microsoft Communication Control, den du direkt mit XppFd einfügen kannst.
Ich glaube aber, dass ohne ständiges Abfragen nichts laufen wird.
- brandelh
- Foren-Moderator
- Beiträge: 15689
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 65 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Hallo Rudolf,
in den XbToolsIII gibt es Funktionen zur Überwachung der seriellen Schnittstelle. Diese sind Eventgesteuert. Ein Bekannter hat damit den seriellen Druckerausgang eines Gerätes angezapft und die Daten importiert (schon unter clipper), war recht aufwändig, insbesondere mußte er mit den Timeouts experimentieren. Nun funktioniert es aber gut.
wenn du die Tools (in Subscription ...) nicht hast, schau auf der Alaska Seite nach ComSilver oder so ähnlich, eine Toolbox für die serielle Schnittstelle ...
in den XbToolsIII gibt es Funktionen zur Überwachung der seriellen Schnittstelle. Diese sind Eventgesteuert. Ein Bekannter hat damit den seriellen Druckerausgang eines Gerätes angezapft und die Daten importiert (schon unter clipper), war recht aufwändig, insbesondere mußte er mit den Timeouts experimentieren. Nun funktioniert es aber gut.
wenn du die Tools (in Subscription ...) nicht hast, schau auf der Alaska Seite nach ComSilver oder so ähnlich, eine Toolbox für die serielle Schnittstelle ...
Gruß
Hubert
Hubert
- Rudolf
- Programmier-Gott
- Beiträge: 1418
- Registriert: Mo, 02. Jan 2006 23:03
- Wohnort: Salzburg/Österreich
- Kontaktdaten:
Hallo,
danke an alle, habe die Tools und werde es mit einem eigenen Thread probieren der auf eine COM Event wartet.
Grüsse
Rudolf
danke an alle, habe die Tools und werde es mit einem eigenen Thread probieren der auf eine COM Event wartet.
Grüsse
Rudolf
Rudolf Reinthaler
http://www.formcommander.net
http://www.formcommander.net
-
- Rekursionen-Architekt
- Beiträge: 193
- Registriert: Fr, 09. Jun 2006 7:52
- Wohnort: Nähe Sömmerda
Hallo Rudolf,
ich würde schon die Schnittstellenabfrage in einem eigenen Thread ausführen und in diesem auch die empfangenen Daten in einen Empfangsbuffer schreiben. Der Buffer könnte z.B. durch den Main-Thread überwacht werden, eventuell kann auch ein User-Event an das Hauptfenster gesendet werden, wenn Daten emfangen wurden.
Grüße
Gerd
ich würde schon die Schnittstellenabfrage in einem eigenen Thread ausführen und in diesem auch die empfangenen Daten in einen Empfangsbuffer schreiben. Der Buffer könnte z.B. durch den Main-Thread überwacht werden, eventuell kann auch ein User-Event an das Hauptfenster gesendet werden, wenn Daten emfangen wurden.
Grüße
Gerd
- Rudolf
- Programmier-Gott
- Beiträge: 1418
- Registriert: Mo, 02. Jan 2006 23:03
- Wohnort: Salzburg/Österreich
- Kontaktdaten:
Hallo Gerd,
habe an diese Lösung gedacht, nur das mit dem User Event habe ich nocht nicht so richtig drauf. Muss mal nach einem Beispiel im Forum suche, dürfte aber nicht so schwierig sein. Habe die Funktion COM_EVENT() in den Tools gefunden, die könnte ich verwenden.
Grüsse
Rudolf
habe an diese Lösung gedacht, nur das mit dem User Event habe ich nocht nicht so richtig drauf. Muss mal nach einem Beispiel im Forum suche, dürfte aber nicht so schwierig sein. Habe die Funktion COM_EVENT() in den Tools gefunden, die könnte ich verwenden.
Grüsse
Rudolf
Rudolf Reinthaler
http://www.formcommander.net
http://www.formcommander.net
-
- Rekursionen-Architekt
- Beiträge: 193
- Registriert: Fr, 09. Jun 2006 7:52
- Wohnort: Nähe Sömmerda
Hallo Rudolf,
zum User-Event:
Zuerst wäre dieses Ereignis zu definieren, am besten in einer ch-Datei
Im COM-Thread ist dann
aufzurufen.
Im Main-Thread würde ich dann innerhalb des Eventloops die Auswertung ausführen:
Gruß
Gerd
zum User-Event:
Zuerst wäre dieses Ereignis zu definieren, am besten in einer ch-Datei
Code: Alles auswählen
#include "appevent.ch"
#define MY_EVENT xbeP_User+1
Code: Alles auswählen
PostAppEvent(MY_EVENT, mp1, mp2, SetAppWindow())
Im Main-Thread würde ich dann innerhalb des Eventloops die Auswertung ausführen:
Code: Alles auswählen
DO WHILE .T.
nEvent := AppEvent( @mp1, @mp2, @oXbp, 50) //0,5s Timeout
IF (nEvent=MY_EVENT)
HandleMyEvent() //zur Auswertung
LOOP
ENDIF
oXbp:handleEvent( nEvent, mp1, mp2 )
ENDDO
Gruß
Gerd
- Rudolf
- Programmier-Gott
- Beiträge: 1418
- Registriert: Mo, 02. Jan 2006 23:03
- Wohnort: Salzburg/Österreich
- Kontaktdaten:
Hallo Gerd,
danke für den Tip, habe diese Classe erstellt, die aber leider nicht funktioniert. Bin kein OOP Profi und kann den Fehler einfach nicht finden, ist sicher nur eine Kleinigkeit. Beim Starten bekomme ich immer folgende Meldung:
oError:args :
-> VALTYPE: O CLASS: ComThread
oError:canDefault : N
oError:canRetry : N
oError:canSubstitute: J
oError:cargo : NIL
oError:description : Access to method not allowed in this context
oError:filename :
oError:genCode : 25
oError:operation : startcom
oError:osCode : 0
oError:severity : 2
oError:subCode : 2223
oError:subSystem : BASE
oError:thread : 1
oError:tries : 0
------------------------------------------------------------------------------
CALLSTACK:
------------------------------------------------------------------------------
Called from START_THREAD(7437)
Called from (B)PROG_START(648)
Called from DC_GETLIST:READGUI(3284)
Called from DC_READGUI(223)
Called from PROG_START(648)
Called from PROGMAIN(206)
Called from MAIN(49)
DBE Component Data BFDBE
DBE Component Order:CDXDBE
No DBF file open
hier meine Klasse:
function start_thread()
******************************************************************
local o:=ComThread():new()
sleep(5)
o:start()
o:startcom()
return o
CLASS ComThread FROM THREAD
******************************************************************
method atend
method startcom
method stopcom
INLINE METHOD init
::Thread:init()
::nComNr := 1
::cKey := ""
::terminated := .f.
RETURN self
INLINE METHOD terminate
RETURN ( ::terminated := .T. )
EXPORTED:
var cKey
var nComNr
PROTECTED:
VAR terminated
ENDCLASS
METHOD ComThread:startcom()
******************************************************************
local nEvent,cIN
::lAktiv := .f.
if ::nComNr > 0
if COM_OPEN(::nComNr)
com_init(::nComNr,9600,"N",8,1)
com_rts(::nComNr,.t.)
com_dtr(::nComNr,.t.)
::lAktiv := .t.
endif
endif
if ::lAktiv
do while ::lAktiv
if ::terminated
::terminated := .f.
::quit()
endif
nEvent := com_event(::nComNr,COM_EVENT_CHAR)
if nEvent = COM_EVENT_CHAR
cIn := com_read(::nComNr,100)
if !empty(cIn) .and. "OUT" $ cIn
if len(cIn) > 10
::cKey := cIn
PostAppEvent(COM_KEY_EVENT, mp1, mp2, SetAppWindow())
else
::cKey := "OUT"
endif
endif
endif
enddo
endif
return self
METHOD ComThread:atEnd()
******************************************************************
if ::lAktiv
com_close(::nComNr)
endif
::lAktiv := .f.
return self
METHOD ComThread:stopcom()
******************************************************************
::lAktiv := .f.
return self
Grüsse
Rudolf
danke für den Tip, habe diese Classe erstellt, die aber leider nicht funktioniert. Bin kein OOP Profi und kann den Fehler einfach nicht finden, ist sicher nur eine Kleinigkeit. Beim Starten bekomme ich immer folgende Meldung:
oError:args :
-> VALTYPE: O CLASS: ComThread
oError:canDefault : N
oError:canRetry : N
oError:canSubstitute: J
oError:cargo : NIL
oError:description : Access to method not allowed in this context
oError:filename :
oError:genCode : 25
oError:operation : startcom
oError:osCode : 0
oError:severity : 2
oError:subCode : 2223
oError:subSystem : BASE
oError:thread : 1
oError:tries : 0
------------------------------------------------------------------------------
CALLSTACK:
------------------------------------------------------------------------------
Called from START_THREAD(7437)
Called from (B)PROG_START(648)
Called from DC_GETLIST:READGUI(3284)
Called from DC_READGUI(223)
Called from PROG_START(648)
Called from PROGMAIN(206)
Called from MAIN(49)
DBE Component Data BFDBE
DBE Component Order:CDXDBE
No DBF file open
hier meine Klasse:
function start_thread()
******************************************************************
local o:=ComThread():new()
sleep(5)
o:start()
o:startcom()
return o
CLASS ComThread FROM THREAD
******************************************************************
method atend
method startcom
method stopcom
INLINE METHOD init
::Thread:init()
::nComNr := 1
::cKey := ""
::terminated := .f.
RETURN self
INLINE METHOD terminate
RETURN ( ::terminated := .T. )
EXPORTED:
var cKey
var nComNr
PROTECTED:
VAR terminated
ENDCLASS
METHOD ComThread:startcom()
******************************************************************
local nEvent,cIN
::lAktiv := .f.
if ::nComNr > 0
if COM_OPEN(::nComNr)
com_init(::nComNr,9600,"N",8,1)
com_rts(::nComNr,.t.)
com_dtr(::nComNr,.t.)
::lAktiv := .t.
endif
endif
if ::lAktiv
do while ::lAktiv
if ::terminated
::terminated := .f.
::quit()
endif
nEvent := com_event(::nComNr,COM_EVENT_CHAR)
if nEvent = COM_EVENT_CHAR
cIn := com_read(::nComNr,100)
if !empty(cIn) .and. "OUT" $ cIn
if len(cIn) > 10
::cKey := cIn
PostAppEvent(COM_KEY_EVENT, mp1, mp2, SetAppWindow())
else
::cKey := "OUT"
endif
endif
endif
enddo
endif
return self
METHOD ComThread:atEnd()
******************************************************************
if ::lAktiv
com_close(::nComNr)
endif
::lAktiv := .f.
return self
METHOD ComThread:stopcom()
******************************************************************
::lAktiv := .f.
return self
Grüsse
Rudolf
Rudolf Reinthaler
http://www.formcommander.net
http://www.formcommander.net
-
- Rekursionen-Architekt
- Beiträge: 193
- Registriert: Fr, 09. Jun 2006 7:52
- Wohnort: Nähe Sömmerda
- Rudolf
- Programmier-Gott
- Beiträge: 1418
- Registriert: Mo, 02. Jan 2006 23:03
- Wohnort: Salzburg/Österreich
- Kontaktdaten:
Hallo Gerd,
vielen Dank, jetzt funktioniert es
Grüsse
Rudolf
vielen Dank, jetzt funktioniert es
Grüsse
Rudolf
Rudolf Reinthaler
http://www.formcommander.net
http://www.formcommander.net