Zähler im Strukturierten Text

schlubber

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

ich will einen Zähler programmieren der in einer bestimmten Zeit (z.B. 5s) von 0 bis 360 hochzählt.
Die Schrittweite soll dabei variabel einstellbar sein.
Programmiersprache ST.

Kann mir jemand weiterhelfen?
LG
 
Ich vermute Du willst eine RAMPE? Da sollte es bei OSCAT was fertiges geben.
Muß beim Hochzählen jeder Zwischenwert einmal mindestens einen Zyklus lang anstehen oder dürfen Zwischenwerte (Schritte) auch übersprungen werden?

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Nein ich will keine Rampe.
Der Zähler soll sozusagen einen Absolutwertgeber simulieren, der Werte von 0 bis 360 (Gradmaß Kreis) in einer bestimmten Zeit ausgibt.
Ziel ist es jede Millisekunde den aktuellen Wert an eine andere Steuerung zu schicken.
Die Steuerung zum Senden ist die Simotion D445-2 DP/PN.
 
Ein Zähler reagiert nur auf impulse , Signale , und meine Idee wäre ein art Blinker (Timer) der dein Zähler antreibt , in Zähler stellsts Du die aktuelle Werte auf Max 360 danach wieder resetten.

die Impuls-Zeit kannst Du an Zähler anpassen bzw. Skalieren.

Zum beispile Impulse: 1ms := aktuelle Zähler +wert .1

 
Ich habe so etwas schon gemacht, komme aber nicht aus der Siemens-Welt. Deshalb zunächst ein paar grundsätzliche Fragen:
Läuft das Programm auf der Steuerung mit einer festen Zykluszeit?
Wenn ja, wird die Zeit für eine Umdrehung des virtuellen Gebers immer ein ganzzahliges Vielfaches der Zykluszeit sein?
Gibt es bei der Steuerung die TIME() Funktion zum Auslesen der Systemzeit?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich weiß nicht wie der Controller programmiert wird und welche Tasks er hat.
Wenn du schreibst, dass die Daten alle ms gesendet werden sollen, gehe ich mal davon aus, dass du einen Task hast, der alle ms aufgerufen wird (vergleichbar mit einem Weckalarm bei S7/TIA). Dann kannst du dort folgendes machen:

Code:
// Zähler inkrementieren
#Zaehler :=#Zaehler+1;

// Zähler nach Ablauf der Zeit für 1 Umdrehung zurücksetzen
IF Zaehler > DrehgeberZeitSoll THEN
    #Zaehler:=0;
END_IF;

// Umrechnung abgelaufene Zeit in °
#Drehgeber := #Zaehler * 360 / #DrehgeberZeitSoll;

In den oben genannten Wertebereichen kann man problemlos mit DINT oder UDINT arbeiten.
Wenn es deutlich darüber hinaus geht, muss man die Gefahr von Überläufen berücksichtigen!

Falls es keinen Task mit fester Zykluszeit gibt, kann man einen IEC Timer hochlaufen lassen und dessen Wert in den Winkel umrechnen.
Dies führt natürlich zu einem gewissen Jitter.

Code:
"SimDrehgeber".TON(IN:=NOT #DrehgeberUeberlauf, // Achtung: Darf keine TEMP Variable sein! 
                   PT:=#DrehgeberZeitSoll,
                   Q=>#DrehgeberUeberlauf, // Achtung: Darf keine TEMP Variable sein!
                   ET=>#DrehgeberZeitAkt); 

#Drehgeber := TIME_TO_DINT(#DrehgeberZeitAkt) * 360 / TIME_TO_DINT(#DrehgeberZeitSoll);
 
Das wird beides nicht so ganz richtig funktionieren. Eigentlich darf der Zähler ja nur bis 359 zählen, weil 360 = 0. Zählerreset deshalb nicht bei
Code:
IF Zaehler>DrehgeberZeitSoll
sondern bei
Code:
IF Zaehler>=DrehgeberZeitSoll
Und bei einer Timer-Lösung, egal ob mit fester Zykluszeit oder nicht, muss der Timer noch im gleichen Zyklus, in dem er abgelaufen ist, noch einmal mit IN:=FALSE und dann mit IN:=TRUE aufgerufen werden, um nicht zwischen den Timer-Abläufen immer einen Zyklus für den Timer-Reset einzuschieben.
 
Zurück
Oben