LabVIEWForum.de - Verarbeiten von ESC-Sequenzen (VT100)

LabVIEWForum.de

Normale Version: Verarbeiten von ESC-Sequenzen (VT100)
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Seiten: 1 2 3
Hallo Gerd,

Zitat:Warum liest du dann nicht einfach 3968 Bytes mit einem Timeout von 600ms? Dann brauchst du kein BytesAtPort und keine Wartezeit…
- Weil ich mir nicht sicher bin, ob bei einer kompletten, neuen Seite nicht schneller ein neues Paket kommt.
- Weil ich denke, dass es sich so leichter auf andere Anwendungen anpassen lässt
- Weil das Problem nicht beim Lesen von der Schnittstelle liegt, sondern bei der Aktualisierung der Tabelle (und dort bei der Grafik)

Zitat:Aus Gründen der Code-Lesbarkeit solltest du, wann immer nicht der Default-Displaystyle genutzt wird, diesen Displaystyle auch anzeigen lassen.
In deinem Fall also für diese ganzen ESC-Sequencen…
Auf die Idee bin ich komischerweise nicht gekommen, obwohl ich das bei Zahlen doch normalerweise auch mache...

Zitat:Du hast das Array um eine Zeile/Spalte zu groß definiert…
Stimmt, habe ich korrigiert.
(Ich hatte mal einen Fehler in der Anzeige, durch den habe ich geglaubt, die Tabelle würde anders zählen...)

Zitat:Und es fehlt die Typdefinition für diesen Cluster!
Stimmt, habe ich erstellt.
Wobei die Frage ist, ob diese Typdefinition einfach in das Projekt gehört oder in das xControl, welches die Daten ja so vorraussetzt.

Zitat:Wieso wird die Cursorposition mit dem Formatstring "%f" geparst? Das sollten doch Integer-Werte sein - du erzwingst ja selbst die Integer-Darstellung am ScanFromString!?
Stimmt, habe ich geändert.

Zitat:Um einen Terminal-Screen zu simulieren, könnte man auch eine einfache String-Anzeige verwenden und dort einen non-proportional font (wie z.B. Consolas) verwenden!
Dann den String-Indicator einfach auf 24×80 Zeichen in der Größe einstellen…
- Weil sich die String-Anzeige nicht wie das klassische Terminal formatieren lässt (https://en.wikipedia.org/wiki/ANSI_escap...:Htop.png)
- Was ist, wenn ein anderer Anwender die Schriftart nicht hat?
- Kann man die Größe einer String-Anzeige in Zeichen festlegen? Ansonsten kann man nicht sicher sein, dass die Anzeige immer passt.


Vielen Dank! Ich habe einiges dazu gelernt.
Leider kann ich diese Idee, bzw. den Wunsch ein VT100-Terminal inkl. Grafik nachzubilden, nicht weiter verfolgen.
Ich sende noch das Update, dann muss ich mich um andere Aufgaben kümmern.
Hallo Nominas,

Zitat:- Weil ich mir nicht sicher bin, ob bei einer kompletten, neuen Seite nicht schneller ein neues Paket kommt.

- Weil das Problem nicht beim Lesen von der Schnittstelle liegt, sondern bei der Aktualisierung der Tabelle (und dort bei der Grafik)
Ich hatte dir schon vor knapp 3 Wochen ein Producer-Consumer-Schema nahegelegt!
Damit würdest du die serielle Schnittstelle ohne Code-Blockade bedienen können. Und das Lesen des seriellen Ports wäre nicht mehr von der Verarbeitung der Daten abhängig!

Zitat:- Weil ich denke, dass es sich so leichter auf andere Anwendungen anpassen lässt
Hier denke ich genau entgegengesetzt!
Warum sollte der Producer (Lesen der seriellen Schnittstelle) irgendetwas vom Consumer (Verarbeiten der Daten) wissen?
Warum sollte Consumer1 (Verarbeiten der Daten) irgendwie davon abhängig sein, wie Consumer2 (Anzeige der Daten) arbeitet?
Warum ist es einfacher, einen großen monolithischen Code-Block zu verwalten anstelle des Auftrennens in Producer-Consumer?
Warum ist es einfacher, diesen Codeblock anzupassen, wenn man "nur" den Consumer auf ein neues Datenformat anpassen müsste?

Das hat nichts mit LabVIEW an sich zu tun: Code sollte immer nur eine möglichst klar umrissene Aufgabe erfüllen! Und das sollte nicht sowas sein wie "seriellen Port schnell bedienen & gesamten Datenblob verarbeiten & komplizierte Anzeige aktualisieren" - das sind 3 ganz klar getrennte Aufgaben!

Zitat:- Weil sich die String-Anzeige nicht wie das klassische Terminal formatieren lässt (https://en.wikipedia.org/wiki/ANSI_escap...:Htop.png)
Jein. Du kannst durchaus den String formatieren - es ist nur ähnlich langsam wie bei der Tabelle…

Zitat:- Was ist, wenn ein anderer Anwender die Schriftart nicht hat?
Wenn ein User auf einem Standard-Windows keine Consolas-Schrift hat, dann hat der Admin geschlampt…
Genau deswegen gibt es Standard-Fonts auf jedem Betriebssystem!

Zitat:- Kann man die Größe einer String-Anzeige in Zeichen festlegen? Ansonsten kann man nicht sicher sein, dass die Anzeige immer passt.
Wenn du einen non-proportional font einstellst, dann stellst du damit auch die Zeichen-Größe (in Pixeln) ein!
Und dann kannst du auch sehr einfach bestimmen, wie groß dein String-Indicator (in Pixeln) sein muss, um die gewünschte Anzahl Zeichen darzustellen: simple Grundrechenarten reichen dafür…

Bei deiner Tabelle solltest du auch einen non-proportional font einstellen, sonst sieht die Anzeige sehr ungleichmäßig aus! (Ich bin bei sowas sehr empfindlich, ein UI MUSS gut aussehen und ein ordentliches UX bieten.)
Anderenfalls müsste ein Tabellenelement so breit sein, dass ein Buchstabe wie "W"/"Q"/"M" reinpasst, aber gleichzeitig würde ein "1"/"l"/"i" etc. sehr verloren darin aussehen…
Hallo Gerd,

1. Lesen vom Port
Die drei Aussagen
- Weil ich mir nicht sicher bin, ob bei einer kompletten, neuen Seite nicht schneller ein neues Paket kommt.
- Weil ich denke, dass es sich so leichter auf andere Anwendungen anpassen lässt
- Weil das Problem nicht beim Lesen von der Schnittstelle liegt, sondern bei der Aktualisierung der Tabelle (und dort bei der Grafik)
gehören zusammen und beziehen sich nur auf Deinen Vorschlag eine feste Anzahl Bytes mit einem festen Timeout zu lesen.

Welche Möglichkeiten gibt es, den Lese-Rythmus zu bestimmen?
1. Termination-Charakter, bei diesen ESC-Sequenzen kann man "\1B" nehmen. Dann wird aber jede Sequenz einzeln an die Datenauswertung und an die Anzeige übergeben. Das habe ich probiert und verworfen...
2a. "BytesAtPort" abfragen und die anstehenden Daten lesen.
2b. Eine feste Anzahl Bytes und einen passenden Timeout vorgeben.
3. Flow-Control. Hab' ich hier nicht und ist wohl eher selten...

Habe ich da noch etwas übersehen?

Ich habe mich für 2a entschieden, weil
a) es vielleicht Fälle gibt (z.B. bei einer statischen Seite) bei denen ein kleineres Paket gesendet wird.
b) das Lesen (hoffentlich) so auch mit anderen seriellen Schnittstellen funktioniert.
c) ich keinen Grund sehe an dieser Stelle noch irgendwelche Millisekunden zu gewinnen.


2. Software-Struktur
Deinen Vorschlag ein Producer-Consumer-Schema zu verwenden, hatte ich aufgegriffen und ausprobiert.
Dadurch kann schon das nächste Paket von der Schnittstelle gelesen werden, während das vorherige verarbeitet wird.
Das funktioniert aber nur, wenn alle Consumer schnell genug sind! Anderenfalls sammeln sich die Daten halt nicht am Port, sondern im Queue.

Zitat:Code sollte immer nur eine möglichst klar umrissene Aufgabe erfüllen! Und das sollte nicht sowas sein wie "seriellen Port schnell bedienen & gesamten Datenblob verarbeiten & komplizierte Anzeige aktualisieren" - das sind 3 ganz klar getrennte Aufgaben!
Hier denke ich genau entgegengesetzt! (auch ein Zitat Wink)
Es bringt doch nichts, wenn ich den seriellen Port schnell bediene und die Daten auch noch schnell genug verarbeite, aber die Anzeige nicht in der gleichen Zeit aktualisiert bekomme.
Weil das eben keine getrennten Aufgaben sind, bestimmt die langsamste Schleife die Ausführungsgeschwindigkeit.

Auch sehe ich hier keine Möglichkeit, Aufgaben noch weiter zu parallelisieren, da die Abarbeitung des Streams in der Reihenfolge passieren muss.

In meinem vorletzten Versuch hatte ich das Aktualisieren noch in einer parallelen Schleife
Weil ich den Ablauf bei so einem kleinen Programm aber möglichst in einer Linie halte mag UND der letzte Versuch gezeigt hat, das die Anzeige gleich schnell aktualisiert wurde, habe ich es geändert.


3. String-Element und Schriftart
Ja, auch ein String lässt sich formatieren. Aber kann ich z.B. den Hintergrund eines einzelnen Zeichens ändern?
[attachment=62464]

Zitat:Wenn ein User auf einem Standard-Windows keine Consolas-Schrift hat, dann hat der Admin geschlampt…
Da hast Du wohl recht, aber zunächst mal passt dann meine Software nicht.
Ach bei einem non-proportional font sind "i" schmaler als "W", sie beanspruchen nur den gleichen Platz. Außerdem wird es durch Serife etwas ausgeglichen.
Aber wenn ein UI gut aussehen MUSS, verwendet man keine Serife...
Ich habe mit der Tabelle ein bisschen rumprobiert und finde, mit einer mittigen Ausrichtung passt das auch mit anderen Schriftarten.


4. Fazit
Wesentliche Punkte bei der aktuellen Lösung sind
1. Die Datenauswertung in ein Array mit Changed-Flag.
- Dadurch werden in der Anzeige nur geänderte Felder aktualisiert.
- Sollte in einem Daten-Paket ein Wert zweimal vorkommen, werden die Felder im Array überschrieben und die Anzeige nur einmal aktualisiert.
2. Die Umsetzung des Array in die Tabelle innerhalb des xControls.
- Das geht schneller.
- Dadurch wird offenbar der Error 1604 vermieden.

Ich habe die Parallelisierung (siehe 2.) verworfen, weil es so für mich schnell genug funktioniert.
Vielleicht gibt es Fälle, wo man das nochmal aufgreifen muss.
Aber dann sollte man evtl. mehrmals das Daten-Array und nicht so oft die Anzeige aktualisieren.
Du hattest ja schon geschrieben, dass das nur 5-10x pro Sekunde sein muss.
Hallo Nominas,

Zitat:4. Fazit
Wesentliche Punkte bei der aktuellen Lösung sind
1. Die Datenauswertung in ein Array mit Changed-Flag.
- Dadurch werden in der Anzeige nur geänderte Felder aktualisiert.
- Sollte in einem Daten-Paket ein Wert zweimal vorkommen, werden die Felder im Array überschrieben und die Anzeige nur einmal aktualisiert.
Sehe ich auch so, deshalb ja der Vorschlag mit der "internen" Datanhaltung…

Zitat:2. Die Umsetzung des Array in die Tabelle innerhalb des xControls.
- Das geht schneller.
- Dadurch wird offenbar der Error 1604 vermieden.
Fehler 1604 hat mit VIServer-Aufrufen von VIs zu tun - ich sehe nicht, wo das hier vorkommen sollte…
(Allein durch das XControl wird nichts schneller. Es ist immer noch der gleiche Code…)

Zitat:Aber dann sollte man evtl. mehrmals das Daten-Array und nicht so oft die Anzeige aktualisieren.
Du hattest ja schon geschrieben, dass das nur 5-10x pro Sekunde sein muss.
Das dürfte wirklich was bringen!
Du musst die Anzeige nicht "so oft wie möglich" und schon gar nicht "schneller/öfter als der Datenlieferant" aktualisieren - deshalb der Vorschlag, die Funktionalitäten aufzutrennen…

Kannst du eigentlich mal ein paar Datenpakete (also komplette ~4kB) bereitstellen? Z.B. als VI mit ein paar Stringkonstanten, die jeweils einen Datenblock enthalten!?
Hallo Gerd,

Zitat:Du musst die Anzeige nicht "so oft wie möglich" und schon gar nicht "schneller/öfter als der Datenlieferant" aktualisieren - deshalb der Vorschlag, die Funktionalitäten aufzutrennen…
Mit diesem Vorschlag hatte ich ja auch verschiedene Versuche gemacht. Das Entscheidende war aber die Erkenntnis, dass man nicht die ganze Tabelle aktualisieren muss.
Genau genommen wird auch nicht die Änderung beurteilt, sondern ob für das Feld ein Wert gesendet wurde.

Für den Punkt "Funktionalität auftrennen" sieht es bei meiner Anwendung wohl so aus:
Beispiel 1: Der Datenlieferant sendet alle 400ms ein 4kB-Paket; die Datenaufbereitung dauert 100ms; das Aktualisieren der Anzeige 700ms
>> In Reihe laufen die Daten am Port auf, parallel sammeln sich die Pakete in der Queue "Anzeige"
Beispiel 2: Der Datenlieferant sendet alle 400ms ein 4kB-Paket; die Datenaufbereitung dauert 100ms; das Aktualisieren der Anzeige 200ms
>> Egal wie, der Datenlieferant bestimmt den Takt.

Wenn der Datenlieferant schneller und vielleicht kleinere Pakete sendet, sieht es natürlich ganz anders aus!

Zitat:Fehler 1604 hat mit VIServer-Aufrufen von VIs zu tun - ich sehe nicht, wo das hier vorkommen sollte…
Das verstehe ich auch nicht. Aber selbst in diesem kleinen VI kommt der Fehler:
[attachment=62465]

Zitat:Kannst du eigentlich mal ein paar Datenpakete (also komplette ~4kB) bereitstellen? Z.B. als VI mit ein paar Stringkonstanten, die jeweils einen Datenblock enthalten!?
Tut mir leid, dass geht nicht. Ich habe dieses Thema in meiner Freizeit verfolgt, weil es mich einfach interessiert hat.
Aber die Anwendung ist, wenn auch vielleicht nicht streng geheim, aber doch firmen-intern.
Hallo Nominas,

Zitat:Das verstehe ich auch nicht. Aber selbst in diesem kleinen VI kommt der Fehler:
Bei mir kommt kein Fehler. (LV2016)

Zitat:Beispiel 1: Der Datenlieferant sendet alle 400ms ein 4kB-Paket; die Datenaufbereitung dauert 100ms; das Aktualisieren der Anzeige 700ms
>> In Reihe laufen die Daten am Port auf, parallel sammeln sich die Pakete in der Queue "Anzeige"
Die Datenaufbereitung stellt immer ein Array mit den aktuellen Daten bereit.
Die Anzeige benötigt nur den aktuellen Zustand - und deshalb nur einen Notifier mit den aktuellen Daten. Schon bestimmt nicht mehr die Anzeige, wie schnell Daten verarbeitet werden! Nur die Datenaufbereitung muss schneller sein als der Datenlieferant…
(10.01.2023 10:52 )GerdW schrieb: [ -> ]Hallo Nominas,

Zitat:Das verstehe ich auch nicht. Aber selbst in diesem kleinen VI kommt der Fehler:
Bei mir kommt kein Fehler. (LV2016)
In LabVIEW 2021 beispielsweise kommt bei mir der Fehler (bei aktiviertem automatischer Fehleranzeige).

Wer weiß, was NI da im Hintergrund mit der Aktualiserung der Tabelle und dem Aufklappen des Picture-Rings programmiert hat.

Workaround: "Clear Errors" nach der Invoke-Node anschließen, um den Fehlerdialog zu ignorieren.

Gruß, Jens
Zitat:Die Anzeige benötigt nur den aktuellen Zustand - und deshalb nur einen Notifier mit den aktuellen Daten. Schon bestimmt nicht mehr die Anzeige, wie schnell Daten verarbeitet werden! Nur die Datenaufbereitung muss schneller sein als der Datenlieferant…
Das meinte ich mit meinen Beispielen. Wenn man versucht immer alle Tabellenfelder zu formatieren, dann dauert das zu lange. Da hilft es aber auch nichts die Funktionen zu trennen.
Wenn man nur notwendige Tabellenfelder aktualisiert, geht das schnell genug. Dann ist das Producer-Consumer-Design aber eher eine Frage von Vorliebe oder Gewohnheit.
Aber nur hier bei meiner Anwendung!
Zitat:Wenn der Datenlieferant schneller und vielleicht kleinere Pakete sendet, sieht es natürlich ganz anders aus!


Mit dem Fehler 1604 ist aber merkwürdig.
- Das Beispiel (irgendwo aus einem Internetforum) scheint in LV2012 zu sein
- Bei Gerd (LV2016) kommt kein Fehler
- Bei mir (LV2018) kommt der Fehler
- Bei Jens (LV2021) kommt der Fehler

Gerd, kann das, wie Jens schreibt, mit der automatischen Fehleranzeige zusammenhängen?


Zitat:Workaround: "Clear Errors" nach der Invoke-Node anschließen, um den Fehlerdialog zu ignorieren.
Das habe ich probiert, aber dann funktioniert ein DropDown, oder in dem kleinen Beispiel der Bild-Ring, nicht mehr oder nicht richtig.
In meinen Versuchen habe ich das auch dann beobachtet, wenn die Eigenschaftsknoten in einem SubVI waren,
aber nicht bei dem xControl, da scheint es zu funktionieren.
(12.01.2023 13:52 )Nominas schrieb: [ -> ]Wenn man versucht immer alle Tabellenfelder zu formatieren, dann dauert das zu lange. Da hilft es aber auch nichts die Funktionen zu trennen.
Verkürzt du dir nicht deine Zeit, die du hast um die Tabelle zu aktualisieren, um die Wartezeit die du für den Empfang verwendest?
Wenn man hier zwei Schleifen verwendet, hat man für die Anzeige zumindest noch die Zeit extra, die verwendet wird, die Daten zu empfangen.

Vermutlich hier nicht viel, aber mehr.

Grüße Timo
Hallo Nominas,

Zitat:Das meinte ich mit meinen Beispielen. Wenn man versucht immer alle Tabellenfelder zu formatieren, dann dauert das zu lange. Da hilft es aber auch nichts die Funktionen zu trennen.
Wenn man nur notwendige Tabellenfelder aktualisiert, geht das schnell genug. Dann ist das Producer-Consumer-Design aber eher eine Frage von Vorliebe oder Gewohnheit.
Und wenn man die Änderungen erst in einem Zwischenbuffer sammelt und die Anzeige nur "bei Bedarf" (oder in regelmäßigen Abständen) aktualisiert, dann macht sich eine Entkoppelung von Funktionen (aka Producer-Consumer) ruckzuck bezahlt…

Zitat:Gerd, kann das, wie Jens schreibt, mit der automatischen Fehleranzeige zusammenhängen?
Ja, das ist sehr wahrscheinlich.
Was aber auch für Jens' Vorschlag bezüglich besserem Errorhandling spricht, d.h. ClearErrors…
Seiten: 1 2 3
Referenz-URLs