# Textsteuerung in ST



## aem (22 Januar 2020)

Hallo zusammen,

bin ziemlich unerfahren im SPS programmieren, also seid bitte nachsichtig wenn ich falsche Begriffe verwende 

Ich möchte gerne Ansteuerung zu einem Ventil mit ST realisieren, wobei die Ventilstellung durch die Eingabe eines Textes geändert wird. Dieser Text könnte z.B. über eine automatische Texterkennung aus gesprochenen Worten ermittelt werden.

Die Texte, die zum Öffnen oder Schließen des Ventils führen, müssen die Zeichenfolgen "Ventil" oder "V1" und zusätzlich für das Öffnen des Ventils "öffne" oder "auf" und für das Schließen "schließe" oder "zu" enthalten.

Es soll in einem FB festgestellt werden, ob bei dem vorgegebenen "Eingabetext" das "Ventil" der Wert TRUE (Ventil auf) oder FALSE (Ventil zu) annehmen soll. Dazu muss geprüft werden, ob der eingegebene Text die angegebenen Schlüsselzeichen enthält.

Ich habe erstmal so versucht zu realisieren:

IF (Text1 = 'Ventil' OR Text1 = 'V1') AND (Text2 = 'öffne' OR Text2 = 'auf') THEN Ventil := TRUE; END_IF;
IF (Text1 = 'Ventil' OR Text1 = 'V1') AND (Text3 = 'schließe' OR Text3 = 'zu') THEN Ventil := FALSE; END_IF; 


Ich denke, der Code erfüllt nicht so ganz die Angaben der Aufgabenstellung, oder ?

Könnt Ihr mir bitte hier weiterhelfen ?

Vielen Dank im voraus


----------



## Heinileini (23 Januar 2020)

aem schrieb:


> Dieser Text könnte z.B. über eine automatische Texterkennung aus gesprochenen Worten ermittelt werden.
> ...
> Ich denke, der Code erfüllt nicht so ganz die Angaben der Aufgabenstellung, oder ?


Doch, doch! Perfekt! Hoffentlich arbeitet die "automatische Texterkennung aus gesprochenen Worten" ebenso perfekt.
Ich würde mal intensiv testen, was für Ergebnisse die TextErkennung zu liefern in der Lage ist ... und wenn's hoffnungsvoll erscheint, ergeben sich wahrscheinlich schon die FussAngeln, die Du im Programm berücksichtigen müsstest.
Spontan würde ich die Vergleiche der Soll- und IstTexte erstmal so erweitern, dass trotz Unterschieden in der Gross-/Kleinschreibung auf Gleichheit erkannt wird.

PS:
Vllt bekommst Du für 'Ventil' 'Wentil' oder 'wenn Thiel' (der Münsteraner TatortKommissar) geliefert. Oder 'doodlebug' (der Spitzname der Engländer für die Wunderwaffe V1) für 'V1'.


----------



## aem (23 Januar 2020)

Hallo Heinileini,

Zunächst vielen Dank für Deine schnelle Antwort

Ich habe das Programm getestet und es hat auch so funktioniert, d.h. Wenn der Eingabetext genauso eingegeben wird, wie in der "IF-Anweisung" definiert ist, reagiert das ventil entsprechend richtig. Frage dazu, was Du erwähnt hast mit Gross- / Kleinschreibung! Kann ich es ohne zusätzliche "OR" Schalter (Text1= 'ventil' OR Text1='v1') realisieren ? Gibt es vllt. eine andere Variante ?


----------



## Brro87 (23 Januar 2020)

Du könntest mit der Function F_ToUCase den String jeweils zuerst auf Grossbuchstaben wandeln und dann erst den Vergleich mit deinen IFs machen.
https://infosys.beckhoff.com/index....ties/html/TcPlcLibUtilities_F_ToUCase.htm&id=


----------



## Heinileini (23 Januar 2020)

Brro87 schrieb:


> Als Schweizer geboren zu werden, ist ein grosses Glück. Es ist aber auch schön, als Schweizer zu sterben. Doch was tut man dazwischen.


Auf den deutschen Autobahnen "Zeit sparen"!


----------



## aem (23 Januar 2020)

Gibt es diese Funktion auch in CoDeSys ? In der Hilfe habe ich sie nicht gefunden


----------



## Brro87 (24 Januar 2020)

Sorry, habe erst jetzt gemerkt das dies eine Beckhoff eigene Funktion ist. Bei Codesys müsste dies wohl die Funktion StrToUpperA in der StringUtils Library können.
https://help.codesys.com/webapp/j_V...ToUpperA;product=StringUtils;version=3.5.15.0

Diese Funktion benutzt eine Pointer to String bzw. CharBufferPtr (POINTER TO BYTE) als Übergabewert, dieser muss beim Aufruf mit ADR(<String>) übergeben werden.
*Beispiel mit deinem Text1 (String): *StrToUpperA(pString:= ADR(Text1))


----------



## Sps_Anfänger.CR (31 Mai 2022)

Hallo ich hätte eine Frage zu diesem Thema.
Ich hätte das in ST so programmiert und es funktioniert auch, aber ich bin mir sicher das ich es nicht so schreiben soll. Könnten mir jemand eine Tipp geben.
Danke im voraus.
MFG


----------



## Heinileini (31 Mai 2022)

Ich würde es in dieser Art angehen (ungetestet):

```
Text1    := ' V1 Ventil ' ;
Text2    := ' auf öffne oeffne ' ;
Text3    := ' zu schließe schliesse ' ;

tiPosBlk := FIND (Eingabetext, ' ') ;
tsTextL  := CONCAT (' ', LEFT (Eingabetext, tiPosBlk) ;
tsTextR  := CONCAT (MID (Eingabetext, 31, tiPosBlk), ' ') ;

tbV1     :=  FIND (Text1, tsTextL) > 0 ;
tbV1Auf  := (FIND (Text2, tsTextR) > 0) AND tbV1 ;
tbV1Zu   := (FIND (Text3, tsTextR) > 0) AND tbV1 ;

Ventil   := (Ventil OR tbV1Auf) AND NOT tbV1Zu ;
```

PS:
zusätzlich verwendete temporäre Variablen:

```
VAR
    tiPosBlk : INT ;
    tsTextL  : STRING ;
    tsTextR  : STRING ;
         
    tbV1     : BOOL ;
    tbV1Auf  : BOOL ;
    tbV1Zu   : BOOL ;
END_VAR
```


----------



## Sps_Anfänger.CR (1 Juni 2022)

Danke für deine schnelle Antwort ich hätte es jetzt so Programmiert, aber es funktioniert nicht.


----------



## Heinileini (1 Juni 2022)

Sps_Anfänger.CR schrieb:


> Danke für deine schnelle Antwort ich hätte es jetzt so Programmiert, aber es funktioniert nicht.


Woran scheitert's? Bei der 31 als LängenAngabe beim MID weiss ich nicht, ob CodeSys das so akzeptiert.
Einen anderen Verdacht habe ich im Moment nicht.

Meldet der Compiler, dass er mit irgendwas nicht zufrieden ist? Was bedeutet "funktioniert nicht"? Tut sich gar nichts? Läuft es, jedoch anders als beabsichtigt?


----------



## Sps_Anfänger.CR (1 Juni 2022)

Es läuft garnicht wenn ich in das EA Feld zb Ventil auf reinschreibe tut sich nichts


----------



## Heinileini (1 Juni 2022)

Sps_Anfänger.CR schrieb:


> Es läuft garnicht wenn ich in das EA Feld zb Ventil auf reinschreibe tut sich nichts


Wenn im Eingabefeld lediglich 'Ventil' drinsteht, sollte sich doch auch nichts tun oder habe ich das falsch verstanden?
Und wenn Du 'Ventil auf' in das EA-Feld reinschreibst?


----------



## Sps_Anfänger.CR (1 Juni 2022)

Habe es auch noch im TIA Portal probiert und da Funktioniert es leider auch nicht


----------



## Sps_Anfänger.CR (1 Juni 2022)

Habe ich gemacht ich habe Ventil auf reingeschrieben aber das Ventil öffnet sich dann leider nicht


----------



## Heinileini (1 Juni 2022)

Ah ja, Left und Mid sind rot unterstrichen. Anscheinend verkraftet Concat es nicht, wenn dort weitere Funktionen stehen?
In meiner Variante aus #9 fehlt eine Klammer - sehe ich gerade - aber die hattest Du ja schon ergänzt.


```
tiPosBlk := FIND (Eingabetext, ' ') ;
tsTextL  := CONCAT (' ', LEFT (Eingabetext, tiPosBlk)) ;
tsTextR  := CONCAT (MID (Eingabetext, 31, tiPosBlk), ' ') ;
```
... ersetzen durch ...

```
tiPosBlk := FIND (Eingabetext, ' ') ;
tsTextL  := LEFT (Eingabetext, tiPosBlk) ;
tsTextL  := CONCAT (' ', tsTextL) ;
tsTextR  := MID (Eingabetext, 31, tiPosBlk) ;
tsTextR  := CONCAT (tsTextR, ' ') ;
```
Vielleicht kommen wir so der Sache näher?


----------



## Sps_Anfänger.CR (1 Juni 2022)

Nein leider nicht habe es in Codesys und im Tia probiert


----------



## Sps_Anfänger.CR (1 Juni 2022)

Ok den Fehler habe ich gefunden mit MID aber es funktioniert leider immer noch nicht


----------



## Heinileini (1 Juni 2022)

Bitte in TIA beim Mid die Parameter P und L tauschen : P:=tiPosBlk und L:=31.
Bei TIA steht in der Beschreibung, dass der StringInhalt bis zum Ende übernommen wird, wenn bei L zuviele Zeichen parametriert sind.
Genau davon war ich auch ausgegangen, als ich für L den konstanten Wert 31 ausgeguckt hatte. Die CodeSys-Beschreibug die ich habe, schweigt sich zu diesem Thema leider aus ...

Sehr "zuvorkommend" von Dir! Du hattest den Fehler schon gefunden, während ich noch am Tippeln war!


----------



## Sps_Anfänger.CR (1 Juni 2022)

Ok danke aber was heißt das jetzt 
Weil es funktioniert ja leider immer noch nicht :/
Danke für deine schnellen Antworten


----------



## Heinileini (1 Juni 2022)

Jetzt ist mir bei den Texten Text1 bis Text3 etwas aufgefallen:
Bitte immer nur 1 Leerzeichen zwischen den einzelnen Begriffen und (noch wichtiger) auch genau 1 Leerzeichen vor dem ersten Begriff und 1 Leerzeichen hinter dem letzten Begriff!


----------



## Sps_Anfänger.CR (1 Juni 2022)

Ok vielen Dank im Tia Portal funktioniert es jetzt im Codesys werde ich es bestimmt auch noch rausfinden.
Danke für die Hilfe


----------



## Sps_Anfänger.CR (6 Juni 2022)

Hallo ich hätte noch ein Frage bezüglich meiner Hausaufgaben von 2.2 und 2.3 ich habe irgendwie keine Ahnung was sie bei 2.3 meinen und 2.2 bei 2.2 hätte ich schon den ganzen Lehrbrief durchgesehen und wir haben das noch  nicht durchgemacht deshalb habe ich leider absolut keine Ahnung. Vielleich kann mir ja jemand weiterhelfen. 
Danke im voraus. 
LG


----------



## holgermaik (7 Juni 2022)

Sps_Anfänger.CR schrieb:


> ich habe irgendwie keine Ahnung was sie bei 2.3 meinen


du sollst aus dem String die linke 4 finden, isolieren und in eine Zahl konvertieren.
Stichwort:
- Find
- Len
- MID
- Right
- Left


----------



## Heinileini (7 Juni 2022)

holgermaik schrieb:


> du sollst aus dem String die linke 4 finden, isolieren und in eine Zahl konvertieren.


Eigentlich in einem String die erste Ziffer (x >= '0' AND x <= '9') finden und diese dann in einen nicht näher spezifizierten GanzzahlDatenTyp konvertieren.



Sps_Anfänger.CR schrieb:


> ... und 2.2 bei 2.2 hätte ich schon den ganzen Lehrbrief durchgesehen und wir haben das noch  nicht durchgemacht deshalb habe ich leider absolut keine Ahnung.


Ebenfalls keine Ahnung. Ist damit die Potenzierung von 4.2 mit 5.3 gemeint? In AWL? Für nur lächerliche 4 Punkte? Das kann doch irgendwie nicht sein ... oder gibt es in CodeSys-AWL dafür tatsächlich eine verwendbare Funktionalität? Z.B. das Rechnen mit Logarithmen?


----------



## Mrtain (7 Juni 2022)

EXPT


----------



## Sps_Anfänger.CR (7 Juni 2022)

Ich darf es leider nicht in Codesys Programmieren sondern in IEC :/


----------



## Mrtain (7 Juni 2022)

Sps_Anfänger.CR schrieb:


> Ich darf es leider nicht in Codesys Programmieren sondern in IEC :/


???


----------



## Sps_Anfänger.CR (7 Juni 2022)

🤷🏽‍♀️


----------



## Mrtain (7 Juni 2022)

Ja aber ist "expt" nicht ein iec operator?


----------



## Heinileini (7 Juni 2022)

Mrtain schrieb:


> EXPT


Tatsächlich. Gibt's in CodeSys!
So gesehen sind die 4 Punkte für die Lösung der Aufgabe angemessen bis reichlich.


----------



## Mrtain (7 Juni 2022)

Heinileini schrieb:


> Tatsächlich. Gibt's in CodeSys!
> So gesehen sind die 4 Punkte für die Lösung der Aufgabe angemessen bis reichlich.


Danke, hab schon an mir gezweifelt


----------



## holgermaik (7 Juni 2022)

Mrtain schrieb:


> Ja aber ist "expt" nicht ein iec operator?


"expt" ist zwar in Codesys V3 integriert aber in der Liste der IEC "A.2 Numerische Funktionen" steht es nicht mit dabei.
Ich denke hier soll eine allg. mögliche Berechnung erläutert werden.
Stichwort
- Wurzelgesetze
- LN (natürlicher Alogarithmus)
- EXP (Exponent Basis e)

PS. 4 Punkte ist dafür aber ganz schön wenig


----------



## PN/DP (7 Juni 2022)

Sps_Anfänger.CR schrieb:


> bei 2.2 hätte ich schon den ganzen Lehrbrief durchgesehen und wir haben das noch  nicht durchgemacht deshalb habe ich leider absolut keine Ahnung.


2.2 "A := 4.2 ** 5.3" als Anweisungsliste (IEC: IL)

```
LD 4.2
EXPT 5.3
ST A
```

Harald


----------



## Sps_Anfänger.CR (21 Juni 2022)

Danke für eure raschen Rückmeldung 
Habe jetzt eine weile an der aufgabe 2.3 getüfftelt aber ich komme irgendwie nicht drauf 😕


----------



## holgermaik (21 Juni 2022)

Eine Möglichkeit wäre von einem bekannten Zeichen aus zu zählen.
Du suchst mit „Find“ ein Zeichen welches immer an der gleichen Position ist. z.B. „leer“ oder „-„. Von dieser festen Position kannst du dann zählen.

Ein anderer Ansatz ist jedes Zeichen vom Anfang an auf eine Zahl zu prüfen. Die erste gefundene Zahl wäre das Ergebnis.


----------



## Heinileini (21 Juni 2022)

Sps_Anfänger.CR schrieb:


> Habe jetzt eine weile an der aufgabe 2.3 getüfftelt aber ich komme irgendwie nicht drauf 😕


Mit MID kannst Du jedes einzelne Zeichen (oder auch mehrere) aus einem String isolieren.
In einer Schleife. ErstesZeichen prüfen, ob es eine Ziffer ist.
Wenn nein, dann mit dem nächsten Zeichen wiederholen u.s.w. bis sich ein Zeichen als Ziffer zu erkennen gibt oder der String zu Ende ist und keine Ziffer dabei war.
Wenn ja, die Suche augenblicklich abbrechen, denn man hat das Gesuchte gefunden.
Woran erkennt man eine Ziffer?
Ziffern sind die ASCII-Zeichen 48 bis 57 (dezimal) bzw. 30h bis 39h (hexadezimal) bzw. '0' bis '9', wobei mit dieser Schreibweise gemeint ist, dass die Ziffern direkt als ASCII-Zeichen zu verstehen sind.
Wenn also die Beurteilung eines Zeichens ergeben soll, ob es sich um eine Ziffer handelt oder nicht, dann prüft man ob das Zeichen >='0' UND Zeichen <='9' ist. (Alternativ über den ZahlenWert des Zeichens: Zeichen >=48 UND Zeichen <=57)

Man kann auch mit der FIND-Funktion arbeiten und nacheinander nach allen 10 denkbaren Ziffern im String suchen lassen.
Der FIND liefert jeweils die Position der ersten gefundenen Ziffer im String (nach der gerade gesucht wird).
Die kleinste Position, die aber grösser als 0 sein muss (denn 0 bedeutet: das Zeichen wurde im String nicht gefunden!) die von den 10 FIND-Funktionen gefunden wurde, ist dann die Position der ersten Ziffer im String.

Letzteres Verfahren (mit FIND) artet aber eher in ein "mit Spatzen auf Kanonen schiessen" aus, ist also eher zu aufwändig und vor allem zeitaufwändig, da alle 10 Ziffern geprüft werden müssen. Es kann bei laaangen Strings, in denen die erste Ziffer erst kurz vor StringEnde auftritt, zeitlich von Vorteil sein.
Ersteres Verfahren (mit MID) würde ich bei kurzen Strings, die nach Ziffern durchsucht werden müssen, vorziehen.


----------



## Sps_Anfänger.CR (27 Juni 2022)

Irgendwie verstehe ich es nicht wir haben das so noch nicht wirklich durgenommen. 
Ich verstehe auch die Angabe nicht wirklich von der Fernschule


----------



## Sps_Anfänger.CR (27 Juni 2022)

hätte es so versucht


----------



## Mrtain (27 Juni 2022)

Du sollst eine Funktion mit Namen "Auflage" schreiben. Übergabeparameter ist "TeilenNr" als string. Rückgabewert soll vom Datentyp eine Ganzahl sein, zum Beispiel ein int.


----------



## Sps_Anfänger.CR (27 Juni 2022)

Ich verstehe einfach die Aufgabenstellung von der ganzen Aufgabe nicht wir haben das so noch nicht durch im Lehrbrief.


----------



## Mrtain (27 Juni 2022)

In der zu schreibenden Funktionen sollst du im übergebenen String nach der ersten Zahl suchen.
Wenn im String zum Beispiel "aBC3456" steht, wäre die Lösung 3. Bei "15dftz6789" wäre die Lösung 1.
2 mögliche Strategien wie man das lösen kann, hat dir Heinileini in Beitrag #37 aufgezeigt.
Programmieren und testen must du es allerdings 😉


----------



## Sps_Anfänger.CR (1 Juli 2022)

Ich habe jetzt die Hausaufgabe abgeschickt und bekamm eine 5 weil anscheinend das Projekt „Textsteuerung“ falsch wahr was ihm genau nicht passte sagte der Professor mir nicht, es hat aber alles einwandfrei funktioniert. 🤷🏽‍♀️


----------



## Sps_Anfänger.CR (1 Juli 2022)

Habe es genau so programmiert funktioniet auch alles🤷🏽‍♀️


----------



## Heinileini (1 Juli 2022)

Sps_Anfänger.CR schrieb:


> Ich habe jetzt die Hausaufgabe abgeschickt und bekamm eine 5 weil anscheinend das Projekt „Textsteuerung“ falsch wahr was ihm genau nicht passte sagte der Professor mir nicht, es hat aber alles einwandfrei funktioniert. 🤷🏽‍♀️


Das tut mir Leid. 
Anscheinend ist Deinem Professor egal, ob Deine Lösung funktioniert oder nicht. Wie soll er das auch beurteilen? Etwa nachprüfen oder sich hineinknien? Das macht nur unnötig Arbeit.
Er hat sicherlich nur geguckt, ob Deine Lösung mit seiner Vorlage identisch ist und er hält es auch nicht für möglich, dass viele Wege nach Rom führen.

Habe Ähnliches in ProgrammierKursen auch schon erlebt. Da ging es z.B. darum, den grösseren (oder war's der kleinere?) von zwei Werten zu ermitteln und ich hatte einen Lösungsweg ohne IF-Abfrage vorgelegt *). Das fanden die natürlich völlig indiskutabel und Lichtjahre am Thema vorbei - warum auch immer. Sie von der Richtigkeit der Lösung zu überzeugen, war ebenso (aus ZeitMangel? aus Überzeugung? keine Ahnung) völlig unmöglich.
Kreativität ist offensichtlich nicht gefragt und führt lediglich zu einer Verhärtung der Fronten - leider.

Lass Dich nicht entmutigen!

PS:
Habe ich Dich richtig verstanden? Du hast eine GesamtNote 5 bekommen, nur weil eine einzige Aufgabe von mehreren nicht nach deren Geschmack war?
Das wäre allerdings bitter.

*)

```
Min := ((Var1 + Var2) - ABS(Var1 - Var2)) / 2 ;
Max := ((Var1 + Var2) + ABS(Var1 - Var2)) / 2 ;
```


----------



## Sps_Anfänger.CR (1 Juli 2022)

Ja das war auch gleich mein erster gedanke aber nutzt nichts. Ich habe gottseidank noch die Möglichkeit das ich es nochmal einreiche, aber wäre natürlich auch toll gewesen wenn der Herr Professor mir gesagt hätte was nicht stimmt. Bzw was Ihm nicht passt, weil ich ja nicht weiss wie genau er es den haben möchte. 

Die beiden Aufgaben wo ich das programmieren muss haben eben die meisten Punkte und ich musste es in Codesys und im Tia Portal Programmieren und dadurch es Ihn ja nicht passte wie ich das mache, habe ich keine Punkte dafür bekommen. 🤷🏽‍♀️


----------



## Heinileini (1 Juli 2022)

Hast Du denn den Lösungsweg vestanden und könntest ihn gegenüber Deinem Professor erklären bzw. rechtfertigen oder ihn sogar davon überzeugen?


----------



## Sps_Anfänger.CR (1 Juli 2022)

Ja aber ich habe bisschen angst das ich dann die möglichkeit nicht mehr bekomme es erneut zu machen


----------



## Heinileini (1 Juli 2022)

Sps_Anfänger.CR schrieb:


> Ja aber ich habe bisschen angst das ich dann die möglichkeit nicht mehr bekomme es erneut zu machen


Tja, anscheinend ist hier Taktik gefragt und nicht so sehr der Lösungsweg ...
Bekommst Du denn eine alternative Lösung auf die Beine? Ich würde mich hier lieber ein wenig zurückziehen, ehe ich Dich (ungewollt!) auf einen weiteren Holzweg locke ...


----------



## Sps_Anfänger.CR (1 Juli 2022)

Ich werde es versuchen und hoffentlich auf einen anderen Lösungsweg kommen, aber danke für die ganze Hilfe


----------



## JesperMP (1 Juli 2022)

Wie lautet die genaue Beschreibung von die Aufgabe ?

Was mich stört ist das "auf", "öffne" und "oeffne" sind gedeckt, aber was mit "Auf", AUF", "Öffne", "Oeffne", "ÖFFNE", "OEFFNE" ?
So eine Kommandozeile Interpreter zu programmieren der jeden sinnvolle Eingabe akzeptiert und alles anders verwerft ist nicht soo einfach.


----------



## Sps_Anfänger.CR (1 Juli 2022)

so


----------



## Heinileini (1 Juli 2022)

JesperMP schrieb:


> So eine Kommandozeile Interpreter zu programmieren der jeden sinnvolle Eingabe akzeptiert und alles anders verwerft ist nicht soo einfach.


Oh ja, Jesper!
Das Problem mit der GrossSchreibung contra KleinSchreibung contra DurcheinanderGemischtGrossUndKleinSchreibung ist aber ein relativ kleines.
Ob das auch für SCL und ST so gilt, forsche ich jetzt nicht nach, aber in VBA fallen mir da spontan die Funktionen UCase und LCase ein.

Mich würde z.B. mehr stören, wenn sich in den Text das Wort 'nicht' einschleicht und bei der Dekodierung schlichtweg ignoriert würde, so dass etwas ausgelöst wird, das ausdrücklich nicht passieren soll.


----------



## JesperMP (1 Juli 2022)

Hmmm..
Genügt es nicht mit FIND ?
Das LEFT, CONCAT und MID ist überflüssig ?
Wenn die Texte gibts (auf, öffne usw. für Ventil öffnen) dann ist es genug um zu erkennen ob die Aktion ausgeführt werden soll.


----------



## Sps_Anfänger.CR (1 Juli 2022)

Kann ich jetzt also nur mit FIND das auch Programmieren?


----------



## JesperMP (1 Juli 2022)

Wenn ich dein Code betrachtet, dann testest du mit FIND ob "auf öffne oeffne" gibts in die Eingabestring. Also nicht ob einer von die einzelne Wörter sondern ob alle Wörter da sind.

IEC 61131-3 FIND sucht einfach für ein Treffer in die String, und gibt zurück ein Offsetwert. Wenn kein Treffer dann gibt es ein 0 zurück.
Ich wurde es ungf. wieso programmieren.
BefehlAuf := (FIND(Eingabestring, "auf")>0) OR (FIND(Eingabestring, "öffne")>0) OR (FIND(Eingabestring, "oeffne")>0) ;


----------



## JesperMP (1 Juli 2022)

Noch etwas.

Dein Ventil ist ein OUTPUT.
Dann kannst du nicht die Status von Ventil abfragen.
Wie du es programmiert hast:
Ventil := (Ventil OR tbV1Auf) AND NOT tbV1zu ;


----------



## Sps_Anfänger.CR (1 Juli 2022)

Ich muss das dann ja wahrscheinlich auch für zu und Ventil machen


----------



## JesperMP (1 Juli 2022)

Warum hast du die Leerzeichen in die Such-Strings ?


----------



## Sps_Anfänger.CR (1 Juli 2022)

Ich hatte letztens Probleme damit das es nicht funktionierte, war mir aber nicht mehr sicher ob es im Codesys oder Tia war


----------



## Sps_Anfänger.CR (1 Juli 2022)

Hätte es jetzt so gelöst?


----------



## Heinileini (1 Juli 2022)

Sps_Anfänger.CR schrieb:


> Kann ich jetzt also nur mit FIND das auch Programmieren?


Ja.

```
Hier einige Beispiele für mögliche Texte:
"Ventil bitte aufmachen",
"Bitte öffnen Sie V1",
"V1 jetzt schließen",
"Ventil zumachen",
"V1 auf",
"öffne das Ventil V1"
```
Diese Beispiele verändern die Sachlage ein wenig.
Der zu testende String darf also weitere Elemente enthalten und besteht nicht nur aus zwei Elementen, die zu testen wären.
"bitte", "machen", "Sie", "jetzt", "das" dürfen eingestreut sein.
"zu" und "auf" müssen auch als Bestandteil eines Wortes berücksichtigt werden, zumindest am Anfang eines Wortes.



JesperMP schrieb:


> Wenn ich dein Code betrachtet, dann testest du mit FIND ob "auf öffne oeffne" gibts in die Eingabestring. Also nicht ob einer von die einzelne Wörter sondern ob alle Wörter da sind.


Nein. Nicht, ob alle Wörter des Strings vorhanden sind, sondern ob ein einziges aus der Auswahl an gleichbedeutetenden Begriffen vorhanden ist.
Allerdings wird vorausgesetzt, dass der zu testende String sich auf zwei Worte beschränkt.



JesperMP schrieb:


> Dein Ventil ist ein OUTPUT.
> Dann kannst du nicht die Status von VENTIL abfragen.
> Wie du es programmiert hast:
> Ventil := (Ventil OR tbV1Auf) AND NOT tbV1zu ;


Stimmt! Ventil war als InOut und nicht als OUTPUT geplant.



Sps_Anfänger.CR schrieb:


> Hätte es jetzt so gelöst?


Deine Lösung hat ebenfalls genau das Problem, das Jesper (Danke!) aufgedeckt hat:
Ventil muss als VAR_IN_OUT deklariert werden.


----------



## Sps_Anfänger.CR (1 Juli 2022)

Ich dachte mir das wären nur Beispiele und das ich sie nicht verwenden muss


----------



## JesperMP (1 Juli 2022)

Heinileini schrieb:


> Nein. Nicht, ob alle Wörter des Strings vorhanden sind, sondern ob ein einziges aus der Auswahl an gleichbedeutetenden Begriffen vorhanden ist.
> Allerdings wird vorausgesetzt, dass der zu testende String sich auf zwei Worte beschränkt.


Wenn ich IEC 61131-3 FIND checkt, dann gibt es immer 2 Strings In1 und In2 als Parameter, und


> The function *FIND* returns the character offset of the first occurrence of *In2* in string *In1*.


edit:
das Beispiel
FIND("Something else", "Some Text")
ergibt die Rückgabewert 0 obwohl "Some" gibts in "Something".
Die Suchstring muss ganzlich mit Leerzeichen und alles in die Vergleichstring geben, sonnst ist das Ergebnis 0.


----------



## Heinileini (1 Juli 2022)

Sps_Anfänger.CR schrieb:


> Ich dachte mir das wären nur Beispiele und das ich sie nicht verwenden muss


Die Aufgabe ist leider nicht klar definiert und es wird durch die Beispiele nur angedeutet, was evtl. an zu testenden Strings angeliefert werden könnte. Das ist leider eine seeehr schwammige Vorgabe, um etwas danach zu programmieren. 
Was machst Du z.B. wenn der String lautet "Vergiss nicht, V1 zu öffnen"? Zu oder auf?



JesperMP schrieb:


> Wenn ich IEC 61131-3 FIND checkt, dann gibt es immer 2 Strings In1 und In2 als Parameter, und
> 
> The function *FIND* returns the character offset of the first occurrence of *In2* in string *In1*.


Ja, genau. Was willst Du uns jetzt damit sagen?


----------



## JesperMP (1 Juli 2022)

Heinileini schrieb:


> Ja, genau. Was willst Du uns jetzt damit sagen?


Ich glaube wir reden uns beide vorbei.
Wenn ich sage 


> Wenn ich dein Code betrachtet, dann testest du mit FIND ob "auf öffne oeffne" gibts in die Eingabestring.


dann meine ich dass mit die Code von SPS-Anfänger wird nach den gesammten String "auf öffne oeffne" getestet, nicht die einzelne Wörter innerhalb von diesen String. 
Aber das bestreitest du in Beitrag #62, oder verstehe ich das falsch ?


----------



## Sps_Anfänger.CR (1 Juli 2022)

Ja kann ich es jetzt trotzdem so programmieten wie ich es gerade gemacht habe aber nur die fehlenden worte dazufüge oder wieder ganz anderes


----------



## JesperMP (1 Juli 2022)

Sps_Anfänger.CR schrieb:


> Ja kann ich es jetzt trotzdem so programmieten wie ich es gerade gemacht habe aber nur die fehlenden worte dazufüge oder wieder ganz anderes


Wenn du die Ventil in ein VAR_IN_OUT und ändert die letzte Zeilen ins
Ventil := (Ventil OR (BefehlVentil AND BefehlAuf)) AND NOT (BefehlVentil AND BefehlZu) ;
dann ist es richtig.
Simulier dein Code, dann siehst du ob es funktioniert wie gewünscht.

edit: Die Klammer sind wichtig !


----------



## JesperMP (1 Juli 2022)

Nebenbei, es ist mir nicht bewusst ob die Vergleich >0 überflüssig ist oder nicht.
Kann sein dass ein logischen Abfrage von FIND die Rückgabewert TRUE gibt wenn das Offset >0 ist.


----------



## Sps_Anfänger.CR (1 Juli 2022)

Das Problem ist aber das in der Angabe stehr boolesche Ausgangsvariable Ventil


----------



## Mrtain (1 Juli 2022)

EDIT: hat sich erledigt


----------



## Heinileini (1 Juli 2022)

JesperMP schrieb:


> edit:
> das Beispiel
> FIND("Something else", "Some Text")
> ergibt die Rückgabewert 0 obwohl "Some" gibts in "Something".
> Die Suchstring muss ganzlich mit Leerzeichen und alles in die Vergleichstring geben, sonnst ist das Ergebnis 0.


Das war Absicht. Das Wort 'auf' soll nicht erkannt/gefunden werden, wenn der zu testende String z.B. aus dem Wort 'Sch*auf*el' besteht.



JesperMP schrieb:


> Ich glaube wir reden uns beide vorbei.
> Wenn ich sage
> 
> dann meine ich dass mit die Code von SPS-Anfänger wird nach den gesammten String "auf öffne oeffne" getestet, nicht die einzelne Wörter innerhalb von diesen String.
> Aber das bestreitest du in Beitrag #62, oder verstehe ich das falsch ?


Nein, Jesper, wir reden nicht aneinander vorbei.
Der zu testende String wird in zwei Hälften zerlegt (wie gesagt, unterstellt wurde, dass er ausschliesslich aus zwei Worten besteht).
Die erste Hälfte wird in der Liste zum Thema Ventil gesucht und
die zweite Hälfte wird separat in der Liste für auf und in der Liste für zu gesucht.



Sps_Anfänger.CR schrieb:


> Kann ich jetzt also nur mit FIND das auch Programmieren?


Ja.


```
Hier einige Beispiele für mögliche Texte:
"Ventil bitte aufmachen",
"Bitte öffnen Sie V1",
"V1 jetzt schließen",
"Ventil zumachen",
"V1 auf",
"öffne das Ventil V1"
```
Diese Beispiele verändern die Sachlage ein wenig.
Der zu testende String darf also weitere Elemente enthalten und besteht nicht nur aus zwei Elementen, die zu testen wären.
"bitte", "machen", "Sie", "jetzt", "das" dürfen eingestreut sein.
"zu" und "auf" müssen auch als Bestandteil eines Wortes berücksichtigt werden, zumindest am Anfang eines Wortes.



JesperMP schrieb:


> Wenn ich dein Code betrachtet, dann testest du mit FIND ob "auf öffne oeffne" gibts in die Eingabestring. Also nicht ob einer von die einzelne Wörter sondern ob alle Wörter da sind.


Nein. Nicht, ob alle Wörter des Strings vorhanden sind, sondern ob ein einziges aus der Auswahl an gleichbedeutetenden Begriffen vorhanden ist.
Allerdings wird vorausgesetzt, das der zu testende String sich auf zwei Worte beschränkt.



JesperMP schrieb:


> Dein Ventil ist ein OUTPUT.
> Dann kannst du nicht die Status von VENTIL abfragen.
> Wie du es programmiert hast:
> Ventil := (Ventil OR tbV1Auf) AND NOT tbV1zu ;


Stimmt! Ventil war als InOut und nicht als OUTPUT geplant.

Tschuldigung, musste ein paar Stunden weg und habe gerade von meinen angefangenen Antworten einiges (z.T. doppelt) und einiges gar nicht mehr hier vorgefunden. 
Ihr beiden ward ja so was von schnell und eifrig mit euren Beiträgen! Ich schicke die Überreste jetzt erstmal ab und versuche mich dann wieder hier einzusynchronisieren ...


----------



## Heinileini (1 Juli 2022)

JesperMP schrieb:


> Nebenbei, es ist mir nicht bewusst ob die Vergleich >0 überflüssig ist oder nicht.
> Kann sein dass ein logischen Abfrage von FIND die Rückgabewert TRUE gibt wenn das Offset >0 ist.


Nein, das Ergebnis von FIND ist nicht BOOL, sondern numerisch.
Aber man könnte statt ...

```
x := (FIND(FindeEvtlHier1, Suche1) > 0) OR (FIND(FindeEvtlHier2, Suche2) > 0)
```
... z.B. auch folgendes schreiben und damit einmal '> 0' eisparen:

```
x := (FIND(FindeEvtlHier1, Suche1) + FIND(FindeEvtlHier2, Suche2)) > 0
```

PS:
Ich will aber nicht ausschliessen, dass der eine oder andere Compiler clever genug ist, mittels impliziter TypKonvertierung (zufällig?) das gewünschte Ergebnis zu liefern.

PPS:
Beispiel für FIND beim Suchen der ersten Ziffer in einem String:

```
VAR_INPUT
    isTxt  : STRING ;
END_VAR
  
VAR_OUTPUT
    oiErg  : INT ;
END_VAR
  
VAR_TEMP
    tiErg  : INT ;
    tiIdx  : INT ;
END_VAR

tiErg := 0 ;
FOR tiIdx := 1 TO LEN(S:= isTxt) DO
    tiErg := FIND(IN1:= "0123456789"; IN2:= MID(IN:= isTxt; L:= 1; P:= tiIdx)) ;
    IF tiErg > 0 THEN EXIT ; END_IF ; // Suche abbrechen, weil 1. Ziffer gefunden wurde
END_FOR ;
oiErg := tiErg - 1 ; // PositionsNr vermindert um 1 ergibt den Wert der gefundenen Ziffer oder -1, wenn keine Ziffer gefunden wurde
```


----------



## Thomas_v2.1 (1 Juli 2022)

Vermutlich schließt die Referenzlösung das Ventil auch bei "Ventil nicht zumachen".


----------



## Heinileini (1 Juli 2022)

Thomas_v2.1 schrieb:


> Vermutlich schließt die Referenzlösung das Ventil auch bei "Ventil nicht zumachen".


Da fängt es wirklich an, schwierig zu werden. Das Wort 'nicht' einfach zu ignorieren (wie z.B. gefahrlos bei "bitte" oder "jetzt"), finde ich falsch,
Das Wort 'nicht' aber einfach als Negation auszuwerten, egal, wo es im Satz vorkommt, finde ich - sagen wir mal - abenteuerlich.
Gleich kommt Harald noch mit seinen Beispielen, dass es auf die Position des Kommas ankommt? 
Ergo, wenn das Wort 'nicht' im Satz vorkommt, neige ich dazu, den ganzen Satz unwirksam zu machen und eine FehlerMeldung zu generieren.

Was soll passieren, wenn der Satz lautet "Die V1 ist nicht aufzuhalten"? Man verzeihe mir bitte den Rückgriff auf die Wunderwaffe des tausendjährigen Reiches. 
Wie wär's mit "Tür abschliessen und Ventilator einschalten" oder "Hyperventilierende gibt es hier zuhauf" oder einfach "Zulaufventil"?


----------



## Thomas_v2.1 (1 Juli 2022)

Darum würde man die Sprache formalisieren, z.B. in mindestens Subjekt und Prädikate, dann Syntax Erkennung, und anschließend die Semantik prüfen. Ein Ventilator lässt sich nur ein- oder ausschalten. Eine Tür öffnen oder schließen und abschließen, ein Ventil öffnen oder schließen usw. Aber ich vermute das war hier nicht die Aufgabenstellung, sondern nur ein paar Wörter in einem String zu suchen und das wars.


----------



## Heinileini (2 Juli 2022)

JesperMP schrieb:


> Warum hast du die Leerzeichen in die Such-Strings ?


Damit z.B. in dem Text ' Ventilator zuhause einschließen ' weder das 'Ventil' in 'Ventilator' noch das 'zu' in 'zuhause' noch das 'schließe' in 'einschließen' gefunden und das Ventil nicht grundlos geschlossen wird. 
Allerdings wird dadurch auch nicht das 'auf' in 'aufmachen' gefunden und nicht das 'öffne' in 'öffnen' u.s.w. ...
Man müsste schon eine präzise Vorgabe haben, um zu entscheiden, was genau gewollt und was genau ungewollt ist.



Thomas_v2.1 schrieb:


> Darum würde man die Sprache formalisieren, z.B. in mindestens Subjekt und Prädikate, ...


Die deutsche Sprache macht es einem manchmal schon extrem schwer, Subjekt und Objekt eindeutig zu unterscheiden, mangels SPO-Regel.


----------



## Thomas_v2.1 (2 Juli 2022)

Zu später Stunde ein kleines Beispiel für eine mögliche Formalisierung:


```
SubjektEinAus = "Ventilator" | "Motor".
SubjektAufZu = "Tür" | "Ventil" | "Fenster".
PrädikatEinAus = "einschalten" | "ausschalten" | "ein" | "aus".
PrädikatAufZu = "auf" | "zu" | "öffnen" | "schließen" | "aufmachen" | "zumachen".

Ausdruck = (SubjektEinAus PrädikatEinAus) | (SubjektAufZu PrädikatAufZu).
Satz = Ausdruck { ("," | "und") Ausdruck}.
```

Ich finde wenn man sich mit dem Thema befasst und auch und ein Minimal-Beispiel umsetzt, lässt sich wirklich sehr viel daraus lernen. Auch wie Compiler funktionieren, warum und wie etwas erkannt und umgesetzt wird.


----------



## Heinileini (2 Juli 2022)

Thomas_v2.1 schrieb:


> Auch wie Compiler funktionieren ...


Die Compiler haben es aber verhältnismässig sehr leicht, da sie nicht in "UmgangsSprache" programmierte Texte verarbeiten/akzeptieren müssen - die Kommentare im Programm gehen sie ja nichts an.
Sie müssen aber trotzdem ständig in riesigen Listen nachschauen, Reservierte Begriffe, VariablenNamen, etc. und sie sind sehr pingelig bezüglich der Schreibweise.


----------



## Sps_Anfänger.CR (13 Juli 2022)

Habe die Hausaufgabe abgeschickt und habe es mir auf eine 3 ausbessern können. Naja immerhin besser als eine 5.
Danke für euer bemühen.


Ich hätte eine Frage bezüglich ein Trace hinzufügen.
Habe es erst schonmal zum laufen gebracht habe dann aber irgendetwas gedrückt und jetzt steht immer das hier. Auch wenn ich es Simulieren möchte, es geht nicht mehr weg. Hat jemand eine Ahnung?


----------



## 1234TFS (26 September 2022)

Sps_Anfänger.CR schrieb:


> Habe die Hausaufgabe abgeschickt und habe es mir auf eine 3 ausbessern können. Naja immerhin besser als eine 5.
> Danke für euer bemühen.



Was war denn dann deine Lösung die du eingereicht hast, mit der du die 3 erhalten hast?


----------

