Hallo Leute,
also irgendetwas stimmt mit der Stringverarbeitung in PureBasic nicht!
Um das zu verdeutlichen habe ich mal 3 lauffähige Beispiele gemacht.
Zum Testen muss über die definierte serielle Schnittstelle (COM1) alle 5 Sekunden die Zeichenkette "DI25=123456<CR>" gesendet werden.
Die empfangene Zeichenkette wird jeweils im Debug-Fenster ausgegeben.
Beispiel 1 ist mit der Variante von CSHW89 realisiert.
Beispiel 2 ist mit der Variante von hjbremer realisiert.
Diese beiden Beispiele verhalten sich völlig gleich.
Irgendwann ist ein empfangenes Zeichen im String nicht mehr vorhanden.
Beispiel 3 ist vom Aufbau her völlig gleich nur das für den Ringpuffer kein String fester Länge sondern ein mit "DIM" dimensioniertes ASCII-Feld verwendet wird.
Und das funktioniert bei gleicher Struktur EINWANDFREI!!!
Würde mich mal interessieren ob ihr den Grund hierfür herausbekommt.
Beispiel 1:
Code: Alles auswählen
#SerialportPLC = 0
#SerialportBaudratePLC = 115200
Global SerialPortNamePLC$ = "COM1"
;
;
#LaengeRegisterKommandoRingpuffer = 30 ;20000
Global RegisterKommandoRingpufferSchreibzeiger.u = 1
Global RegisterKommandoRingpufferLesezeiger.u = 1
Global RegisterKommandoRingpuffer.s{#LaengeRegisterKommandoRingpuffer+1} = Space(#LaengeRegisterKommandoRingpuffer)
Global RegisterKommandoPuffer.s
;
;
Procedure IncRegisterKommandoRingpufferSchreibzeiger()
RegisterKommandoRingpufferSchreibzeiger.u = RegisterKommandoRingpufferSchreibzeiger.u + 1
If RegisterKommandoRingpufferSchreibzeiger.u > #LaengeRegisterKommandoRingpuffer
RegisterKommandoRingpufferSchreibzeiger.u = 1
EndIf
EndProcedure
;
;
Procedure IncRegisterKommandoRingpufferLesezeiger()
RegisterKommandoRingpufferLesezeiger.u = RegisterKommandoRingpufferLesezeiger.u + 1
If RegisterKommandoRingpufferLesezeiger.u > #LaengeRegisterKommandoRingpuffer
RegisterKommandoRingpufferLesezeiger.u = 1
EndIf
EndProcedure
;
;
Macro SetChar(_str_, _idx_, _char_)
PokeC(@_str_+SizeOf(Character) * _idx_, _char_)
EndMacro
;
;
Procedure RegisterEmpfang()
Puffer.b = 0
RegisterEmpfangen.i = #False
If IsSerialport(#SerialportPLC)
While AvailableSerialPortInput(#SerialportPLC) > 0
ReadSerialPortData(#SerialportPLC, @Puffer.b, 1)
EmpfangenesZeichen.s = Chr(Puffer.b)
SetChar(RegisterKommandoRingpuffer.s, RegisterKommandoRingpufferSchreibzeiger.u, Puffer.b)
IncRegisterKommandoRingpufferSchreibzeiger()
If Puffer.b = 13
RegisterEmpfangen.i = #True
Break
EndIf
Wend
If RegisterEmpfangen.i = #True
RegisterKommandoPuffer.s = ""
While RegisterKommandoRingpufferLesezeiger.u <> RegisterKommandoRingpufferSchreibzeiger.u
RegisterKommandoPuffer.s = RegisterKommandoPuffer.s + Mid(RegisterKommandoRingpuffer.s, RegisterKommandoRingpufferLesezeiger.u, 1)
IncRegisterKommandoRingpufferLesezeiger()
Wend
Debug RegisterKommandoPuffer.s
EndIf
EndIf
EndProcedure
If OpenSerialPort(#SerialportPLC, SerialPortNamePLC$, #SerialportBaudratePLC, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)
SetSerialPortStatus(#SerialportPLC, #PB_SerialPort_DTR, 0)
EndIf
Quit.i = #False
Repeat
RegisterEmpfang()
;
Until Quit.i = #True
Beispiel 2:
Code: Alles auswählen
#SerialportPLC = 0
#SerialportBaudratePLC = 115200
Global SerialPortNamePLC$ = "COM1"
;
;
#LaengeRegisterKommandoRingpuffer = 30 ;20000
Global RegisterKommandoRingpufferSchreibzeiger.u = 1
Global RegisterKommandoRingpufferLesezeiger.u = 1
Global RegisterKommandoRingpuffer.s{#LaengeRegisterKommandoRingpuffer+1} = Space(#LaengeRegisterKommandoRingpuffer)
Global RegisterKommandoPuffer.s
;
;
Procedure IncRegisterKommandoRingpufferSchreibzeiger()
RegisterKommandoRingpufferSchreibzeiger.u = RegisterKommandoRingpufferSchreibzeiger.u + 1
If RegisterKommandoRingpufferSchreibzeiger.u > #LaengeRegisterKommandoRingpuffer
RegisterKommandoRingpufferSchreibzeiger.u = 1
EndIf
EndProcedure
;
;
Procedure IncRegisterKommandoRingpufferLesezeiger()
RegisterKommandoRingpufferLesezeiger.u = RegisterKommandoRingpufferLesezeiger.u + 1
If RegisterKommandoRingpufferLesezeiger.u > #LaengeRegisterKommandoRingpuffer
RegisterKommandoRingpufferLesezeiger.u = 1
EndIf
EndProcedure
;
;
Procedure RegisterEmpfang()
Structure Zeichen
c.c[0]
EndStructure
;
Puffer.b = 0
RegisterEmpfangen.i = #False
If IsSerialport(#SerialportPLC)
While AvailableSerialPortInput(#SerialportPLC) > 0
ReadSerialPortData(#SerialportPLC, @Puffer.b, 1)
EmpfangenesZeichen.s = Chr(Puffer.b)
*c.zeichen = @RegisterKommandoRingpuffer.s
*c\c[RegisterKommandoRingpufferSchreibzeiger.u] = Puffer.b
IncRegisterKommandoRingpufferSchreibzeiger()
If Puffer.b = 13
RegisterEmpfangen.i = #True
Break
EndIf
Wend
If RegisterEmpfangen.i = #True
RegisterKommandoPuffer.s = ""
While RegisterKommandoRingpufferLesezeiger.u <> RegisterKommandoRingpufferSchreibzeiger.u
RegisterKommandoPuffer.s = RegisterKommandoPuffer.s + Mid(RegisterKommandoRingpuffer.s, RegisterKommandoRingpufferLesezeiger.u, 1)
IncRegisterKommandoRingpufferLesezeiger()
Wend
Debug RegisterKommandoPuffer.s
EndIf
EndIf
EndProcedure
If OpenSerialPort(#SerialportPLC, SerialPortNamePLC$, #SerialportBaudratePLC, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)
SetSerialPortStatus(#SerialportPLC, #PB_SerialPort_DTR, 0)
EndIf
Quit.i = #False
Repeat
RegisterEmpfang()
;
Until Quit.i = #True
Beispiel 3:
Code: Alles auswählen
#SerialportPLC = 0
#SerialportBaudratePLC = 115200
Global SerialPortNamePLC$ = "COM1"
;
;
#LaengeRegisterKommandoRingpuffer = 30 ;20000
Global RegisterKommandoRingpufferSchreibzeiger.u = 0
Global RegisterKommandoRingpufferLesezeiger.u = 0
Global Dim RegisterKommandoRingpuffer.a(#LaengeRegisterKommandoRingpuffer+1)
Global RegisterKommandoPuffer.s
;
;
;Hilfsprozeduren
;
Procedure IncRegisterKommandoRingpufferSchreibzeiger()
RegisterKommandoRingpufferSchreibzeiger.u = RegisterKommandoRingpufferSchreibzeiger.u + 1
If RegisterKommandoRingpufferSchreibzeiger.u > #LaengeRegisterKommandoRingpuffer
RegisterKommandoRingpufferSchreibzeiger.u = 0
EndIf
EndProcedure
;
;
Procedure IncRegisterKommandoRingpufferLesezeiger()
RegisterKommandoRingpufferLesezeiger.u = RegisterKommandoRingpufferLesezeiger.u + 1
If RegisterKommandoRingpufferLesezeiger.u > #LaengeRegisterKommandoRingpuffer
RegisterKommandoRingpufferLesezeiger.u = 0
EndIf
EndProcedure
;
;
Procedure RegisterEmpfang()
Puffer.a = 0
RegisterEmpfangen.i = #False
If IsSerialport(#SerialportPLC)
While AvailableSerialPortInput(#SerialportPLC) > 0
ReadSerialPortData(#SerialportPLC, @Puffer.a, 1)
RegisterKommandoRingpuffer.a(RegisterKommandoRingpufferSchreibzeiger.u) = Puffer.a
IncRegisterKommandoRingpufferSchreibzeiger()
If Puffer.a = 13
RegisterEmpfangen.i = #True
Break
EndIf
Wend
If RegisterEmpfangen.i = #True
RegisterKommandoPuffer.s = ""
While RegisterKommandoRingpufferLesezeiger.u <> RegisterKommandoRingpufferSchreibzeiger.u
RegisterKommandoPuffer.s = RegisterKommandoPuffer.s + Chr(RegisterKommandoRingpuffer.a(RegisterKommandoRingpufferLesezeiger.u))
IncRegisterKommandoRingpufferLesezeiger()
Wend
Debug RegisterKommandoPuffer.s
EndIf
EndIf
EndProcedure
If OpenSerialPort(#SerialportPLC, SerialPortNamePLC$, #SerialportBaudratePLC, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)
SetSerialPortStatus(#SerialportPLC, #PB_SerialPort_DTR, 0)
EndIf
Quit.i = #False
Repeat
RegisterEmpfang()
;
Until Quit.i = #True
Gruß
Daffy