Step 7 Schieberegister

RBonni88

Level-1
Beiträge
8
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Freunde der gepflegten SPS Programmierung,

ich wollte zur Datenspeicherung in einem DB den BLKMOV Befehl benutzen. Damit ich sehe, was während der letzten zehn Aufträge durch die Maschine produziert wurde und nicht nur das aktuelle Ergebnis sehe, wollte ich gerne jeweils bei Auftragswechsel die Daten aus dem ersten Datenwort ins zweite, aus dem zweiten ins dritte, usw. schreiben. Praktisch gesehen ein Schieberegister, wenn ich mich richtig an die alten Berufsschultage erinnere.

Wenn ich den Befehl nun auslöse, passiert folgendes:
02.PNG
Die Daten aus dem ersten Datenwort werden in alle anderen Zeilen übertragen. Wenn ich das per PLCSIM simuliere, funktioniert es wunderbar. Da werden bei jedem einzelnen triggern die Wörter eine Zeile weitergeschoben. Sobald ich es in das Maschinenprogramm schiebe, passiert immer das gleiche.

Programmiert habe ich die ganze Misere folgendermaßen:
01.jpg

Ich bin für jegliche Hilfen oder Tipps dankbar.

Vielen Dank und beste Grüße,
RBonni88
 
Hallo,
ich kann jetzt mit deinem FUP nicht so viel anfangen ... aber vioelleicht grundsätzlich :
- dieses Schieben darf nur einen Zyklus lang erfolgen. Du musst dir also auf deinen Start-Impuls eine Flanke bilden ...
- das Schieben selbst musst du in umgekehrter Reihenfolge machen - also Element 3 -> 4, dann 2 -> 3, dann 1 -> 2, dann neues Element in 1 eintragen ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi, der Quellbereich darf den Zielbereich nicht überlappen bei SFC20 (wenn ich mich recht erinnere). Du schaufelst Daten nach vorne, liest diese Daten wieder und schaufelst sie weiter. Dann steht überall das Gleiche. Entweder eine Zwischenbereich zum umkopieren, einzeln kopieren, oder anderst aufziehen.
 
In der Simulation wird der SFC20 anders implementiert sein, als in einer echten CPU. Ich denke dass BLKMOV eine Schleife ist die Byte/Wort/D-Wort weise kopiert. Da darf der Quellbereich nicht in den Zielbereich ragen. Was er ja bei DBX0.0 BYTE 36 -> DBX4.0 BYTE 36 macht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie oben bereits geschrieben darf sich beim BlockMove Quelle und Ziel eigentlich nicht überschneiden. Eigentlich deshalb weil von "oben" nach "unten" meiner Meinung nach trotzdem funktioniert. Würde ich aber nicht machen wollen, weil das offiziell nicht sein darf und es bei zukünftigen Firmwareversionen anders sein könnte. Ich würde die zu schiebenden Daten erst mal gruppieren und dann davon ein Array machen. Dann das Ganze verdoppeln für einen Temporären Bereich für das Schieben. Das reduziert die Anzahl der benötigten BlockMovs auf 2: Einer der erst mal nach Temp kopiert, der zweite der dann wieder zurück kopiert mit entsprechendem Offset.1.png2.jpg
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi, der Quellbereich darf den Zielbereich nicht überlappen bei SFC20 (wenn ich mich recht erinnere). Du schaufelst Daten nach vorne, liest diese Daten wieder und schaufelst sie weiter. Dann steht überall das Gleiche. Entweder eine Zwischenbereich zum umkopieren, einzeln kopieren, oder anderst aufziehen.

Überlappen ist abhängig von der CPU. Mit den größeren 300er CPUs funktioniert es problemlos.
 
Und warum willst du BLKMOV benutzten? Das einfache Move reicht doch vollkommen aus.
In FUB wird das ganze natürlich ein wenig lang. Das sähe in AWL oder SCL schöner aus, aber egal.
Hier nur mal ein Ansatz, damit du weisst was die Leute meinen:
Erst alle Werte einzeln eine Stelle hoch schieben, dann den ersten Index mit dem neuen Wert belegen. Und das ganze natürlich Flankengesteuert.

Unbenannt.jpg
 
Zuletzt bearbeitet:
Moin RBonni,

mal am eigentlichen Thema vorbei die Frage:
Warum spendierst Du nicht einfach einen Zähler, der Dir das aktuelle Element zeigt und schreibst immer an die Position des Zählers? So sparst Du Dir das komplette Umkopieren und kannst Deine Daten unstrukturiert liegen lassen, wie momentan.

Ansonsten stimme ich Oberchefe zu: Nicht jede Variable als Array anlegen, sondern die Variablen in einen UDT zusammenpacken und daraus ein Array machen.

Und falls Du SCL benutzt, würde ich das überhaupt nicht über Blockmove machen, da das ja einfache Datentypen sind: Mit einer FOR-Schleife durchgehen und mit direkter Zuweisung umkopieren. Auch dann kannst Du die Daten so unstrukturiert liegen lassen und bist nicht auf Systemfunktionen angewiesen. Könnte man auch kombinieren mit UDT und direkt komplette UDTs umkopieren.

Gruß
Jens
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Warum spendierst Du nicht einfach einen Zähler, der Dir das aktuelle Element zeigt und schreibst immer an die Position des Zählers?

Ein Grund das nicht zu machen wäre, weil du so die richige Reihenfolge nicht mehr kennst. Also die ältesten Daten bzw. die neusten sind nicht immer an der gleichen Stelle.
Kommt halt drauf an was du noch mit den Daten machen willst. Willst du sie noch sauber in einer HMI darstellen oder einfach nur Durchschnittswerte berechnen.
Davon ab, finde ich das Zählen an sich komplizierter als schnell alle Daten um eine Position zu verschieben. Wobei "kompliziert" in dem Kontext natürlich relativ ist :eek:.
 
Und warum willst du BLKMOV benutzten? Das einfache Move reicht doch vollkommen aus.
In FUB wird das ganze natürlich ein wenig lang. Das sähe in AWL oder SCL schöner aus, aber egal.
Hier nur mal ein Ansatz, damit du weisst was die Leute meinen:
Erst alle Werte einzeln eine Stelle hoch schieben, dann den ersten Index mit dem neuen Wert belegen. Und das ganze natürlich Flankengesteuert.

Anhang anzeigen 53156

Würdest Du erklären warum BLKMOV mit MOVE zu ersetzen besser sein soll?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Würdest Du erklären warum BLKMOV mit MOVE zu ersetzen besser sein soll?

Weil man mit BLKMOV im Prinzip kompliziertere Sachen schieben kann, und der Ersteller aber nur einefache Werte mit spezifischen Speicherbereichen verschieben will.

Und MOVE ist ja nur ein einfaches Load und Transfer:
L DB2.DBD 32
T DB2.DBD 36

Während BLKMOV der Aufruf eines komplett anderen Bausteins ist, an dem Parameter (wenn auch nicht viele) übergeben werden.
Funktionieren tut beides. Ich bin nur ein Fan von Minimalismus.
Wenn ich eine Karre voll Sand habe, besorge ich mir dafür ja auch keinen LKW, übertrieben gesagt.
 
warum BLKMOV mit MOVE zu ersetzen besser sein soll?
Will man mit BLKMOV 9 DWORD in einen ungünstig überlappenden Zielbereich kopieren, dann muß man 2x BLKMOV und einen Zwischenspeicher benutzen. Das benötigt schon allein 14x L+T zur Übergabe der Adressen an 2x BLKMOV und Abholen des RET_VAL, und da sind die 9 DWORDs selber noch lange nicht kopiert! (*) Da kann man auch gleich mit nur 9x L+T (MOVE) die DWORDs mit Einzel-MOVE kopieren, und braucht dafür auch keinen temporären Zwischenspeicher. Die 9x MOVE sind viel effizienter als 2x BLKMOV.

(*) dazu kommen noch 2x CALL, dann müssen die BLKMOV die Übergabeparameter abholen und Pointer basteln, und prüfen ob die Adressen korrekt sind, und dann indirekt adressiert die 9 DWORD kopieren

Harald
 
Weil man mit BLKMOV im Prinzip kompliziertere Sachen schieben kann, und der Ersteller aber nur einefache Werte mit spezifischen Speicherbereichen verschieben will.

Und MOVE ist ja nur ein einfaches Load und Transfer:
L DB2.DBD 32
T DB2.DBD 36

Während BLKMOV der Aufruf eines komplett anderen Bausteins ist, an dem Parameter (wenn auch nicht viele) übergeben werden.
Funktionieren tut beides. Ich bin nur ein Fan von Minimalismus.
Wenn ich eine Karre voll Sand habe, besorge ich mir dafür ja auch keinen LKW, übertrieben gesagt.

Ja, aber warum soll man nun eine große Verschachtelung sowie Tipparbeit auf sich nehmen, wenn es bereits eine Anweisung gibt die das in zwei Schritten erledigen kann? Das erschließt sich mir nicht so ganz.
Minimalistisch wäre wenn ich wenig Code habe und es dadurch übersichtlich bleibt.

Das mit Deinem Sand...wenn mein Kreuz nach 10 Karren schmerzen würde, dann würd ich lieber den LKW nutzen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Warum soll man unnötig vermeidbare Kopf-Arbeit auf sich nehmen? ;)
Die Verschiebung mit 9x MOVE kann man in FUP/KOP symbolisch programmieren. Das 1x oder 2x BLKMOV geht nicht symbolisch, sondern mindestens eine ANY-Adresse muß manuell als Absolut-Adresse ausgerechnet und am BLKMOV angegeben werden.

Harald
 
Warum soll man unnötig vermeidbare Kopf-Arbeit auf sich nehmen? ;)
Die Verschiebung mit 9x MOVE kann man in FUP/KOP symbolisch programmieren. Das 1x oder 2x BLKMOV geht nicht symbolisch, sondern mindestens eine ANY-Adresse muß manuell als Absolut-Adresse ausgerechnet und am BLKMOV angegeben werden.

Harald
Echt? Ausgerechnet Du störst Dich an dem bissle Kopfrechnen? Das wär mir wirklich neu, schätze Dich da anders ein :D.

Er hat 3 Bereiche zu 36 Byte(10 Werte), davon müssen jeweils 32 Byte(9 Werte) verschoben werden. Einer wird überschrieben, fällt halt raus, einer wird hinzugefügt.
Das würde bedeuten Ihr möchtet lieber 3x9 Werte umkopieren statt 3x2 Anweisungen nutzen. Auf beide kommen noch 3 Einträge drauf für die neuen.
Das mit dem Speicherplatz (Temp-Bereich) und Zyklusbelastung lasse ich gerade absichtlich aussen vor, da davon gar nicht die Rede ist und ich nicht weiß ob das überhaupt relevant ist.

Ich finde daher die Lösung BLKMOV zu nutzen übersichtlicher und eleganter, aber jedem das seine.
 
Ich finde hier im speziellen Beispiel 9x symbolische MOVE übersichtlicher und leichter verstehbar/überprüfbar, als 1 oder 2 BLKMOV mit einer "Magic"-Adresse. Und ich finde die MOVEs auch besser an die aktuellen Fähigkeiten des TE angepasst.

PS: und die Lösung mit den 9x MOVE ist außerdem später mal viel leichter in TIA portierbar.

Harald
 
Zuletzt bearbeitet:
Zurück
Oben