# RS-Flipflop in SCL schreiben



## hanspeter (15 Januar 2022)

Hallo zusammen, ich hoffe ich bin hier im richtigen Thema, ist mein erste Beitrag.

Wie im Anhang zu sehen soll ein RS-Flipflop in SCL realisiert werden ohne auf die bestehenden Standardfunktionen zurückzugreifen. Vorgegeben sind die Variablen und die Anzahl an Codezeilen.

Ich sitze jetzt seit 3 Stunden daran und hab immer noch keine gescheite Lösung finden können das mit zwei Codezeilen hinzubekommen und ich verstehe nicht wie ich die "state" Variable einsetzen kann, nur das sie was mit dem Halten des Ausgangs zutun hat, nachdem beide Eingänge wieder auf 0 sind. Im Internet finde ich sonst auch keinen Quellcode zu diesem Problem es wird meist nur auf die bestehenden Standardfunktionen hingewiesen, zu denen es keinen Quellcode gibt, oder das man die FUP Bausteine nutzen soll.

Ist hier vllt jemand unterwegs der mit weiterhelfen kann den RS-Flipflop in SCL in zwei Zeilen zu schreiben? Es kann auch sein das mir irgendein Puzzleteil fehlt und die Aufgabe eigentlich ganz einfach ist, aber ich komme zu keiner Lösung.

In Aufgabe 3 habe ich ein ähnliches Verständnisproblem mit der "state" Variable und der Umsetzung der Funktion in nur zwei Codezeilen...


----------



## 312C (15 Januar 2022)

Hallo,

dein "state" wird gespeichert, also kannst du es auch wieder lesen. Dein State-Speicher soll also high sein, wenn Set und nicht Reset High ist oder State und nicht reset high ist. Das Ergebnis kannst du dann einfach dem Ausgang zuweisen. z.B. So:
out:=state
state:= (set and not reset )or (state and not reset)

Bei der Flankenauswertung kannst du die State-Variable nutzen, um das Signal zu speichern: Du möchtest einen Wechsel von false auf true erkennen, also ist dein Ausgangssignal = neues Signal und nicht gespeichertes Signal vom letzten Zyklus. Ich hoffe das hilft dir schon etwas weiter.


----------



## hucki (15 Januar 2022)

312C schrieb:


> out:=state
> state:= (set and not reset )or (state and not reset)


"not reset" kann man noch ausklammern (was die Klammern dann auch komplett überflüssig macht):

```
state := state or set and not reset;
```
Die Reihenfolge von "or set" und "and not reset" bestimmt die Dominanz (beim letzten Operanden).



Und hier kann man auch wieder mal die Umständlichkeit von Schulaufgaben sehen. 😮‍💨
Jeder normale Programmierer würde erst die Zuweisung von state und dann erst die von out schreiben, um nicht überflüssigerweise einen Zyklus zwischen Ereignis und Reaktion vergehen zu lassen.


----------



## PN/DP (16 Januar 2022)

hucki schrieb:


> "not reset" kann man noch ausklammern (was die Klammern dann auch komplett überflüssig macht):
> 
> ```
> state := state or set and not reset;
> ...


Ganz so einfach ist es nicht, weil die Operation AND eine höhere Priorität als OR hat. Der Code funktioniert so nicht, state läßt sich mit reset nicht rücksetzen. Nach dem Ausklammern wird eine Klammer benötigt:

```
state := (state OR set) AND NOT reset;
```
... und da erkennt man dann auch die zugrundeliegende typische Selbsthaltung:

```
state := (set OR state) AND NOT reset;
```




312C schrieb:


> out:=state
> state:= (set and not reset )or (state and not reset)


Hier sind die Klammern unnötig/überflüssig ("Angstklammern"), erhöhen aber die Verstehbarkeit des (relativ umständlichen) Codes für Programmierer, denen die Vorrangregeln/Priorität der Operationen nicht geläufig sind.

Harald


----------



## hucki (16 Januar 2022)

PN/DP schrieb:


> Ganz so einfach ist es nicht, weil die Operation AND eine höhere Priorität als OR hat.


Wenn man (hucki) zu blöd zum Nachlesen ist (er wollt' ja sicher gehen, weil er sich die Priorität einfach nicht merken kann) und bei der falschen Sprache nachschlägt:


> Die Priorität der logischen Operatoren ist folgendermaßen geregelt:
> 
> *not* hat die höchste Priorität.
> *and* und *or* haben die gleiche Priorität und werden von links nach rechts abgearbeitet


*Dussel*
😤

PS: war wohl MATLAB


----------



## Heinileini (16 Januar 2022)

hucki schrieb:


> Wenn man (hucki) zu blöd zum Nachlesen ist (er wollt' ja sicher gehen, weil er sich die Priorität einfach nicht merken kann) ...


Aber die Regel "PunktRechnung vor StrichRechnung" kennt man (vermutlich auch hucki  ).
Wenn man dann noch die Bezeichnungen "logische Multiplikation" für AND und "logische Addition" für "OR" kennt, kann man es sich zusammenreimen.


----------



## Onkel Dagobert (16 Januar 2022)

Klammern setzen ist an dieser Stelle keinesfalls ein Fehler. Ich würde es auch nicht "Angstklammern" nennen, denn sie verbessern auf jeden Fall die Lesbarkeit. Im Übrigen gibt es in Galaxien fernab der Milchstraße auch noch andere Verknüpfungsregeln. Ich merke mir so etwas auch nie.


----------



## Ralle (16 Januar 2022)

Ich setze  immer Klammern, sobald es mal komplizierter wird und mach manchmal sogar noch Einrückungen. 
SCL ist halt nicht unbedingt für logische Verknüpfungen optimal aber die sind eben bei unseren SPS dringend notwendig.


----------



## hucki (16 Januar 2022)

Ralle schrieb:


> SCL ist halt nicht unbedingt für logische Verknüpfungen optimal,


Und seit SCL-Netzwerke in KOP (/FUP)-Bausteinen möglich sind, gibt es für mich auch keinen wirklichen Grund mehr, mir solche Verknüpfungen in SCL anzutun.


----------



## Heinileini (16 Januar 2022)

hucki schrieb:


> > *not* hat die höchste Priorität.
> > *and* und *or* haben die gleiche Priorität und werden von links nach rechts abgearbeitet


Sprachen, in denen ohne Rücksicht auf Prioritäten von links nach rechts abgearbeitet wird, sind eher die Ausnahme.
Mir fällt auf die Schnelle nur der "G-Code" als Beispiel ein. "Geklammert" werden hier nur die Kommentare.
"Links vor rechts" gilt hier (übrigens auch) für arithmetische Operationen (rechnen mit R-Parametern) und wird eisern eingehalten - man kann sich wirklich darauf verlassen, ABER die Reihenfolge, in der die ProgrammZeilen abgearbeitet werden, ist abenteuerlich.

Mein persönlicher Favorit für "AngstKlammern" ist der NOT-Operator. Da habe ich immer wieder mal Bedenken, ob der Compiler mich auch versteht, wenn ich auf Klammern verzichte.


----------



## rostiger Nagel (16 Januar 2022)

Aus Lesbarkeitgründen, würde ich aus so einen Einzeiler,
immer einen Zweizeiler machen.

```
state := NOT reset //Aus
AND (set OR state); //Ein
```


----------



## hanspeter (16 Januar 2022)

312C schrieb:


> Bei der Flankenauswertung kannst du die State-Variable nutzen, um das Signal zu speichern: Du möchtest einen Wechsel von false auf true erkennen, also ist dein Ausgangssignal = neues Signal und nicht gespeichertes Signal vom letzten Zyklus. Ich hoffe das hilft dir schon etwas weiter.



ich habe die Flankenauswertung jetzt so umgesetzt:


```
FUNCTION_BLOCK pflankfb

VAR_INPUT
    click: BOOL;
END_VAR

VAR_OUTPUT
    out: BOOL;
END_VAR

VAR
    state: BOOL;
END_VAR


out:= click AND state;

state:= not click;
```


wenn ich den Funktionsbaustein dann über das Hauptprogramm in Einzelzyklen abrufe, dann ist:

->vor start: alle werte = false
-> Zyklus 1: click = false, dadurch wird state = true
-> Zyklus 2: click = false, state = true
ich setze click manuell auf true:
->Zyklus 3: out wird true
->Zyklus 4: out = false, click =true
->Zyklus 5: out = false, click= true

Wenn der Eingang "click" von false zu true wechselt wird "out" einen Zyklus lang true und anschließend wieder false.

Damit ist die Funktion der positiven Flankenerkennung doch gegeben oder nicht ?


Und vielen dank für alle bisherigen Antworten und Ausführungen, das hat schon sehr geholfen


----------



## Heinileini (16 Januar 2022)

hanspeter schrieb:


> Damit ist die Funktion der positiven Flankenerkennung doch gegeben oder nicht ?


Ja, aber ich bervorzuge, für die Abfrage im nächsten Zyklus den tatsächlichen (und nicht den invertierten) Zustand nach state zu speichern.
Geschmackssache.


----------



## 312C (16 Januar 2022)

Heinileini schrieb:


> Ja, aber ich bervorzuge, für die Abfrage im nächsten Zyklus den tatsächlichen (und nicht den invertierten) Zustand nach state zu speichern.
> Geschmackssache.



Das finde ich auch deutlich intuitiver: 
out:= click and not state;
state:= click;


----------



## hucki (16 Januar 2022)

312C schrieb:


> Heinileini schrieb:
> 
> 
> > Ja, aber ich bervorzuge, für die Abfrage im nächsten Zyklus den tatsächlichen (und nicht den invertierten) Zustand nach state zu speichern.
> ...


Insbesondere, wenn man auch (oder nur) die negative Flanke benötigt:

```
fp := in and not state;
fn := not in and state;
state := in;
```


----------



## hucki (16 Januar 2022)

Heinileini schrieb:


> Sprachen, in denen ohne Rücksicht auf Prioritäten von links nach rechts abgearbeitet wird, sind eher die Ausnahme.
> Mir fällt auf die Schnelle nur der "G-Code" als Beispiel ein.


Und ausgerechnet so eine hab' ich beim Nachschlagen erwischt 😭:


hucki schrieb:


> ... war wohl MATLAB



Vlt. sollte ich mal Lotto spielen...


... oder auch nicht - zielsicher zur Niete!


----------



## AlterNeuling (21 Januar 2022)

312C schrieb:


> Hallo,
> 
> dein "state" wird gespeichert, also kannst du es auch wieder lesen. Dein State-Speicher soll also high sein, wenn Set und nicht Reset High ist oder State und nicht reset high ist. Das Ergebnis kannst du dann einfach dem Ausgang zuweisen. z.B. So:
> out:=state
> ...


Der Herr De Morgan sagt: state := (set or state) and not reset; Er spart ein AND


----------



## Heinileini (21 Januar 2022)

Onkel Dagobert schrieb:


> Im Übrigen gibt es in Galaxien fernab der Milchstraße auch noch andere Verknüpfungsregeln. Ich merke mir so etwas auch nie.


Danke, Dagobert, für den Link zum Thread aus dem Jahr 2005! Den kannte ich noch nicht. Amüsant bis aufregend, in jedem Fall aber ganz schön verwirrend.


----------



## StructuredTrash (22 Januar 2022)

Für mich ist "state:=click" oder "state:=not click" keine Frage des Geschmacks, sondern hängt davon ab, ob ich im ersten Zyklus nach Programmstart einen Ausgangsimpuls haben möchte, wenn click zu diesem Zeitpunkt schon true ist.


----------

