Seite 1 von 2
RS232 lesen
Verfasst: 15.03.2013 13:29
von gbalzarek
Ich schreibe ein QB4-DOS-Programm für Windows um.
Jetzt habe ich folgendes Problem:
Ich lese Binärdaten mit ReadSerialPortData() von der seriellen Schnittstelle ein. Leider kommen falsche Daten zurück. Die Zahl der eingelesenen Bytes stimmt, aber die Bytes stimmen nicht und ändern sich ab und zu. Erwartet wird $81 $FF $65 $31 $37 $B3, ich bekomme aber bestenfalls $81 $31 $B3 $00 $00 $00 zurück.
Wenn ich das DOS-Programm in der Commandbox starte kommen immer die richtigen Werte zurück. Die Hardware sollte also korrekt funktionieren.
Mit den Handshake-Flags habe ich schon experimentiert, mit dem Datentyp der Puffervariablen auch, aber das ist es wohl nicht.
Woran kann das liegen?
Re: RS232 lesen
Verfasst: 15.03.2013 13:37
von Kiffi
gbalzarek hat geschrieben:Mit den Handshake-Flags habe ich schon experimentiert, mit dem Datentyp der Puffervariablen auch, aber das ist es wohl nicht.
Baudrate stimmt?
Grüße ... Kiffi
Re: RS232 lesen
Verfasst: 15.03.2013 17:55
von gbalzarek
Ja, die stimmt.
Re: RS232 lesen
Verfasst: 15.03.2013 19:06
von 7x7
Benutzt du vielleicht einen Ser/USB-Adapter-Konverter? Treiber-Problem?
Re: RS232 lesen
Verfasst: 15.03.2013 19:25
von gbalzarek
Nein, der PC hat eine echte RS232-Schnittstelle.
Ich benutze übrigens 9600 Baud, ist also nicht allzu schnell.
Re: RS232 lesen
Verfasst: 15.03.2013 21:07
von Falko
Dürfte man deinen Code hier sehen?
Gruß,
Falko
Re: RS232 lesen
Verfasst: 15.03.2013 23:36
von NicTheQuick
Vielleicht machst du ja was falsch beim Auslesen der Daten aus dem Eingangspuffer. Ich hatte mal eine Pseudoklasse für die serielle Schnittstelle in PB geschrieben. Ich such sie mal raus.
Gefunden:
Code: Alles auswählen
Interface Serial
open.i(device.s, baudrate.i, parity.i = #PB_SerialPort_NoParity, dataBits.i = 8, stopBit.i = 1, handShake.i = #PB_SerialPort_NoHandshake)
close.i()
sendData(*buffer, length.i)
sendChar(char.a)
receiveChar.a()
sendUnicode(unicode.u)
receiveUnicode.u()
sendString(string.s)
receiveString.s(length.i = -1)
availableData.i()
isOpen.i()
lock()
unlock()
tryLock.i()
free()
bps.f()
EndInterface
Structure SerialS
vTable.i
device.s
baudrate.i
handle.i
hMutex.i
lastTime.i
bytesSent.i
EndStructure
Procedure.i Serial_new()
Protected *this.SerialS
*this = AllocateMemory(SizeOf(SerialS))
If Not *this : ProcedureReturn #False : EndIf
*this\vTable = ?vTable_Serial
*this\hMutex = CreateMutex()
*this\bytesSent = 0
ProcedureReturn *this
EndProcedure
Procedure.i Serial_open(*this.SerialS, device.s, baudrate.i, parity.i = #PB_SerialPort_NoParity, dataBits.i = 8, stopBit.i = 1, handShake.i = #PB_SerialPort_NoHandshake)
If IsSerialPort(*this\handle)
CloseSerialPort(*this\handle)
EndIf
*this\handle = OpenSerialPort(#PB_Any, device, baudrate, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 4096, 4096)
If Not *this\handle : ProcedureReturn #False : EndIf
*this\device = device
*this\baudrate = baudrate
ProcedureReturn #True
EndProcedure
Procedure Serial_close(*this.SerialS)
If IsSerialPort(*this\handle)
CloseSerialPort(*this\handle)
EndIf
EndProcedure
Procedure Serial_sendData(*this.SerialS, *buffer, length.i)
Protected pos.i = 0
If IsSerialPort(*this\handle)
While pos < length
pos + WriteSerialPortData(*this\handle, *buffer + pos, length - pos)
Wend
*this\bytesSent + length
EndIf
EndProcedure
Procedure Serial_sendChar(*this.SerialS, char.a)
Protected pos.i = 0
If IsSerialPort(*this\handle)
While pos < 1
pos + WriteSerialPortData(*this\handle, @char, 1)
Wend
*this\bytesSent + 1
EndIf
EndProcedure
Procedure.a Serial_receiveChar(*this.SerialS)
Protected result.a
If IsSerialPort(*this\handle)
While Not ReadSerialPortData(*this\handle, @result, 1) : Wend
ProcedureReturn result
EndIf
ProcedureReturn 0
EndProcedure
Procedure Serial_sendUnicode(*this.SerialS, unicode.u)
Protected pos.i = 0
If IsSerialPort(*this\handle)
While pos < 2
pos + WriteSerialPortData(*this\handle, @unicode + 1 - pos, 2 - pos)
Wend
EndIf
EndProcedure
Procedure.u Serial_receiveUnicode(*this.SerialS)
Protected pos.i = 0, result.u = 0
If IsSerialPort(*this\handle)
While pos < 2
pos + ReadSerialPortData(*this\handle, @result + 1 - pos, 2 - pos)
Wend
*this\bytesSent + 2
EndIf
ProcedureReturn result
EndProcedure
Procedure Serial_sendString(*this.SerialS, string.s)
Protected pos.i, length.i = Len(string)
If IsSerialPort(*this\handle)
While pos < length
pos + WriteSerialPortData(*this\handle, @string + pos, length - pos)
Wend
*this\bytesSent + length
EndIf
EndProcedure
Procedure.s Serial_receiveString(*this.SerialS, length.i = -1)
Protected pos.i = 0, *mem, result.s = "", c.a
If IsSerialPort(*this\handle)
If length = 0 : ProcedureReturn "" : EndIf
While length
While Not ReadSerialPortData(*this\handle, @c, 1) : Wend
If Not c : Break : EndIf
result + Chr(c)
length - 1
Wend
EndIf
ProcedureReturn result
EndProcedure
Procedure.i Serial_availableData(*this.SerialS)
If IsSerialPort(*this\handle)
ProcedureReturn AvailableSerialPortInput(*this\handle)
EndIf
ProcedureReturn 0
EndProcedure
Procedure.i Serial_isOpen(*this.SerialS)
ProcedureReturn IsSerialPort(*this\handle)
EndProcedure
Procedure Serial_lock(*this.SerialS)
LockMutex(*this\hMutex)
EndProcedure
Procedure Serial_unlock(*this.SerialS)
UnlockMutex(*this\hMutex)
EndProcedure
Procedure.i Serial_tryLock(*this.SerialS)
ProcedureReturn TryLockMutex(*this\hMutex)
EndProcedure
Procedure Serial_free(*this.SerialS)
FreeMutex(*this\hMutex)
FreeMemory(*this)
EndProcedure
Procedure.f Serial_bps(*this.SerialS)
Protected newTime.i = ElapsedMilliseconds()
Protected bps.f = *this\bytesSent / ((newTime - *this\lastTime) / 1000.0)
*this\lastTime = newTime
*this\bytesSent = 0
ProcedureReturn bps
EndProcedure
DataSection
vTable_Serial:
Data.i @Serial_open(), @Serial_close(), @Serial_sendData(), @Serial_sendChar(), @Serial_receiveChar(), @Serial_sendUnicode(), @Serial_receiveUniCode()
Data.i @Serial_sendString(), @Serial_receiveString(), @Serial_availableData()
Data.i @Serial_isOpen(), @Serial_lock(), @Serial_unlock(), @Serial_tryLock(), @Serial_free()
Data.i @Serial_bps()
EndDataSection
Beispiel:
Code: Alles auswählen
XIncludeFile "Serial.pbi"
Global serial.Serial = Serial_new()
If serial\open("/dev/rfcomm0", 9600)
serial\sendChar(12)
Define.i i
For i = 0 To 5
Debug serial\receiveChar()
Next
serial\close()
EndIf
serial\free()
Re: RS232 lesen
Verfasst: 15.03.2013 23:58
von ts-soft
Suchst Du die auch noch heraus?

Re: RS232 lesen
Verfasst: 16.03.2013 00:07
von NicTheQuick
Ah, hab ich vergessen raus zu nehmen. Da steht normalerweise Structure und Interface drin. Aber die hab ich schon dazu kopiert. Ich entferne die Zeile mal.
Re: RS232 lesen
Verfasst: 16.03.2013 11:15
von gbalzarek
Falko hat geschrieben:Dürfte man deinen Code hier sehen?
ja, das sind die Programmteile:
Code: Alles auswählen
OpenSerialPort(0, "COM"+ser$, 9600, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)
.
.
.
While AvailableSerialPortInput(0)>0 ;Geräteantworten lesen und darstellen
If ReadSerialPortData(0,@byte.b,1)
AddGadgetItem(37,-1, " <"+Right("00" + Hex(byte), 2)+ "H")
EndIf
Wend
Die While-Schleife befindet sich in der Event-Schleife.