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

Code: Alles auswählen

XIncludeFile "Serial.pbh"
Suchst Du die auch noch heraus? :wink:

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.