# Bool-Array in Byte-Array



## Techniker (15 Dezember 2005)

Hallo,

ich hab ein kleines Problem mit einem Bool-Array. Ich wollte die Werte 
eines Bool-Arrays in ein Byte-Array transferieren. Da aber ein Bool intern
den Speicher von der Größe eines Bytes belegt, ist das etwas schwieriger.

z.B.: Testbool ARRAY[1..80] of BOOL
              Testbyte ARRAY[1..10] of BYTE

Von Hand zu Fuss ist das kein Problem:

Testbyte[9].7:= Testbool[72];

aber das ganze sollte natürlich automatisch ablaufen in einem FB, wo ich 
nur noch Quelle, Ziel und Anzahl eingebe.

Programmiersoftware:XSoft 2.3.3 (Codesys)

Für ein paar Denkanstösse bin ich sehr Dankbar.


Schöne Grüße


----------



## HeizDuese (15 Dezember 2005)

> z.B.: Testbool ARRAY[1..80] of BOOL
> Testbyte ARRAY[1..10] of BYTE
> 
> Von Hand zu Fuss ist das kein Problem:
> ...




*So vielleicht ? :*


VAR i: INT;
      Testbyte: ARRAY[1..80] OF BYTE;
      Testbool: ARRAY[1..80] OF BOOL;
END_VAR


FOR i := 1 TO 80 DO
     Testbyte_ := BOOL_TO_BYTE(Testbool);
END_FOR_


----------



## Techniker (15 Dezember 2005)

Zitat:


> VAR i: INT;
> Testbyte: ARRAY[1..80] OF BYTE;
> Testbool: ARRAY[1..80] OF BOOL;
> END_VAR
> ...


_

Nein, so bestimmt nicht. 
So belegt ja jedes einzelne Bit ein ganzes Byte!
Das wäre nicht Sinn der Sache.

Hier mal ein kleiner Ausschnitt aus meinen Überlegungen:


		Code:
	

VAR_INPUT
	pBool_array		: DWORD;		(* Adresse des Bool-Arrays *)
	pByte_array		: DWORD;		(* Adresse des Byte-Arrays *)
	iwOffset_Bool		: UINT;			(* Ab diesem Element soll kopiert werden *)
	iwOffset_Byte		: UINT;
	iwBool_Anzahl	: UINT;			(* Anzahl der Elemente, die kopiert werden sollen *)
END_VAR
VAR_OUTPUT
END_VAR
VAR
	pt_Bool		: POINTER TO  BOOL;
	pt_Byte		: POINTER TO  BYTE;
	index			: UINT;
	Hilfsbit				: BOOL;
	Hilfsbyte			: BYTE;
END_VAR



(* Adresse des Bool- und Byte-Array an Pointer übergeben *)
pt_Bool:= pBool_array + iwOffset_Bool;
pt_Byte:= pByte_array + iwOffset_Byte;


Hilfsbyte:= pt_Byte^;

(* Elemente des Bool-Array abfragen (nur soviele wie in der Anzahl steht, vom Offset an *)
	FOR index:= iwOffset_Bool TO iwOffset_Bool + iwBool_Anzahl - 1  DO

		Hilfsbit:= pt_Bool^;
(*		Hilfsbyte:= pt_Byte^; *)

		(* Wert an die richtige Bitposition im Byte schieben und mit dem alten Bytewert verknüpfen *)
	IF Hilfsbit THEN
		Hilfsbyte:= Hilfsbyte OR SHL(1, index - iwOffset_Bool MOD 8);
	ELSE
		Hilfsbyte:= Hilfsbyte AND NOT SHL(1,index - iwOffset_Bool MOD 8);
	END_IF;
	(* Neue Adresse berechnen (Pointermanipulation)*)
	pt_Bool:= pt_Bool + 1;
	IF (index  MOD 8) = 0 THEN
		IF index - iwOffset_Bool > 0 THEN
			pt_Byte:= pt_Byte + 1;
		END_IF
	END_IF;
END_FOR;


Das Auswerten der einzelnen Bits und "packen" in ein Byte funktioniert
prima. Nur das Beschreiben des Zieles ist ein Problem. Der Baustein 
soll universal einsetzbar sein, und Somit keine festen Array-Grenzen als
Ein-oder Ausgänge haben. Quelle und Ziel sollen über Pointer adressiert
werden._


----------



## volker (15 Dezember 2005)

ohne mir deinen code jetzt genauer anzusehen.

du kannst das bool array doch ohne problem byte,word,dword weise ansprechen.

nehmen wir an dein array beginnt bei dbx0.0
wenn du nun schreibst 
L DBB 0
lädst du die ersten 8 bit des arrays.


----------



## Techniker (15 Dezember 2005)

> nehmen wir an dein array beginnt bei dbx0.0
> wenn du nun schreibst
> L DBB 0
> lädst du die ersten 8 bit des arrays.



Ich bin hier aber in diesem Fall leider nicht in der Siemens-Welt:



> Programmiersoftware:XSoft 2.3.3 (Codesys)


----------



## volker (15 Dezember 2005)

ok. das hab ich oben überlesen.


----------



## HeizDuese (15 Dezember 2005)

Nun ja, die gewünschte Variante birgt auch Risiken (das in undefinierten Bereichen geschrieben wird).

Hier noch eine andere Variante mit statischen Array-Grenzen, die den Zweck ansonsten erfüllt:

*
(* ======= Variablendeklaration ======== *)

VAR i,j: INT;
          b: BYTE;
	TestByte: ARRAY[1..10] OF BYTE;
	TestBool: ARRAY[1..80] OF BOOL;

	Muster: BYTE;
END_VAR




(* =======       Programm     ======== *)

FOR i := 0 TO 9 DO  (* Anzahl Bytes = 10 *)
	b := 0;
 	FOR j := 0 TO 7 DO  (* Anzahl Bits je Byte =  8 *)
  		Muster := INT_TO_BYTE(SHL(1, j));
  		IF Testbool[(i * 8) + j + 1] THEN
   			b := b OR Muster;
 		END_IF
	END_FOR (* j *)
	Testbyte[i + 1] := b;
END_FOR (* i *)*


----------



## Techniker (15 Dezember 2005)

```
(* ======= Variablendeklaration ======== *)

VAR i,j: INT;
b: BYTE;
TestByte: ARRAY[1..10] OF BYTE;
TestBool: ARRAY[1..80] OF BOOL;

Muster: BYTE;
END_VAR




(* ======= Programm ======== *)

FOR i := 0 TO 9 DO (* Anzahl Bytes = 10 *)
b := 0;
FOR j := 0 TO 7 DO (* Anzahl Bits je Byte = 8 *)
Muster := INT_TO_BYTE(SHL(1, j));
IF Testbool[(i * 8) + j + 1] THEN
b := b OR Muster;
else
b := b and not Muster; <==
END_IF
END_FOR (* j *)
Testbyte[i + 1] := b;
END_FOR (* i *)
```


Das ist soweit ok. Das Rücksetzen des Bit hab ich noch eingefügt.
Aber so bin ich natürlich nicht flexibel. Ich hab 2 verschieden große
Array's und die sollen dann ab einem bestimmten Offset des Byte-Array's
eingefügt werden.

Mfg


----------



## HeizDuese (15 Dezember 2005)

Das rücksetzen ist nicht nötig, da *b* bei jedem Neustart der inneren (FOR j :=) - Schleife auf 0 gesetzt wird!

Wenn man statt *b := 0* geschrieben hätte: *b := Testbyte[i + 1];*
müsste man tatsächlich diesen AND NOT - Part einfügen.


----------



## Maxl (6 Januar 2006)

Gibts da keine fertige Library-Funktion dafür??

Zumindest bei B&R gibts sowas schon fertig.....


----------



## Techniker (13 Januar 2006)

@ Maxl

Wie heißt denn die Library bei B&R?
Das würde mich jetz mal interessieren....


----------

