Neuling steigt von S7 um, Multiplexer programmieren

HaraldT

Level-1
Beiträge
53
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Abend,

ich möchte für mein Haus eine WAGO Steuerung nutzen.
Wie im Titel beschrieben ist Codesys für mich Neuland.

Ich habe als erstes das Ampelprojekt erfolgreich abgearbeitet und danach einen eigenen Baustein programmiert (Stromstoßrelais) - funktioniert auch ^^

Zum einarbeiten war das soweit in Ordnung aber nun wird es für mich komplizierter.

Ich habe mir einen Baustein geschrieben (der sehr wahrscheinlich nicht funktioniert) um mit einem RTD Eingang 16 PT1000 einzulesen.

Der Baustein ist exemplarisch nur mit 2 Werten programmiert.

Als Sprache habe ich mir AWL ausgesucht weil ich mit ST wirklich noch nicht zurecht komme.

Ich würde mich über Tipps freuen wie man in Codesys AWL "richtig" programmiert. Ich vermute der TON funktioniert vielleicht auch nicht.

Code:
PROGRAM Multiplex
VAR_INPUT
    Analog_IN: INT;
END_VAR


VAR
    MB: BYTE := 0;
    Pause: TON;
    Temp1: INT;
    Temp2: INT;


END_VAR

Code:
    (*************************************************************************************
das Merkerbyte ist für die Dezimalzählung von 0-15 und für das 
Bitmuster:


0    0    0    0        0
0    0    0    1        1
0    0    1    0        2
0    0    1    1        3


zuständig. Die Dezimalzahl wird genutzt um einen Analogeingang auf 16 verschiedene Variablen zu speichern.
Das Bitmuster wird in das Ausgangsbyte geschoben um beim Multiplexer den nächsten PT1000 anzusteuern.
***************************************************************************************)




    LD        MB (* Merkerbyte -  wird hochgezählt*)
    GT        15 (*größer 15 soll dann genull werden*)
    JMPC    NULL
    (*anstonsten addiere eine 1 dazu*)
    LD        MB
    ADD        1
    ST        MB
    ST        OUT_Mux  (*OUT_Mux AT %QB1: BYTE;      Ich hoffe man kann so ein Ausgangsbyte ansteuern?*)


    (*1 Sek. Pause um den Eingang zu beruhigen*)
    LD        TRUE
    ST        Pause.IN
    CAL        Pause(PT:= T#1s)
    LD        Pause.Q


    (*Ab hier wird MB verglichen und der Wert vom Analogeingang in die passede Variable geschrieben*)
    LD        MB
    EQ        1
    LD        Analog_IN
    ST        Temp1




    LD        MB
    EQ        2
    LD        Analog_IN
    ST        Temp2


    (* Ein letzter Sprung damit MB nicht genullt wird*)
    JMP        ENDE


NULL:LD        0
    ST        MB


ENDE:
 
Ich bin jetzt nicht so fit in TwinCat/CodeSys-AWL ... was mir aber aufgefallen ist :
Du hast den Timer-Baustein in einer bedingten Bearbeitung stehen. Das kommt generell nicht so gut, da der Baustein so niemals eine Flanke an seinem IN mitbekommt. Das solltest du als erstes mal ändern.

Deine "Beruhigungszeit" wird so auch nicht funktionieren - der MB zählt ja munter weiter. Dann macht man so eine "Beruhigung", so fern denn benötigt, eigentlich über eine Mittelwert-Bildung des Analogwertes. So wird (vorausgesetzt es ist irgendwann korrekt programmiert) doch immer nur der Aktualwert eingelesen.

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich habe zwar schon lange nicht mehr in AWL programmiert, und schon gar nicht in Codesys, aber folgendes ist mir aufgefallen (wie würdest Du das denn in Step7 AWL lösen?):

Du behandelst so nur 15 Meßstellen, MB = 0 wird nicht behandelt, da Du gleich um 1 inkrementierst. Die Abfrage größer 15 solltest du an's Ende setzen. Erst inkrementieren und dann abfragen.
Dazu mußt Du dann wie Larry schon bemerkt hat den Timer mit einbeziehen, also ist Timer abgelaufen -> dann inkrementieren.

Der Timer funktioniert nicht. Der muß einen Flankenwechsel am In sehen. Du lädst hier aber immer True, daher wird die Timerfunktion nur einmal durchlaufen und dann nie wieder. Am besten so abfragen: Pause.In = 0? dann Pause.In = 1 setzen.

Dazu fehlt Dir auch noch die Abfrage ob der Timerausgang Timer.Q auf 1 gewechselt hat, also die Zeit abgelaufen ist. Das LD Timer.Q bringt da nicht viel. Der der Abfrage auf Timer.Q = 1 setzt Du dann erst einmal den In auf 0, fragst den Analogwert ab und inkrementierst wie oben bereits erwähnt Dein MB.

Den Timeraufruf solltest Du als erstes machen, so das der Timer in jedem Zyklus aufgerufen wird.

Timeraufruf
MB auf Ausgang setzen
Timer.In auf 1 setzen, falls vorher 0
Abfrage ist Timer abgelaufen, dann
-Timer.In auf 0 setzen
-Analogwert abfragen
-MB inkrementieren
-Abfrage ob MB > 15, dann
--MB auf 0 setzen

In dieser Reihenfolge sollte es funktionieren.

Gruß
 
Vielen Dank für den Gedankenanstoß wie die Reihenfolge aussehen sollte und wie der Timer immer wieder neu angestoßen wird.

in S7 ist das relativ einfach zu lösen.

MB dient wie hier als vergleicher für Dezimal und wird gleichzeitig in das Ausgangsbyte geschrieben. Ebenso wie in Codesys möglich.
Der Timer wird in S7 mit dem VKE wechsel von 0->1 angestoßen, ebenso wie in Codesys.
Dort gibt es zwei befehle SET(setzt auf 1) und CLR(setzt auf 0).

Aber wenn ich das richtig sehe, ist das was ich möchte nichts anderes als eine Case Anwendung in ST. Das könnte ich noch hinbekommen ;)
 
Zurück
Oben