# Byte to Bool in SCL



## paula23 (29 Januar 2011)

Hallo Leute,

ich habe mal wieder ein SCL Problem,

Da ich PEBs verarbeite kann ich keine Bools verwenden ohne diese vorher zu zerlegen. Nun dachte ich mir ich kann das doch direkt im Baustein machen.

Heist ich würde nur noch ein Byte einlesen und die einzelnen Bits im Baustein verarbeiten. Wie zerlege ich das im SCL Code ?

Danke.


----------



## Larry Laffer (29 Januar 2011)

Hallo (nochmal) ...
Bei dieser Geschichte ist auch der AT-Befehl (wie in dem anderen Thread) die beste Vorgehensweise. Allerdings kannst du hier nicht auf Byte-Basis arbeiten sondern auf WORD-Basis - liegt an der Grundform der Speicherbelegung ... S7 will immer in Richtung WORD/INT als Grundlage.
Du könntest also eine AT-Sicht auf einen WORD oder eine Struktur aus 2 Byte als BOOL-Array (z.B) machen.

Das könnte dann z.B. so aussehen :
	
	



```
myVar1 : WORD ;
myVar2 AT myVar1 : struct 
                            Byte1 : byte ;
                            Byte2 : byte ;
                            end_struct ;
myVar3 AT myVar1 : array[0..15] of Bool ;

usw.
```
Du kannst hier nun, wie schon von Ralle in dem anderen Thread demonstriert, mittels myVar3 auf die einzelnen Bits des myVar1 zugreifen oder diese verändern.

Gruß
Larry


----------



## Thomas_v2.1 (29 Januar 2011)

Larry Laffer schrieb:


> Allerdings kannst du hier nicht auf Byte-Basis arbeiten sondern auf WORD-Basis - liegt an der Grundform der Speicherbelegung ... S7 will immer in Richtung WORD/INT als Grundlage.



Wie kommst du zu dieser Annahme dass eine AT-Sicht auf Byte nicht funktioniert, bzw. die Aussage mit WORD/INT als Grundlage?

```
b1 : BYTE;
a_b1 AT b1 : ARRAY[0..7] OF BOOL;
```
Funktioniert auf jeden Fall.


----------



## Larry Laffer (29 Januar 2011)

Hallo Thomas,
ich kann mir vorstellen, dass das sogar funktioniert was du da schreibst - gestestet habe ich es nicht. Ich wäre da aber sehr vorsichtig mit weiteren deklarierten Variablen weil wenn du nach deinem Byte ein weiteres Byte anlegst so wird es im Speicher nicht an der nächsten Word-Adresse sondern an der folgenden Byte-Adresse angelegt - und das kann dann (gerade in Verbindung mit AT) zu "lustigen" Effekten kommen.
Ergo ... geht möglicherweise ... ich halte mich da aber doch auch gerne an die "Spielreglen" und Besonderheiten von SCL.

Gruß
Larry


----------



## Bernard (29 Januar 2011)

*Byte nach Array of Bool*

Hallo allerseits,

anbei ein Link auf einen Threade der vor einiger Zeit lief.

http://www.sps-forum.de/showthread.php?p=237611#post237611

viel Grüße Bernard


----------



## Thomas_v2.1 (29 Januar 2011)

Larry Laffer schrieb:


> Ich wäre da aber sehr vorsichtig mit weiteren deklarierten Variablen weil wenn du nach deinem Byte ein weiteres Byte anlegst so wird es im Speicher nicht an der nächsten Word-Adresse sondern an der folgenden Byte-Adresse angelegt



Wenn das erste Byte z.B. in den Lokaldaten an Adresse 0.0 angelegt wird, wo sollte denn eine zweite Variable vom Typ Byte deiner Meinung nach angelegt werden, wenn nicht an Adresse 1.0? Du legst doch nicht wenn du in AWL programmierst ein Reservebyte dazwischen, oder doch?


----------



## Larry Laffer (29 Januar 2011)

@Thomas:
Manchmal habe ich schwer das Gefühl, ihr wollt mich nicht verstehen ... 

Nein ... ich lege da kein Reserve-Byte dazwischen. Das ist auch nicht das, was ich meinte ...
Sowohl deine "b1" wie auch deine "a_b1" verwenden trotz anders lautender Deklaration vom Speicher erst mal ein WORD. Was ich meinte ist : wenn hinter deiner b1 noch eine b2 gleichen Typs (also auch Byte) unmittelbar dahinter deklariert wird, so ist sie ggf. mit in dem Zugriffsbereich der a_b1. Ich habe da jetzt leider keine Möglichkeit, das zu testen - werde ich aber alsbald mal nachholen. Was passiert da also mit b2 ?
Aber vielleicht nimmt ja vor Montag (eher kann ich nicht) noch Einer den Ball auf - das würde mich jetzt nämlich selbst interessieren ...

Gruß
Larry


----------



## paula23 (29 Januar 2011)

Ich danke euch, ich denke das wird helfen.


----------



## Thomas_v2.1 (29 Januar 2011)

Larry Laffer schrieb:


> @Thomas:
> Manchmal habe ich schwer das Gefühl, ihr wollt mich nicht verstehen ...
> 
> Nein ... ich lege da kein Reserve-Byte dazwischen. Das ist auch nicht das, was ich meinte ...
> Sowohl deine "b1" wie auch deine "a_b1" verwenden trotz anders lautender Deklaration vom Speicher erst mal ein WORD. Was ich meinte ist : wenn hinter deiner b1 noch eine b2 gleichen Typs (also auch Byte) unmittelbar dahinter deklariert wird, so ist sie ggf. mit in dem Zugriffsbereich der a_b1. Ich habe da jetzt leider keine Möglichkeit, das zu testen - werde ich aber alsbald mal nachholen. Was passiert da also mit b2 ?



Das ist auch schwer zu verstehen. Vor allem, wenn der Fragesteller ein BYTE! in 8 Bits zerlegen will, du in deinem ersten Beispiel mit Word und Structs um die Ecke kommst.

Alle elementaren Datentypen die größer/gleich 2 Byte sind, sowie zusammengesetzte Datentypen wie Strukturen, UDT, Arrays etc. fangen im Speicher immer auf einer geraden Adresse an.
Inwiefern diese "Lücke" im Speicher die sich manchmal ergibt, und einer AT-Sicht auf eine Variable vor dieser Lücke Probleme bereiten soll ist mir schleierhaft.


----------



## Larry Laffer (29 Januar 2011)

Thomas_v2.1 schrieb:


> Das ist auch schwer zu verstehen. Vor allem, wenn der Fragesteller ein BYTE! in 8 Bits zerlegen will, du in deinem ersten Beispiel mit Word und Structs um die Ecke kommst.



Wenn du es nicht verstanden hast ... kein Problem ... ich erkläre es dir gerne noch einmal ...
Was war unklar ?


----------



## Azrael666 (4 Mai 2017)

Hallo Leute, 

ich kram mal dieses ältere Thema raus, da ich gerade an dem selben Problem sitze. Das ist aktuell mein Code, nur leider scheint da irgendwas nicht so ganz zu funktionieren:


```
FUNCTION BYTE_TO_BIT : VOID // FC 683
TITLE   = 'Version 3.0.00'
VERSION : '3.0'
AUTHOR  : 
NAME    : BYTOB
FAMILY  : BYTOB


VAR_INPUT
    InByte :   BYTE;
END_VAR


VAR_OUTPUT
    BIT_0 :    BOOL;
    BIT_1 :    BOOL;
    BIT_2 :    BOOL;
    BIT_3 :    BOOL;
    BIT_4 :    BOOL;
    BIT_5 :    BOOL;
    BIT_6 :    BOOL;
    BIT_7 :    BOOL;
END_VAR


VAR_TEMP
    TempByte : BYTE;
    TempBool AT TempByte : ARRAY[0..7] OF BOOL;
END_VAR


TempByte := InByte;


BIT_0 := TempBool[0];
BIT_1 := TempBool[1];
BIT_2 := TempBool[2];
BIT_3 := TempBool[3];
BIT_4 := TempBool[4];
BIT_5 := TempBool[5];
BIT_6 := TempBool[6];
BIT_7 := TempBool[7];


END_FUNCTION
```

Hat jemand vielleicht eine Idee?

MFG


----------



## hucki (4 Mai 2017)

Welche CPU?

Bei 1200/1500 muss entweder die standardmäßige Optimierung des Bausteins deaktiviert werden oder besser statt der Sicht den Slicezugriff, z.B. BIT_0 := InByte.x0, verwenden, dann kann der FC optimiert bleiben und die Temp-Variablen entfallen.


----------



## Azrael666 (4 Mai 2017)

Ups sorry,

ne kein TIA Portal. Ganz Oldschool Simatic V5.5
CPU ne alte 315-2 DP

Slicezugriff funktioniert hier nicht.


----------



## Larry Laffer (4 Mai 2017)

Ohne es ausprobiert zu haben würde ich sagen, dass dein AT-Befehl hier nicht so ganz sauber läuft. Versuch mal den AT auf ein Array [0..15] of BOOL laufen zu lassen und die Bits 8 .. 15 zu benutzen ...

Gruß
Larry


----------



## Azrael666 (4 Mai 2017)

Wenn ich das wie folgt ändere:


```
TempBool AT TempByte : ARRAY[0..15] OF BOOL;
```

kann ich nicht mehr kompilieren. 
Fehler: "Der Typ der Sicht ist nicht mit dem Typ der Variablen verträglich"

@Larry: deine Variante von hier Byte to Bool in SCL mit dem WORD hab ich auch schon versucht, funktioniert leider auch nicht.


----------



## JesperMP (4 Mai 2017)

Es funktioniert nicht mit 1 Byte, den AT muss ein mindestens Umfang von 2 Bytes haben.

Probier mal so:

```
VAR_TEMP
   Temp_struct: STRUCT
      byte_0 : BYTE ;
      byte_1 : BYTE ;
   END_STRUCT;
   Temp_bool AT Temp_struct : ARRAY[0..15] OF BOOL ;

...

Temp_struct.byte_1 := input_byte ;

BIT_00 := Temp_bool[8] ;
BIT_01 := Temp_bool[9] ;

....
```
Nicht getestet !


----------



## Azrael666 (4 Mai 2017)

@JesperMP:

habs umgebaut. Sieht jetzt so aus : 


```
VAR_TEMP    
Temp_Struct : STRUCT
        Byte_0  : BYTE;
        Byte_1  : BYTE;
    END_STRUCT;
    
    TempBool AT Temp_Struct : ARRAY[0..15] OF BOOL;
END_VAR


Temp_Struct.Byte_1 := InByte;


BIT_0 := TempBool[8];
BIT_1 := TempBool[9];
BIT_2 := TempBool[10];
BIT_3 := TempBool[11];
BIT_4 := TempBool[12];
BIT_5 := TempBool[13];
BIT_6 := TempBool[14];
BIT_7 := TempBool[15];
```

funktioniert leider auch nicht.


----------



## Larry Laffer (4 Mai 2017)

@Jesper:
So, wie du es beschreibst wird es funktionieren ... daran habe ich nicht gedacht ...


----------



## JesperMP (4 Mai 2017)

Ich ein ähnliche Program wo es funktioniert.

Vielleicht
Temp_struct.byte_0 := InByte ;


----------



## Larry Laffer (4 Mai 2017)

Probier mal mir der Zuweisung auf Temp_Struct.Byte0 ... (ohne die Indexe von TempBool zu ändern)


----------



## Azrael666 (4 Mai 2017)

Ähm so, aktueller Status. Es funktioniert. Ich hatte einen kleinen dummen Fehler bei der Verwendung des Bausteins. 

Also hier ist der Code, so wie es funktioniert:


```
FUNCTION BYTE_TO_BIT : VOID // FC 683
TITLE   = 'Version 3.0.00'
VERSION : '3.0'
AUTHOR  : 
NAME    : BYTOB
FAMILY  : BYTOB


VAR_INPUT
    InByte :   BYTE;
END_VAR


VAR_OUTPUT
    BIT_0 :    BOOL;
    BIT_1 :    BOOL;
    BIT_2 :    BOOL;
    BIT_3 :    BOOL;
    BIT_4 :    BOOL;
    BIT_5 :    BOOL;
    BIT_6 :    BOOL;
    BIT_7 :    BOOL;
END_VAR


VAR_TEMP
    Temp_Struct : STRUCT
        Byte_0  : BYTE;
        Byte_1  : BYTE;
    END_STRUCT;
    
    TempBool AT Temp_Struct : ARRAY[0..15] OF BOOL;
END_VAR


Temp_Struct.Byte_0 := InByte;


BIT_0 := TempBool[0];
BIT_1 := TempBool[1];
BIT_2 := TempBool[2];
BIT_3 := TempBool[3];
BIT_4 := TempBool[4];
BIT_5 := TempBool[5];
BIT_6 := TempBool[6];
BIT_7 := TempBool[7];


END_FUNCTION
```

Btw: Falls noch jemand dieser "Fehler" bei der Verwendung des Codebausteines in KOP passiert. An die Ausgänge nicht immer die selbe temporäre Variable schreiben!!

@Larry und @ JesperMP : Vielen Dank für die Hilfe!!!


----------



## JesperMP (4 Mai 2017)

Eigentlich wundert es mich das die bits nicht mit 1 Byte versetzt sind wegen "Big Endian".
Aber diese Little/Big Endian Geschickte wird nie natürlich für mich.
Gut dass es geklappt hat !


----------



## PN/DP (4 Mai 2017)

JesperMP schrieb:


> Eigentlich wundert es mich das die bits nicht mit 1 Byte versetzt sind wegen "Big Endian".


Die sind deshalb nicht versetzt weil TempBool ein ARRAY OF BOOL ist. Wenn TempBool oder Temp_Struct ein Word wäre, dann würde sich Big Endian auswirken.

Harald


----------

