Synchronisation uC - LabVIEW - Druckversion +- LabVIEWForum.de (https://www.labviewforum.de) +-- Forum: LabVIEW (/Forum-LabVIEW) +--- Forum: LabVIEW Allgemein (/Forum-LabVIEW-Allgemein) +---- Forum: Instrument IO & VISA (/Forum-Instrument-IO-VISA) +---- Thema: Synchronisation uC - LabVIEW (/Thread-Synchronisation-uC-LabVIEW) Seiten: 1 2 |
Synchronisation uC - LabVIEW - ETech_Uri - 11.02.2015 11:01 Hallo liebe Community, im Rahmen meiner Masterarbeit möchte ich einen Versuchsstand mit LabVIEW steuern. Dazu nutze ich den Mikrocontroller 80C166 von Siemens/Infinion über eine RS232. Neben diversen Funktionalitäten bin ich aktuell dran, Messwerte zu verarbeiten die permanent vom uC gesendet werden. Die Struktur einer Botschaft ist immer die gleiche: 1 Startbyte 20 Datenbyte (10 I16-Zahlen) 1 Stoppbyte = 22 Gesamtbyte Ich arbeite mit den "Standardeinstellungen" der RS232 bei variabler Baudrate und ohne Flusssteuerung (aktuelle Tests mit Baudrate 57600). Mit dem angehängten VI funktioniert alles weitestgehend so wie ich mir das vorstelle, bis auf das die Synchronisation bei sehr kleinen Sendezeiten <50ms verloren geht. Die dadurch falsch empfangenen Pakete verwerfe ich und lösche den I/O-Buffer um einen Bufferüberlauf zu vermeiden. Nach gewisser Zeit synchronisiert sich der Datenaustausch wieder, empfängt korrekt und fällt irgendwann wieder "außer Tritt". Meine erste Vermutung war das der uC falsch sendet bzw. asynchron wird. Mit HTerm habe ich das überprüft und festgestellt, dass dies nicht der Fall ist und hier alles iO ist (Timestamp und Struktur passen immer). Daher gehe ich davon aus das mein VI die Ursache ist (Laufzeiten?)... nun suche ich nach Möglichkeiten hier stabiler/besser zu werden, so dass eine möglichst große Anzahl an Datenpaketen verarbeitet werden kann (bspw. mit "Warten auf Vielfaches von ms" mit der Sendezeit, aber das hat nicht wirklich geholfen). Meine LabVIEW-Erfahrungen halten sich in Grenzen (beschäftige mich erst seit Beginn des Jahres damit) und ich habe auch im Forum schon etwas gesucht, aber nicht wirklich was passendes gefunden. Daher würde ich mich über eine konstruktive Diskussion und Vorschläge zur Verbesserung sehr freuen und danke schon jetzt Jedem, der sich mit der Thematik beschäftigen wird. Ich werde auch weiter daran arbeiten und hier Neuigkeiten posten. Grüße, Uri [attachment=52090] RE: Synchronisation uC - LabVIEW - GerdW - 11.02.2015 11:18 Hallo Uri, mehrere Fehler: - Wartezeit in dieser Schleife ist unnötig und stört hier - Vergleich auf exakt 22 bei BytesAtPort stört hier - BytesAtPort ist generell störend - ständiges Leeren des Buffers ist störend - unsynchronisiertes Lesen und darauffolgendes Auswerten fester Byte-Indices ist störend Besser: - Generell 22 Byte vom VISA-Port lesen - gelesene Bytes zu einem Array/String zusammenbauen - aus diesem Datenstrom dann selbst den Anfang/das Ende der Botschaft suchen - Botschaft aus dem Datenstrom entnehmen und auswerten Ansonsten: - Dein E-Counter-FeedbackNode als U32 initialisieren! - Dein "Status" nicht innerhalb der Case-Struktur, sondern davor beschreiben. Das erspart dir 2 lokale Variablen! Nachtrag und Vorschlag: [attachment=52102] Dies ist ein Grundgerüst, das Finden/die Auswertung der Botschaft müsste noch etwas verfeinert werden… RE: Synchronisation uC - LabVIEW - jg - 11.02.2015 11:47 Wer hat denn den µC programmiert? Es ist extrem störend, dass Start- und Stoppbyte (0x01 und 0x02) auch im normalen Datenstrom auftauchen können. Wie soll man da eine sinnvolle Synchronisation auf den Datenstrom hinbekommen? Viel einfacher wäre es, wenn das Stoppbyte nicht in den Normaldaten auftaucht, dann könnte man einfach mit dem Termination Char arbeiten. Zum Thema Sync gibt es hier, Beitrag 3, Hinweise. Gruß, Jens RE: Synchronisation uC - LabVIEW - ETech_Uri - 11.02.2015 12:20 Danke für eure zügigen Antworten @Gerd: Werde mir deinen Vorschlag mal anschauen und sehen was damit zu erreichen ist (11.02.2015 11:47 )jg schrieb: Wer hat denn den µC programmiert? Es ist extrem störend, dass Start- und Stoppbyte (0x01 und 0x02) auch im normalen Datenstrom auftauchen können. Wie soll man da eine sinnvolle Synchronisation auf den Datenstrom hinbekommen? Viel einfacher wäre es, wenn das Stoppbyte nicht in den Normaldaten auftaucht, dann könnte man einfach mit dem Termination Char arbeiten.Die Programmierung an und für sich macht jmd anders der auch keine wirkliche Ahnung von LabVIEW/serieller Kommunikation hat - ist aber auch noch nicht festgelegt. Die Befürchtung schlecht gewähler Bytes hatten wir auch schon immer im Hinterkopf irgendwo^^ Es ging hier hauptsächlich darum erstmal zu schauen was überhaupt möglich ist - hier sind also Änderungen, die das Verhalten verbessern jederzeit möglich und auch Vorschläge dafür gern gehört. Edit Habe mal Gerds Grundgerüst nachvollzogen und auf meine Zwecke angepasst - prinzipiell geht mir so bei 10ms Sendeintervall (das ist das Kleinste was ich momentan betrachte) keine Botschaft mehr verloren - s. dazu Anhang. Herzlichen Dank für die Anregung und das Beispiel. Jedoch funktioniert das erstmal nur dann, wenn auch wirklich das Startbyte das erste Byte ist. Starte ich asynchron kommt logischerweise ein Fehler, um diese Behandlung muss ich mich noch kümmern. RE: Synchronisation uC - LabVIEW - Lucki - 11.02.2015 14:02 Daß das Vi "weitgehendst so funktioniert wie ich mir vorstelle" kann ich mir nicht vorstellen. Beispiel Startbyte-Erkennung: Du entfernst das erste Zeichen aus dem String und vergleichst es mit "01". Wie kann ein einstelliger String je identisch mit einem zweistelligem String sein? Das Gleiche beim Stoppbyte. Und überhaupt: Wenn direkt die Datenbytes übertragen werden, dann werden a) meistens undarstellbare Stringzeichen übertragen, und b) funktioniert dann die Synchronisierung mit Start- und Stoppbyte nicht, denn jedes der 256 dafür möglichen Zeichen kann auch mitten im Datensatz auftauchen. Deshalb liegt die Vermutung nahe, dass bei Dir die Daten als lesbare ASCII-Zeichen übertragen werden, und das heißt: Für jedes zu übertragende Zahlenbyte braucht man 2 Stringbytes für die Übertragung, also z.B für der Übertragung der Zahl 255 die beiden Stringzeichen "FF". (Manchmal werden sogar Dezimalstrings benutzt , dann braucht man drei Zeichen für ein byte, also hier im Beispiel die Zeichenkette "255") Für Deinen Datensatz heißt das entweder: Du sendest zehn I16-Zahlen. Dafür brauchts Du aber einem HEX-String der Länge 40 und nicht 20, wie Du schreibst, alsa mit Start- und Stoppbyte 42. oder: Der String hat die Länge 22 so wie von Dir beschreiben. Dann werden aber darin nur fünf I16-Zahlen übertragen und nicht 10 wie Du schreibst. Also kläre das erst mal, dann werden wir weiter sehen. Und poste mal einen Originalstring vom µC, dann wird man sehen, was wirklich ankommt. Gruß Ludwig Edit: Die letzen beiden Antworten habe ich beim Abfassen des Beitrages hier noch nicht gekannt. Und es gibt keine spezifische "serielle Labview-Kommunikation", von der Du im letzten Beitrag schreibst. Um am µC eine brauchbare serielle Ausgabe zu programmieren, muß man nicht den geringsten Schimmer von Labview haben. RE: Synchronisation uC - LabVIEW - GerdW - 11.02.2015 14:19 Hallo Lucki, Zitat:Wie kann ein einstelliger String je identisch mit einem zweistelligem String sein?Die Stringkonstanten "01" und "02" im VI aus dem ersten Beitrag sind auf HEX-Display eingestellt - und nicht im Normalmodus. Vielleicht hilft das bei der Beantwortung deiner Frage… RE: Synchronisation uC - LabVIEW - Lucki - 11.02.2015 14:44 @Gerd Danke, Dein Hinweis war wichtig, das hatte ich übersehen. Und vor allem wird auch für den empfangenen String in der Anzeite die HEX-Darstellung verwendet, und das wurde offensichtlich gemacht, weil tatsächlich undarstellbare Zeichen gesendet werden. Man kann dann trotzdem Start und/oder Stopbyte verwenden, aber es wird kompliziert. Beispiel: FF als Start oder Stopbyte. Dann darf FF weder im high- noch im low-byte der I16-Zahlen vorkommen. Die Zahlen, bei denen das der Fall ist, müssen auf komplizierte Weise konvertiert und rückkonvertiert werden. Für solche konvertierten Zahlen muss ein Zahlenbereich am oberen oder unteren Ende des Zahlenraums reserviert werden, der dann normal nicht verwendet werden kann. Das ist aber solange Krampf, solange man auf die erhöhte Übertragungsgeschwindigkeit nicht wirklich angewiesen ist. Eine andere Synchronisierungsmöglichkeit wäre die Detektierung der Pausen zwischen den Datensätzen. Fügt man aber senderseitig diese Pausen ein, dann macht man den Vorteil der erhöhten Übertragunsgeschwindigkeit wieder zunichte. Außerdem ist es nicht absolut zuverlässig, Pausen kann es auch so mitten in der Übertragung geben. RE: Synchronisation uC - LabVIEW - ETech_Uri - 11.02.2015 14:47 Ich versuche mal zu erläutern sofern ich dich richtig verstehe (11.02.2015 14:02 )Lucki schrieb: Daß das Vi "weitgehendst so funktioniert wie ich mir vorstelle" kann ich mir nicht vorstellen. Beispiel Startbyte-Erkennung: Du entfernst das erste Zeichen aus dem String und vergleichst es mit "01". Wie kann ein einstelliger String je identisch mit einem zweistelligem String sein? Das Gleiche beim Stoppbyte.Ich vergleiche das erste Zeichen/Byte des empfangenen "Strings" mit 0x01 - die Konstante ist quasi hexadezimal und entspricht ja dann einem Byte. Dasselbe beim Stoppbyte, nur mit anderem Hex-Zeichen... meine Tests haben gezeigt das es so funtioniert. (11.02.2015 14:02 )Lucki schrieb: Und überhaupt: Wenn direkt die Datenbytes übertragen werden, dann werden a) meistens undarstellbare Stringzeichen übertragen, und b) funktioniert dann die Synchronisierung mit Start- und Stoppbyte nicht, denn jedes der 256 dafür möglichen Zeichen kann auch mitten im Datensatz auftauchen.Ich übertrage ja einen Binärstring bestimmer Struktur, die Idee/Anregung habe ich auch hier aus dem Forum. I16 hat eine Länge von 2 Byte, damit kann ich Werte von -32768 ... 32767 realisieren. Müsste ich das mit Zeichen machen bräuchte ich dafür 1 bis. max 6 Byte was unvorteilhaft wäre für die Geschwindigkeit. 10 I16 Zahlen sind 20 Datenbyte was mit Start/Stop 22 Gesamtbyte macht. Am Ende ist das ja nur eine Sache wie ich meine Bytes interpretiere. Ein Hex-String der Länge 40 entspricht ja einer Größe von 20 Bytes wenn ich mich nicht irre (11.02.2015 14:02 )Lucki schrieb: Also kläre das erst mal, dann werden wir weiter sehen. Und poste mal einen Originalstring vom µC, dann wird man sehen, was wirklich ankommt.Im Anhang dazu mal ein Shot aus HTerm mit 1 Botschaft (ASCII, HEX, Binär) (11.02.2015 14:02 )Lucki schrieb: Und es gibt keine spezifische "serielle Labview-Kommunikation", von der Du im letzten Beitrag schreibst. Um am µC eine brauchbare serielle Ausgabe zu programmieren, muß man nicht den geringsten Schimmer von Labview haben.Da habe ich mich wohl unter Umständen falsch ausgedrückt RE: Synchronisation uC - LabVIEW - GerdW - 11.02.2015 14:56 Hallo Uri, Zitat: I16 hat eine Länge von 2 Byte, damit kann ich Werte von -32768 ... 32767 realisieren. Müsste ich das mit Zeichen machen bräuchte ich dafür 1 bis. max 6 Byte was unvorteilhaft wäre für die Geschwindigkeit.Falsch. Ein I16 benötigt zwei Byte, das stimmt. Damit kann man Werte von 0x8000 bis 0x7ffff darstellen, du benötigst also immer 4 Byte (in ASCII-Hex-Darstellung) - und nicht variable 1 bis 6 Byte! Und du hättest den Vorteil (wie von Lucki bemerkt), dass du deine Daten nur als lesbare ASCII-Zeichen verschickst und JEDES "non-readable" Zeichen problemlos als TermChar verwenden kannst! RE: Synchronisation uC - LabVIEW - jg - 11.02.2015 14:58 (11.02.2015 14:47 )ETech_Uri schrieb: Ich übertrage ja einen Binärstring bestimmer Struktur, die Idee/Anregung habe ich auch hier aus dem Forum. I16 hat eine Länge von 2 Byte, damit kann ich Werte von -32768 ... 32767 realisieren. Müsste ich das mit Zeichen machen bräuchte ich dafür 1 bis. max 6 Byte was unvorteilhaft wäre für die Geschwindigkeit. 10 I16 Zahlen sind 20 Datenbyte was mit Start/Stop 22 Gesamtbyte macht. Am Ende ist das ja nur eine Sache wie ich meine Bytes interpretiere.Aber genau hier entsteht das von mir beschriebene Problem. Diese 2 Bytes können als String in Hex-Darstellung alle Werte zwischen 0x0000 bis 0xFFFF enthalten, und somit auch die von dir gewählten Start- und Stopp-Bytes 0x01 und 0x02. Extrembeispiel: Alle deine I16-Werte sind 513dez, also in Hex-Darstellung 0x0201. Dein Datenstring inkl. Start- und Stopp-Byte lautet somit 21-mal "0x01 0x02". Was ist jetzt der Anfang, was das Ende der Nachricht? Deutlich einfacher wäre das Parsen, wenn das Übertragungsformat anders wäre. Lucki hat hier einen Vorschlag angedeutet. Du könntest die I16-Werte nicht binär übertragen, sondern vor der Übertragung in einen Hex-String wandeln. Jeder Wert entspricht somit einem String aus 4 ASCII Zeichen, wobei jedes ASCII-Zeichen aus der Menge {0-9, A-F} stammt. Das Start-Byte kannst du dir dann schenken, und als Stopp-Byte nimmst du z.B. <CR> oder <LF>, ein ASCII-Zeichen, welches jetzt nicht mehr in den Daten vorkommt. Nachteil: Die Übertragung ist jetzt 41 Zeichen lang. Gruß, Jens |