Seite 2 von 2
Re: Daten von einen Serial Port empfangen und verarbeiten
Verfasst: 01.03.2016 18:21
von HHYayo
HeX0R hat geschrieben:Es scheint doch aber so zu sein, dass das Paket, dass Du bekommst immer gleich lang ist, richtig?
Dann lässt sich das Ganze doch aber wirklich recht einfach umsetzen.
Je nachdem, ob da jetzt als Zeilenvorschub nur ein oder zwei Zeichen kommen, ist Dein Rückgabepaket immer 16 oder 19 Zeichen lang (ich denke mal die eckige Klammer gehört noch dazu).
Also musst Du einfach warten, bis Dir AvailableSerialPortInput(0) 16 oder 19 zurückgibt, dann liest Du alles in einem Rutsch in einen Memorypuffer und holst Dir die Bytes Nr. 12 + 13 bzw. 14 + 15.
Oder aber, falls die Pakete variabel in der Länge sind, ist evtl. die eckige Klammer das Abschlusszeichen, dann solange den Puffer füllen, bis die am Ende da steht.
[Edit]
Hier mal ein simples Beispiel (ungetestet)
Code: Alles auswählen
Enumeration
#SEND_TIMER
#RECEIVE_TIMER
EndEnumeration
Procedure main()
Protected *Buffer, BufferPos, AvailableBytes, Value
If OpenSerialPort(0, "COM5", 9600, #PB_SerialPort_EvenParity , 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024) = 0
MessageRequester("Error", "Can't open RS232!")
ProcedureReturn
EndIf
*Buffer = AllocateMemory(8192)
If *Buffer = 0
MessageRequester("Error", "No memory available!")
ProcedureReturn
EndIf
;create a stupid window
OpenWindow(0, 0, 0, 215, 80, "RS232", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TextGadget(0, 5, 15, 100, 24, "Value:")
StringGadget(1, 110, 15, 100, 24, "", #PB_String_ReadOnly)
CreateStatusBar(0, WindowID(0))
AddStatusBarField(#PB_Ignore)
;send any 200ms
AddWindowTimer(0, #SEND_TIMER, 200)
;receive any 5ms
AddWindowTimer(0, #RECEIVE_TIMER, 5)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Timer
Select EventTimer()
Case #SEND_TIMER
If WriteSerialPortString(0, "010D" + #CRLF$, #PB_Ascii) = 0
MessageRequester("Error", "SendString Error!")
Break
EndIf
Case #RECEIVE_TIMER
AvailableBytes = AvailableSerialPortInput(0)
If AvailableBytes > 0
ReadSerialPortData(0, *Buffer + BufferPos, AvailableBytes)
BufferPos + AvailableBytes
StatusBarText(0, 0, "Received: " + Str(BufferPos) + "Bytes")
;check for '>'
If PeekB(*Buffer + BufferPos - 1) = 62
;end of packet
If BufferPos = 16
;one linefeed char
Value = Val("$" + PeekS(*Buffer + 12, 2, #PB_Ascii))
Else
;two linefeed chars
Value = Val("$" + PeekS(*Buffer + 14, 2, #PB_Ascii))
EndIf
SetGadgetText(1, Str(Value))
BufferPos = 0
EndIf
EndIf
EndSelect
EndSelect
ForEver
CloseSerialPort(0)
EndProcedure
main()
Musst nur aufpassen, dass bei Fehlfunktion der Puffer nicht überläuft.
Ich mache da üblicherweise eine dynamische Anpassung, war ich jetzt aber zu faul

Wie du richtig erkannt hast empfange ich hier speziell immer dieselbe Paket-Größe. Im späteren Verlauf könnte es sein, dass ich Pakete in unterschiedlicher Größe empfangen und verarbeiten muss, welche jedoch nach dem gleichen Prinzip aufgebaut sind und sich lediglich wie auch in diesen Fall am Ende vom Aufbau und der Länge variabel sind. Von daher denke ich ist dein Example früher oder später einmal bedeutend für mich, danke!
Ich würde gerne mal noch eine Frage bezüglich der Kompatibilität der früheren und neueren Versionen von Purebasic stellen.
Mit einer älteren Version habe ich über den API's SetWindowLongPtr_ und SetLayeredWindowAttributes_ eine Procedur geschrieben, mit der ich ein Fenster randlos und ohne "Design" nach und nach von einen Transparenzwert 0-255 "aufgehen" lasse, in dem sich ein ImageGadget befindet (Welches ebenfalls langsam eingeblendet wurde). Seit der aktuellen Version funktioniert es jedoch nicht mehr, da sich lediglich das Fenster langsam einblendet, jedoch nur komplett schwarz und ohne den Image. Kommt Purebasic nicht mehr mit den genannten API's klar ? War eine hübsche Spielerei die ich gerne wieder verwenden würde
Mit freundlichen Grüßen
HHYayo
Re: Daten von einen Serial Port empfangen und verarbeiten
Verfasst: 01.03.2016 18:38
von NicTheQuick
Hast du vielleicht eher dein Windows gewechselt? Purebasic hat kein Problem mit API. Der wahrscheinlichere Fall ist, dass du sie falsch benutzt und sie deswegen nicht Versionsübergreifend korrekt funktioniert.
Re: Daten von einen Serial Port empfangen und verarbeiten
Verfasst: 01.03.2016 19:09
von HHYayo
NicTheQuick hat geschrieben:Hast du vielleicht eher dein Windows gewechselt? Purebasic hat kein Problem mit API. Der wahrscheinlichere Fall ist, dass du sie falsch benutzt und sie deswegen nicht Versionsübergreifend korrekt funktioniert.
Ich verstehe das nicht. Ich habe zu Testzwecken den gleichen Code genutzt, die gleiche Bild-Datei und hab alles unter denselben Umständen laufen lassen wie ich es vor einen halben Jahr erfolgreich compiliert habe. Dies war zu der Zeit auf einem Laptop mit Windows 7 und 64bit, mittlererweile ist es zwar ein Rechner, jedoch ebenfalls mit Windows 7 und 64bit. Meinen Code habe ich ebenfalls bereits überprüft und mit anderen in Forum vergleichen können.
Was hat denn mein jetziges Windows nicht, welches mein Altes hatte ?
Mit freundlichen Grüßen
HHYayo
Nachtrag: Mir ist mal aufgefallen, dass nichtmal mehr die damals bereits erstellte und funktionierende Binary das Bild nicht mehr anzeigt. Denn muss es ja wirklich an meiner Hardware liegen... Kann sein das es mit der Grafikkarte oder ähnlichen zu tun hat ?
Re: Daten von einen Serial Port empfangen und verarbeiten
Verfasst: 01.03.2016 21:37
von HeX0R
Kannst Du nicht mal nen 10 Zeiler machen, der das Problem zeigt?
Re: Daten von einen Serial Port empfangen und verarbeiten
Verfasst: 02.03.2016 15:55
von HHYayo
HeX0R hat geschrieben:Kannst Du nicht mal nen 10 Zeiler machen, der das Problem zeigt?
Na klar:
Code: Alles auswählen
Enumeration
#Image
EndEnumeration
Procedure.i SetWindowTransparency(Window.i, transparency.i)
If IsWindow(Window)
Protected WindowID = WindowID(Window)
SetWindowLongPtr_(WindowID,#GWL_EXSTYLE,#WS_EX_LAYERED)
SetLayeredWindowAttributes_(WindowID,0,transparency,#LWA_ALPHA)
EndIf
EndProcedure
defaultF$ = ""
pattern$ = "Alle Dateien (*.*)|*.*"
pattern = 0
imagepath$ = OpenFileRequester("Test Bild auswählen!",defaultF$,pattern$,pattern)
image = LoadImage(#Image,imagepath$)
Window= OpenWindow(#PB_Any, x, y, 600, 250, "", #PB_Window_BorderLess | #PB_Window_ScreenCentered)
Image= ImageGadget(#PB_Any, 0, 0, 600, 250, image)
For transp=0 To 255
SetWindowTransparency(Window,transp)
Delay(5)
Next
Mit freundlichen Grüßen
Deis-Performance
Re: Daten von einen Serial Port empfangen und verarbeiten
Verfasst: 02.03.2016 16:06
von NicTheQuick
Es wäre besser du arbeitest noch die Events ab, die im Fenster auftreten können.
Code: Alles auswählen
For transp=0 To 255
SetWindowTransparency(Window,transp)
Delay(5)
While WindowEvent() : Wend
Next
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Bei mir funktioniert es jedenfalls unter Windows 7 Pro 64 Bit.
Re: Daten von einen Serial Port empfangen und verarbeiten
Verfasst: 02.03.2016 16:31
von HHYayo
NicTheQuick hat geschrieben:Es wäre besser du arbeitest noch die Events ab, die im Fenster auftreten können.
Code: Alles auswählen
For transp=0 To 255
SetWindowTransparency(Window,transp)
Delay(5)
While WindowEvent() : Wend
Next
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Bei mir funktioniert es jedenfalls unter Windows 7 Pro 64 Bit.
Jep, gleiches Windows...
Mit meiner Funktion wird lediglich nach und nach ein schwarzes Fenster eingeblendet statt den Image. Mit dem Abarbeiten der Events des Fensters passiert genau das Gleiche, nur dass das Fenster denn nicht schwarz ist sondern eher Hellgrau/Weiß ist.
Kann doch nicht sein.
Mit freundlichen Grüßen
HHYayo
Re: Daten von einen Serial Port empfangen und verarbeiten
Verfasst: 02.03.2016 16:44
von mhs
Zwei Dinge die mir aufgefallen sind:
1. image = LoadImage(#Image,imagepath$) ist nicht offiziell dokumentiert. Laut Beschreibung hat LoadImage nur "irgendeinen" Rückgabewert ungleich Null.
Sicherer wäre, wenn du die ID per ImageID() ermitteln würdest
Code: Alles auswählen
LoadImage(#image, imagepath$)
ImageGadget(#PB_Any, 0, 0, 600, 250, ImageID(#image))
2. Du verwendest keinen ImageDecoder wie UseJPEGImageDecoder(), dadurch kannst du nur *.bmp öffnen, evtl hast du hier ein falsches Bild ausgewählt?
Re: Daten von einen Serial Port empfangen und verarbeiten
Verfasst: 02.03.2016 17:04
von HHYayo
mhs hat geschrieben:Zwei Dinge die mir aufgefallen sind:
1. image = LoadImage(#Image,imagepath$) ist nicht offiziell dokumentiert. Laut Beschreibung hat LoadImage nur "irgendeinen" Rückgabewert ungleich Null.
Sicherer wäre, wenn du die ID per ImageID() ermitteln würdest
Code: Alles auswählen
LoadImage(#image, imagepath$)
ImageGadget(#PB_Any, 0, 0, 600, 250, ImageID(#image))
2. Du verwendest keinen ImageDecoder wie UseJPEGImageDecoder(), dadurch kannst du nur *.bmp öffnen, evtl hast du hier ein falsches Bild ausgewählt?
Unglaublich, sollte man natürlich auch dran denken. Jetzt habe nur den Testcode geschrieben und genutzt um zu schauen ob es geht und da wirklich UsePNGImageDecoder() vergessen.
Nun funktioniert es, vielen Dank!
Mit freundlichen Grüßen
HHYayo