Hej leute hab da mal ne kurze frage.
Ist es unter C / C++ möglich wie in der Programmierung von SPS Systemen
unter der (Programmiersprache structured text in der codesys umgebung)
Sprünge in der Switchcase zu machen?
Z.B. in structured text kann ich sagen:
case 10:
if bla bla
then 20:
case 20:
if bla bla
then 30:
case 30:
if bla bla
then 10:
So kann ich von case 10 nach 20 nach 30 und wieder nach 10.
Gibt es einen Befehl wie man bei C / C++ von case zu case springen
kann??
Danke im voraus.
LG
Hallo,
das geht nicht mit C/C++.
Warscheinlich ist switch/case nicht das richtige Konstrukt um deine
Daten auszuwerten.
Was willst du denn genau machen?
Grüße,
Shabi N. schrieb:> Gibt es einen Befehl wie man bei C / C++ von case zu case springen> kann??
Ja, einfach das break weglassen, dann läuft man in den nächsten Case.
Ist aber nicht MISRA.
Also mein haupt Vorhaben (Endziel) ist es einen mini SPS mit einem
Microcontroller wie z.b. atmega 328... nach zu bauen.
Ich kann halt nur C/c++ und strutured Text.
Wenn es natürlich eine Umgebung gibt mit der man µC mit strutured Text
programmieren kann, wäre es auch eine Option.
LG
Shabi N. schrieb:> Wenn es natürlich eine Umgebung gibt mit der man µC mit strutured Text> programmieren kann,
??? Ich dachte du kannst c/c++:
Shabi N. schrieb:> Ich kann halt nur C/c++ und strutured Text.
Also programmiere den µC in c!
Shabi N. schrieb:> Also mein haupt Vorhaben (Endziel) ist es einen mini SPS mit einem> Microcontroller wie z.b. atmega 328... nach zu bauen.
Eine SPS selbst bauen? Inclusive einem Compiler oder Interpreter?
So ganz verstehe ich es noch nicht.
Wenn du in jedem case nur eine Funktion aufrufst und ein break hast,
hast du erstens saubereren Code und zweitens kannst du ja aus einer
Methode eine andere aufrufen.
Man muss nicht ein ganzes Programm in eine einzige Methode oder gar in
ein switch/case quetschen.
@UDO Nein der µC dient nur als Steuerung wie zb eine SPS Steuerung...
Die Steuerung wird dann Regler ansteuern die wiederum Motoren ansteuern.
Es werden auch einige Sensoren wie zb Lichtschranken an die Steuerung
angeschlossen aber das ist erstmal nebensache...
> Ich kann halt nur C/c++ und strutured Text.
Sehr schön. Dann programmier Dir einen Interpreter für structured Text
in C oder C++, der auf dem µC der Wahl läuft. Das war jetzt einfach.
Technisch sehe ich da kein Problem. Die Syntax sagt:
1
statement:
2
labeled-statement
3
…
4
5
labeled-statement:
6
identifier ':' statement
7
'case' constant-expression ':' statement
8
'default' ':' statement
Es spricht (syntaktisch) also nichts dagegen, zwei labels
hintereinander zu setzen, von denen eines per switch, das andere per
goto angesprungen wird, also etwa:
1
switch(…){
2
case10:
3
label_10:
4
…
5
gotolabel_10;
6
}
Ich habe's nicht probiert, sollte aber gehen. Ob das sinnvoll ist steht
natürlich auf einem anderen Blatt. Wie hier schon gesagt wurde deutet
einiges darauf hin, dass das Design sich verbessern lässt.
@ Markus F
Ja soetwas hab ich gesucht. Ich kenne den Befehl GOTO aber dachte immer
das ein GOTO absolut Tabu ist und man keine Programm Sprünge damit
machen sollte.
Weiß jetzt natürlich nicht ob es in einem Switch case anders ist...
Danke schonmal an alle werde mal ein paar tests machen...
LG
Shabi N. schrieb:> @ Markus F> Ja soetwas hab ich gesucht.
Au weia, da hab' ich dir was gezeigt.
Ich bin absolut sicher, das goto-Rumgehüpfe ist nicht die richtige
Lösung für dein Problem.
Am besten beschreibst Du einfach mal, was dein Problem überhaupt ist?
Shabi N. schrieb:> Ja soetwas hab ich gesucht. Ich kenne den Befehl GOTO aber dachte immer> das ein GOTO absolut Tabu ist und man keine Programm Sprünge damit> machen sollte.
Kommt drauf an.
GOTO wird in der Kernel- und Treiberprogrammierung verwendet, um
efizienten Code zu schreiben.
Aber in einem switch-case mit einem goto wild zwischen den cases hin und
her zu springen ist unsauber, schlecht und auch ueberhaupt nicht sinn
und zweck von switch-case/goto. Entweder du benutzt switch-case oder
goto, aber nicht beides zusammen.
Markus F. schrieb:> Am besten beschreibst Du einfach mal, was dein Problem überhaupt ist?
Wahrscheinlich einen unsauberen Zustandsautomat völlig zu verhunzen :-(
Na ja der TO schaufelt seinem Programm damit langfristig das Grab.
Warnungen gabs genug.
Markus F. schrieb:> Shabi N. schrieb:>> @ Markus F>> Ja soetwas hab ich gesucht.>> Au weia, da hab' ich dir was gezeigt.
Das war aber abzusehen.
Sorry, aber das musste auch mal gesagt werden. Einem Anfänger sowas zu
zeigen ist fahrlässig.
Kaj schrieb:> Shabi N. schrieb:>> Ja soetwas hab ich gesucht. Ich kenne den Befehl GOTO aber dachte immer>> das ein GOTO absolut Tabu ist und man keine Programm Sprünge damit>> machen sollte.> Kommt drauf an.> GOTO wird in der Kernel- und Treiberprogrammierung verwendet, um> efizienten Code zu schreiben.
Und vor allen Dingen wird das von Programmierern gemacht, die wissen was
sie tun und die das was sie da tun auch unter Kontrolle halten können.
Ich habe nicht den Eindruck, dass der TO in diese Kategorie fällt.
Karl Heinz schrieb:>> Das war aber abzusehen.> Sorry, aber das musste auch mal gesagt werden. Einem Anfänger sowas zu> zeigen ist fahrlässig.
Wahrscheinlich hätten wir's noch drei oder vier Minuten geheimhalten
können, dann hätt' er's bei Google gefunden ;)
C ist nun mal eine Sprache, mit der man sich elegant in den eigenen Fuß
schießen kann. Wer's richtig lernen will, muß das wohl hin und wieder
machen...
Also Leute damit hier keine Missverständnisse entstehen.
Ich will weder etwas verhunzen noch eine Sprache Unsauber nutzen.
Meine ursprüngliche Frage war ja nur ob es einen Befehl gibt um switch
case in C wie in strutured Text nutzen zu können.
Das Projekt ist noch in der Brain storming Phase und es ist noch nichts
passiert...
Wenn alle stricke reißen nutze ich einen Raspbarry und werde mich
hiernach orientieren.
http://www.sps-forum.de/beckhoff-codesys-iec61131/68431-codesys-auf-dem-raspberry-pi-jetzt-verfuegbar.html
@ UDO
nicht immer gleich vom schlimmsten ausgehen nur weil einer eine Frage
stellt :-)
Lange Rede kurzer Sinn wenn ich es richtig verstanden habe kann man in C
sowas wie in structured text nicht realisieren.
Somit bleibt mir doch noch die Möglichkeit Funktionen zu nutzen.
Und dazu nur eine Frage:
Ist es ok zwischen Funktionen hin und her zu springen oder ist das
unsauber und nicht im sinne des erfinders?
LG
Shabi N. schrieb:> Und dazu nur eine Frage:> Ist es ok zwischen Funktionen hin und her zu springen oder ist das> unsauber und nicht im sinne des erfinders?
Das ist nicht im Sinne des Erfinders.
Sobald du 'herumspringen' benutzt, solltest du dir überlegen, ob du
nicht einen groben Designfehler hast. Ja, es gibt Fälle, in denen ein
goto bzw. ein ähnlicher Mechanismus die sauberste Lösung darstellt. Aber
diese Fälle sind rar gesät und in den nächsten paar Jahren wirst du
nicht in die Verlegenheit kommen, so etwas benutzen zu müssen. Bis dahin
gilt: wenn du versucht bist einen goto zu benutzen, dann ist dein Design
schlecht und du solltest lieber an deinem Design arbeiten.
Ich bin jetzt 30 Jahre im Geschäft (davon 20 Jahre C++) und in all den
Jahren hab ich ein einziges mal einen goto gebraucht. Und selbst den
haben wir Jahre später zugunsten einer besseren Lösung ausgebaut.
Shabi N. schrieb:> Also mein haupt Vorhaben (Endziel) ist es einen mini SPS mit einem> Microcontroller ...
Dafür brauchst du das von dir angestrebte Gefrickel nicht (und auch kein
C++).
man Zustandsautomat
Um auf eine Frage zu kommen:
Ja, diese Möglichkeit gibt es, nennt sich "GOTO" und ist wildestes
Gefrickel.
Roland
Shabi N. schrieb:> @ UDO> nicht immer gleich vom schlimmsten ausgehen nur weil einer eine Frage> stellt :-)
Ich habe dir oben einen Beispielcode für einen einfachen
Zustandsautomaten gepostet, das Stichwort "Zustandsautomat" wurde
mehrfach erwähnt, du darfst es gerne weiter ignorieren. :-)
Bzgl vom Schlimmsten ausgehen: Ich habe dein Beispiel gesehen, das ist
schon schlimm, und wenn solche Krebsgeschwüre in einem Programm wachsen,
dann kommt irgendwann etwas raus was man nur noch wegwerfen kann.
Jahrzehntelange Erfahrung lehrt: Am besten so schnell wie möglich
wegwerfen.
Karl Heinz schrieb:> Markus F. schrieb:>> Shabi N. schrieb:>>> @ Markus F>>> Ja soetwas hab ich gesucht.>>>> Au weia, da hab' ich dir was gezeigt.>> Das war aber abzusehen.> Sorry, aber das musste auch mal gesagt werden. Einem Anfänger sowas zu> zeigen ist fahrlässig.
Viel mehr würden mich einige andere Dinge stören: Ein goto ist
überflüssig (obwohl man es der Lesbarkeit halber akzeptieren und hoffen
kann, dass der Compiler es wegoptimiert), ein break ist definitiv zu
viel und könnte sogar zu einem statement not reachable oder ähnlichem
Fehler führen, und das es sich beim ersten Zeichen der Label um eine
kleines L und nicht die Ziffer 1 handelt, was den entscheidenden
Unterschied zwischen einem Identifier und eine numerischen Konstante
ausmacht, ist bei dem verwendeten Font für den Anfänger auch nicht
unbedingt einfach zu erkennen.
Abgesehen davon halte ich die kontextlose Verteufelung des goto für
nicht weniger fahrlässig. Das Ergebnis sind dann solche Auswüchse, wie
wir oben gesehen haben. Sorry Udo (urschmitt), aber bei solchem Code
sträuben sich bei mir die Nackenhaare. Was spricht dagegen, das ganz
natürlich und sauber mit goto zu lösen?:
1
voidfsm()
2
{
3
state_10:
4
...
5
gotostate_10;// Endlosschleife ?
6
7
state_20:
8
...
9
if(endebedingung)return;// Reihenfolge getauscht, da nur eine Anweisung
10
if(...)gotostate_30;// der beiden einen Effekt haben kann und diese
11
// Reihenfolge dem zu erwartenden Effekt entspricht
12
state_30:
13
...
14
if(...)gotostate_10;
15
}
Der Code ist strukturell identisch, kürzer, nicht schlechter lesbar,
eher im Gegenteil macht er einige mögliche Fehler offensichtlicher
(siehe Kommentare), kommt ohne zwei überflüssige Variablen, eine
überflüssige Schleife und ein überflüssiges switch aus, der Compiler
wird meckern, wenn ein nicht vorhandener Zustand angesprungen werden
sollte und obendrein ist der Code auch noch effizienter.
Die immer noch weit verbreitete goto-Phobie stammt noch aus einer Zeit,
in der die meisten Programmierer mit Basic oder Assembler begonnen
haben, in Sprachen also, in denen das goto oft die einzige Möglichkeit
der Verzweigung war, und die dann dieses gewohnte und leider auch sehr
flexible Sprachmittel als Universalwerkzeug kritiklos auf alle passenden
und unpassenden Situationen übertrugen, auch dann, wenn andere Sprachen
besser Alternativen boten. Damals dürfte sie daher sogar berechtigt
gewesen sein. Diese Zeiten sind aber lange vorbei. Neuere Lehrbücher
erwähnen goto wenn überhaupt dann nur noch am Rande. Der TO ist das
beste Beispiel, der goto ja offenbar noch nicht einmal kannte. Die
Gefahr des Missbrauchs würde ich daher heute als deutlich geringer
einschätzen
Andererseits verbaut man sich mit dem Verzicht aber Möglichkeit, siehe
das Beispiel von Udo. Das goto ist zunächst ein Sprachmittel wie jedes
andere auch, es kann gebraucht und missbraucht werden, es kann adäquat
sein oder nicht, aber nicht gut oder schlecht per se. Was adäquat
bedeutet hängt vom zu Grunde liegenden Modell ab und für einen nicht
ereignisgetriebenen endlichen Automaten, der abhängig von Zustand und
Input eine Aktion ausführen und dann zum nächsten Zustand gehen soll
(go to next state), gibt es meine bescheidenen Meinung nach kein
adäquateres Sprachmittel als das goto. Alles andere führt zu unnötigem
Overhead, zusätzlicher Komplexität, schlechterer Lesbarkeit, höherer
Fehleranfälligkeit und schlechteren Prüfmöglichkeiten für den Compiler.
Also mal etwas mehr Mut zum goto! Das man wissen muss was man tut,
gilt natürlich immer noch, aber das gilt immer und woher soll ein
Anfänger es lernen, wenn wir es ihm nicht zeigen. After all:
'There never has been nor ever will be a programming language, where it
is at least a bit difficult to write bad code!'
PS: Die häufige Verwendung von goto in vielen Treibern und anderen
Kernelkomponenten halte ich übrigens für keine adäquate Anwendung. Ich
habe noch keine Situation erlebt, die man mit strukturierten Mitteln
nicht genauso gut oder besser hätte lösen können.
A. H. schrieb:> as Ergebnis sind dann solche Auswüchse, wie> wir oben gesehen haben. Sorry Udo (urschmitt), aber bei solchem Code> sträuben sich bei mir die Nackenhaare.
Na was genau sträubt denn deine Nackenhaare? :-)
Die Zeilen habe ich schnell zusammengetippt, falls also ein Semikolon
fehlt...
Statt hier seitenweise einen Vortrag zu halten zeige wie man es besser
macht.
[ ] Du weisst was ein Zustandsautomat ist?
@ Karl Heinz
Danke für deine Tipps im Grunde hast du ja recht mit dem Designe
überprüfung....
@ UDO
Ich den Zustandsautomat nicht ignoriert. Was soll ich denn noch dazu
sagen. (Siehe Digitaltechnik 1. Semester...)
Allen anderen danke ich vielmals für eure Tipps.
LG
Mal eine ganz andere Frage: Wozu mußt du in deinem Zustandsautomat wild
zwischen den Zuständen hin und her springen? Die Variable, die du in dem
zu den cases gehörenden switch abfragst, enthält den Zustand (der
übrigens nicht über "magic numbers", sondern über Namen zu
identifizieren sein sollte). Wenn du den Zustand ändern willst, weist du
den der Variablen zu, und das nächste mal, wenn der Automat aufgerufen
wird (also das switch ausgeführt wird), passiert ganz von selbst der
Sprung an die richtige Stelle. Wozu sollte man da mitten aus einem
Zustand heraus direkt in einen anderen rüberspringen wollen?
Shabi N. schrieb:> Z.B. in structured text kann ich sagen:>> case 10:> if bla bla> then 20:>> case 20:> if bla bla> then 30:>> case 30:> if bla bla> then 10:>> So kann ich von case 10 nach 20 nach 30 und wieder nach 10.
Und wann kommt er dann zum Switch? Das sieht mir nach einer
Endlosschleife aus, in der ich mir die Zustände auch gleich sparen kann.
Udo Schmitt schrieb:> Statt hier seitenweise einen Vortrag zu halten zeige wie man es besser> macht.
Nanu, hast Du Deinen eigenen Code nicht mehr erkannt? Das Beispiel oben
habe ich 1:1 von Dir abgeschrieben, lediglich jedes case Label durch
ein goto Label ersetzt, jedes a= durch eine goto Anweisung (was ja
letztlich nichts anderes ist als eine Zuweisung an den Befehlszähler)
und dann alles weggestrichen, was überflüssig geworden war.
Wobei ich gerade feststelle, dass mir da ein Fehler unterlaufen ist: Ich
hätte auch jedes break ersetzen müssen, nicht nur das erste. Hier also
die korrigierte Variante:
1
voidfsm()
2
{
3
state_10:
4
...
5
gotostate_10;// Endlosschleife ?
6
7
state_20:
8
...
9
if(endebedingung)return;// Reihenfolge getauscht, da nur eine Anweisung
10
if(...)gotostate_30;// der beiden einen Effekt haben kann und diese
11
gotostate_20;// Reihenfolge dem zu erwartenden Effekt entspricht
12
13
state_30:
14
...
15
if(...)gotostate_10;
16
gotostate_30;
17
}
> [ ] Du weisst was ein Zustandsautomat ist?
Ich hoffe, sonst würde ich mir hier keine Meinung erlauben ;-)
@ah8, danke für deinen "Vortrag"! Deine Ausführungen zum sinnvollen
Einsatz von GOTO sprechen mir absolut aus der Seele! Und das Beispiel
mit dem kleinen Zustandsautomaten passt wunderbar!
(meint der Michi, der Goto ganz ganz selten verwendet, dann aber mit
(sehr) gutem gewissen, und der das allgemeine GOTO-bashing nicht leiden
kann, und der außerdem den Essay "real programmers don't use pascal"
liebt...)
Shabi N. schrieb:> Ich kann halt nur> C/c++
Das bezweifle ich.
> und strutured Text.
Das bezweifle ich ebenfalls, sonst würdest du den Namen nicht falsch
schreiben.
Wie wäre denn ein C-Buch?
kopfkratz
Also entweder Du willst einen Interpreter realisieren oder nur
"rumtrollen", was ist es ?
Du kannst entweder wie schon gesagt einen Zustandsautomaten mit
passenden Übergängen realisieren oder einen echten Interpreter.
Bei einem Interpreter solltest Du Dir mal grundlegendes Wissen über
BNF&Co. ansehen und auch verstehen.
Wenn Du dann weißt wie man Token erkennt und entsprechend auswertet
kannst Du eine SPS mit Deinem Code kontrollieren.
Die Frage ist halt mal wieder was wirklich geplant ist und was wirklich
benötigt wird ?
Eine gute Übung wäre z.B. wenn Du jetzt einfach mal hingehst und Dir
einen BNF Interpreter baust der eine Textdatei mit der BNF Deiner
Programmersprache lesen und interpretieren kann.
Wenn Du soweit bist kannst Du sicherlich eine SPS realisieren.
@ Progger
Danke für deine Verurteilung...
Hab halt nen Tippfehler gemacht der sich durch copy and paste nach unten
geschlichen hat.
@ Kopfkratzer
Im Grunde ist es eine Maschine die mehrere Achsen und Sensoren hat die
je nach Code/ Programm bewegt/ausgewertet werden. Die abläufen sind
immer die selben.
ZB.
-Maschine an
-Referenzfahr aller achsen
-Maschine starten
-Maschinenablauf
-Maschine Stoppen
...
Um alles zu erklären müsste ich viel zu weit ausholen.
Den Tipp mit dem BNF find ich super. Werde bei Zeiten mal rein schauen
und mich mit befassen. Hab aktuell noch einige andere Projekte die
abgeschlossen werden müssen...
Um das ganze jetzt zusammen zu fassen:
Mit C/C++ wäre es zwar möglich aber ist unsauber und nicht im sinne des
erfinders.
Ich denke ich werde dann eine andere Lösung suchen wie die von oben mit
nem Raspbarry. Da kann man auch in der CODESYS Umgebung programmieren.
Danke an alle.
LG
Shabi N. schrieb:> Um das ganze jetzt zusammen zu fassen:> Mit C/C++ wäre es zwar möglich aber ist unsauber und nicht im sinne des> erfinders.
Also, zu behaupten dass sich so etwas in C/C++ nicht sauber
implementieren lässt wäre nun der völlig falsche Schluss. Das Problem
ist, dass Du zwei Sprachmittel miteinander kombinieren möchtest, die
unterschiedlichen Ansätzen folgen, nämlich das switch und das goto.
Die Wahl der Sprachmittel wird durch das zu Grunde liegendes Modell
bestimmt und Dein Versuch legt den Verdacht nahe, dass Du Dir über diese
Modell noch nicht hinreichend im Klaren bist. Sollte das stimmen so wäre
es Dein Design, dass unsauber ist, nicht aber das Problem und auch die
Sprache.