Forum: Mikrocontroller und Digitale Elektronik Variablen: Settings, Parameters, Inputs & Co


von Walter T. (nicolas)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich bin an einem sehr softwarelastigen Hobbyprojekt, das unter der Last 
seiner eigenen Komplexität stöhnt. Die Komplexität liegt 50:50 in der 
Mensch-Maschine-Schnittstelle und im eigentlichen Regelprozeß. Zur 
Mensch-Maschine-Schnittstelle habe ich vor längerer Zeit einen eigenen 
Thread aufgemacht. Hier geht es nur um den Regelprozeß.

Komplexität läßt sich ja am besten dadurch handhaben, daß sie sorgfältig 
in Teile zerlegt wird. Für eine gute Handhabung dieser Teile ist auch 
eine sinnvolle Benennung hilfreich. Auf der untersten Ebene ist das die 
Benennung der Variablen.

In meinem Regelprozeß scheint es sechs Arten von Variablen zur 
Unterscheidung zu geben:

Settings Variablen, wie sie im Einstellungs-Menü eingestellt und im 
nichtflüchtigen Speicher hinterlegt werden.

Parameters Variablen, die aus den Settings errechnet werden, um vom 
Regelprozeß genutzt werden können. Für den Regelprozeß sind sie 
Konstanten.

Inputs Variablen, die Sensorwerte und/oder physikalische Größen 
widerspiegeln. Für den Regelprozeß sind sie nur-lesbare Variablen.

Outputs Variablen, die an einer höhere Ebene des Regelprozesses oder 
weitergegeben werden oder unmittelbar an einen Aktuator geschickt 
werden. Für den Regelprozeß sind sie les- und schreibbare Variablen.

Signals (???) allgemeine flüchtige Variablen, die die Verbindung 
zwischen den Funktionsblöcken in einem Durchlauf der Regelschleife 
bilden. Dazu zählen auch Funktionsparameter und Rückgabewerte.

Status Zustandsvariablen, die aus dem bisherigen Verlauf der Signale 
errechnet wurden und sich zwischen den Durchläufen der Regelschleife 
nicht ändern. Sie sind meist als „static“ oder (seltener) als „global“ 
implementiert.


Die Namen habe ich mir aus den Fingern gesaugt. Insbesondere mit der 
Benennung „Signals“ bin ich aber nicht glücklich. Ich habe es von 
Simulink übernommen, wo jede Art von Variable zwischen den 
Funktionsblöcken so bezeichnet wird. Gibt es bessere Bezeichnungen? Oder 
habe ich vielleicht sogar eine Art vergessen, weil er in meinem Projekt 
nicht vorkommt?

von Walter T. (nicolas)


Angehängte Dateien:

Lesenswert?

Ich habe mal die Zeit genutzt, die Skizze noch etwas zu verfeinern.

Ich denke, die Unterscheidung Settings und Parameters funktioniert - 
auch wenn ich nicht vermute, dass es im allgemeinen Sprachgebrauch diese 
Unterscheidung gibt.

Mit der Unterscheidung Signals und Status bin ich immer noch nicht 
ganz glücklich - aber ich vermute, ich werde mich daran gewöhnen.


Mit der ersten Unterscheidung dürfte sich das Durcheinander bei den 
Variablen außerhalb des Control -Blocks in den Griff bekommen lassen. 
Noch bin ich mir unsicher, ob für die Input -Variablen ein großer 
Stapel "get"-Funktionen oder ein dickes globales Struct Mittel der Wahl 
ist.

Der nächste Schritt wird es dann sein, innerhalb des Control -Blocks 
Ordnung zu schaffen.


Edit: Bitte entschuldigt die Dateigröße. Wie aus einer 81 kB großen 
CorelDraw-Datei ohne Einbettung der Schriften eine 1,4 MB-PDF werden 
kann, ist mir selbst ein Rätsel. Kann ein Moderator bitte die 
überflüssigen Bilder löschen?

von Micha (nichtgast)


Lesenswert?

Moin,

was ist das, so was wie ein Blog oder versuchst du deine Gedanken zu 
ordnen?

von Walter T. (nicolas)


Lesenswert?

Eigentlich hatte ich gehofft, ein paar Tipps zur üblichen Nomenklatur 
und zur Implementierung zu bekommen. So selten sind ja 
regelungstechnische Systeme auch nicht. Aber wenn außer mir keiner etwas 
schreibt, wird es tatsächlich eine Art "Rubber Duck Debugging". 
Funktioniert auch.

von Peter D. (peda)


Lesenswert?

Walter T. schrieb:
> Für eine gute Handhabung dieser Teile ist auch
> eine sinnvolle Benennung hilfreich.

Die Namensgebung ist sehr vom persönlichen Geschmack abhängig. Eine 
generelle Empfehlung kann man daher nicht geben.
Ich würde Variablen auf keinen Fall nach ihrem Typ benennen, sondern 
ausschließlich ihre Funktion beschreibend, z.B. reg_par_i für den 
I-Anteil usw.
Funktional zusammenhängende Variablen fasse ich in eine Struct zusammen, 
d.h. reg_par.i, reg_par.d usw.
Camelcase mag ich nicht, ich bevorzuge Unterstriche.

von Micha (nichtgast)


Lesenswert?

Peter D. schrieb:
> reg_par_i

bloß nicht so. Da hast du in einem halben Jahr keine Ahnung mehr, was 
das bedeuten soll.
Schreib die aus. Das kostet grad ein wenig Platz. Die IDE hilft beim 
tippen mit Code Completion und du kannst einfach drüber lesen ohne 
Nachdenken zu müssen

von Walter T. (nicolas)


Lesenswert?

Bezeichnung der Variablennamen ist ein Thema, wo jeder eine andere 
Meinung hat. Deswegen ist es auch gar nicht so ergiebig. Zumal in den 
meisten IDEs eine Umbenennung mit wenigen Handgriffen erledigt ist.

Interessanter finde ich Fragen wie:

Wie organisiert man sinnvollerweise Inputs?
 - Großes globales struct und eine große update_input()-Funktion?
 - Viele einzelne Get-Funktionen? Haben solche Funktionen 
Nebenwirkungen?
 - Oder vielleicht sogar eine Funktionstabelle?
 - Oder gar eine noch schönere Lösung?

Wann hat welche Lösung einen Vorteil?

von Peter D. (peda)


Lesenswert?

Walter T. schrieb:
> Wie organisiert man sinnvollerweise Inputs?

Ganz wie Du willst.
Sind es ADC-Kanäle, lese ich die immer reihum ein und schreibe sie in 
ein Array. Das gleiche nur umgekehrt mache ich mit DAC-Ausgängen. Das 
erfolgt im Hintergrund, z.B. im 1ms Timerinterrupt.
Der Vorteil ist, die Mainloop muß nicht darauf warten. Sie schnappt sich 
die Werte und legt die Ergebnisse ab (EVA-Prinzip).

von HW&SW (Gast)


Lesenswert?

Der Control-Block würde bei uns wie folgt aussehen:

S-Switch, PID, V-Limiter und R-Limiter wären Module mit folgenden 
Attributen:

 * einen modulspezifischen Status (z.B. Init, Run, Restart, ...)
 * einen allgemeinen Status (Für alle gleiche Werte, z.B. Aktiv, Idle, 
Aus, ..)
 * verschiedene modulspezfische Bits oder Werte, z.B. verschiedene 
Error-Flags, Regelwerte etc.

Jedes Modul bekommt Rechenzeit analog einer SPS-Loop.

Eine Programmierung sieht dann in etwa so aus:
1
  /* in V-Limiter */ 
2
  if(Input.Vcc.Value > Par.VccMax.Value) 
3
  {
4
     Set(V_Limiter.ErrBits.VccOFL);
5
     V_Limiter.State = Z_VL_OFL;
6
     V_Limiter.Out.EngVal = 0;
7
     Set(Output.Leds.ErrLedVccOFL);
8
  }

Wobei das natürlich arg verkürzt ist, wir haben z.B. die Parameter 
Modulspezifisch und setzen/lesen Input/Output hingegen zentral (weil es 
halt nur einen physikalischen Kontext gibt)

So Kurz-Notation wie Z_VL_xx für "Zustand_V_Limiter_xx" sind erst mit 
größeren Projekten sinnvoll, wenn das Muster erkennbar und gewohnt ist. 
Bei nur ein paar Tausend Zeilen Code verwirrt das zu sehr, da lieber 
ausschreiben.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.