UPT Programmiertool : CAN-Simulator
Inhalt
- CAN Message Generator / Bus-Simulator
- Einleitung
- Extraktion von CAN-Signal-Definitionen aus UPT-Variablen
- Behandlung von 'zu sendenden' UPT-Variablen ('TX' aus Sicht des simulierten Gerätes)
- Die Option 'Werte in Simulation einspeisen'
- Die Option 'Auf echtem CAN-Bus senden'
- Definitionstabelle für CAN-Signale
- Stimulus (Numerischer Ausdruck mit einer 'Generatorfunktion')
- Sendezyklus (Interval für periodisch gesendete Signale)
- Parameter zum Abbilden ('mappen') von Signalen in CAN-Messages
- Das "Update-Intervall" des Simulators
- Automatisierung / Programmierbare Testabläufe
- Tabelle mit programmierbaren "Conditional Actions" (Ereignisse und Reaktionen)
- 'select'..'case'..'endselect'-Blöcke in den 'Conditional Actions'
- Spezielle Interpreterfunktionen des CAN-Simulators
- CAN-Empfang per can_rx(<ID> <Datenfeld>) abfragen
- Spezielle Interpreterkommandos des CAN-Simulators
- Zugriff auf CAN-Signale, interne Variablen, programmierbare Timer
- Details zum kommandogesteuerten Senden von Signalen
- Signal-Sende-Timing und per Kommando "erzwungenes" Senden
- Das Senden gemultiplexter CAN-Messages
- Direktes Senden / "Einspeisen" von CAN-Messages per can_tx(<ID> <Datenfeld>)
- Haltepunkte und Einzelschritt-Betrieb in den Conditional Actions
- Programmierbare Buttons (auf Registerkarte "Automatisierung")
- Textkonsole (Editorfenster mit Anzeige von per 'csim.print' erzeugten Meldungen)
- Optionen zur Synchronisation zwischen Applikation (Display-Simulator) und CAN-Simulator
- Tipps zur Verwendung des CAN Message Generators (für Fortgeschrittene)
CAN Message Generator / Bus-Simulator
Einleitung
Steht Ihnen ein 'realer' CAN-Bus, z.B. Fahrzeug mit Motorsteuergerät und passendem CAN-Bus-Adapter
zur Verfügung, dann benötigen Sie den in diesem Dokument beschriebenen CAN-Generator/Simulator nicht.
Ein Test der Applikation am 'echten Gerät' ist immer besser als diese Simulation, denn die Simulation
kann keine Fehler wie z.B. falsch eingestellte CAN-Bus-Parameter (Baudrate, Sampling Point, Abschlusswiderstände),
Kabelfehler, usw. aufdecken.
Ist der Weg zum 'echten CAN-Netzwerk' aber zu weit, bietet sich der Ersatz von (aus Sicht des Terminals empfangenen) CAN-Signalen
durch den in diesem Dokument beschriebenen CAN-Generator/Simulator an. Der Simulator kann aus dem
Hauptmenü des Programmiertools
über 'Werkzeuge' .. 'CAN Message Generator / Bus Simulator' geöffnet werden.
Der CAN-Simulator kann Signale ohne physikalisches CAN-Interface in die Simulation innerhalb des Programmiertools
einspeisen, oder mit Hilfe eines geeigneten CAN-Interfaces die Signale (verpackt in CAN- oder CAN-FD-Messages)
auf einem oder zwei 'echten' CAN-Bussen zu senden.
Screenshot des 'CAN-Simulators' (Teil des UPT-Programmiertools) mit Definitionen von zu sendenden CAN-Signalen.
Farbige Markierungen entsprechen dem CAN-Message-Layout (rechts unten).
Die Bedeutung der Spalten in der oben gezeigten Tabelle wird in den folgenden Kapiteln noch genauer vorgestellt.
In der Spalte Expression / Stimulus kann
ein numerischer Ausdruck definiert werden, mit dem das in der Zeile definierte CAN-Signal
mit 'ständig neuen' Werten versorgt werden kann. Der i.A. aus einem Stimulus berechnete
'aktuelle' Wert wird in der Spalte 'Current Value' angezeigt. Darüberhinaus können
mit dem CAN-Simulator auch komplexere Testabläufe automatisiert werden.
Extraktion von CAN-Signal-Definitionen aus UPT-Variablen
Fast alle Informationen über ein bestimmtes Signal (z.B. "Drehzahl") sind bereits in der Applikation
enthalten (z.B. nach Import aus einer entsprechenden Datenbank). Sie können daher mit
wenigen Mausklicks aus den UPT-Display-Variablen, aber auch (falls vorhanden) aus der importierten
CAN-Datenbank übernommen werden:
- Fenster des CAN-Simulators öffnen: Im Hauptmenü unter Werkzeuge .. CAN Message Generator / Bus-Simulator
- Dort: Signal hinzufügen .. ALLE Signale aus UPT-Display-Variablen übernehmen
- Haken vor Werte in Simulation einspeisen setzen, evtl. auch Auf echtem CAN-Bus senden (Vorsicht !).
- In die Zeile mit dem zu ändernden Wert klicken um ein Signal zu selektieren
- Mit dem vertikalen Schieber den selektierten Wert ändern
Der oben beschriebene Ablauf ist nur die einfachste (schnellste) Möglichkeit, um ein einzelnes Signal zu
verändern. Sollen mehrere Werte 'ständig' geändert werden, bietet sich die Eingabe eines numerischen Ausdrucks
(Stimulus, 'Erregerfunktion') in der Tabellenspalte Expression (Stimulus) an.
Behandlung von 'zu sendenden' UPT-Variablen ('TX' aus Sicht des simulierten Gerätes)
Da das UPT (User Programmable Terminal, z.B. "MKT-View") CAN-Signale optional auch senden kann
(statt diese als reine 'Anzeige' nur zu empfangen),
besteht bei der oben beschriebenen Extraktion von CAN-Signal-Definitionen ein potenzielles Problem:
Würde der CAN-Simulator solche Signale ebenfalls auf dem CAN-Bus senden,
könnten sich von der CAN-Hardware nicht auflösbare Kollisionen (*) ergeben.
Ausser für "Stress-Tests" (bei dem im Labor CAN-Identifier-Kollisionen bewusst provoziert werden)
sollte das gleichzeitige Senden des gleichen CAN-Message-Identifiers von mehreren CAN-Knoten vermieden werden.
Seit 2023-01-05 vermeidet der im "CAN Terminal Programming Tool" integrierte CAN-Simulator das oben beschriebene Problem wie folgt:
- Nur CAN-Signale, die vom UPT im Normalbetrieb EMPFANGEN werden (per UPT-Display-Variable mit CAN-Anbindung, Markierung "RX")
werden bei der Übernahme in den CAN-Message-Generator / Bus-Simulator für das aktive SENDEN markiert;
- CAN-Signals, die vom UPT im Normalbetrieb GESENDET werden (ebenfalls per Display-Variable mit CAN-Anbindung, Markierung "TX")
werden in den CAN-Message-Generator / Bus-Simulator als RECEIVE-ONLY übernommen,
und in der Signal-Definitionstabelle in der Spalte "TX cyle" mit dem Zusatz "(RX)",
d.h. "Empfangen, aber nicht Senden" gekennzeichnet.
Die Option 'Werte in Simulation einspeisen'
Mit der Option Werte in Simulation einspeisen dienen die z.B. per Schieber geänderten Werte
in der programmiertool-interne "Simulation" als Ersatz für vom CAN-Bus empfangene.
Diese Option reicht in vielen Fällen bereits aus, um eine Applikation am PC / im PC zu testen.
Sie hat - im Gegensatz zur Option 'Auf echtem CAN-Bus senden'
keine Auswirkungen auf die Funktion externer Geräte, und erfordert kein CAN-Bus-Interface am PC.
Die Option 'Auf echtem CAN-Bus senden'
Die Option Auf echtem CAN-Bus senden sollte nur verwendet werden, wenn der PC (Programmiertool) direkt
mit dem MKT-View per CAN-Interface verbunden ist,
aber darüberhinaus keine anderen Teilnehmer am CAN-Netzwerk hängen.
Das Programmiertool sendet nämlich in diesem Fall die Telegramme, die das Terminal (MKT-View)
im Normalfall nur empfangen würde - was, im laufenden Betrieb "am Fahrzeug" zu schwerwiegenden
Kollisionen führen dürfte, wenn zwei Knoten (der PC und ein Steuergerät im Fahrzeug) CAN-Telegramme
mit dem gleichen CAN-Message-Identifier senden. In einigen Fällen kann dies bis zum Zustand 'Bus-Off' führen,
d.h. einer der Teilnehmer stellt seine CAN-Sendungen ein.
Die Option 'Auf echtem CAN-Bus senden' wirkt sich wie hier
beschrieben auch auf das Verhalten des Simulator-Befehls can_tx()
(zum direkten "Senden" kompletter CAN-Messages) aus.
Siehe auch: Aufzeichnen und Abspielen von CAN-Telegrammen per 'CAN-Snooper',
Abspielen von aufgezeichneten CAN-Telegrammen im Simulator,
Das CAN-Bus-Interface im/am PC.
Definitionstabelle für CAN-Signale
Im allgemeinen werden die Signaldefinitionen für den CAN-Simulator wie in der Einleitung beschrieben
aus den Variablen-Definitionen der Applikation extrahiert.
Alternativ können Signaldefinitionen auch manuell in die Definitionstabelle eingegeben werden.
Definitionstabelle für den CAN-Signal-Simulator
Die Spalten in der Tabelle entsprechen z.g.T. den im Handbuch des Programmiertools vorgestellten
Eigenschaften von Variablen, die mit CAN-Signalen verknüpft sind.
Details zur Bedeutung "CAN-(Message-)ID", "Position des niederwertigsten Bits", "Intel/Motorola" (Byte Order),
usw. finden Sie im oben verlinkten Dokument.
Name
- Im Normalfall aus der Variablen-Definitions-Tabelle übernommener Name.
Bei Signalen, die nicht aus einer CAN-Datenbank importiert wurden, sollte hier ein eindeutiger,
'sprechender' Name eingegeben werden.
- Tipp zu den Signalnamen:
- Per Kontext-Menü (Anklicken des Namens mit der rechten Maustaste)
kann eine globale Suche
nach dem Namen gestartet werden (d.h. nicht nur in der CAN-Simulation,
sondern auch auf allen Anzeigeseiten, und in Event-Definitionen
der Applikation, in denen eine gleichnamige Display-Variable verwendet wird).
Expression (Stimulus)
- Optionale 'Generatorfunktion'. Wenn vorhanden, wird dieser numerische Ausdruck vom Display-Interpreter
ständig neu berechnet (Intervall aus dem Eingabefeld auf der rechten Seite), und das Ergebnis als neuer
Signalwert in die Spalte "Current Value" übernommen.
Per Doppelklick in leere Zellen in dieser Spalte kann ein numerischer Ausdruck erzeugt werden,
mit dem eine niederfrequente Sinusfunktion für das entsprechende Signal berechnet werden kann.
Jedes Signal erhält dabei eine leicht unterschiedliche Frequenz. Die Amplitude wird passend zu den
Einstellungen in den Spalten MinValue und MaxValue
skaliert. Um dies für alle in der Tabelle enthaltenen Signale zu wiederholen, wählen Sie
unter 'Weitere Optionen...' den Menüpunkt 'Stimuli für ALLE Signale erzeugen'. So können
mit wenig Aufwand für alle in der geladenen Applikation verwendeten CAN-Signale
ständig wechselnde "Dummy-Werte" erzeugt werden, z.B.:
isin(tsim_ms) / 4
erzeugt eine Sinusfunktion
mit der Amplitude 32767/4 = ca. 8191
und Periodendauer 1024 Millisekunden, d.h. Frequenz etwa 1 Hz,
deren erster positiver Nulldurchgang
beim Start der CAN-Simulation beginnt.
(Erläuterung: Die Interpreter-Funktion tsim_ms liefert
die seit dem Start der CAN-Signal-Simulation ("Run") vergangene Zeit in Millisekunden als Integer-Wert.
Die ältere -aber in jeder Firmware vorhandene- Funktion ti_ms
liefert dagegen die seit dem Start der Display-Applikation (bzw. "simulierten Einschalten" des Targets)
verstrichene Zeit. Die Funktion isin
erwartet einen Argumentenbereich von 0..1023 (entspricht 0..360°) für eine volle Sinusschwingung,
und liefert einen Wertebereich von -32767 bis +32767. Ein- und Ausgänge sind Integer-Werte.)
Current Value
- Aktueller Wert für die Simulation. Quelle: Vertikaler Schieber oder der o.g. numerische Ausdruck (Stimulus).
TX cycle (ms)
- Sendezyklus für dieses Signal in Millisekunden.
Ohne Sendezyklus (0 ms) wird ein Signal bei jeder Änderung (per Schieber oder Stimulus) sofort gesendet,
d.h. "ereignisgesteuert".
Unter 'Weitere Optionen...' / 'Sende-Intervall für ALLE Signale setzen' können Sie mit zwei Mausklicks
die zyklische Sendung aller in der Tabelle definierter Signale erzwingen.
Das Intervall wird dabei aus dem Eingabefeld in der rechten Fensterhälfte in alle
Definitionszeilen übernommen, für die noch kein Sende-Intervall definiert ist.
Message ID
- Hexadezimaler CAN-Message-Identifier. Dreiziffrig für "Standard-IDs" (11 Bit), achtziffrig für "Extended IDs" (29 bit).
Bus
- Für Systeme mit mehreren CAN-Schnittstellen, die auch mit unterschiedlichen Baudraten
betrieben werden können.
Diese Funktion wurde bislang nur mit mehrkanaligen Interfaces von Kvaser getestet, z.B. 'Kvaser Hybrid 2xCAN/LIN'.
Für "Bus 1" definierte Signale/Messages werden dann auf Kvaser's "Ch.1" (Label am DSUB-Stecker) gesendet, usw.
LSB pos
- Position des niederwertigen Bits im CAN-Datenfeld (0..63 bei "normalem" CAN).
Num bits
- Anzahl Datenbits, mit denen dieses Signal AUF DEM CAN-BUS übertragen wird.
Byte order
- Hier nur 'M'="Motorola" oder 'I'="Intel", der altbekannte nervtötende Krampf namens 'Endianness'..
Data Type
- U=unsigned integer, S=signed integer, F=single precision float, D=double precision float.
Typ des per CAN übertragenen 'rohen' Wertes (nicht skaliert).
Factor
- Multiplikator für die Konvertierung des per CAN übertragenen 'rohen' Wertes in einen physikalischen Wert.
Offset
- Wird bei der Konvertierung des per CAN übertragenen 'rohen' Wertes in einen physikalischen Wert addiert:
Physikalischer Wert (z.B. Öldruck in Bar) = CAN-Rohwert * Faktor + Offset
MinValue
, MaxValue
- Zulässiger Bereich für den physikalischen Wert. Wird im CAN-Simulator auch für den vom "vertikalen Schieber"
verwendet: Ganz oben = Maximum, ganz unten = Minimum.
Multiplexer
- Definition eines Signal-Multiplexers für mehrfach genutze Bitfelder im CAN-Message-Datenfeld.
Details und Format wie hier beschrieben.
Im CAN-Simulator werden gemultiplexte Signale automatisch (der Reihe nach) mit den
in der Definitionstabelle enthaltenen Multiplexer-Werten gesendet.
Der Sendezyklus eines gemultiplexten Signals bestimmt, wie oft der entsprechende
Multiplexer, und damit möglicherweise auch andere Signale (in der gleichen Message)
gesendet werden.
Ist das Multiplexer-Signal selbst (mit einem eigenen Signal- bzw. Variablenamen)
in einer eigenen Tabellen-Zeile definiert, dann darf für die Zeile des Multiplexers
kein Stimulus definiert sein. Grund:
Würde der Multiplexer z.B. mit einer Sinusfunktion als Stimulus belegt,
dann würden alle (gemultiplexten) Signale in der gleichen CAN-Message mit undefinierten
Werten gesendet.
Seit 02/2021 weist der CAN-Simulator durch ein rotes Kreuz in der Tabellenzelle mit dem
Stimulus (Expression) darauf hin, dass an dieser Stelle
mit hoher Wahrscheinlichkeit ein Fehler vorliegt.
Fälschlicherweise definierter Stimulus ("Expression") für ein Multiplexer-Signal.
Der Fehler-Indikator ("rotes Kreuz") verschwindet wenn der fehlerhafte Stimulus entfernt wird.
Siehe auch: Besonderheiten beim Senden gemultiplexter CAN-Messages.
Um die Definitionstabelle schnell mit Daten zum Testen einer 'Display-Applikation' zu füllen,
laden Sie die Applikation (*.upt oder *.cvt) zunächst im Programmiertool.
Dann schalten Sie aus dem Hauptfenster des Tools in den Simulator um ("Werkzeuge".."CAN Messag Generator / Bus Simulator"),
und klicken auf den Button mit dem Titel "Signal(e) hinzufügen" / "Add Signal(s)",
und wählen im unten gezeigten Popup-Menü die Funktion
"ALLE Signale aus UPT-Display-Variablen übernehmen" / "Copy ALL signals from UPT display variables" :
Schritte zum schnellen Ausfüllen der 'Signal-Definitions-Table' mit Daten aus der geladenen Display-Applikation
Über den Button "Weitere Optionen.." ("More ...") ...
"Stimuli für ALLE Signale erzeugen" ("Generate stimuli for ALL signals")
können Sie anschließend für jedes Signal einen eigenen Stimulus erzeugen
(Sinuskurve mit zum Wertebereich passender Amplitude, und von der Signalnummer
abhängiger Frequenz, damit alle Signale unterschiedliche Werte haben).
Der Inhalt der Definitionstabelle kann auch als CSV-Datei exportiert werden.
Wählen Sie dazu unter 'Weitere Optionen' den Menüpunkt 'Definitionen in Datei speichern'.
Im gleichen Menü finden Sie auch die Funktion zum Importieren der Definitionstabelle.
Wenn die CSV-Datei mit den Signaldefinitionen existiert, wird sie beim nächsten Programmstart
nach dem Öffnen des CAN-Simulators automatisch geladen.
Das 'Update-Intervall' des CAN-Simulators
Das in rechten Teil des Simulatorfensters einstellbare 'Update-Intervall' steuert
die Aktualisierungsrate der Simulation. Dazu gehören die zyklische Auswertung der
Tabelle mit den Signal-Definitionen (inkl. Stimuli),
aber auch das SPS-ähnliche Abarbeiten der "Conditional Actions"
(Details dazu im folgenden Kapitel). Abhängig von der verwendeten Hardware (PC),
Grafik und Betriebssystem könnte die grafische Benutzeroberfläche etwas länger
als den eingestellten Wert benötigen. Dies wurde bislang nur bei Intervallen
unter 100 Millisekunden beobachtet.
Automatisierung / Programmierbare Testabläufe
In den meisten Fällen reicht die in den vorhergehenden Kapiteln beschriebene zyklische Sendung
von CAN-Signalen als 'Ersatz' für ein echtes Netzwerk.
Für komplexe Testfälle bietet der CAN-Simulator aber auch eine 'programmierbare'
Steuerung, mit der ähnlich wie mit den 'Event-Definitionen' im Display-Programm
bestimmte Ereignisse definiert werden können, und abhängig davon daraufhin
durchgeführte Reaktionen.
Tabelle mit programmierbaren "Conditional Actions" (Ereignisse und Reaktionen)
Die "Conditional Actions" werden als Tabelle auf der Registerkarte 'Automatisierung' des CAN-Simulators angezeigt.
Die Funktion ähnelt den vom Display bekannten Event-Definitionen.
Ähnlich wie bei einer SPS werden alle Zeilen (mit 'Ereignissen' und 'Reaktionen') genau einmal pro
Update-Zyklus abgearbeitet.
Liefert eine in der Spalte "IF..." programmierte Bedingung (numerischer Ausdruck) einen Wert ungleich Null (d.h. logisch "TRUE"),
dann wird die in der Spalte "THEN..." definierte Reaktion (Kommadozeile) ausgeführt.
Ausdrücke und Kommandos werden vom gleichen Interpreter ausgewertet, der auch für die Simulation des
programmierbaren Terminal verwendet wird. Speziell für den CAN-Simulator wurde der Befehlssatz des
Interpreters allerdings so erweitert, dass sich CAN-Simulation und Simulation der Display-Applikation
"nicht in die Quere" kommen. So verfügt der CAN-Simulator über eine eigene Zeitbasis (tsim),
eigene Timer (csim.t0 .. t9), eigene Variablen (csim.var.<VarName>),
einen eigenen Befehl zum Prüfen des Empfangs einer bestimmten CAN-Nachricht (csim.can_rx()), usw.
'Conditional Actions' im CAN-Simulator (mit Test aus programs/CANSim_for_SignalMultiplexerTest.csv).
In der Statuszeile (unten) wird der momentane Wert aus dem Ausdruck 'unter dem Mauspfeil' angezeigt.
Alle Bedingungen, deren Auswertung im letzten Update-Zyklus einen Wert ungleich Null lieferten (d.h. "TRUE")
werden in der Tabelle mit einem grünen Hintergrund hervorgehoben.
Tritt bei der Berechnung oder beim Aufruf eines Kommandos ein Fehler auf, dann wird
die entsprechende Tabellenzelle rot markiert,
und die Statuszeile (unterhalb der Tabelle) zeigt eine detailierte Fehlermeldung.
Eine gelb gefärbte Zelle in der ersten Spalte (mit den Zeilennummern)
bedeutet, dass ein in dieser Zeile gesetzter Haltepunkt
die Ausführung der "Conditional Actions" pausiert hat. In diesem Fall kann der Ablauf
Schritt für Schritt (ab der "gelben Zeile") fortgesetzt werden.
Um die Reihenfolge der 'Ereignisse und Reaktionen' in der Definitionstabelle zu ändern,
ziehen Sie die Zelle mit dem Titel 'Nr' bei gedrückter linker Maustaste nach oben
oder unten. Während des Verschiebens zeigt die Tabelle die neue Position der Zeile,
an der die verschobene Zeile beim Loslassen der Maustaste eingefügt würde,
mit einer breiten horizontalen Line an.
Um den aktuellen Wert einer Variablen, oder dem Teil eines numerischen Ausdrucks
in der Tabelle zu inspizieren, bewegen Sie den Mauspfeil an die
entsprechende Position innerhalb der Tabelle, ohne die Tabelle anzuklicken.
Wenn der Interpreter das 'Wort' unter dem Mauspfeil auswerten kann, dann wird
das Ergebnis im Anzeige/Editierfeld direkt unterhalb der Tabelle angezeigt.
'select'..'case'..'endselect'-Blöcke in den 'Conditional Actions' (CA)
Neben einfachen "IF.."/"THEN.." - Bedingungen kann die Definitiontabelle unter 'Automatisierung'
auch zur Implementierung von Auswahllisten (Verzweigung nach einer Vielzahl von Werten)
verwendet werden. Hier ein Beispiel, mit der ein Drehzahlverlauf beim Anlassen eines Motors simuliert wurde:
Ähnlich wie ein Anweisungsblock mit select..endselect in der Script-Sprache
'rutscht' auch im CAN-Simulator das Programm nicht von einer case-Zeile in die nächste
case- oder default-Zeile durch. Im Gegensatz zur Programmiersprache "C" ist daher kein
'break' nach jedem 'case' erforderlich, um dieses 'Durchrutschen' (fall-through) zu verhindern.
Hinweis: Im Gegensatz zur Pascal und zu MKT's Script-Sprache wird hier bei 'select'..'case'..'endselect'
kein 'else' zur Abdeckung 'aller anderen Werte' verwendet, sondern das aus 'C' geläufige 'default:'-Label.
Dieses Prinzip wurde gewählt, um nicht mit der normalen else-Abfrage
(als "Gegenteil von der Bedingung in der vorhergehenden Zeile") zu kollidieren.
- select( <selectValue> )
Speichert den aktuellen Inhalt des 'Auswahlwertes' in einem internen Puffer, der dann in allen folgenden 'case'-Zeilen
mit den dort definieren Werten verglichen wird - bis zum Ende des Konstruktes in der Zeile mit dem passenden endselect.
- case <caseValue> :
Vergleicht den links vom 'case' definierten Wert mit dem von select gepufferten Auswahlwert,
und liefert als Bedingung zum Abarbeiten der Zeile mit diesem 'case' (und aller eventuell folgenden Zeilen
mit einer leeren 'IF..'-Spalte) bei Übereinstimmung der Werte den Wert TRUE, sonst FALSE.
- case <fromValue> to <toValue> :
Eine 'case'-Marke kann nicht nur einen einzelnen Wert, sondern wie im Beispiel gezeigt einen ganzen Zahlenbereich abdecken.
Das Schlüsselwort "to" (zwischen Bereichsanfang und -Ende) bedeutet in diesem Zusammenhang "bis".
Die Bedingung "case 3 to 100:" ist daher erfüllt, wenn der Auswahlwert zwischen 3 und 100 (inklusive) liegt.
Der Doppelpunkt nach dem case-Wert ist optional (aber für "C"-Anwender fast unverzichtbar).
- default :
Liefert als Bedingung in der CA-Tabelle den Wert TRUE ("erfüllt"), wenn keiner der vor der Zeile mit dem 'default'
enthaltenen 'case'-Werten oder case..to-Bereichen
eine Übereinstimmung mit dem bei select gepufferten Auswahlwert erkannt wurde.
Die Reaktion in der 'default'-Zeile (oder den Zeilen nach 'default' mit leerer 'IF..'-Spalte)
kann daher genutzt werden, um "alle anderen Fälle" zu behandeln.
Wie bei 'case'-Marken ist auch der nach 'default' folgende Doppelpunkt optional.
- endselect
Beendet einen aus 'select', 'case', und optional 'default' bestehenden Block.
Nach Abarbeiten einer passenden 'case'-Zeile oder der 'default-Zeile(n) wird das Programm
in der nach dem 'endselect' folgenden Zeile fortgesetzt. Der bei 'select' gepufferte Auswahlwert
wird aus dem internen Puffer wieder entfernt.
Hinweis: Als diese Beschreibung erstellt wurde, unterstützte 'select' im CAN-Simulator
nur numerische Auswahlwerte (Ganzzahl oder Fließkomma). Zeichenketten
konnten im Gegensatz zur Script-Sprache nicht als Auswahlwerte verwendet werden.
Im Gegensatz zu "C" (und zur compilierten Script-Sprache) sind case-Werte nicht
auf Konstanten beschränkt, denn der Interpreter muss Werte (egal ob Konstante oder Variable)
immer zur Laufzeit auswerten.
Spezielle Interpreterfunktionen des CAN-Simulators
In den meisten Fällen bestehen die im vorhergehenden Kapitel beschriebenen
'Bedingungen' (Ereignisse) aus einfachen Vergleichen, wie z.B. tsim > 10.
Im CAN-Simulator können auch normale Interpreter-Funktionen verwendet werden,
z.B. für die Statusabfrage des CAN-Controllers.
Darüberhinaus stehen im für den CAN-Simulator erweiterten Interpreter noch
die foldenden Funktionen zur Verfügung, die speziell für den Einsatz in den
'Conditinal Actions' (Tabellenspalte 'IF..')
vorgesehen sind:
- initialising
Dieses Flag ist nur einmal während der Initialisierung gesetzt, d.h. beim
ersten Abarbeiten der 'Conditional Actions' (beim Start per 'Run',
oder nach dem Laden einer neuen Konfiguration aus einer *.csv - Datei).
Es wird üblicherweise verwendet um den Anfangswert von selbstdefinierten Variablen
zu setzen.
- always
Diese 'Bedingung' (Konstante) ist IMMER 'true'. Sie dient als besser lesbarer Ersatz
für die Integer-Konstante 1 (Eins). Die Aktion in Tabellenzeilen
mit der Bedingung always wird daher immer (in jedem Update-Zyklus)
ausgeführt.
- never
Das Gegenteil von 'always' - eine Bedingung mit diesem Inhalt ist nie erfüllt
(sie liefert bei der Auswertung durch den Interpreter den Wert Null bzw. boolesche Konstante FALSE).
So merkwürdig dieses Schlüsselwort erscheinen mag: Es ist besser lesbar als der Wert Null (0),
und kann gut zum vorübergehenden 'Passivieren' einer Definitionszeile verwendet werden
(ohne die Zeile zu löschen), oder um Kommentarzeilen in der Tabelle einzufügen (die dann nie mit einem
grünen Hintergrund hervorgehoben werden, weil die Bedingung nie erfüllt ist).
- else
Liefert TRUE ("erfüllt") wenn die Bedingung in der vorhergehenden Definitionszeile
den Wert FALSE ("nicht erfüllt") geliefert hat. Verwenden Sie diese Bedingung,
um "etwas bestimmtes" bei erfüllter Bedingung in Zeile N, und "etwas anderes"
bei nicht erfüllter Bedingung in Zeile N+1 durchzuführen. Beispiele finden Sie
am Ende dieses Kapitels.
Hinweis: Fehlt die Angabe einer Bedingung in einer bestimmten Zeile (leere Zelle
in der 'IF..'-Spalte), dann wird beim Abarbeiten der Conditonal Actions
für diese Zeile der gleiche Bedingungszustand (TRUE,FALSE) wie in der
vorhergehenden Zeile verwendet.
- sometimes
Glückwunsch - Sie haben die Dokumentation gründlich genug gelesen, um dieses
Osterei aus dem Jahre 2021 zu finden. Raten Sie, wie oft die Bedingung
'sometimes' wohl erfüllt sein konnte - oder probieren Sie es aus.
- csim.tsim, tsim
Liefert die aktuelle 'CAN-Simulationsdauer' als Fließkommawert in Sekunden.
Der Modul-Präfix "csim." kann beim Lesezugriff ausnahmsweise weggelassen werden.
Dieser Zeitgeber startet beim Anklicken des 'Run'-Buttons bei Null, und dient in manchen
Simulation als Parameter zur Berechnung von laufenden Signalwerten, z.B.:
csim.sig.Fahrtstrecke_km := tsim * (50.0/3.6) // Fahrt mit 50 km/h
Für Sonderzwecke (z.B. einen simulierten 'Zeitsprung') kann csim.tsim per Zuweisung
auch programmgesteuert modizifiert werden.
- csim.t0 .. t9
Prüft ob der angegebene Timer des CAN-Simulators (einer von zehn verfügbaren Timern)
abgelaufen ist, oder (bei periodischen Timern) das Ende einer Periodendauer
erreicht wurde. Wurde der Timer noch nie per csim.ts gestartet
(ts = "timer start"), dann liefert diese Funktion den Wert FALSE (Bedingung nicht erfüllt).
Ein Beispiel zum Starten und Abfragen von Timern finden Sie hier.
Hinweis: Ähnliche Timer existieren im Interpreter auch 'außerhalb' des CAN-Simulators
(für die Display-Applikation, t0 .. t3).
Um Konflikte zwischen der im Programmiertool simulierten Display-Applikation
und der CAN-Simulation zu vermeiden, sollte letzere nur csim.t0 bis csim.t9
verwenden, nicht t0 .. t3.
- csim.tv0 .. tv9
Liest den momentanen Zählerstand (tv = "timer value") eines der zehn
im CAN-Simulator verfügbaren Timer. Das Ergebnis ist ein Fließkommawert in Sekunden.
Die Zeitmessung beginnt beim Start des Timers (z.B. csim.ts0(12.3))
bei Null (Sekunden), und läuft bis zur Periodendauer bzw Intervallzeit (in diesem Beispiel 12.3)
hoch. An dem Zeitpunkt würde ein Single-Shot-Timer stehenbleiben (tv liefert eine
einmal ablaufende Rampenfunktion), während ein periodischer Timer eine
eine steigende Sägezahnfunktion liefert.
- can_rx(<ID> <Datenfeld>) : CAN-Empfang prüfen (komplette Message mit bestimmtem ID
oder/und einem bestimmten Datenfeld).
Vorgesehen für den Einsatz als 'Bedingung' (condition) bei automatisierten Testabläufen per
'conditional actions' (Tabelle mit Ereignissen und Reaktionen).
Syntax und Beispiele folgen im nächsten Unterkapitel.
- select, case, default, endselect :
Diese Konstruktion (für Auswahllisten) wird in einem eigenen Kapitel erläutert.
Zur Erinnerung: Eine Funktion liefert einen Wert an den Aufrufer zurück, und kann daher auch
als Teil eines numerischen Ausdrucks verwendet werden. Ein Kommando (bzw. Prozedur) tut dies nicht,
und kann daher kein Teil eines numerischen Ausdrucks bzw. einer Bedingung sein.
CAN-Empfang per can_rx(<ID> <Datenfeld>) abfragen
Die Interpreterfunktion can_rx dient zum Testen, ob seit dem letzten Aufruf
eine CAN-Message mit einem bestimmten Identifier oder/und einem bestimmten
Inhalt im Datenfeld empfangen wurde.
Die Syntax ist an den CAN-Tester für Windows angelehnt, und entspricht
dem Format des Kommandos can_tx() (mit dem
CAN-Telegramme in die Simulation eingespeist, aber auch auf einem
'echten' CAN-Bus gesendet werden können).
Die Länge des CAN-Datenfelds ergibt sich automatisch aus dem
z.B. hexadezimal definierten Datenfeld (mit "xx" als Platzhalter
für Datenbytes, die für die Filterung jeden beliebigen Wert annehmen dürfen).
Für den Einsatz als 'Bedingung' (condition) liefert can_rx() [beim Aufruf
mit einer Argumentenliste in Klammern] den Wert 1 = TRUE, wenn eine entsprechende
CAN-Message im CAN-FIFO gefunden wurde; anderfalls 0 = FALSE.
Beispiele :
can_rx( 0x123 00 11 22 33 44 55 66 77 )
prüft, ob seit dem letzten Durchlauf durch die gleiche Zeile in den
'conditional actions' eine CAN-Message mit dem hexadezimalen Identifier 0x123,
und dem hexadezimalen 8-Byte-Datenfeld 00 11 22 33 44 55 66 77
empfangen wurde.
can_rx( 0x123 FF xx xx )
prüft, ob seit dem letzten Durchlauf (.. s.O. ..) eine CAN-Message
mit einem Drei-Byte-Datenfeld empfangen wurde, bei der im ersten
Datenbyte der Wert 0xFF (hexadezimal) enthalten war.
Der Wert im zweiten und dritten Datenbyte spielt in diesem Beispiel
keine Rolle ('xx' dient wie im CAN-Tester für Windows als Platzhalter
für ein in der Message vorhandenes Datenbyte mit beliebigem
Inhalt (Wert).
Spezielle Interpreterkommandos des CAN-Simulators
Zusätzlich zu den Standard-Kommandos
des Interpreters wurden die folgenden Befehle speziell für die Verwendung
in der Spalte mit dem Titel 'THEN..' in der Tabelle mit den
'Conditional Actions' implementiert:
Zugriff auf CAN-Signale, interne Variablen, und programmierbare Timer
In der Tabelle mit den "Conditional Actions" werden üblicherweise nur wenige CAN Signale
(per Signalname) gesetzt, die der CAN-Simulator dann einmal pro Update-Zyklus in CAN-Telegramme
oder vergleichbare 'Container' umgesetzt und gegebenenfalls gesendet werden - ähnlich wie bei
Signalen, für die ein eigener Stimulus definiert wurde. Beispiele dafür
wurden im vorhergehenden Kapitel präsentiert.
Der Interpreter bietet darüberhinaus selbstdefinierte interne Variablen,
die im Gegensatz zu CAN-Signalen und Applikations-Variablen ("Netzwerk-Variablen") nur innerhalb des CAN-Simulators
bekannt sind.
Auch die programmierbaren Timer können als 'Signalgeneratoren'
für CAN-Signale verwendet werden. Dazu kann z.B. der Timer-Wert per Stimulus, aber auch per 'Conditional Action'
an das Signal gekoppelt werden. Die dazu benötigten Funktionen und Kommandos wurden bereits vorgestellt.
Im nächsten Unterkapitel folgen Details die für einfache Test-Anwendungen nicht erforderlich sind.
Details zum kommandogesteuerten Senden von Signalen
In diesem Unterkapitel werden Details und Erweiterungen zum Setzen von Signalen (Zuweisungen an csim.<SigName>) vorgestellt.
Eine Zuweisung kann in der langen Form erfolgen, z.B.:
oder in der kurzen Form (ohne ".sig" und ".value", falls sich dadurch keine Kollision mit anderen Namen ergibt):
Diese Zuweisungen erfolgen als Kommando in den 'Conditional Actions', Spalte "THEN.." (Aktion).
Jede Zuweisung kann so an eine beliebige Bedingung geknüpft sein.
Selbst wenn für das Ziel (im Beispiel "EngineRPM" = Motordrehzahl) ein Stimulus definiert
wäre, hätte die Zuweisung per Kommando immer Vorrang vor dem vom Stimulus gelieferten Wert.
Erst wenn die Bedingung für die Zuweisung an das Signal nicht mehr erfüllt ist, übernimmt wieder
der Stimulus die Kontrolle (sofern vorhanden).
Der Stimulus für ein bestimmtes Signal kann auch 'programmgesteuert'
dauerhaft ein- und ausgeschaltet werden (also nicht nur für einen Update-Zyklus). Beispiel:
csim.sig.EngineRPM.enable_stimulus := 0 // disable signal stimulus
csim.sig.EngineRPM.enable_stimulus := 1 // enable signal stimulus
Stimuli die per "enable_stimulus = 0" passiv sind
werden in der Signal-Definitionstabelle mit einem blauen
Kreuz (unter dem numerischen Ausdruck) markiert.
Stimuli die nur temporär im aktuellen Zyklus keine Verwendung fanden (da das Signal
per Zuweisung an den aktuellen Wert gesetzt wurde) werden
in der Tabelle mit einem grünen Kreuz markiert.
Zur Erinnerung: Die Auswertung der Stimuli und 'Conditional Actions' erfolgt ähnlich wie bei einer
SPS (Speicherprogrammierbaren Steuerung). Das Senden aller Funktionsausgänge (hier z.B. CAN-Signale)
erfolgt nur einmal pro Zyklus (genau: am Ende vom Zyklus, nachdem alle Zeilen in der Signal-Definitions-Tabelle
und in den 'Conditional Actions' abgearbeitet wurden). Egal wie oft Sie den Wert eines CAN-Signals
in einem Zyklus neu setzen - das Signal wird bis auf seltene Ausnahmen (*)
maximal einmal pro Zyklus gesendet.
Der in der Signal-Definitionstabelle definierbare Sendezyklus ("TX cycle" in Millisekunden)
stellt in diesem Fall nur das Minimum dar: Ein Signal mit "TX cycle"=50 ms wird bei einem
Update-Intervall von 200 Millisekunden maximal 5 mal pro Sekunde
gesendet, nicht 20 mal.
Das folgende Kapitel beschreibt den Zusammenhang zwischen dem Update-Intervall
des Simulators, dem individuellen Sende-Zyklus eines Signals,
dem Setzen eines Signalwertes per Zuweisung an csim.sig. (Kommando),
und dem Zeitpunkt, an dem die i.A. aus mehreren Signalen zusammengesetzte CAN-Message
(oder ähnlicher Container) tatsächlich gesendet wird.
Signal-Sende-Timing / per Kommando "erzwungenes" Senden
Am Ende eines Zyklus (mit einstellbarem Update-Intervall)
werden alle zu sendenden Signalwerte in ihre 'Container' (CAN Messages, PDUs, PDOs, etc)
gemappt, in die im Display-Simulator laufende Applikation eingespeist, oder/und
per CAN-Bus in ein "echtes" Netzwerk gesendet.
Wie bereits in den vorhergehenden Kapiteln erläutert, werden Signale, für die
kein zyklisches Senden in der Definitionstabelle
konfiguriert wurde ("TX Cycle" = 0), ereignisgesteuert gesendet (d.h. immer dann,
wenn der per Stimulus oder Zuweisung gesetzte Wert vom alten Wert aus dem vorherigen
Update-Zyklus abweicht).
Es kann daher bis zu einem Update-Intervall dauern
bis der neue Wert 'im Netzwerk' erscheint.
Für spezielle Anwendungen kann das Senden eines Signals unabhängig vom Sendezyklus
oder Änderung des Signalwertes erzwungen werden. Beispiel:
- Setzen Sie in den 'Conditional Actions' den Signalwert:
csim.sig.EngineRPM.value := 2300
- Setzen Sie zusätzlich das "Sende-Anforderungs-Flag" (tx_flag) per Kommando:
csim.sig.EngineRPM.tx_flag := 1
Auf diese Weise wird das Signal (am Ende des Update-Zyklus) auch dann gesendet,
wenn kein zyklisches Senden konfiguriert wurde (TX Cycle = 0), und der Wert
gegenüber dem vorherigen Zyklus nicht geändert wurde.
Das "Sende-Anforderungs-Flag" (tx_flag) wird automatisch gelöscht, sobald das
zu sendende Signal in seinen Container (CAN-Message, ..) gemappt wurde.
Das Senden gemultiplexter CAN-Messages
Abhängig von den Sende-Intervall können gemultiplexte Signale
beim Senden per CAN-Simulator ein auf den ersten Blick "unerwartetes" Verhalten zeigen:
- Enthält eine CAN-Message ("CAN Frame" mit einem bestimmten Message-ID) sowohl
gemultiplexte als auch nicht gemultiplexte ("normale") Signale, dann werden
die nicht gemultiplexten Signale eventuell häufiger gesendet, als der
in der Signal-Definitionstabelle definierte Sendezyklus ("TX cycle") vorgibt.
Ist in einer Message z.B. ein einmal pro Sekunde zu sendendes, nicht gemultiplextes
Signal namens "NonMuxedSignal" enthalten, und gemultiplexte Signale "MuxedSignal1" und "MuxedSignal2"
die alle 100 oder 50 ms gesendet werden sollen, dann wird -"wohl oder übel"-
auch "NonMuxedSignal" alle 100 oder 50 Millisekunden mitgesendet. Vom beabsichtigten
langsamen Sendezyklus der nicht gemultiplexten Signale bleibt also "nicht viel übrig".
- Enthält eine CAN-Message mehrere gemultiplexte Signale mit unterschiedlichen
Multiplexer-Werten, und zwei (oder mehr) Signale stehen am Ende eines Update-Zyklus
zur Sendung an (wegen automatisch oder manuell gesetztem tx_flag),
dann wird der CAN-Simulator bei entsprechender CAN-Bitrate innerhalb von Bruchteilen
einer Millisekunde mehrere CAN-Messages mit dem gleichen CAN-Message-ID, aber
unterschiedlichen Multiplexern aussenden. Dies könnte bei bestimmten Empfängern,
z.B. bei Mikrocontrollern ohne ausreichend großem CAN-Empfangspuffer zu Problemen führen
(einige der gemultiplexten Signale kommen nicht beim Empfänger an, obwohl sie vom
CAN-Simulator korrekt "auf die Reise" geschickt wurden).
CAN-Senden per can_tx(<ID> <Datenfeld>)
Das Interpreterkommando can_tx kann zum Senden einfacher CAN-Messages
verwendet werden, die nicht vom CAN-Simulator wie in den vorhergehenden Kapiteln
beschrieben aus einzelnen Signalen zusammengestellt werden sollen.
Stattdessem wird der zu sendende CAN-Message-Identifier, und i.A. auch das zu
sendende Datenfeld direkt in der geklammerten Parameterliste übergeben.
Die Länge des Datenfelds wird nicht extra angegeben (die Anzahl zu sendender
Bytes ergibt sich schlicht und einfach aus deren Zählung).
Beispiele :
can_tx( 0x123 00 11 22 33 44 55 66 77 )
"Sendet"(*) eine CAN-Message mit dem hexadezimalen 11-Bit-Message-Identifier 0x123,
und dem hexadezimalen 8-Byte-Datenfeld 00 11 22 33 44 55 66 77,
oder (ohne die Option 'Auf echtem CAN-Bus senden')
speist eine entsprechende CAN-Message in die im Programmiertool laufende
Simulation ein (als Ersatz für eine von einem Steuergerät gesendete
Message).
can_tx( 0xABCDEF.x 01 02 03 04 05 06 )
"Sendet"(*) eine CAN-Message mit 29-Bit-Message-ID 0x00ABCDEF (.x = "Extended"),
und dem angegebenem Datenfeld.
Der "can_tx()"-Befehl des CAN-Simulators verwendet den gleichen Parser wie der
in manchen programmierbaren Geräten ("ohne CANopen") implementierte Befehl
ctx(). Da beide Befehle den gleichen
Parser verwenden, kann auch can_tx() den Inhalt von Variablen (im Datenfeld)
verwenden, mit Konvertierung in die hier
spezifizierten Datentypen (z.B. ".il" = "Intel-Long", ".mw" = "Motorola-Word", ... ).
"Senden" auf einem 'echten' CAN-Bus erfolgt nur, wenn die Option 'Auf echtem CAN-Bus senden'
gesetzt ist. Ohne diese Option werden die per can_tx() -und aus Sicht des simulierten Steuergerätes- "gesendeten"
CAN-Messages lediglich in die im Programmiertool laufende Simulation des Anzeigegerätes (MKT-View) eingespeist.
Haltepunkte und Einzelschritt-Betrieb in den Conditional Actions
Für die 'Hardcore'-Fehlersuche können in den Conditional Actions (CA) auch
Haltepunkte (breakpoints) gesetzt werden. Erreicht das Programm dann die entsprechende
Zeile mit einer erfüllten Bedingung (condition = TRUE), dann
'feuert' der Haltepunkt, und das periodische Abarbeiten der CA-Tabelle
(wie auch das periodische Auswerten der Stimuli für CAN-Signale) wird
unterbrochen (pausiert). Diese Pause beginnt genau zwischen der Auswertung
der Bedingung (condition) und dem Abarbeiten der entsprechenden Reaktion (action).
Um einen Haltepunkt zu setzen, klicken Sie in der Tabelle auf der Registerkarte
Automatisierung
in der gewünschten Zeile auf die erste Spalte (mit dem Titel 'Nr'), und wählen
im daraufhin angezeigten Kontext-Menü den Eintrag 'Breakpoint in Zeile X umschalten'.
Dies funktioniert sowohl bei laufendem wie auch bei gestopptem CAN-Simulator.
Wenn der Haltepunkt später auslöst, bleibt die Simulation an der Stelle stehen,
und die noch abzuarbeitende Zeile wird durch einen
gelben Hintergrund markiert.
Gleichzeitig erscheint ein entsprechender Hinweis in der Statuszeile, z.B.:
Conditional actions hit breakpoint in line 34, press F11 for single-step.
Drücken Sie in diesem Zustand die Funktionstaste F11 (mit dem Tastaturfokus in der CA-Tabelle),
um die Anweisungen in der Tabelle schrittweise abzuarbeiten, oder klicken Sie
auf 'Run' um das Programm weiterlaufen zu lassen (bis zum nächsten Stop per Haltepunkt).
In diesem Fall started 'Run' die Simulation nicht neu, und setzt auch nicht
das initialising-Flag mit dem üblicherweise
selbstdefinierte Variablen auf die Startwerte gesetzt werden.
Siehe auch: Optionen zur Synchronisation zwischen Applikation (Display-Simulator) und CAN-Simulator.
Programmierbare Buttons (auf Registerkarte "Automatisierung" / "Automation")
Die drei Buttons im oberen Teil der Registerkarte "Automatisierung" sind frei programmierbar.
Sie können z.B. zum Aufruf beliebiger Kommandos durch den Bediener verwendet werden,
ähnlich wie die Kommandozeilen in der Spalte mit dem Titel 'THEN...' in den 'Conditional Actions'.
Ist eine Kommandozeile für einen Button hinterlegt, dann wird diese beim Anklicken
des Buttons mit der linken Maustaste aufgerufen.
Andernfalls, oder beim Anklicken eines 'programmierbaren' Buttons mit der rechten Maustaste,
oder (für Touchscreen-Benutzer) beim Anklicken mit gedrückter Shift-Taste wird das
unten gezeigte Popup-Menü geöffnet, mit dem der Button gegebenenfalls "umprogrammiert" werden kann:
Screenshot des CAN-Simulators mit Kontext-Menü für "Programmierbare Buttons"
Die 'Beschriftung' eines Buttons ('Caption') kann nicht nur manuell, sondern auch programmgesteuert
geändert werden. Dazu dient eine Zuweisung an csim.btn[0..2].caption.
Der 'OnClick'-Handler eines Buttons (Kommandozeile, die beim Anklichen des Buttons an den Interpreter übergeben wird)
kann ähnlich wie die Zellen in der Tabellenspalte mit dem Titel "THEN.." (Aktionen)
frei programmiert werden. Mehrere Kommandos können per Doppelpunkt getrennt in eine Zeile eingetragen werden, z.B.:
Alternativ kann die Beschriftung selbst als 'variable Anzeige' verwendet werden. Als 'Caption'
wird dafür ein String-Ausdruck wie im folgenden Beispiel (Anzeige eines Zählers für bestimmte
CAN-Messages) verwendet:
Caption: "Count7=";csim.Count7
Die für einen programmierbaren Button als 'Caption:' definierte Zeichenkette wird vom
Interpreter periodisch ausgewertet (alle 500 ms), und das Resultat ('Evaluated:')
als Beschriftung übernommen. Wie beim Befehl csim.print
werden mehrere Parameter per Komma getrennt. Bei der 'Ausgabe' (hier: Beschriftung eines Buttons)
wird statt Komma ein einzelnes Leerzeichen emittiert. Ein Semikolon (als Trennzeichen)
erzeugt dagegen kein Leerzeichen. Im oben gezeigten Beispiel ist 'Count7' eine
anwenderdefinierte Variable, die nur innerhalb des CAN-Simulators gültig ist.
Die "Programmierung" der Buttons ('Caption' und Kommandozeile für den 'OnClick'-Handler)
wird zusammen mit anderen Tabellen in der Konfigurationsdatei (*.csv) abgespeichert.
Diese kann so zu Testzwecken zusammen mit der Applikation (*.cvt) an den Endkunden
oder weitere Entwickler weitergegeben werden, falls dort kein 'echtes' CAN-Netzwerk vorhanden ist.
Textkonsole (Editorfenster mit Anzeige von per 'csim.print' erzeugten Meldungen)
Die während eines Testlaufs mit dem Kommando csim.print
oder csim.write generierten
Ausgaben werden in einer mehrzeiligen 'Konsole' (Editor) auf der Registerkarte Automatisierung,
oder als Vollbild unter 'Konsole' angezeigt:
Screenshot mit der 'Text-Konsole' des CAN-Simulators
mit absichtlich übertriebenem Einsatz von Farben.
Texte können aus der 'Konsole' per Copy & Paste zu Dokumentationszwecken als 'Rich Text'
in eigene Dateien übernommen werden.
Das Konsolenfenster war ursprünglich auf 100 Zeilen mit 128 Zeichen pro Zeile begrenzt. Werden per
print oder write
mehr Zeilen in das Fenster gedruckt, dann wird der vorhandene Text automatisch gescrollt,
wobei die obere (älteste) Zeile verschwindet.
Die momentane Position des Textcursors kann als Null-basierte Textkoordinate per
csim.tscreen.cx (cursor x = Spalte) und csim.tscreen.cy (cursor y = Zeile)
gelesen und gesetzt werden.
Die Konstanten csim.tscreen.width und csim.tscreen.height liefern
die Größe des Textpuffers für Anzeige in der Konsole, gemessen in
'Zeichen pro Zeile' (128 ?) und 'Anzahl Zeilen' (100 ?).
Vorder- und Hintergrundfarben sind wegen der Anzeige als 'Rich Text' sehr begrenzt.
Bei der Zuweisung an csim.tscreen.fc (foreground colour) und csim.tscreen.bc (background colour),
oder bei der Übergabe von Farbwerten als Funktionsparameter an csim.print
sollten daher nur die folgenden symbolischen Farb-Konstanten
verwendet werden:
clBlack | clWhite | clRed | clGreen | clBlue |
clCyan | clMagenta | clYellow | clDkGray | clLtGray |
Per Default erfolgt die Anzeige in der Konsole 'schwarz auf weiß'. Per csim.tscreen.cls
kann der Inhalt der kompletten Textkonsole gelöscht werden (wobei der Hintergrund mit der vorher an
csim.tscreen.bc zugewiesenen Farbe gefüllt wird). Mit dem Kommando
csim.tscreen.fill(x1,y1,x2,y2," ") kann ein rechteckiger Bereich
des Fensters mit dem angegebenen Zeichen (in diesem Beispiel mit Lerzeichen) gefüllt werden.
Beide Kommandos für die Ausgabe von Texten (csim.print
und csim.write) unterstützen die unten aufgeführten
Steuerzeichen und einige (wenige) HTML-ähnliche Tags. Der einzige Unterschied zwischen 'print' und 'write'
ist das autmomatische Anhängen von 'carriage return' ("\r") und 'new line' ("\n") an den auszugebenden
String bei print (mit automatischem Löschen aller alten Zeichen im Rest der Zeile). Beides unterbleibt
bei write.
Steuerzeichen und -Sequenzen in Zeichenketten bei der Ausgabe in die Textkonsole:
- "\r" : Carriage Return (ASCII-Steuerzeichen #13). Setzt den Textcursor auf den Anfang der
aktuellen Zeile, d.h. ohne eine neue Zeile zu beginnen.
Dieses Steuerzeichen eignet sich z.B. zum laufenden Aktualisieren der aktuellen Zeile, ohne
neue Zeilen in der Konsole zu erzeugen. Stattdessem wird, beim Einsatz von "\r"
am String-Anfang der alte Text beliebig oft überschrieben. Beispiel:
- "\n" : New Line (ASCII-Steuerzeichen #10). Setzt den Textcursor in den Anfang der nächste Zeile.
Wird aus historischen Gründen auch nach dem "Carriage-Return"-Zeichen verwendet.
- "<b>Bold Text</b>",
- "<i>Italic Text</i>",
- "<u>Unterlined Text</u>":
HTML-ähnliche Start- und End-Tags für die Ausgabe von Fettschrift, Kursivschrift, und unterstrichenem Text.
Die Funktion entspricht dem Format-String des Display-Interpreters.
Im Gegensatz zu echten HTML-Tags dürfen die obigen Steuersequenzen "beliebig durcheinandergewürfelt" werden,
d.h. Start- und End-Tag müssen nicht unbedingt paarweise verwendet werden.
Optionen zur Synchronisation zwischen Applikation (Display-Simulator) und CAN-Simulator
Unter 'Weitere Optionen' (Button im Fenster des CAN-Simulators) stehen die folgenden
Optionen zur Synchronisation von Display-Applikation und CAN-Simulation zur Verfügung:
- Per RUN nicht nur den CAN-Simulator, sondern auch die Applikation starten:
Diese Option bezieht sich auch auf das Fortsetzen der Display-Applikation,
wenn diese z.B. per Haltepunkt im Script pausiert war. In diesem Fall
handelt es sich nicht um einen Neustart.
- Per STOP nicht nur den CAN-Simulator, sondern auch die Applikation anhalten:
Mit 'anhalten' ist hier nicht das endgültige Abbrechen, sondern nur das
vorübergehende Anhalten ("Pause") gemeint. Sowohl der CAN-Simulator, als auch
die im Display-Simulator des Programmiertools laufende Anwendung ("Display-Applikation")
inklusive Script können nahezu gleichzeitig angehalten und wieder fortgesetzt werden.
- Haltepunkte in der Display-Applikation stoppen auch den CAN-Simulator:
Mit dieser Option kann z.B. verhindert werden, dass beim Auflaufen auf einen
Haltepunkt in einem CAN-Empfangs-Handler im Script
weitere Telegramme vom CAN-Simulator 'ins Leere' gesendet werden.
Die CAN-Simulation wird in diesem Beispiel erst dann fortgesetzt, wenn auch
das Script (in der Anwender-Applikation) weiterlaufen darf, und der
CAN-Empfangs-Handler zum Verarbeiten des nächsten vom CAN-Simulator
gesendeten Telegramms bereit ist.
- In den meisten Geräten (mit ausreichend großem Programmspeicher, z.B. MKT-View III/IV/V)
können die aktuellen Werte aller Variablen (darunter auch die per CAN-Bus empfangenen)
wie folgt tabellarisch angezeigt werden:
Wie hier beschrieben das 'System-Menü' aufrufen,
unter 'Main system menu' das Untermenü 'Diagnostics' aufrufen,
dort die Funktion 'Variables' anwählen (per ENTER).
Die CAN-Bus-Verbindung zwischen PC (mit Programmiertool) und dem Gerät herstellen,
im Programmiertool / 'CAN Message Generator' die Option 'Auf echtem CAN-Bus senden' aktivieren,
die CAN-Simulation per Button 'Run' starten.
Die am Gerät angezeigten Werte sollten nun mit den vom Simulator in der Tabellenspalte
'Current Value' übereinstimmen (dies gilt nur für Werte, die vom Simulator tatsächlich mit einem
geeigneten Sende-Intervall per CAN-Bus gesendet werden).
- Die meisten CAN-Interfaces (z.B. von Kvaser) ermöglichen es mehreren Programmen gleichzeitig
auf die Hardware zuzugreifen. So können die vom CAN-Message-Generator gesendeten Telegramme auch
mit anderen Tools angezeigt, decodiert, und aufgezeichnet werden (z.B. MKT's CAN-Tester für Windows).
- Bei der Verwendung einer CAN-FD-fähigen Hardware sendet der CAN-Simulator automatisch 'FD'-Frames,
wenn sich beim Zusammenstellen des Datenfelds eine Größe von über 8 Bytes ergibt, d.h. wenn das
Datenfeld von "classic CAN" nicht ausreicht. Darüberhinaus kann im Optionsmenü des CAN-Simulators
eingestellt werden, ob 'lange' Frames nicht nur als 'FDF' (mit bis zu 64 Datenbytes), sondern auch
mit 'BRS' (Bitrate Switch) gesendet werden sollen. Wählen Sie dazu unter 'Weitere Optionen...'
den Eintrag "Bei mehr als 8 Datenbytes 'CAN FD mit Bitrate-Switch' senden" .
- Funktioniert die Übertragung von CAN-Signalen nicht wie geplant,
überprüfen Sie zunächst die Einstellungen des CAN-Interfaces (am PC),
die Verkabelung (bei mehrkanaligen Geräten bzw. Interfaces bitte auch die Port-Nummer kontrollieren),
den CAN-Abschlusswiderstand (an beiden "Enden" des CAN-Busses),
die CAN-Bus-Parameter wie z.B. Baudrate, Abtastpunkt, usw.