TIA Gibt es eine Bitsumme auf der S7-1200?

Wenn du ihn selber schreiben möchtest, dann könntest du in FUP eine Variable ( INT ) auf 0 setzen und in den Netzwerken darunter die einzelnen Bit´s abfragen und bei TRUE +1 addieren. Mal als Beispiel.

Oder du nimmst etwas fertigen. z.B. OSCAT ( BIT_COUNT ).
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du müsstest die Oscat-Bibliothek in Dein TIA zuerst importieren. Erst dann kannst du den Baustein in Dein Projekt laden. Für einen Anfänger nicht die allerleichteste Aufgabe.
 
das Problem ist das ich den Baustein im TIA Portal nicht finde.
Oscat war/ist eine Bibliothek dritter für 300/400 Steuerungen. Für TIA gibt es nichts direktes/du müsstest die Funktionen umschreiben.

Bei Siemens hab ich nur das gefunden

Screenshot 2024-04-15 115353.png
Solltest du in der Hilfe (F1) finden


In der Bibliothek gibt es eine Bitcount Funktion, leider erst ab V16, ich schaue mal ob ich die Quelle kopieren kann:

LGF_BitCount.txt in LGF_BitCount.scl abändern.. aus der V17 Bibliothek exportiert
 

Anhänge

  • LGF_BitCount.txt
    3,8 KB · Aufrufe: 7
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Angenommen Du möchtest ein Bitsum für DWORD ausführen, könntest Du folgenden Code als Textdatei (myBITSUM.scl) abspeichern, anschließend in TIA unter Externe Quelle einfügen und Baustein aus Quelle generieren ausführen:

Code:
FUNCTION_BLOCK "myBITSUM"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT
      Input : DWord;
   END_VAR

   VAR_OUTPUT
      Summe : Int;
   END_VAR

   VAR DB_SPECIFIC
      statWERT : DWord;
      atWERT { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} AT statWERT : Array[0..31] of Bool;
   END_VAR

   VAR_TEMP
      i : Int;
   END_VAR


BEGIN
    #Summe := 0;
    FOR #i := 0 TO 31 DO
        IF #atWERT[#i] THEN
            #Summe := #Summe + 1;
        END_IF;
    END_FOR;
    
END_FUNCTION_BLOCK
 
Eure Hilfe in allen Ehren aber was hilft es einem, der sich selbst als Anfänger einstuft, irgendwelche Bibliotheken / Quellen zu geben?
Der Lernerfolg ist gleich Null.

Bitte nicht falsch verstehen aber wenn diese Aufgabe jemanden in seinen Fähigkeiten übersteigt, dann helfen wohl auch keine externen Programmquellen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der Vollständigkeit halber:
Hier gibts Oscat für Tia:

Und das ist der Code:
Code:
FUNCTION "BIT_COUNT" : Int
TITLE = BIT_COUNT
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : hugo
FAMILY : GATE
NAME : BITCT
VERSION : 1.1
//
//BIT_COUNT counts the amount True of bits in a dword.
//for exabple: bit_count(3) returns 2 because two bits (bits 0 and 1) are true and all others are false.
//
//
   VAR_INPUT
      IN : DWord;
   END_VAR

   VAR_TEMP
      temp : DWord;
      attemp AT temp : Array[0..31] of Bool;
   END_VAR


BEGIN
    
      
      #BIT_COUNT := 0;
      #temp := #IN;
      
      WHILE DWORD_TO_DINT(#temp) <> 0 DO
        IF #attemp[24] THEN #BIT_COUNT := #BIT_COUNT +1; END_IF;
        #temp := SHR(IN:=#temp,N:=1);
      END_WHILE;
      
    (* revision history
    5.7.2007  rev 1.0    original version
    
    10.9.2007  rev 1.1    hm
      changed algorithm for better performace
      the execution time has reduced by a factor of 5
      deleted unused variable temp
    *)
    
END_FUNCTION
 
Das sehe ich anders. Noch nie hat ein Codeschnipsel einen User dümmer gemacht. Da profitiert jeder von, auch Anfänger. Vielleicht nicht heute, nicht morgen, aber irgendwann.

Ich sehe das auch anders, weil ich es in der Praxis immer öfter erlebe. In der Regel muss es meist schnell gehen, daher geben wir unseren Anfängern (leider, ich weiß, ich weiß) auch öfter mal Quellcode oder programmieren denen, mitsamt ausführlicher Erläuterung, den einen oder anderen Kniff hin... der Lerneffekt geht dabei leider gegen 0, so meine Erfahrung aus vielen Stunden des "Vorturnens".

Es ist was völlig anderes, ob man sich den Code online anschaut und denkt "Ach sooooo hat er das gemacht..." oder ob man tatsächlich selbst von 0 startet und nach Stunden dann endlich der Groschen gefallen ist.

Mein Ausbilder sagte immer "Schweißen kommt von schweißen..." was so viel heißt "Du kannst mir noch so lange zugucken, lernen wirst du es erst, wenn du es selbst machst."
Und natürlich hatte er Recht... wobei ich tatsächlich kein außerordentliches Talent bin und es nie wirklich gut konnte... braucht man als Elektroingenieur aber zum Glück auch nicht mehr, puh...
 
Würde folgendes funktionieren? Ungetestet.

Code:
FUNCTION CountTrueBits: INT ;

VAR_INPUT
    idwIn     : DWORD ;
END_VAR
   
VAR_TEMP
    tiCnt     : INT ;
    tdwVal    : DWORD ;
    tdwValNew : DWORD ;
END_VAR

tiCnt  :=     0 ;
tdwVal := idwIn ;

WHILE tdwVal <> 0 DO
    tdwValNew := tdwVal AND (tdwVal AND (DINT_TO_DWORD(-DWORD_TO_DINT(tdwVal)) XOR 16#FFFFFFFF) ;
    IF tdwValNew <> tdwVal THEN
        tiCnt  := tiCnt + 1 ;
        tdwVal := tdwValNew ;
    END_IF ;
END_WHILE ;

CountTrueBits := tiCnt ;
Löscht in einer Schleife die True-Bits und zählt sie.
Schleife wird beendet, sobald kein True-Bit mehr vorhanden ist.
Die TypeCasts werden vermutlich zu Warnungen führen, die zu ignorieren sind.

... braucht man als Elektroingenieur aber zum Glück auch nicht mehr, puh...
Ach, Du meinst das Schweissen. Auf die Gefahr hin, dass es Dich nicht interessieren wird:
Wenn ich mir mal wieder beim Löten einen FingerNagel angebrutzelt hatte, habe ich mich immer mit dem Spruch getröstet "Lieber LötHände als SchweissFüsse".
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
      WHILE DWORD_TO_DINT(#temp) <> 0 DO
        IF #attemp[24] THEN #BIT_COUNT := #BIT_COUNT +1; END_IF;
        #temp := SHR(IN:=#temp,N:=1);
      END_WHILE;
Wozu dient DWORD_TO_DINT()? Der Vergleich '<> 0' sollte m.E. mit DWORD genauso gut funktionieren wie mit DINT.
Warum wird das Bit 24 abgefragt? Sollen denn nur 3 Byte und nicht alle 32 Bits geprüft werden?
 
Der "attem[24]" wird wohl abgefragt, da die AT-Ansicht das erste/rechteste Bit (0.0) dort abbildet.
Mit SHR werden dann nach und nach die Bits im DWort auf "attem[24]" geschoben und dort gezählt.

Ohne es getestet zu haben, sollte es auch per Slice-Zugriff möglich sein auf das erste Bit per tempDWord.X0 zuzugreifen.
Dann bräuchte man die AT-Ansicht nicht, welche in der 1500er zumindest eh eine Krücke ist.
 
Zuletzt bearbeitet:
Alternativ hätte ich diese Variante anzubieten.
Kommt ohne Schleife, AT-Sicht oder Slice-Zugriffe aus...
Code:
FUNCTION "BitCount" : DInt
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT
      Bits : DWord;   // Zu zählende Bits
   END_VAR

   VAR_TEMP
      x : DWord;   // Interne Hilfsvariable
   END_VAR
BEGIN
    // Zählen der gesetzen Bits mittels der "Teile und Herrsche" Methode
    // aus "Hackers Delight".
    #x := #Bits;
    #x := (#x & 16#55555555) + (SHR(IN := #x, N := 1) & 16#55555555);
    #x := (#x & 16#33333333) + (SHR(IN := #x, N := 2) & 16#33333333);
    #x := (#x & 16#0F0F0F0F) + (SHR(IN := #x, N := 4) & 16#0F0F0F0F);
    #x := (#x & 16#00FF00FF) + (SHR(IN := #x, N := 8) & 16#00FF00FF);
    #x := (#x & 16#0000FFFF) + (SHR(IN := #x, N := 16) & 16#0000FFFF);
    #BitCount := DWORD_TO_DINT(#x);
END_FUNCTION
 
Zurück
Oben