# Zähler in St Programmieren



## p.sasse (19 April 2016)

Hallo,
ich bin noch blutiger Anfänger was das programmieren in st angeht.
daher hoffe ich es kann mir hier jemand weiter helfen.

Ich habe vor einen zähler zu bauen der ein byte von 0 bis huntert hoch oder runter zählt durch drücken 2 er tasten am display. (key 1 und key 2 )
und duch drücken von Key3 wird ein fester wert (werkseinstellung) in den zähler geschrieben.

in fup mit dem Baustein ctud ist das für mich kein problem, doch da ich den zähler als retain schreiben will geht das mit ctud nicht, da bei 20 benötigten zählern der retain speicher nicht reicht, deshalb habe ich vor mir selber im st eine art stud zu schreiben, nur bis jetzt ohe erfolg.



> PROGRAM Begrenzung_Durchfluss1_STVAR
> impulse1 :TP;
> impulse2 :TP;
> 
> ...





> IF impulse1.Q THEN zaehler :=zaehler-1;END_IF
> 
> 
> IF impulse2.Q THEN zaehler :=zaehler+1;
> ...






ich hoffe mir kann jemand weiter helfen.
danke schon mal dafür.
Gruß Pascal


----------



## L.T. (19 April 2016)

Hallo Pascal,

der ST Code ist zwar noch etwas übersichtlich aber ich versuch mal ein paar Ideen zu geben.
Der Zähler muss so aufgebaut werden, dass er nur bei der Flanke deines Signals zählt. 
Dementsprechend musst du dafür auch eine Flankenauswertung durchführen. Sonst würde das Programm bei einer Task-Zykluszeit von 2 ms z.B. hier 5 statt 1 hoch zählen.
Entweder du bastelst diese Flankenauswertung selbst über einen Merker oder du benutzt ein R_Trig.
Über den R_Trig.Q kannst du dann den Zähler in die jeweilige Richtung zählen. (Vorher vielleicht noch abfragen ob der Zähler bereits an einem seiner Limits ansteht)

Gruß L.T.


----------



## PN/DP (19 April 2016)

p.sasse schrieb:


> in fup mit dem Baustein ctud ist das für mich kein problem, doch da ich den zähler als retain schreiben will geht das mit ctud nicht, da bei 20 benötigten zählern der retain speicher nicht reicht, deshalb habe ich vor mir selber im st eine art stud zu schreiben


Hallo Pascal,

dann nimm Dir den CTUD als Vorbild und programmiere Dir Deinen eigenen angepassten CTUD_100-Baustein.
Das könnte etwa so aussehen:

```
FUNCTION_BLOCK CTUD_100
VAR_IN
  CU : Bool;
  CD : Bool;
  RESET : Bool;
  LOAD : Bool;
  PV : INT;
END_VAR
VAR_OUT
  CV : INT;
END_VAR

VAR RETAIN
  zaehler: BYTE;
END_VAR
VAR
  HM_up : Bool;
  HM_dn : Bool;
END_VAR

  IF CU AND NOT HM_up AND zaehler < 100 THEN
    zaehler := zaehler + 1;
  END_IF

  IF CD AND NOT HM_dn AND zaehler > 0 THEN
    zaehler := zaehler - 1;
  END_IF

//  IF LOAD ...

  IF RESET THEN
    zaehler := 0;
  END_IF

  HM_up := CU;
  HM_dn := CD;

  CV := BYTE_TO_INT(zaehler);
```
Das Programmieren des Setzens auf einen Vorgabewert und Kommentare dranschreiben habe ich Dir gelassen 

Ob es für Retain reicht, einfach VAR RETAIN zu deklarieren weiß ich nicht. (Ich kenne Codesys nicht genug.)
Eventuell mußt Du ein globales RETAIN-Byte als VAR_IN_OUT an den Baustrein übergeben.
PS: Die Größe des Retain-Speichers kann man irgendwo einstellen.




p.sasse schrieb:


> > IF zaehler=100 THEN zaehler100 TRUE


Sowas ist Mist, weil bei solchen unvollständigen Sachen der zaehler100 nach einmaliger Zuweisung für immer TRUE bleiben wird.
Besser:

```
zaehler100 := (zaehler = 100);  //oder:  zaehler100 := (zaehler >= 100);

//falls für obigen CTUD_100 auch Ausgänge QD und/oder QU benötigt werden:
  QD := (zaehler = 0);
```

Harald


----------



## p.sasse (19 April 2016)

Hallo,
Danke euch beiden für die schnelle Antwort, leider kommen ich heute nicht mehr dazu es zu testen, bin schon wieder an einem anderem projekt auf der arbeit :???:.
ich melde mich morgen, ob ich es hin bekommen habe.

gruß pascal


----------



## p.sasse (20 April 2016)

Hallo.
So habe es gerade so programmiert, und es klappt wunderbar, es reicht auch bei codesys den zähler so alt retain zu deklarieren.
danke noch mal, ihr habt mir gut weiter geholfen.
gruß pascal


----------

