TIA Abfrage ob Eingänge 1 oder 0 sind

4nD1

Level-2
Beiträge
512
Reaktionspunkte
13
Zuviel Werbung?
-> Hier kostenlos registrieren
Abfrage ob mehrere Eingänge 1 oder 0 sind

Hallo Leute,

Ich will eine Einfache Abfrage machen ob ein Eingang 1 oder 0 ist. Dies soll dann mit mehreren Eingängen gemacht werden. Hierbei steht jeder Eingang für eine Maschine. Ich wollte es erst mit einem Und und Negierungen machen aber das funktioniert leider nicht wirklich. Da ich ja sicherstellen muss das auch erfasst wird wenn Maschine 4 läuft und nicht Maschine 1. Hat da einer ne Idee wie ich das einfach machen kann?
Es gibt ja dann die unterschiedlichen Zustände z.b Maschine 1 und Maschine 4 oder Maschine 3 Maschine 2 und Maschine 1 an. Das will ich einfach erfassen weil mit dieser Entscheidungsmatrix entschieden werden soll wie schnell eine Pumpe läuft.

Ich hoffe ihr könnt mir weiterhelfen
 
Zuletzt bearbeitet:
Da hatte einer mal hier einen kleinen Baustein vorgestellt, welcher als Output die Anzahl der "1" Bits ausgibt ...
Mir fällt gerade nur nicht ein welcher Thread dies war :confused:!
 
In SCL:
AnzahlMaschinen := BOOL_TO_INT("Maschine 1 Betrieb") + BOOL_TO_INT("Maschine 2 Betrieb") + BOOL_TO_INT("Maschine 3 Betrieb") + BOOL_TO_INT("Maschine 4 Betrieb");
 
Ich kann mir an den Tread errinneren.
Es geht um diese Baustein.

Code:
 FUNCTION_BLOCK "Bitsumme"
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      DBNR : Int;
   END_VAR
   VAR_OUTPUT 
      Anzahl_Bits : DInt;
   END_VAR
   VAR_TEMP 
      DBNR_t : Int;
      Pointer_daten_bit_t : DWord;
      SchleifenZaehler_T : DInt;
      Bitzaehler_t : DInt;
   END_VAR

BEGIN
NETWORK
TITLE = 
      L #DBNR                     ;//Indirektes Öffenen des Datenbausteines über In Parameter
      T #DBNR_t;
      AUF DB[ #DBNR_t];
//******************************************************************************** ***********
      LAR1 P#0.0                     ;//Initialisierung des Datenbitpointers 
//******************************************************************************** ***********
      L DINT#0                       ;//Initialisierung des Bitzaehlers
      T #Bitzaehler_t;
//******************************************************************************** ***********
      L DBLG                      ;//auslesen der Datenbausteinlänge in Byte
      L DINT#8                       ;//multiplikationfaktor Byte nach Bit 
      *D;
next:      T #SchleifenZaehler_T       ;//Vorspannen des Schleifenzaehlers in DINT,da die Schleife grösser als 32767 sein Könnte
      CLR                             ;//Erzwingen VKE=0 
      U DBX[ AR1, P#0.0];
      SPBN m001                      ;//wenn Bit=0 Springe
      L DINT#1                       ;//Zaehlen wenn ein Bit=1
      L #Bitzaehler_t;
      +D;
      T #Bitzaehler_t;
m001:      +AR1 P#0.1                     ;//Pointererhöhung für nächsten Schleifendurchlau
      L #SchleifenZaehler_T       ;//dekrementierung SchleifenZaehler_T um 1
      L DINT#1;
      -D;
      L DINT#1;
      >=D;
      SPB nex2                      ;// Rücksprung in Schleife wenn noch nicht alle Bits des DB auf 1 Geprüft
      SPA m002;
nex2:      TAK;
      SPA next;
m002:      NOP 0;
//******************************************************************************** ***********
      L #Bitzaehler_t             ;// Übergabe der Temporär gezaehlten 1=Bit an Output
      T #Anzahl_Bits;

END_FUNCTION_BLOCK

Bram
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn es nur wenige Maschinen sind oder wenn man den Maschinen unterschiedliche Gewichtungen zuordnen muss, kann man es auch ganz einfach wie folgt umsetzen.

Code:
FUNCTION FC 3 : REAL
TITLE =
VERSION : 0.1


VAR_INPUT
  MASCHINE_1_BM : BOOL ;    //Betriebsmeldung Maschine
  MASCHINE_2_BM : BOOL ;    //Betriebsmeldung Maschine
  MASCHINE_3_BM : BOOL ;    //Betriebsmeldung Maschine
  MASCHINE_4_BM : BOOL ;    //Betriebsmeldung Maschine
END_VAR
VAR_TEMP
  Y : REAL ;    //Stellgrad [0..100%]
END_VAR
BEGIN
NETWORK
TITLE =


//*** Initialisierung
      L     0.000000e+000; 
      T     #Y; 

//*** Maschine 1
      U     #MASCHINE_1_BM; 
      SPBN  M001; 
      L     #Y; 
      L     2.000000e+001; // 20%
      +R    ; 
      T     #Y; 
M001: NOP   0; 

//*** Maschine 2
      U     #MASCHINE_2_BM; 
      SPBN  M002; 
      L     #Y; 
      L     3.000000e+001; // 30%
      +R    ; 
      T     #Y; 
M002: NOP   0; 

//*** Maschine 3
      U     #MASCHINE_3_BM; 
      SPBN  M003; 
      L     #Y; 
      L     2.500000e+001; // 25%
      +R    ; 
      T     #Y; 
M003: NOP   0; 

//*** Maschine 4
      U     #MASCHINE_4_BM; 
      SPBN  M004; 
      L     #Y; 
      L     2.500000e+001; // 25%
      +R    ; 
      T     #Y; 
M004: NOP   0; 

//*** Stellgrad ausgeben
      L     #Y; 
      T     #RET_VAL; // 0..100%


END_FUNCTION
 
Wenn es nur wenige Maschinen sind oder wenn man den Maschinen unterschiedliche Gewichtungen zuordnen muss, kann man es auch ganz einfach wie folgt umsetzen.
Yepp, das wäre auch mein Favorit.

Wenn es nur ein paar Maschinen sind würde ich nicht zusammengepackte Bits zählen sondern sequentiell die bedingten Additionen ausprogrammieren. Das wird übersichtlich und schafft eine einfache Möglichkeit, die Maschinen unterschiedlich gewichtet in die Berechnung eingehen zu lassen.
Code:
Summe := 0 ;
IF "Maschine 1 Betrieb" THEN Summe := Summe + 1; END_IF;
IF "Maschine 2 Betrieb" THEN Summe := Summe + 2; END_IF; //Maschine 2 hat mehr Bedarf
IF "Maschine 3 Betrieb" THEN Summe := Summe + 1; END_IF;
...
IF "Maschine n Betrieb" THEN Summe := Summe + 1; END_IF;

Noch viele weitere Programmvarianten zum Bits zählen und davon abhängig gestaffelte Sollwerte, auch für TIA, findet man mit der Forumsuche nach BITSUM.

Harald
 
Hi,
ich würde es auch mit ein paar ausprogrammierten Zeilen machen:


Summe :=0;
summe := summe + bool_to_int(maschine1);
summe := summe + bool_to_int(maschine2);
summe := summe + bool_to_int(maschine3);
summe := summe + bool_to_int(maschine4);

Ist ggf. übersichtlicher aber eine Einzelbewertung minimal aufwendiger (bool_to_int(machinex) * Faktor

LG
Shrimps
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich kann mir an den Tread errinneren.
Es geht um diese Baustein.

Code:
 FUNCTION_BLOCK "Bitsumme"
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      DBNR : Int;
   END_VAR
   VAR_OUTPUT 
      Anzahl_Bits : DInt;
   END_VAR
   VAR_TEMP 
      DBNR_t : Int;
      Pointer_daten_bit_t : DWord;
      SchleifenZaehler_T : DInt;
      Bitzaehler_t : DInt;
   END_VAR

BEGIN
NETWORK
TITLE = 
      L #DBNR                     ;//Indirektes Öffenen des Datenbausteines über In Parameter
      T #DBNR_t;
      AUF DB[ #DBNR_t];
//******************************************************************************** ***********
      LAR1 P#0.0                     ;//Initialisierung des Datenbitpointers 
//******************************************************************************** ***********
      L DINT#0                       ;//Initialisierung des Bitzaehlers
      T #Bitzaehler_t;
//******************************************************************************** ***********
      L DBLG                      ;//auslesen der Datenbausteinlänge in Byte
      L DINT#8                       ;//multiplikationfaktor Byte nach Bit 
      *D;
next:      T #SchleifenZaehler_T       ;//Vorspannen des Schleifenzaehlers in DINT,da die Schleife grösser als 32767 sein Könnte
      CLR                             ;//Erzwingen VKE=0 
      U DBX[ AR1, P#0.0];
      SPBN m001                      ;//wenn Bit=0 Springe
      L DINT#1                       ;//Zaehlen wenn ein Bit=1
      L #Bitzaehler_t;
      +D;
      T #Bitzaehler_t;
m001:      +AR1 P#0.1                     ;//Pointererhöhung für nächsten Schleifendurchlau
      L #SchleifenZaehler_T       ;//dekrementierung SchleifenZaehler_T um 1
      L DINT#1;
      -D;
      L DINT#1;
      >=D;
      SPB nex2                      ;// Rücksprung in Schleife wenn noch nicht alle Bits des DB auf 1 Geprüft
      SPA m002;
nex2:      TAK;
      SPA next;
m002:      NOP 0;
//******************************************************************************** ***********
      L #Bitzaehler_t             ;// Übergabe der Temporär gezaehlten 1=Bit an Output
      T #Anzahl_Bits;

END_FUNCTION_BLOCK

Bram

Wenn es nur wenige Maschinen sind oder wenn man den Maschinen unterschiedliche Gewichtungen zuordnen muss, kann man es auch ganz einfach wie folgt umsetzen.

Code:
FUNCTION FC 3 : REAL
TITLE =
VERSION : 0.1


VAR_INPUT
  MASCHINE_1_BM : BOOL ;    //Betriebsmeldung Maschine
  MASCHINE_2_BM : BOOL ;    //Betriebsmeldung Maschine
  MASCHINE_3_BM : BOOL ;    //Betriebsmeldung Maschine
  MASCHINE_4_BM : BOOL ;    //Betriebsmeldung Maschine
END_VAR
VAR_TEMP
  Y : REAL ;    //Stellgrad [0..100%]
END_VAR
BEGIN
NETWORK
TITLE =


//*** Initialisierung
      L     0.000000e+000; 
      T     #Y; 

//*** Maschine 1
      U     #MASCHINE_1_BM; 
      SPBN  M001; 
      L     #Y; 
      L     2.000000e+001; // 20%
      +R    ; 
      T     #Y; 
M001: NOP   0; 

//*** Maschine 2
      U     #MASCHINE_2_BM; 
      SPBN  M002; 
      L     #Y; 
      L     3.000000e+001; // 30%
      +R    ; 
      T     #Y; 
M002: NOP   0; 

//*** Maschine 3
      U     #MASCHINE_3_BM; 
      SPBN  M003; 
      L     #Y; 
      L     2.500000e+001; // 25%
      +R    ; 
      T     #Y; 
M003: NOP   0; 

//*** Maschine 4
      U     #MASCHINE_4_BM; 
      SPBN  M004; 
      L     #Y; 
      L     2.500000e+001; // 25%
      +R    ; 
      T     #Y; 
M004: NOP   0; 

//*** Stellgrad ausgeben
      L     #Y; 
      T     #RET_VAL; // 0..100%


END_FUNCTION


Super danke für die Ansätze.

Nun frage ich ich mich wie bekomme ich das nun in TIA als Baustein und in meine S7-1200?
 
Yepp, das wäre auch mein Favorit.

Wenn es nur ein paar Maschinen sind würde ich nicht zusammengepackte Bits zählen sondern sequentiell die bedingten Additionen ausprogrammieren. Das wird übersichtlich und schafft eine einfache Möglichkeit, die Maschinen unterschiedlich gewichtet in die Berechnung eingehen zu lassen.
Code:
Summe := 0 ;
IF "Maschine 1 Betrieb" THEN Summe := Summe + 1; END_IF;
IF "Maschine 2 Betrieb" THEN Summe := Summe + 2; END_IF; //Maschine 2 hat mehr Bedarf
IF "Maschine 3 Betrieb" THEN Summe := Summe + 1; END_IF;
...
IF "Maschine n Betrieb" THEN Summe := Summe + 1; END_IF;


Harald

Verstehe ich das richtig das ich nur das dann einfügen muss und das dürfte funktionieren oder muss ich dort noch ne andere Anweisung mit einbauen um die Summe dann weiter zu verarbeiten? [Hab noch nicht sehr viel Erfahrung mit SCL:confused:]
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das ist erstmal nur das Zusammenzählen, wieviele Maschinen laufen bzw. wieviel Pump-Bedarf besteht. Aus dieser Summe-Information mußt Du nun noch nach Deinen Kriterien den Pumpensollwert festlegen oder ausrechnen. Das ist beim Programm von Onkel Dagobert #6 am besten zu sehen. Im Grunde macht das Programm vom Onkel die gleiche bedingte Addition in AWL, wie ich sie in SCL gezeigt habe. Der Onkel addiert je Maschine unterschiedliche Gewichtungen in % und gibt einen Sollwert 0..100% aus.

Was hast Du denn für eine SPS?
Wie lauten die Regeln für die Geschwindigkeit Deiner Pumpe?

Harald
 
Habe eine S7-1214DC/DC/Rel.
Wenn eine Maschine läuft soll mit 25% gepumpt werden. Mit 2MAE dann 50% mit 3MAE 75% und mit 4MAE dann 100%. Und das sollt dann in einen Datenbaustein geschrieben werden.
 
OK, weil alle Maschinen gleich gewichtet sind kannst Du die Anzahl eingeschalteter Maschinen zählen (ergibt 0 bis 4) und die Anzahl mit 25 multiplizieren um auf 0 bis 100 (%) zu kommen.
Alternativ kannst Du auch gleich je 25 addieren:
Code:
Summe := 0 ;
IF "Maschine 1 Betrieb" THEN Summe := Summe + 25; END_IF;
IF "Maschine 2 Betrieb" THEN Summe := Summe + 25; END_IF;
IF "Maschine 3 Betrieb" THEN Summe := Summe + 25; END_IF;
IF "Maschine 4 Betrieb" THEN Summe := Summe + 25; END_IF;

"MyDB".Pumpesollwert := Summe ; //0..100 an Pumpensollwert geben

Vermutlich ist meine SCL-Syntax nicht ganz TIA-konform (Schreibweise der Variablen). Da hat Siemens einige Male "Neuerungen" eingeführt, doch ich habe kein aktuelles TIA. Auch fehlen noch die Deklarationen der Variablen. Du mußt wissen, welchen Datentyp Du brauchst.
S7-1200 kann kein AWL.

So einfacher Code mit bedingten ADD läßt sich auch gut in FUP oder KOP programmieren ("Maschine x Betrieb" kommt dann jeweils an den EN-Eingang der ADD-Boxen).

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
OK, weil alle Maschinen gleich gewichtet sind kannst Du die Anzahl eingeschalteter Maschinen zählen (ergibt 0 bis 4) und die Anzahl mit 25 multiplizieren um auf 0 bis 100 (%) zu kommen.
Alternativ kannst Du auch gleich je 25 addieren:
Code:
Summe := 0 ;
IF "Maschine 1 Betrieb" THEN Summe := Summe + 25; END_IF;
IF "Maschine 2 Betrieb" THEN Summe := Summe + 25; END_IF;
IF "Maschine 3 Betrieb" THEN Summe := Summe + 25; END_IF;
IF "Maschine 4 Betrieb" THEN Summe := Summe + 25; END_IF;

"MyDB".Pumpesollwert := Summe ; //0..100 an Pumpensollwert geben

Vermutlich ist meine SCL-Syntax nicht ganz TIA-konform (Schreibweise der Variablen). Da hat Siemens einige Male "Neuerungen" eingeführt, doch ich habe kein aktuelles TIA. Auch fehlen noch die Deklarationen der Variablen. Du mußt wissen, welchen Datentyp Du brauchst.
S7-1200 kann kein AWL.

So einfacher Code mit bedingten ADD läßt sich auch gut in FUP oder KOP programmieren ("Maschine x Betrieb" kommt dann jeweils an den EN-Eingang der ADD-Boxen).

Harald

Super Danke dir. Also TIA merkt nur mit der Summe das der Syntax nicht passt sonst scheint alles okay zu sein

Und wenn ich jetzt die Werte auch noch in einen Datenbaustein haben will um sie über die Visu zu ändern wie muss ich das dann machen?

Um hier Flexibel zu sein dachte ich mit einem Vergleicher der die Summe dann vergleicht und je nachdem welcher Wert erreicht wird ob 1 oder 2 etc dann in den Datenbaustein schreibt. Dort liegen dann die Werte für die Stufen.
 
Zuletzt bearbeitet:
Du könntest die %-Stufen in einem ARRAY[0..4] OF INT hinterlegen und den Wert anhand der Anzahl gezählter Maschinen entnehmen.
Code:
//irgendwo ein "Sollwerttabelle : ARRAY[0..4] OF INT" mit den Werten 0, 25, 50, 75, 100 anlegen.

Summe := 0 ;
IF "Maschine 1 Betrieb" THEN Summe := Summe + 1; END_IF;
IF "Maschine 2 Betrieb" THEN Summe := Summe + 1; END_IF;
IF "Maschine 3 Betrieb" THEN Summe := Summe + 1; END_IF;
IF "Maschine 4 Betrieb" THEN Summe := Summe + 1; END_IF;

"MyDB".Pumpesollwert := Sollwerttabelle[Summe] ; //0..100 an Pumpensollwert geben

Harald
 
Code:
#Summe := 0;
IF #MAE_1_Betrieb THEN
    #Summe := #Summe + 1; // Maschine 1 An
END_IF;
IF #MAE_2_Betrieb THEN
    #Summe := #Summe + 1; // Maschine 2 An
END_IF;
IF #MAE_3_Betrieb THEN
    #Summe := #Summe +1; // Maschine 3 An
END_IF;
IF #MAE_4_Betrieb THEN
    #Summe := #Summe +1; // Maschine 4 An
END_IF;
#Sollwert_FU_1 := #Summe; //1-4 Erkennung wieviele Maschinen Inbetrieb sind und weitergabe des Wertes an Ausgang

So ich habe das nun mal als Temp alles gemacht und nun rufe ich den Baustein in einem anderen FC auf und verknüpfe da die Werte die ich dann will. =)
 
Zurück
Oben