RS232 lesen

Anfängerfragen zum Programmieren mit PureBasic.
gbalzarek
Beiträge: 38
Registriert: 06.07.2006 22:18
Wohnort: D-Südwest

RS232 lesen

Beitrag 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?
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: RS232 lesen

Beitrag 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
a²+b²=mc²
gbalzarek
Beiträge: 38
Registriert: 06.07.2006 22:18
Wohnort: D-Südwest

Re: RS232 lesen

Beitrag von gbalzarek »

Ja, die stimmt.
Benutzeravatar
7x7
Beiträge: 591
Registriert: 14.08.2007 15:41
Computerausstattung: ganz toll
Wohnort: Lelbach

Re: RS232 lesen

Beitrag von 7x7 »

Benutzt du vielleicht einen Ser/USB-Adapter-Konverter? Treiber-Problem?
- alles was ich hier im Forum sage/schreibe ist lediglich meine Meinung und keine Tatsachenbehauptung
- unkommentierter Quellcode = unqualifizierter Müll
gbalzarek
Beiträge: 38
Registriert: 06.07.2006 22:18
Wohnort: D-Südwest

Re: RS232 lesen

Beitrag von gbalzarek »

Nein, der PC hat eine echte RS232-Schnittstelle.
Ich benutze übrigens 9600 Baud, ist also nicht allzu schnell.
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Re: RS232 lesen

Beitrag von Falko »

Dürfte man deinen Code hier sehen?

Gruß,
Falko
Bild
Win11 Pro 64-Bit, PB_6.11b1
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8808
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: RS232 lesen

Beitrag 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()
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: RS232 lesen

Beitrag von ts-soft »

Code: Alles auswählen

XIncludeFile "Serial.pbh"
Suchst Du die auch noch heraus? :wink:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8808
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: RS232 lesen

Beitrag 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.
gbalzarek
Beiträge: 38
Registriert: 06.07.2006 22:18
Wohnort: D-Südwest

Re: RS232 lesen

Beitrag 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.
Antworten