# Word to Bool --- Sprache: SCL - S7



## 3njoyeD (28 April 2014)

Abend Community,

ich steh grad ein wenig auf dem Schlauch, war schon wieder etwas länger her.

Folgenden Code möchte ich in eine For-Schleife packen:

Bausteinschnittstelle:
Input: 
- Variable "w_EingangsWort" Datentyp: Word
Output: 
- x_Bit0 bis x_Bit15 Typ: Bool
Temp: 
- Variable: "w_ZwischenSpeicher" Typ: Word
- Variable: "ui_"VergleichsWert" Typ: UInt


```
// EingangsWort in Zwischenspeicher transferieren
#w_ZwischenSpeicher:=#w_EingangsWort;

// Konvertiere Variable "w_ZwischenSpeicher" in Datentyp UINT & transferiere in Variable "ui_VergleichsWert
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

// Wenn das Eingangswort einen Dezimalwert gleich oder größer 32768 (letztes Bit) wird Bit15 true
IF #ui_VergleichsWert>=32768 THEN
  #x_Bit15 := true;
END_IF;

// Bit14
// Verschiebe alle Bits um eine Stelle nach links -> Das vorletze Bit (14) wird nun an die Stelle 15 gerückt
#w_ZwischenSpeicher := SHL(IN:=#w_ZwischenSpeicher, N:=1);
//Siehe Zeile 4:
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

// Wenn Vergleichswert größer oder gleich dem Wert des letzten Bit´s
// wird durch die Verschiebungsfunktion in Zeile 14 das nun entsprechend letzte Bit logisch 1
IF #ui_VergleichsWert>=32768 THEN
  #x_Bit14 := true;
END_IF;

//Bit 13
// Wiederhole bis Bit1
#w_ZwischenSpeicher := SHL(IN:=#w_ZwischenSpeicher, N:=1);
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

IF #ui_VergleichsWert>=32768 THEN
  #x_Bit13 := true;
END_IF;

//Bit 12
#w_ZwischenSpeicher := SHL(IN:=#w_ZwischenSpeicher, N:=1);
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

IF #ui_VergleichsWert>=32768 THEN
  #x_Bit12 := true;
END_IF;

//Bit 11
#w_ZwischenSpeicher := SHL(IN:=#w_ZwischenSpeicher, N:=1);
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

IF #ui_VergleichsWert>=32768 THEN
  #x_Bit11 := true;
END_IF;

//Bit 10
#w_ZwischenSpeicher := SHL(IN:=#w_ZwischenSpeicher, N:=1);
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

IF #ui_VergleichsWert>=32768 THEN
  #x_Bit10 := true;
END_IF;

//Bit 9
#w_ZwischenSpeicher := SHL(IN:=#w_ZwischenSpeicher, N:=1);
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

IF #ui_VergleichsWert>=32768 THEN
  #x_Bit9 := true;
END_IF;

//Bit 8
#w_ZwischenSpeicher := SHL(IN:=#w_ZwischenSpeicher, N:=1);
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

IF #ui_VergleichsWert>=32768 THEN
  #x_Bit8 := true;
END_IF;

//Bit 7
#w_ZwischenSpeicher := SHL(IN:=#w_ZwischenSpeicher, N:=1);
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

IF #ui_VergleichsWert>=32768 THEN
  #x_Bit7 := true;
END_IF;

//Bit 6
#w_ZwischenSpeicher := SHL(IN:=#w_ZwischenSpeicher, N:=1);
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

IF #ui_VergleichsWert>=32768 THEN
  #x_Bit6 := true;
END_IF;

//Bit 5
#w_ZwischenSpeicher := SHL(IN:=#w_ZwischenSpeicher, N:=1);
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

IF #ui_VergleichsWert>=32768 THEN
  #x_Bit5 := true;
END_IF;

//Bit 4
#w_ZwischenSpeicher := SHL(IN:=#w_ZwischenSpeicher, N:=1);
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

IF #ui_VergleichsWert>=32768 THEN
  #x_Bit4 := true;
END_IF;

//Bit 3
#w_ZwischenSpeicher := SHL(IN:=#w_ZwischenSpeicher, N:=1);
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

IF #ui_VergleichsWert>=32768 THEN
  #x_Bit3 := true;
END_IF;

//Bit 2
#w_ZwischenSpeicher := SHL(IN:=#w_ZwischenSpeicher, N:=1);
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

IF #ui_VergleichsWert>=32768 THEN
  #x_Bit2 := true;
END_IF;

//Bit 1
#w_ZwischenSpeicher := SHL(IN:=#w_ZwischenSpeicher, N:=1);
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

IF #ui_VergleichsWert>=32768 THEN
  #x_Bit1 := true;
END_IF;

//Bit 0
#w_ZwischenSpeicher := SHL(IN:=#w_ZwischenSpeicher, N:=1);
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

IF #ui_VergleichsWert>=32768 THEN
  #x_Bit0 := true;
END_IF;
```

Jetzt stottere ich hier rum & weiß nicht, wie ich die For-Schleife:


```
FOR _counter_ := _start_count_ TO _end_count_ DO
  // Statement section FOR
  ;
END_FOR;
```

belegen muss..

Mag mir bitte jemand einen Anfangstipp geben? Wäre lieb 

lg
-3D-


----------



## RONIN (28 April 2014)

3njoyeD schrieb:


> ```
> FOR _counter_ := _start_count_ TO _end_count_ DO
> // Statement section FOR
> ;
> ...



Bin zwar in SCL auch nicht geübt aber...

```
//Schleifenvariable i, z.B deklariert in TEMP

 FOR i := 1 TO 15 BY 1 DO    //For-Schleife wird 15mal durchlaufen.

//Hier kommt jetzt dein Code
//du kannst hier drinnen i auch als Indikator verwenden in welchem Durchlauf du dich befindest.

END_FOR;
```

 Sag uns doch mal was die mit deinem Code oben erreichen willst, bzw. welche Hardware du hast. S7-300/400 oder S7-1200/1500...
Bzw. Welche Umgebung TIA oder Step7?
 Wenn du das willst was ich glaube, reine Konvertierung eines Words in 16 Bool, geht das wesentlich einfacher.


----------



## 3njoyeD (28 April 2014)

TIA V12 SP1
S7-1200

Ich nutze diesen Baustein um Zustandswörter vom Frequenzumrichter abzufragen.

Ich versuch mich nochmal 

Ich denke es ist mit einer Schleife wesentlich einfacher & mit 10 Zeilen Quellcode abgehackt  
Schön wärs jedenfalls, wenn ich das hinbekommen könnte


----------



## 3njoyeD (28 April 2014)

2 Fragen:
1.) Warum kann ich nicht vom hohen Wert zum niedrigen runterzählen?
2.) Wie funktioniert das nochmal, wenn ich die boolsche Variable direkt mit dem Counter ansprechen möchte?


```
FOR #i_counter := 13 TO 0 DO    

#w_ZwischenSpeicher := SHL(IN:=#w_ZwischenSpeicher, N:=1);
#ui_VergleichsWert :=WORD_TO_UINT (#w_ZwischenSpeicher);

  IF #ui_VergleichsWert>=32768 THEN
  #x_Bit(#i_counter) := true;
END_IF;

END_FOR;
```

lg
-3D-


----------



## RONIN (28 April 2014)

3njoyeD schrieb:


> 2 Fragen:
> 1.) Warum kann ich nicht vom hohen Wert zum niedrigen runterzählen?
> 2.) Wie funktioniert das nochmal, wenn ich die boolsche Variable direkt mit dem Counter ansprechen möchte?


1.) Ich sehe in deinem Code auch nirgens den Punkt in dem #i_counter verringert wird.
In der For Loop gibts zwei Möglichkeiten...

```
FOR #i_counter := 0 TO 13 BY 1 DO  
//...
END_FOR;
//oder
FOR #i_counter := 0 TO 13 DO  
#i_counter := i_counter + 1;
END_FOR;
```
<EDIT> OK, das is Blödisinn, siehe huckis Antwort weiter unten </EDIT>
Ich weiß nicht ob die negative Zählrichtung erlaubt ist. Falls nicht musst du entweder deine Code umbauen oder dich vom For trennen und mit einem WHILE arbeiten.


 2.) So wie du es schreibst müssten die Bits als ARRAY vorliegen. Die Richtige Antwort für deinen gewünschten Bit-Zugriff lautet AT-Sicht.
Lies dir dazu dieses THEMA durch. Da wird dir erstens die AT-Sicht näher gebracht, zweitens sind dort die Bausteine die zu programmieren versuchst in fertiger Form und das mittels AT-Sicht noch um ein ganzes Stück einfacher. Ohne die ganze Bit-Verschieberei bzw. die ganzen Vergleiche auch wesentlich performanter.

3.) Ein weiter Möglichkeit zum indirekten Zugriff auf Bits ab S7-1200/1500. Der Slice Zugriff


----------



## 3njoyeD (28 April 2014)

PERFEKT! :s12:

Genau sowas habe ich gesucht. Da werd ich mich morgen direkt an die Arbeit begeben.

Vielen Dank!


----------



## RONIN (28 April 2014)

Ja, dieses Thema "Word zu Bool" hatten wir in letzter Zeit schon öfters. Muss wohl an der daran liegen das die Leute langsam anfangen mit TIA zu bzw. 1200/1500 zu arbeiten.


----------



## PN/DP (29 April 2014)

... und mit dem TIA kann man ja nun jede Aufgabe in 10 Minuten lösen ohne Ahnung von den Grundlagen der Datenverarbeitung zu haben... daher wohl die Fragen.

Im Übrigen wird es wohl viel einfacher, übersichtlicher, kürzer und performanter sein, einfach seriell 16 Slice-Abfragen zu proggen statt die Lösung umständlich in eine Schleife zu zwängen.

```
x_Bit0 := w_EingangsWort.x0 ;
x_Bit1 := w_EingangsWort.x1 ;
...
x_Bit15 := w_EingangsWort.x15 ;
```
oder falls TIA aus irgendeinem Grund das Slice nicht zuläßt, dann good old school ausmaskieren:

```
x_Bit0 := (w_EingangsWort AND 1) <> 0 ;
x_Bit1 := (w_EingangsWort AND 2) <> 0 ;
...
x_Bit15 := (w_EingangsWort AND 16#8000) <> 0 ;
```

Harald


----------



## hucki (29 April 2014)

RONIN schrieb:


> ```
> FOR #i_counter := 0 TO 13 DO
> #i_counter := i_counter + 1;
> END_FOR;
> ...


Der Code wird sicher nicht wie gedacht funktionieren.
Wenn BY nicht angegeben ist, wird immer BY 1 verwendet. Erhöht man die Variable noch selbst, entspricht das im obigen Beispiel BY 2.

Negative Richtungen sind möglich (ich weiß jetzt aber aus dem Kopf nicht, ob auch andere Werte als -1):


```
FOR i_counter:= 10 TO 1 BY -1 DO
...;

END_FOR;
```


----------



## hucki (29 April 2014)

hucki schrieb:


> Richtungen sind möglich (ich weiß jetzt aber aus dem Kopf nicht, ob auch andere Werte als -1):
> 
> 
> ```
> ...


Ein Besonderheit gibt's dabei. Wenn die Schleife von 1 nach 10 geht, hat die Variable am Ende den Wert 10.
Geht sie jedoch von 10 nach 1, hat sie nicht, wie anzunehmen, am Ende den Wert 1 sondern 0.

Über diese Falle bin ich bei der 4-gewinnt-Geschichte mit meinem Array-Index gestolpert.


PS: Die Schleifenausführung selbst ist davon aber nicht betroffen. Die wird letztmalig mit 1 gemacht.


----------



## 3njoyeD (29 April 2014)

Erstma vielen Dank für die vielen Antworten & die sehr guten Lösungsansätze.



PN/DP schrieb:


> ... und mit dem TIA kann man ja nun jede Aufgabe in  10 Minuten lösen ohne Ahnung von den Grundlagen der Datenverarbeitung zu  haben...
> 
> 
> 
> ...



Die Syntax von SCL ähnelt Java, aber sie ist leider nicht identisch.

Wenn ich viele Sprachmöglichkeiten habe & strukturierten Text sehe, bevorzuge ich ihn da man bei z.B. Berechnungen wesentlich weniger Zeilen/Netzwerke braucht, als in FUP oder KOP.

Dieser Code:


```
x_Bit0 := w_EingangsWort.x0 ;
x_Bit1 := w_EingangsWort.x1 ;
...
x_Bit15 := w_EingangsWort.x15 ;
```

Benötigt keine einzige temporäre Variable, ist für meine Zwecke völlig ausreichend & es gibt dabei keine umständlichen Vergleichswerte wie im Startbeitrag: 

Input:
- Variable "w_EingangsWort" Datentyp: Word
Output:
- x_Bit0 bis x_Bit15 Typ: Bool
Temp:
- Variable: "w_ZwischenSpeicher" Typ: Word
- Variable: "ui_"VergleichsWert" Typ: UInt

Aktuell zu diesem Thema keine weiteren Fragen.

Danke nochmal.


----------



## 3njoyeD (29 April 2014)

Erstmal vielen Dank für die vielen Antworten & die sehr guten Lösungsansätze.



PN/DP schrieb:


> ... und mit dem TIA kann man ja nun jede Aufgabe in  10 Minuten lösen ohne Ahnung von den Grundlagen der Datenverarbeitung zu  haben...
> 
> 
> 
> ...



Die Syntax von SCL ähnelt Java, aber sie ist leider nicht identisch.

Wenn ich viele Sprachmöglichkeiten habe & strukturierten Text sehe, bevorzuge ich ihn da man bei z.B. Berechnungen wesentlich weniger Zeilen/Netzwerke braucht, als in FUP oder KOP.

Dieser Code:


```
x_Bit0 := w_EingangsWort.x0 ;
x_Bit1 := w_EingangsWort.x1 ;
...
x_Bit15 := w_EingangsWort.x15 ;
```

Benötigt keine einzige temporäre Variable, ist für meine Zwecke völlig ausreichend & es gibt dabei keine umständlichen Vergleichswerte wie im Startbeitrag: 

Input:
- Variable "w_EingangsWort" Datentyp: Word
Output:
- x_Bit0 bis x_Bit15 Typ: Bool
Temp:
- Variable: "w_ZwischenSpeicher" Typ: Word
- Variable: "ui_"VergleichsWert" Typ: UInt

Aktuell zu diesem Thema keine weiteren Fragen.

Danke nochmal.


----------

