Seite 1 von 1

rs232 in Pure Basic einlesen

Verfasst: 26.08.2009 23:06
von dirtyklaus
Hallo,

habe folgendes Problem:

ich sende von einem Microcontroler über rs232 (über RS232 to USB) an Com3 in laufender Folge Positionsangabe etwa folgener Art:

@X123Y123Z123T123"return"

diese Folge wird ständig mit aktuellen Daten gesendet.

In PueBasic kann ich nun den Strom wieder in einer Console über den Print befehl anzeigen.

Ich möchte aber die 4 Werte in 4 Variablen speichern, also X,Y,Z,T und nicht als String verarbeiten.

Wie kriege ich aus dem Strom an Bytes wieder benutzbare Variablen?

Das @ Zeichen soll nur eine Art Sync sein, also danach geht es los.
Jeder Datensatz endet mit einem "return" - also nächste Zeile. Das wird auch in der Console richtig vom Print Befehl angezeigt.

Gruß

Klaus

Verfasst: 26.08.2009 23:15
von STARGÅTE
Suche nach dem Anfang (zB X) und dann nach derem ende (zb Y)
das da zwischen ist dann der Wert:

Code: Alles auswählen

String$
String$ = "@X100Y123Z123T123"
Start = FindString(String$,"X",1)+1
Ende = FindString(String$,"Y",Start)
Wert = Val(Mid(String$, Start, Ende-Start))
Debug Wert
das gleiche dann für Y Z unt T

Verfasst: 27.08.2009 01:03
von Falko
Mich würde interessieren, ob der Microcontroller eine feste Anzahl von Bytes sendet und diese immer gleich bleiben. Für eine CNC-Steuerung wäre das
auch praktisch, da man so Koordinaten in Echtzeit verarbeiten könnte.

Wenn die Pakete eine gleiche Anzahl von Bytes haben also auch eine vorangestellte "0", dann könnte man es eventuell auch so lösen.

Code: Alles auswählen

Read_S.s="@X123Y456Z789T123" 

If Left(Read_S,1)="@"
 X.l=Val(Mid(Read_S,3,3))
 Y.l=Val(Mid(Read_S,7,3))
 Z.l=Val(Mid(Read_S,11,3))
 T.l=Val(Mid(Read_S,15,3))
 
 Debug "X:"+Str(X)+" "+"Y:"+Str(Y)+" "+"Z:"+Str(Z)+" "+"T:"+Str(T)
EndIf
Ansonsten würde ich STARGÅTE's Code vorziehen :allright:

rs232 in Pure Basic einlesen

Verfasst: 27.08.2009 12:54
von dirtyklaus
Danke für die Tips, werde beide mal probieren.

Die Länge der Strings kann ja von mir vorgeben werden. Ich übertrage einen Bereich von 0-255 je Wert, wenn ich vor dem Senden 100 dazu addiere ist der Wert in jedem Fall 3 stellig.

Was ich mache will ist folgendes:
Ich habe einen XYZ Acceleration Messer am Microprozessor. Die drei Werte der Beschleunigung werden abgefragt und ungefragt über RS232 abgeschickt. Die vierte Variable T ist die Zeitsynchronisation.

In PureBasic will ich diese Werte dazu benutzen eine 3D Szene, z.B. einen Würfel in Echtzeit mithilfe des Accelerators zu bewegen.
Bin erst am Anfang - aber langsam geht es voran.

Gruß - Klaus

Verfasst: 27.08.2009 16:20
von HeX0R
Muss das denn ein String sein?
Finde das etwas merkwürdig/umständlich.

Es würde doch genügen 4 Bytes zu versenden oder nicht?

Verfasst: 27.08.2009 17:58
von dirtyklaus
Tatsächlich ist es das was ich machen will, 4 Bytes versenden. Aber woher weiß ich dann beim Lesen im Datenstrom, welches welches Byte ist? Der Strom ist unaufhörlich, d.h. der Sender sendet immer weiter - ohne Quittung o.Ä.

Deswegen bin ich auf die Idee gekommen einen String zu senden.

Tatsächlich werde ich - auch im Hinblick auf eine spätere Anwendung 4 Words verschicken, aber das ist eigendlich egal.

Wie geht das denn also, vier Bytes versenden ist vom Micoprozessor kein Problem, brauche aber doch noch irgend einen Sync oder so?

Verfasst: 27.08.2009 18:06
von HeX0R
Du denkst dir einfach ein Mickymaus-Protokoll aus.

z.B. in der Art:

Code: Alles auswählen

Structure _MY_SEND_PROTOCOL_
  StartWord.w
  x.b
  y.b
  z.b
  t.b
  ChecksumCRC16.w
EndStructure
Das wären dann immer 8 Bytes, die du versendest / empfängst.
StartWord ist dann quasi ein Identifierword, das immer gleich ist, und woran du erkennst, dass das was da kommt auch wirklich von deiner Kiste ist.
Dadurch wird die Wahrscheinlichkeit schon sehr gering, dass du zufällig mitten im Paket bist (mit der Checksummenüberprüfung wird es sogar nahezu unmöglich).
(Alternativ kannst du auch ein StartLONG benutzen).
z.B. StartWord = $5B1A

Ist StartWord <> $5B1A (also du vermutlich mitten im Paket) liest du solange den Käse aus der Queue, bis das besagte Startword ansteht.

Alternativ gibts dann am Ende noch eine CRC16-Prüfsumme, um zu sehen, dass das Paket i.O. ist.

[Edit]
Hier habe ich noch eine CRC16-Procedure in PB:

Code: Alles auswählen

#CRC16POLY = $A001

Procedure CRC16(*MEMStart.BYTE, L)
	Protected P, k, MyCRC = $FFFF
	;
	While L
		P = *MEMStart\b & $FF
		For k = 1 To 8
			If (P ! MyCRC) & 1 = 1
				MyCRC >> 1
				MyCRC ! #CRC16POLY
				MyCRC & $FFFF
			Else
				MyCRC >> 1
			EndIf
			P >> 1
		Next
		*MEMStart + 1
		L - 1
	Wend

	ProcedureReturn MyCRC
EndProcedure

Verfasst: 28.08.2009 08:39
von dirtyklaus
Habe bis jetzt mit einem String gearbeitet, weil ich die Daten die Microprocessor sendet, mit einem Terminalprogramm mitgelesen habe - das ist dann doch einfacher Klarttext zu sehen. Arbeite mich halt Schritt für Schritt zum Ziel.
Aber ich werde das auch mal probieren - mit den Bytes direkt und der Prüfsumme.
Danke.