Wie kriege ich den input eines seriellen Geräts?
Übersicht

![]() |
poetBetreff: Wie kriege ich den input eines seriellen Geräts? |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich hab ein USB Gerät (monome.org), das über entsprechende Treiber wie ein altbackened serielles Gerät eingebunden ist. Mit den Stream Funktionen kann ich den COM Port auch öffnen und Daten rausschicken. Nur mit dem lesen der Daten die vom Gerät kommen haperts. Hat da jemand Erfahrung mit?
Mit dem folgenden Code kann ich das Gerät steuern: Code: [AUSKLAPPEN] Local mH:TStream
mH = OpenStream("COM3:") WriteByte(mH,%10000000) WriteByte(mH,%11111111) FlushStream(mH) CloseStream(mH) Aber wenn ich mit ReadByte() versuche was zu lesen kommt nichts. Und wenn ich mir mit StreamSize() die länge des Streams anzeigen lasse verändert sich daran nichts wenn ich auf dem Gerät die Knöpfe drücke. Ich hab auch schon versucht mit ReadStream() einen reinen Lesezugriff zu bekommen, aber das hat auch nichts gebracht. |
||
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Code: [AUSKLAPPEN] SuperStrict
Framework BRL.StandardIO Import BRL.PolledInput Const GENERIC_READ : Int = $80000000 Const GENERIC_WRITE : Int = $40000000 Const OPEN_EXISTING : Int = 3 Const FILE_ATTRIBUTE_NORMAL : Int = $80 Const INVALID_HANDLE_VALUE : Int = -1 Extern "Win32" Function apiCreateFile:Int(FileName$z, DesiredAccess:Int, ShareMode:Int, .. SecurrityAttribute:Byte Ptr, CreationDisposition:Int, .. FlagsAndAttributes:Int, TemplateFile:Int) = "CreateFileA@28" Function apiCloseHandle:Int(Obj:Int) = "CloseHandle@4" Function apiWriteFile:Int(File:Int, Buffer:Byte Ptr, NumberOfBytesToWrite:Int, .. NumberOfBytesWritten:Int Ptr, Overlapped:Byte Ptr) = "WriteFile@20" Function apiReadFile:Int(File:Int, Buffer:Byte Ptr, NumberOfBytesToRead:Int, .. NumberOfBytesRead:Int Ptr, Overlapped:Byte Ptr) = "ReadFile@20" Function apiGetCommState:Int(File:Int, DCB:Byte Ptr) = "GetCommState@8" Function apiSetCommState:Int(File:Int, DCB:Byte Ptr) = "SetCommState@8" Function apiBuildCommDCB:Int(Def$z, DCB:Byte Ptr) = "BuildCommDCBA@8" Function apiGetCommTimeouts:Int(File:Int, CommTimeouts:Byte Ptr) = "GetCommTimeouts@8" Function apiSetCommTimeouts:Int(File:Int, CommTimeouts:Byte Ptr) = "SetCommTimeouts@8" Function GetLastError:Int() = "GetLastError@0" End Extern Type TDCB Field DCBlength : Int Field BaudRate : Int Field Control : Int Field Reserved : Short Field XonLim : Short Field XoffLimc : Short Field ByteSize : Byte Field Parity : Byte Field StopBits : Byte Field XonChar : Byte Field XoffChar : Byte Field ErrorChar : Byte Field EofChar : Byte Field EvtChar : Byte Field Reserved1 : Short End Type Type TCommtimeouts Field ReadIntervalTimeout : Int Field ReadTotalTimeoutMultiplier : Int Field ReadTotalTimeoutConstant : Int Field WriteTotalTimeoutMultiplier : Int Field WriteTotalTimeoutConstant : Int End Type Type TComm Extends TStream Field Handle : Int = INVALID_HANDLE_VALUE Field Port : Byte Field ReadTimeout : Int Field WriteTimeout : Int Method Open:Int(Port:Byte) Local Handle : Int Handle = apiCreateFile("COM"+String(Port), GENERIC_READ | GENERIC_WRITE, .. 0, Null, OPEN_EXISTING, 0, 0) If Handle = INVALID_HANDLE_VALUE Then Return False Else Self.Handle = Handle Self.Port = Port Return True EndIf End Method Method Read:Int(Buffer:Byte Ptr, Size:Int) Local Count:Int If Self.Handle = INVALID_HANDLE_VALUE Then Return 0 If Not apiReadFile(Self.Handle, Buffer, Size, Varptr(Count), Null) Then Return 0 Return Count End Method Method Write:Int(Buffer:Byte Ptr, Size:Int) Local Count:Int If Self.Handle = INVALID_HANDLE_VALUE Then Return 0 If Not apiWriteFile(Self.Handle, Buffer, Size, Varptr(Count), Null) Then Return 0 Return Count End Method Method Close() If Self.Handle <> INVALID_HANDLE_VALUE Then apiCloseHandle(Self.Handle) Self.Handle = INVALID_HANDLE_VALUE EndIf End Method Method Set:Int(Settings:String) Local DCB:TDCB If Self.Handle = INVALID_HANDLE_VALUE Then Return False DCB = New TDCB If (Not apiGetCommState(Self.Handle, DCB)) Or .. DCB.DCBlength <> SizeOf(TDCB) Then Return False If Not apiBuildCommDCB(Settings, DCB) Then Return False If Not apiSetCommState(Self.Handle, DCB) Then Return False Return True End Method Method SetTimeouts:Int(ReadTimeout:Int, WriteTimeout:Int) Local Timeouts:TCommtimeouts If Self.Handle = INVALID_HANDLE_VALUE Then Return False Timeouts = New TCommtimeouts If Not apiGetCommTimeouts(Self.Handle, Timeouts) Then Return False Timeouts.ReadTotalTimeoutConstant = ReadTimeout Timeouts.WriteTotalTimeoutConstant = WriteTimeout If Not apiSetCommTimeouts(Self.Handle, Timeouts) Then Return False Return True End Method End Type Global COM1 : TComm Global Message : String COM1 = New TComm Print(COM1.Open(1)) Print(COM1.Set("baud=9600 parity=N data=8 stop=1")) Print(COM1.SetTimeouts(500, 500)) Repeat Message = Input("Message: ") If Message = "end" Then Exit Else COM1.WriteLine(Message) EndIf Print(COM1.ReadLine()) Forever COM1.Close() End mfg olli Edit: Jetzt gehts, habe nur "Return True" vergessen. |
||
![]() |
poet |
![]() Antworten mit Zitat ![]() |
---|---|---|
Sehr cool, vielen Dank.
Ich musste noch die Methoden ReadBytes() ändern, so das sie keine Exception wirft wenn es nichts zu lesen gibt, aber damit läufts jetzt. Zum testen hab ich den Serial Port Monitor verwendet, der kann auch selber ne Verbindung aufbauen und macht das mit den Read Abfragen dann noch ein bischen schöner indem er IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_WAIT_ON_MASK) setzt. Das Kommando wird dann erst beendet wenn es was zu lesen gibt. Aber dazu muss das ganz wohl als eigener Thread laufen. Falls du dazu noch ne Idee hast wie man das umsetzten könnte wäre Klasse. Aber soweit bin ich damit schon sehr glücklich. Vielen Dank nochmal. |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group