Step 7 Laufschrift für LED-Anzeige programmieren

thomas1285

Level-1
Beiträge
16
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich hoffe hier kann mir jemand weiterhelfen.
Ich habe eine 315-PN/DP. Daran ist mittels Profinet eine LED-Anzeige mit 8 Zeichen angeschlossen.
Die Texte landen in einem DB. Jedes ASCI-Zeichen ist 1 Byte groß.

Der Text soll dann als Laufschrift durchlaufen. Nach dem letzten Zeichen sollen dann 3-4 Leerzeichen folgen und dann geht der Text wieder von vorne los.

Stehe da grade noch aufm Schlauch.
Es wäre super, wenn ich ein paar Programmbeispiele- oder Fragmente bekommen könnte.

Schonmal vielen Dank.

Mfg
Thomas
 
Hallo,
ich empfehle dir, dich dazu mit indirekter Adressierung auseinander zu setzen.
Hier wäre ein Beitrag, der die Basics dafür recht schön erklärt : http://www.sps-forum.de/faq/8887-pointer-zeiger-fifo-lifo.html

Du bildest dir einen Zeiger, der auf den Anfang des Datenbereichs zeigt und liest die ersten 8 Zeichen ab da und übergibst die den PAB's / AB's.
Nun wartest du einen Moment (Timer) und erhöhst den Pointer um eins und wiederholst das Ganze mit der Übertragung.
Wird dein Ende-Zeiger größer als dein Datenbereich dann schreibst du deine Leerzeichen und schließlich setzt du ihn wieder auf Anfang - das Gleiche mit dem Start-Zeiger.

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du richtest Dir einen Schiebetakt von z.B. 250ms ein (aus Taktmerkerbyte oder Timer).
Mit jeder Taktflanke verschiebst Du den anzuzeigenden Text in einem BYTE-Array um ein Zeichen nach vorn und fügst hinten ein neues Zeichen ein. Mit dem selben Takt sendest Du die ersten 8 BYTE des Arrays zur Anzeige bzw. kopierst aus dem Array in die PROFINET-Ausgangsbytes der Anzeige (kopieren könnte man auch in jedem OB1-Zyklus).

Alternativ kann man auch einen Pointer oder Index auf den Anfang des darzustellenden Text-Bereichs im Gesamt-Text im Takt weitersetzen und ab der gepointerten/indizierten Adresse in die Ausgangsbytes kopieren.

In AWL oder SCL eigentlich recht einfach quick-n-dirty gecoded.

Harald
 
Bei 8 Zeichen kannst du das sogar im KOP mit einem Zähler, ein paar Vergleichern und ein paar Move-Befehlen machen.

Den Zähler mit einem passenden Taktmerker hochzählen,
dann Vergleich auf Wert 1 und mit Move DBB1 nach ABx.
dann Vergleich auf Wert 2 und mit Move DBB2 nach ABX.
...
Wenn Zähler = 12 -> Reset

Für einen Einsteiger wird das wohl das Einfachste sein.

Gruß
Dieter
 
Bei 8 Zeichen kannst du das sogar im KOP mit einem Zähler, ein paar Vergleichern und ein paar Move-Befehlen machen.
Kann es sein, dass Du da was missverstanden hast?
8 Zeichen ist die LED-Anzeige lang. Der Text selbst kann länger sein.
... eine LED-Anzeige mit 8 Zeichen angeschlossen.


@thomas1285,

btw., wie lang ist denn der Text maximal?
Und woher weißt Du, wo der Text im DB endet, wenn er nicht die maximale Länge hat?
Gibt's ein Abschlusszeichen oder ist irgendwo die aktuelle Länge angegeben?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Bei 8 Zeichen kannst du das sogar im KOP mit einem Zähler, ein paar Vergleichern und ein paar Move-Befehlen machen.
Ja kann man. Und wenn man BLKMOV statt MOVE zum Umkopieren nimmt, dann gehts auch kurz für beinahe beliebig langen Text.

Man kann den Lauftext ohne indirekte Adressierung in FUP/KOP realisieren, wenn man das Linksschieben per Umkopieren macht (2. bis letztes Zeichen des Ausgabepuffers zu 1. bis vorletztes Zeichen kopieren). Das geht ohne ANY-Pointer mit einem fest parametrierten SFC20 BLKMOV. Allerdings nur absolut adressiert, nicht symbolisch. Siehe Anhang.
Code:
DB9.DBB0..22 : "DB9".Ausgabetext_1 : '        Mein Lauftext! '
                                     //Ausgabetext mit 8 führende und ein abschließendes Leerzeichen
DB8.DBB0..22 : "DB8".Ausgabepuffer
AB100..AB107 : PROFINET-Ausgänge zu 8-stelliger LED-Anzeige

Länge_LED_Anzeige ==> Anzahl_führende_Leerzeichen (8)
Textlänge + Länge_LED_Anzeige ==> Anzahl_Schiebetakte (14 + 8 = 22)
Textlänge + Länge_LED_Anzeige + 1 ==> ARRAY_Größe (14 + 8 + 1 = 23)
ARRAY_Größe - 1 ==> Blocklänge des Schiebe-BLKMOV (22)

Harald
 

Anhänge

  • FB108_Lauftext_FUP.jpg
    FB108_Lauftext_FUP.jpg
    130,4 KB · Aufrufe: 66
Vielen vielen Dank für die Hilfe!

@PN/DP
Das funktioniert echt super. Ein Problem habe ich aber noch. Der letzte BLK_MOVE schiebt die Daten aus dem Ausgangspuffer nicht in die PAB´s.
Das mit dem P#A100.0 Byte 8 scheint die Steuerung nicht hinzubekommen.
Jetzt mache ich das Umkopieren noch von Hand.
 
wie muss ich den Pointer anlegen, damit die Länge des Textes variabel gestaltet werden kann?
Da muss ich ja das Byte... ( z.B. Byte 22 ) in P#DB9.DBX0.0 Byte 22 anpassen!?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich muss nochmal nerven :)

gibt es einen Baustein, der eine Textvariable, die aus dem WinCC kommt, in die einzelnen Zeichen zerlegt und in einem Datenbaustein als Byte speichert?
 
Zuletzt bearbeitet:
Jaaa, wenn das Ganze jetzt mit variablen Textlängen funktionieren soll, dann wird 's in FUP/KOP langsam schwierig.
Der kurze Beispielcode zeigt eigentlich nur, wie es grundsätzlich funktiert. Nun mußt Du den Code nach Deinen eigentlichen Anforderungen anpassen, den Anzeigetext von außen füttern, ggf. Parameter variabel gestalten...
Erzähl doch mal mehr, was Du eigentlich tun willst. Wieviele verschiedene Texte? Wie lang ist der längste Text, wie lang der kürzeste? Wie oft ändert sich der Ausgabetext?


Wenn Du nur 1 Text mit variablem Inhalt ausgeben willst (der z.B. von einer Visu/WinCC kommt), dann kannst Du das Beispiel auf die maximale Stringlänge auslegen und nur so oft schieben, wie tatsächlich Zeichen vorhanden sind.

z.B. Ausgabe max 60 Zeichen Text
  • das Beispiel in #6 arbeitet mit einem festen Text, der in DB9.DBB0..DBB22 liegt. Das änderst Du zu einem String der maximal benötigten Länge + mindestens 8 Leerzeichen, z.B. in DB9 ab DBB0:
    DB9: +0.0 | Ausgabetext | STRING[68] | Anfangswert: ' ' (mind. 1 Zeichen lang)
  • für das Texteingabefeld von WinCC legst Du irgendwo eine String-Variable für die maximal benötigte Stringlänge an, z.B.
    Eingabetext | STRING[60]
  • in WinCC legst Du eine String-Variable für das E/A-Feld auf diese Variable an.
    Und ein E/A-Feld zum Eingeben des Textes in diese Variable.
  • mit der IEC Function FC2 CONCAT bastelst Du 8 führende und 8 nachfolgende Leerzeichen an den Eingabetext.
    Dafür brauchst Du einen STRING mit 8 Leerzeichen:
    Leer8 | STRING[8] | Anfangswert: '........' (8 Leerzeichen)
  • Damit Du CONCAT auch gleich für die ohnehin benötigte Kopierfunktion in den Ausgabepuffer benutzen kannst, muß der Ausgabepuffer (Schiebepuffer) vom Typ STRING sein:
    DB8: +0.0 | Ausgabepuffer | STRING[76] | Anfangswert: '.........' (mind. 9 (Leer)Zeichen)
  • Netzwerk 4 muß auf die neue Länge und Adresse des Ausgabepuffer angepasst werden
    1. BLKMOV (Text links schieben) : SRCBLK:=P#DB8.DBX3.0 BYTE 75 und DSTBLK:=P#DB8.DBX2.0 BYTE 75
    2. BLKMOV (Ausgabe zu Anzeige): SRCBLK:=P#DB8.DBX2.0 BYTE 8
  • in Netzwerk 3 ersetze SFC20 BLKMOV durch 2x FC2 CONCAT (siehe Bild im Anhang)
  • in Netzwerk 3 mußt Du die Anzahl Schiebetakte (max-Vergleichswert für den Schiebezähler) anpassen von 22 zur tatsächlichen Textlänge des Ausgabetextes. (da wird es in FUP/KOP langsam aufwendig wegen der Typprüfung)
    Dazu nimmst Du die aktuelle Stringlänge von "DB9".Ausgabetext (aus dem zweiten Byte des Strings von Adresse DB9.DBB1) und ändere den Vergleich von CMP>=I zu CMP>I
    (siehe Bild im Anhang)

Wenn Du den Lauftext noch variabler brauchst, dann wirst Du Dich wohl mit indirekter Adressierung mit AWL oder SCL beschäftigen müssen. Das geht nicht in FUP/KOP. Und dann kann man es auch ohne die absoluten Adressangaben programmieren.


Ausgabe an die Ausgangsbytes zur LED-Anzeige:
Der SFC20 BLKMOV kann nur ins Prozessabbild A... kopieren, nicht zur Peripherie PAB...
Am einfachsten ist es, wenn Du die A-Adressen der LED-Anzeige ins Prozessabbild der Ausgänge legst, dann kannst Du SFC20 benutzen. Wenn die Adressen außerhalb des Prozessabbilds liegen, dann kommt es darauf an, wie die Konsistenz für das PROFINET-Device projektiert ist. Wenn Konsistenz über die gesamte Länge (8 Byte) projektiert ist, dann mußt Du mit SFC15 DPWR_DAT kopieren. Wenn nicht, dann kannst Du mit mehreren MOVE-Blocks von DB8.DBB2..DBB9 zu PA.. kopieren.

Harald
 

Anhänge

  • FB108_Lauftext_variabel_FUP.jpg
    FB108_Lauftext_variabel_FUP.jpg
    77,5 KB · Aufrufe: 46
Zuviel Werbung?
-> Hier kostenlos registrieren
Noch eine kurze Frage...

Wie bekomme ich dort jetzt noch eine Art Reset eingefügt?

D.h. damit würde ich die Laufschrift zurücksetzen. Es wird dann nichts mehr angezeigt und die Laufschrift "steht" sozusagen still.
Und wenn ich einen neuen Text aus der Visualisierung in die SPS schicke, soll es wieder neu beginnen.
 
Einfach Eingabetext einen leeren String '' (?), oder besser einen String mit 1 oder mehr Leerzeichen zuweisen (z.B. den "DB9".Leer8 ).

Oder im Netzwerk 3 unter dem MOVE noch einen Umschalter (UND, UND-NOT) einbauen, der entweder die beiden CONCAT oder einen BLKMOV aufruft. Der BLKMOV soll am besten den "DB9".Leer8 auf den Ausgabepuffer kopieren.

Harald
 
Arrggh! :oops:
BLKMOV kann man nicht so einfach verwenden, der überschreibt die Maximallänge des Strings Ausgabetext. :(

Mit CONCAT geht es wie gewünscht. siehe im Bild die 3 neuen Blöcke (violett)

Dafür brauchst Du noch einen String mit nur 1 Leerzeichen
"DB9".Leer1 ist ein STRING[1] mit Anfangswert ' ' (1 Leerzeichen)

#Blank ist ein BOOL in STAT:
- ist #Blank=FALSE, dann wird sofort "DB9".Eingabetext ausgegeben
- ist #Blank=TRUE, dann bleibt die Anzeige leer (nach Ende des aktuell ausgegebenen Textes)

Harald
 

Anhänge

  • FB108_Lauftext_Blank_FUP.jpg
    FB108_Lauftext_Blank_FUP.jpg
    58,3 KB · Aufrufe: 34
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich habe jetzt eine zweizeilige Anzeige mit jeweils 8 Zeichen.
Dazu habe ich alles verdoppelt und das funktioniert auch soweit. D.h. ich habe jetzt 2 FB´s. Einen für jede Zeile.
Jetzt habe ich das Problem, dass die Texte, die dort ausgegeben werden sollen nicht gleichlang sind.
Ich muss das jetzt aber so hinbekommen, dass sich die beiden Zeilen synchronisieren, d.h. immer gleichzeitig anfangen.
Also, dass die "kürzere" Zeile nach dem Durchlaufen solange wartet, bis die "längere" Zeile auch fertig ist.

Ich hoffe man kann verstehen, worauf ich hinaus will...
 
Und das mit dem zusätzlichen CONCAT funktioniert zwar, aber nach ner gewissen Zeit wird doch ein undefiniertes Zeichen ausgegeben.
Und das bleibt dann da stehen, bis man den Text wieder laufen lässt.
 
Zurück
Oben