TIA SCL Schieberegister

EMZ

Level-2
Beiträge
232
Reaktionspunkte
4
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi SPS-Forum,

bin SCL Anfänger. Ich möchte einen Schieberegister programmieren. Ich hatte schonmal in der Vergangenheit von einem User sowas als Programmierhilfe bekommen. Allerdings möchte ich es einbisschen anders.

Zum Thema: (die Schreibweise ist eventuell mit Fehler, da es noch nicht programmiert wurde somit Syntaxfehler etc. nicht beachten)

Ich möchte eine For-Schleife programmieren:
IF Freigabe THEN

For Index := 0 to 10 by 1 do Array [index] := Array [index+1];
End_FOR;
Ausgang := Index <1;
END_IF;


Funktion: Ich möchte erstmal nur bis 10 hochzählen und dann soll ein Ausgang gesetzt werden dass „10“ erreicht wurde. So will ich mich Schrittweise einsteigern.

Schnittstellen:
Name Datentyp
Input: Freigabe Bool

Output: Ausgang Bool

Temp: Array Array [0…10]


Static: Index int

Würde diese Programmierung so funktionieren ?

Gruß
EMZ
 
Die Programmierung würde irgendwas tun, doch ob das das ist was Du beabsichtigst?
Was soll das Programm irgendwann mal tun?

- "Ausgang := Index <1;" an dieser Stelle ist Index niemals < 1, weil die Schleife immer die 11 Durchläufe macht, was soll der Output "Ausgang" signalisieren?
- Dir ist klar, daß ein Array in TEMP sich nichts über mehrere Bausteinaufrufe merken kann?

Harald
 
Außerdem mußt Du die Endwerte beim Schleifendurchlauf bzw. des Arrays beachten!

Wenn Index in der FOR-Schleife 10 wird, greifst Du mit
Code:
[COLOR=#333333]Array [10] := Array [10+1];[/COLOR]
auch auf Array[11] zu, das aber gar nicht deklariert wurde.
 
Du hast einen Zugriff auf den Array Index 11 (Array [index+1]).
Laut deiner Deklaration geht dein Array aber nur bis 10.
Das wird mit Sicherheit auch nicht lange gut gehen.
 
Ich möchte eine FOR-Schleife programmieren:

Funktion: Die For-Schleife soll bis 10 hochlaufen und beim Erreichen vom Endwert 10 dann einen Ausgang setzen, welches mir signalisiert dass bis 10 gezählt wurde.
Wenn während des Zählvorgangs eine weitere Freigabebedienung kommt, soll dieser auch gezählt, erkannt und verarbeitet werden, deshalb Schieberegister.

IF Freigabe THEN

For Index := 0 to 9 by 1 do Array [index] := Array [index+1];
End_FOR;

Ausgang := Index <0;
END_IF;


Was sagt ihr zu dem?
 
1. Verwende bitte die Code-Tags für Dein Programm (letzter Button 2. Symbolreihe).

2. Die Variable Index wird am Ende der FOR-Schleife immer den dort angegebenen Endwert (bei deiner letzten Version = 9) haben, solange kein eventueller vorzeitiger Abbruch der Schleife programmiert ist.
Das hast Du zumindest bis jetzt nicht.

3. Außerdem kann der Index selbst mit Abbruchbedingung nicht kleiner als der Startwert werden. Ausgang kleiner als Null wird also nie erfüllt werden können. (Oder ist das ein Tippfehler und da sollte ursprünglich 10 stehen. Dann müßte es jetzt trotzdem 9 sein.)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn während des Zählvorgangs eine weitere Freigabebedienung kommt, ...
4. Woher sollen die denn kommen?

Die Schleife wird in einem einzigen Zyklus durchlaufen. Da können also keine Ereignisse von außerhalb der SPS mehr Einfluss nehmen, die nicht schon mit Beginn des Zyklusses vorhanden sind.
 
Ich frage mal anders :

Ich habe eine FOR-Schleife programmiert :
Code:
[COLOR=#333333][COLOR=#333333]For Index := 0 to 9 by 1 do Array [index] := Array [index+1];[/COLOR][/COLOR]
[COLOR=#333333][COLOR=#333333]End_FOR; [/COLOR][/COLOR]

Das Problem ist, wie kann ich die FOR-Schleife "starten" lassen.

Nur mit der einfachen FOR-Schleife beginnt ja kein Vorgang.
Eine Startbediengung muss noch hin, allerdings wüsste ich nicht wie.

Deshalb würde ich das so machen :

Code:
IF Freigabe then

[COLOR=#333333][COLOR=#333333]        For Index := 0 to 9 by 1 do Array [index] := Array [index+1];[/COLOR][/COLOR]
[COLOR=#333333][COLOR=#333333]        End_FOR; 
END_IF;
[/COLOR][/COLOR]

Die Freigabe bekommt 1 Signal, dann startet die FOR-Schleife und zählt von 0 bis 9 (10 hoch) und beendet die Schleife bei erreichen von der Wertigkeit 9.
Bei jedem Schleifendurchgang wir dem Index +1 dazugerechnet also
Code:
Array[0] := Array[1]
Array[1] := Array[2]
.
.
.
Array[8] := Array[9]
END_FOR;

dann soll ein Ausgang gesetzt werden, der mir nur mitteilt, dass ein Zyklus von 0-9 also 10 Schritte durch sind.

Deshalb: (keine Ahnung ob das so funktioniert)

Code:
Ausgang := Index = 9

so war meine denkweise.


wozu ich absolut keine Ahnung habe:
wie ich während des Zählvorganges andere Freigaben auswerte.

Ich möchte von euch auch keine Lösung, ich möchte lernen, deshalb bitte nur um Aufklärung meiner Fehler und Tipps :)
 
Zuletzt bearbeitet:
Es sieht so aus als wolltest du eine Schrittkette erstellen.
Da is eine for schleife aber nicht das Mittel der Wahl.

Ein Case ist da besser.
Wenn eine Bedingung erfüllt ist kannst du dann die nächste Case nummer zuweisen und da dann wieder auf die nächste Bedingung prüfen.


Gruß

Jens
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das Problem ist, wie kann ich die FOR-Schleife "starten" lassen.

Nur mit der einfachen FOR-Schleife beginnt ja kein Vorgang.
Doch, genau dann beginnt sie!
Mit vorgeschalteten IF-Bedingungen wird genau genommen die Schleife nicht gestartet, sondern die Ausführung ggf. verhindert.


Deshalb würde ich das so machen :
Code:
IF Freigabe then

[COLOR=#333333][COLOR=#333333]        For Index := 0 to 9 by 1 do Array [index] := Array [index+1];[/COLOR][/COLOR]
[COLOR=#333333][COLOR=#333333]        End_FOR; 
END_IF;
[/COLOR][/COLOR]
Ist vollkommen OK.
So wird die Schleife nur gestartet, wenn Freigabe TRUE ist. Ansonsten wird sie übersprungen.

dann soll ein Ausgang gesetzt werden, der mir nur mitteilt, dass ein Zyklus von 0-9 also 10 Schritte durch sind.

Deshalb: (keine Ahnung ob das so funktioniert)
Code:
Ausgang := Index = 9
Das funktioniert zwar, da aber Index am Ende der FOR-Schleife eh' immer 9 sein wird, kannst Du auch einfach schreiben:
Code:
Ausgang:= TRUE;
Bei beiden Varianten ist es aber wichtig, dass Ausgang auch irgendwo wieder auf FALSE gesetzt wird.
Ansonsten ist Ausgang nach dem erstmaligen Schleifendurchlauf von da an immer auf 1.

Und wie bereits gesagt, alle 9 Schleifendurchläufe finden in einem einzigen Zyklus (und ggf. in jedem Zyklus) statt!
 
Code:
    [B]Input    [/B]                    
       
    eingang    Bool    2.0    false    True    False    
[B]
    Output[/B]                        
    Ausgang    Bool    4.0    false    True    False    

    [B]InOut  [/B]                      
                            
    [B]Static   [/B]                     
    freigabe    Bool    6.0    false    True    False    
    Schiebereg    Array[0..100] of Bool    8.0        True    False
    
    [B]Temp[/B]                        
    start    Bool    0.0                
    Index    Int    2.0
                
    [B]Constant[/B]                        



#start := true;


IF #start THEN
    FOR #Index := 0 TO 3 BY +1 DO
        #Schiebereg[#Index] := #Schiebereg[#Index +1 ]  // Statement section FOR
        ;
    END_FOR;
 
    IF #Schiebereg[3] THEN
        #Ausgang := true;
   
    END_IF;
    
   
    
END_IF;



Ich krieg diese Schleife irgendwie nicht zum Laufen.

Ich will dass die FOR Schleife folgendes macht: von 1 bis 3 hochzählen ....
Dann hat Schieberegister [3] und Ausgang soll gesetzt werden.
Was mache ich falsch?
 
Ich krieg diese Schleife irgendwie nicht zum Laufen.
Was meinst Du mit "irgendwie"?
Der Programmcode der Schleife sieht eigentlich nicht so aus, als ob er nicht "laufen" würde. Wird der Programmcode nicht abgearbeitet? Oder geht Deine SPS in STOP? Oder geht die Schleife oder das Verschieben "zu schnell"? Oder ist das, was die Schleife tut, einfach nur nicht das, was Du erwartest was sie tun sollte? Was soll sie denn tun?
Ist Dir auch klar, daß die Schleife immer gleich alle Durchläufe von #Index = 0 bis #Index = 3 macht wenn das Programm an dieser Stelle abgearbeitet wird, also nicht bei jedem Programmaufruf nur einen Durchlauf?


Ich will dass die FOR Schleife folgendes macht: von 1 bis 3 hochzählen ....
Dann solltest Du auch schreiben "FOR #Index := 1 TO 3" und nicht "FOR #Index := 0 TO 3"
Oder ist das was Du hier schreibst was Du willst, nicht das was Du wirklich willst?

Soll die FOR-Schleife auch etwas tun (einen Job ausführen) als nur bis 3 zählen? Dann verrate uns was das sein soll.

Was Du programmiert hast ist:
"Ich habe ein Array mit ... (was für eine Art Information ist da drin gespeichert???). Die Schleife kopiert (verschiebt) die Array-Elemente 1 bis 4 auf die Arrayplätze 0 bis 3. Wenn dabei das Element, was von Platz 4 zu Platz 3 kopiert wurde, true ist, dann soll der Ausgang eingeschaltet werden. Die Array-Elemente 5 bis 100 werden nicht verschoben. (warum nicht? Warum werden nicht alle Elemente verschoben, wo es doch ein Schieberegister sein soll?)"
Eine solche Erklärung taucht nicht auf in dem, was Du schreibst, was die Schleife tun soll...


Dann hat Schieberegister [3] und Ausgang soll gesetzt werden.
??? Das verstehe ich nicht.

Hinweis: Wie hucki schon schrieb, die Ausgangszuweisung innerhalb der IF-Anweisung ist nicht vollständig. Der Ausgang wird nie mehr false werden, sobald einmal true zugewiesen wurde.


Was mache ich falsch?
Keine Ahnung, Du schreibst ja nicht, was falsch ist. Dein größtes Problem ist vermutlich, daß Du nicht verständlich machst/machen kannst, was Du eigentlich erreichen willst. Die Schleife programmierst Du doch bestimmt nicht nur deshalb, um das erste Mal im Leben eine Schleife programmiert zu haben. Die Schleife wird doch auch etwas tun sollen - bitte schreibe in Umgangsprache was für eine Aufgabe die Schleife erfüllen soll (NICHT: "soll von 1 bis 3 hochzählen" - SONDERN: z.B. "gute/schlechte Teile auf einem Band aussortieren")

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@TE:
Wenn ich etwas programmiere (ganz egal was) dann überlege ich mir als allererstes den Ablauf davon und versuche das dann in Code umzusetzen.
Deinen Ablauf (so entnehme ich es jedenfalls dem bisherigen Verlauf und darüber hinaus meiner Glaskugel) hast du dir möglicherweise so gedacht :
- du hast ein Schieberegister (ich bleibe mal bei dem Ausdruck) mit 10 Plätzen.
- mit dem IN "Set" deines FB (ich weiß, den gibt es in deiner Überlegung noch nicht) setzt du den Index 0 des "Schieberegisters"
- mit dem IN "Takt" deines FB (den gibt es so richtig auch noch nicht) willst du den Speicher deines "Schieberegisters" um eins weiterschieben - und zwar jedes Mal dann wenn "Takt" kommt
- mit dem OUT "Platz_3" deines FB (auch den gibt es so noch nicht) möchtest du dir anzeigen lassen, ob der Index 3 deines "Schieberegisters" gesetzt ist.

Falls meine Beschreibung so in etwa mit deinen Vorstellungen übereinstimmt so lönntest du jetzt vielleicht mal überlegen, wie man das Code-technisch umsetzen könnte.
Mit deinem bisherigen Code hat das allerdings nicht besonders viel gemeinsam ...

Gruß
Larry
 
Irgendwie habe ich mit all diesen Problemen ein Déjà-vu.
:rolleyes:


Liebling Schieberegister:
:ROFLMAO:


Es sind immer die gleichen Probleme:

Wird der Baustein mit dem Schieberegister überhaupt aufgerufen?

Werden überhaupt irgendwo Werte in Dein Array gespeichert, die dann verschoben werden können?
Oder schiebst Du nur "leeren" Inhalt? Dann "siehst" Du natürlich auch nichts, obwohl die Schleife abgearbeitet wird.

Was erwartest Du wirklich von Deinem Ausgang mitgeteilt zu bekommen?
Das die Schleife im Zyklus bis zum Ende durchgelaufen ist (da kannst Du ohne Schleifenabbruch immer von ausgehen; entspricht den Versionen Deiner 1. Posts) oder das ein Wert komplett durch Dein Schieberegister durchgeschoben wurde (also x Aufrufe der Schleife wie bei den früheren Threads; entspricht der Version Deines letzten Posts)?

Hast Du überhaupt mittlerweile die Funktionsweise eines Schiebregisters verstanden?
(Selbst damit bin ich mir immer noch nicht so sicher.)



Dein Hauptproblem ist nach wie vor, das korrekte Formulieren Deiner Aufgabe. Auch Dir selbst gegenüber.
Dadurch bist Du leider nicht wirklich in der Lage, beim Programmieren auch systematisch vorzugehen. Noch weniger dann bei der Fehlersuche.
Denn genau das, was Du oben jeweils beschreibst, macht Deine Schleife. Es scheint aber einfach nicht das zu sein, was Du in Wirklichkeit erwartest.
 
@TE:
Wenn ich etwas programmiere (ganz egal was) dann überlege ich mir als allererstes den Ablauf davon und versuche das dann in Code umzusetzen.
Deinen Ablauf (so entnehme ich es jedenfalls dem bisherigen Verlauf und darüber hinaus meiner Glaskugel) hast du dir möglicherweise so gedacht :
- du hast ein Schieberegister (ich bleibe mal bei dem Ausdruck) mit 10 Plätzen.
- mit dem IN "Set" deines FB (ich weiß, den gibt es in deiner Überlegung noch nicht) setzt du den Index 0 des "Schieberegisters"
- mit dem IN "Takt" deines FB (den gibt es so richtig auch noch nicht) willst du den Speicher deines "Schieberegisters" um eins weiterschieben - und zwar jedes Mal dann wenn "Takt" kommt
- mit dem OUT "Platz_3" deines FB (auch den gibt es so noch nicht) möchtest du dir anzeigen lassen, ob der Index 3 deines "Schieberegisters" gesetzt ist.

Falls meine Beschreibung so in etwa mit deinen Vorstellungen übereinstimmt so lönntest du jetzt vielleicht mal überlegen, wie man das Code-technisch umsetzen könnte.
Mit deinem bisherigen Code hat das allerdings nicht besonders viel gemeinsam ...

Gruß
Larry


Genau das möchte ich !

Ich würde das jetzt so programmieren : (bitte syntaxfehler ignorieren)

Code:
start := takt

if start then
  for := index 1 to 3 by +1 do 
    schiebereg [index]  := schiebereg[index +1] 
  End_for

   If schiebereg [3] then ausgang := true  
   End_if
       Else if
       Then ausgang := false



mein Wissensstand reicht aktuell nur bis hier hin
ich vermute es läuft nicht so wie ich es möchte, weil ich kein "takt" habe.
ich wüsste um ehrlich zu sein auch nicht wie ich den takt in mein schieberegister einprogrammier.
ich würde einen Input (bool) nehmen und diesen dann takt nennen siehe erste Zeile progrommcode.

würde das so ? Ich denke nicht aber genau hier komme ich nicht weiter wenn ich genau die Funktion die Larry beschrieben hat programmieren will.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Lassen wir mal alles aussen vor - du hast nämlich den Unterschied zwischen dem, was ich geschrieben habe und dem, was du zusammengecodet hast noch nicht erkannt.
Wo in deinem Programm-Code wird denn eines deiner Array-Elemente (z.B. das Erste) denn irgendwann einmal gesetzt ? Deine Schleife verschiebt im Augenblick nur False-Inhalte ...

Gruß
Larry
 
Warum nur False Inhalte ?
Vielleicht weil ich nach jedem Takt die IF Anweisung "takte" und somit die For Schleife abgebrochen wird und wieder gestartet?
Ich denke, dass ich die Variable "start" speichernd abarbeiten muss und dann durchs register schieben oder ?
 
Zuletzt bearbeitet:
ich vermute es läuft nicht so wie ich es möchte, weil ich kein "takt" habe.
ich wüsste um ehrlich zu sein auch nicht wie ich den takt in mein schieberegister einprogrammier.
Du mußt doch wissen, bei welchem Ereignis der Inhalt Deines Schieberegisters weitergeschoben werden soll - dieses Ereignis (oder die positive Flanke davon) muß Dein "takt" werden.
Desweiteren muß es notwendigerweise auch Ereignisse geben, bei denen irgendwas in Dein Schieberegister eingefüllt wird (in das hinterste oder erste freie/leere Schieberegister-Element gespeichert wird).
Wenn Du diese Ereignisse noch dazuprogrammierst, dann wird Dein Schieberegister anfangen zu "leben" und etwas beobachtbares tun.

Harald
 
Zurück
Oben