Digitale Eingänge mit TwinCat auslesen

sucb76

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

ich bin noch SPS-Anfänger und habe eine wahrscheinlich recht simple Frage :)

Ich betreibe momentan eine KL3403-Leistungsmessklemme mit einem BK9000-Koppler direkt an meinem Rechner. Dies funktioniert soweit auch zufriedenstellend.
Jetzt soll noch eine digitale Eingangsklemme KL1418 dazukommen. Der Aufbau ist folgender: BK9000-KL1418-KL3403-KL9010 (Abschlussklemme).
Die Klemmen werden über die Scan-Funktion auch alle erkannt. Nun möchte ich natürlich die digitalen Eingänge auslesen. Hierzu muss ich den einzelnen Eingängen Variablen zuweisen.
Daran scheitert es momentan noch. Bei der Leistungsmessklemme wurden mir schon Variablen von TwinCat "vorgeschlagen", die aus dem Funktionsblock für diese Klemme kommen. Bei der KL1418 gibt es jedoch keinen Funktionsblock und daher auch keine passenden Variablen. Wie verknüpfe ich nun die reale Adresse (Beispiel: 12.0) eines Kanals mit einer virtuellen Variable, mit der ich dann arbeiten kann? Gehört das in die globale Variablenliste oder eine andere? Und muss in der Gerätekonfiguration noch irgendetwas geändert werden?

Viele Grüße

Chris
 
Hallo,

die Eingänge können in der Definition der Variablen direkt mit diesen verknüpft werden:

Code:
Variable_1 AT %IX0.0: Bool; (* optionaler Kommentar *)

Als Adresse ist natürlich die tatsächlich vorhandene Hardware-Adresse zu verwenden.

Diese Variablen-Konfiguration kann in einem Programm oder Global passieren.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du musst die Eingangsvariablen bei dir im Programm deklarieren.
z.B.
Code:
VAR
  I_xEingang1 AT%I* :BOOL;  (*ein digitaler Eingang*)
  Q_xAusgang1 AT%Q* :BOOL; (*ein digitaler Ausgang*)
END_VAR

Das AT%I sagt dem Kompiler, das es sich im eine Eingangsvariable handelt. Der * bedeutet, das du es dem Kompiler überlässt welche Speicheradresse die Variable bekommt. (ist all. die beste Variante finde ich)
AT%Q ist entsprechend für Ausgangsvariablen.

Danach übersetzt du dein Programm und liest die .tpy Datei im Systemmanager neu ein. Dann sollte dir für die digi Eingänge auch die passenden Variablen vorgeschlagen werden.
 
Danke schon mal!

Ich habe nun in der Liste der globalen Variablen folgendes hinzugefügt:

Code:
Eingang1 AT %IX12.0 : BOOL;

12.0 ist die reale Adresse des ersten Kanals der Klemme.

Außerdem habe ich Eingang1 bereits in das Unterprogramm eingefügt, wo ich ihn brauche. Wird von TwinCat gefunden und es gibt keine Fehlermeldung.

Die Variable ist allerdings unter Verknüpfungen noch nicht auffindbar, wenn ich sie mit einem Kanal der Klemme verbinden möchte. Ich vermute, es liegt daran:

Danach übersetzt du dein Programm und liest die .tpy Datei im Systemmanager neu ein

Wie genau mache ich das? Habe im Systemmanager alles durchsucht und nichts dergleichen gefunden.

PS: Ich nutze TwinCat 3.
 
Zuletzt bearbeitet:
Im Baum-Menü auf der linken Seite öffnest du den Ast "SPS - Konfiguration". Darunter findest du dein SPS-Projekt (mit so einem kleinen IEC 1131 Symbol). Wenn du darauf klickst, erscheint auf der rechten Seite die Einstellung für den Projektpfad. Dort müsste der Pfad für die .tpy Datei angeben sein (entweder als absoluter Pfad oder relativ zum SPS-Projekt). Daneben gibt es den Button "Neu Einlesen". Klickst du da drauf, wird die .tpy Datei neu im Systemmanager eingelesen und die Variablen sollten angezeigt werden.

Wenn die Verknüpfung passt, musst du noch die Konfiguration aktivieren. => Menü => Aktionen => Aktiviert Konfiguration ...
 
Rechtsklick auf das SPS Projekt "Test Project" und dann "Neu erstellen". Danach einmal alles speichern. Dann solltet Du die Variable im E/A-Baum für die Verknüpfung zur Verfügung haben.
 
Jawoll, so hat es funktioniert, danke! :)
Hatte immer nur die Konfiguration neu aktiviert, aber scheinbar hat es an dem "Neu erstellen" gehapert. Wird dann morgen in der Praxis erprobt.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich bin's nochmal....zunächst mal: Eure Hilfe hat mich schon einen Schritt weiter gebracht. Der digitale Eingang wird in der Software erkannt und schaltet auf TRUE, sobald Spannung anliegt. Nun möchte ich diese TRUE Impulse zählen. Dafür habe ich den Eingang vor einen CTU-Block (Aufwärtszähler) geschrieben. Der Zähler bleibt jedoch bei 0 stehen. Mit einer zusätzlichen Flankenerkennung klappt es auch nicht. Auch ein RS-Flipflop wird vom digitalen Eingang nicht angesprochen. Kann ich einen realen Eingang nicht direkt vor einen Funktionsblock schreiben? Die Lösung ist wahrscheinlich unglaublich banal, ich komme jetzt aber schon seit Stunden nicht dahinter. Brauche dringend Hilfe, danke schon mal!

PS: Ich habe testweise auch eine Programmzeile a la

Code:
IF Eingang1 =1 THEN
x= x+1;
END_IF

ausprobiert und dies führte dazu, dass x sich erhöhte. An der generellen Erkennung des Eingangs kann es also nicht liegen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ist das dein Hauptprogramm (also direkt mit der Task verknüpft) oder ist das ein zusätzliches Programm, das von dir selber aufgerufen werden muss, damit es abgearbeitet wird?
Wenn Bausteine nichts machen, dann meisten weil sie oder ihr übergeordneter Baustein garnicht aufgerufen werden.
Ich gehe mal davon aus, das du den Test-Code in ST in einem anderen Baustein ausgeführt hast?

Du kannst ja mal Spassenshalber die Ablaufkontrolle aktivieren, nur um sicher zu gehen. =Link - Ablaufkontrolle=
 
Es ist ein Unterprogramm, welches auch in MAIN aufgerufen wird. Ich habe nun anstatt FUP einen Zähler direkt in ST geschrieben mithilfe einer Flankenerkennung anhand eines Beispiels hier aus dem Forum. Jetzt funktioniert es! Warum weiß ich nicht, aber damit bin ich erstmal zufrieden. Evtl. kriege ich es auch noch mit FUP ans Laufen....
 
Wenn jemand auf ST umsteigt, kann ich das nur befürworten. Trotzdem wäre es interessant, herauszufinden, warum das nicht funktioniert hat, denn an der Sprache wird es kaum liegen.
Es könnte sein, dass das PRG "KWH" mit dem Eingang nicht zurechtkommt. Deklariere den "Eingang1 AT %IX12.0:BOOL" mal in Deinem Hauptprogramm und verpasse dem PRG "KWH" eine VAR_INPUT "Eingang1:BOOL". Beim Aufruf von "KWH" musst Du dann den "Eingang1" aus dem Hauptprogramm an den "Eingang1" von "KWH" übergeben. Sollte es dann funktionieren, wäre das ein guter Grund mehr, auf den Aufruf von Programmen aus anderen Programmen zu verzichten und stattdessen
Funktionsbausteine zu verwenden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo StructuredTrash,
das sehe ich ähnlich mit ST aber ob PRG versus FB besser ist:
Ich habe für mein Miniheizungsprojekt viele PRG-Teile geschrieben, jedoch saubererweise niemals IO´s in diesen verwendet, sondern nur vie VAR_INUT genutzt.
Syntaktisch exakt wie bei einem FB !
Wenn ich doch niemals diesen Code mehrfach verwende, warum sollte ich ihn dann als FB deklarieren ?
Für´s Debuggen ist ein einfaches PRG ja noch simpler als ein FB !?

FB´s nutze ich nur, wenn ich ihn mehrfach brauche...

Oder gibt es hierbei Unterschiede, welche ich noch nicht gelernt habe ?

BTW: Mir ist bewusst, das ein PRG völlig autark von der SPS getaktet o.ä. werden kann.
Aber ansonsten sollte es doch das gleiche wie ein "einmaliger" FB sein oder ?

Beste Grüße
Shrimps
 
@shrimps:
Sag niemals Nie. Ich habe mein erstes TC-Projekt auch so geschrieben wie Du, aus genau den Gründen, die Du nennst. Zwei Jahre später habe ich mich darüber geärgert, als unsere Konstrukteure mir eine Maschine vorsetzten, an der alles doppelt vorhanden war. Ansonsten hast Du recht, die Unterschiede merkt man nur, wenn man Böses vorhat (oder aus Versehen tut). Z. B. stehen die Daten der Programme nicht zwangsläufig in einem zusammenhängenden Block, die Instanzdaten von FBs
in einem PRG dagegen schon.
 
Gründe liegen in der Betriebssicherheit

Hallo StructuredTrash,
das sehe ich ähnlich mit ST aber ob PRG versus FB besser ist:
Ich habe für mein Miniheizungsprojekt viele PRG-Teile geschrieben, jedoch saubererweise niemals IO´s in diesen verwendet, sondern nur vie VAR_INUT genutzt.
Syntaktisch exakt wie bei einem FB !
Wenn ich doch niemals diesen Code mehrfach verwende, warum sollte ich ihn dann als FB deklarieren ?
Für´s Debuggen ist ein einfaches PRG ja noch simpler als ein FB !?

FB´s nutze ich nur, wenn ich ihn mehrfach brauche...

Oder gibt es hierbei Unterschiede, welche ich noch nicht gelernt habe ?

BTW: Mir ist bewusst, das ein PRG völlig autark von der SPS getaktet o.ä. werden kann.
Aber ansonsten sollte es doch das gleiche wie ein "einmaliger" FB sein oder ?

Beste Grüße
Shrimps


Der Hauptunterschied ist, dass Du einen FB unter verschiedenen Namen mehrfach instanzieren kannst und musst.

Ein PRG ist immer automatisch und genau einmal instanziert.

Ich halte es für einen Nachteil, dass man aus einem PRG einen anderen PRG aufrufen kann, dadurch können zumindest theoretisch Rekursionen auftreten. PRG1 ruft PRG2 auf, welches wiederum möglicherweise PRG1 aufruft, was dann natürlich PRG2 aufruft ...

Die SPS hängt dann ewig und wird abstürzen. Das ist Theorie, vielleicht wird es auch in den Implementationen der diversen Compiler überprüft.

Ich selber halte mich an die Regel:

1 Hauptprogramm ruft FUNCTIONS auf oder instanziert die FB und ruft sie auf.

FB ruft FUNCTIONS auf oder instanziert weitere FB und ruft sie auf. (Ich meine, gleiche FB Typen können im FB nicht instanziert werden.)

FUNCTIONS können nur FUNCTIONS aufrufen. FUNCTIONS können keine FB instanzieren somit auch nicht aufrufen.

Alle diese Regeln sind begründet in der Erfahrung, dass man defensiv programmieren sollte, um die Übersicht nicht zu verlieren.
Fehler werden somit auf der Compiler Ebene schon unmöglich gemacht.
Das ist dann auch der Vorteil der SPS, sie ist fast nicht vom Anwendungs Programmierer zum Absturz zu bringen.

Wer tricksen möchte oder sich für clever genug hält, kann sich immer noch ein rohes Embedded System nehmen und mit ASM oder C ein vollkommen freies Feld für sich erobern.
 
Ok, dann wäre das geklärt. Mein Tip sollte allerdings nicht dazu dienen, PRG-Aufrufe aus PRGs salonfähig zu machen. Ich kann RobiHerb nur zustimmen und den Einsatz von FBs empfehlen. Ein PRG ist ja sozusagen ein global verfügbarer FB, entsprechend hoch ist die Gefahr, dass man ihn versehentlich in einem Zyklus mehrfach oder gar aus verschiedenen Tasks heraus aufruft.
 
Zurück
Oben