Zugriff auf einen UDT / Array mit Variablen?

Zuviel Werbung?
-> Hier kostenlos registrieren
Ja danke, jetzt läuft der Simulator, aber die beiden For-Schleifen werden jetzt
nicht mehr bearbeitet
REPEAT
FOR index1 := 6 TO 0 BY -1 DO
FOR index2 := 6 TO 0 BY -1 DO
index3 := index3+1;
sortierpuffer[index3]:= Matrizze[index1,index2];
END_FOR;
END_FOR;
UNTIL index3>=49
END_REPEAT;
und die Matrizzenwerte bewegen sich nach kurzer Zeit so um die 50 bis 100 (Zufallszahl bei jedem Zyklus)
aber müssten die durch die Vektorisierung nicht deutlich höher sein.
 
Ich denke schon, dass die "FOR..TO"-Schleifen bearbeitet werden ...

Meinst du nicht, dass ich es mittlerweile verdient hätte, mal dein ganzes SCL-Script zu sehen ? Vielleicht hast du ja noch irgendwo eine nette kleien Gemeinheit versteckt ...;)

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo, die Forschleifen wurden nicht abgezählt,
jetzt habe ich die erste Forschleife durch eine While-Schleife ersetzt
jetzt geht der Simulator wieder un Stopp (Bereichslängenfehler)

FUNCTION_BLOCK FB1
var_input
zahl : DINT;
Takt,Sortieren,sort : BOOL;
END_VAR
VAR_TEMP
shrhilf1: DWORD;
shrhilf2: DWORD;
index3 : INT;
index4 : DINT;
index5 : DINT;
hilfs: DINT;
tauschen:BOOL;
puffer1,puffer2:DWORD;
END_VAR
VAR
Matrizze : ARRAY[0..6,0..6] OF DINT;
sortierpuffer : ARRAY[0..48]OF DINT;
index1 : INT;
index2 : INT;
hilf: BOOL:=false ;
flanke:BOOL:=false;
END_VAR
BEGIN
IF Takt=true then
IF hilf = false THEN
hilf:= true;
ELSE
hilf:=false;
END_IF;
IF hilf = true THEN
index1:=DINT_TO_INT(zahl);
ELSE
index2:=DINT_TO_INT(zahl);
IF Matrizze[index1,index2] = 0 THEN
index4:=INT_TO_DINT(index1);
index5:=INT_TO_DINT(index2);
shrhilf1:=DINT_TO_DWORD(index4);
shrhilf2:=DINT_TO_DWORD(index5) ;
Matrizze[index1,index2]:=DWORD_TO_DINT(SHR(in:=shrhilf1, N:=16)
OR SHR(in:=shrhilf2, N:=24));
END_IF;
Matrizze[index1,index2]:=Matrizze[index1,index2] +1;
index1:=index2;
hilf:=true;
END_IF;
END_IF;
IF Sortieren=true then
index3:=49;
index1:= 7;
WHILE index1 >= 0 DO
index1:=index1-1;
FOR index2 := 6 TO 1 BY -1 DO
index3 := index3-1;
sortierpuffer[index3]:= Matrizze[index1,index2];
END_FOR;
END_WHILE;
END_IF;
IF sort=true THEN
REPEAT
tauschen:= false;
FOR index3:=48 TO 1 BY -1 DO
puffer1:=DINT_TO_DWORD(sortierpuffer[index3]);
puffer2:=DINT_TO_DWORD(sortierpuffer[index3-1]);
sortierpuffer[index3]:= DWORD_TO_DINT(puffer1 AND 16#0000FFFF);
sortierpuffer[index3-1]:= DWORD_TO_DINT(puffer2 AND 16#0000FFFF);
IF sortierpuffer[index3-1] > sortierpuffer[index3] THEN
sortierpuffer[index3-1]:=DWORD_TO_DINT(puffer1);
sortierpuffer[index3]:= DWORD_TO_DINT(puffer2);
tauschen:= true;
ELSE sortierpuffer[index3]:= DWORD_TO_DINT(puffer1);
sortierpuffer[index3-1]:=DWORD_TO_DINT(puffer2);
END_IF;
END_FOR;
UNTIL NOT tauschen
END_REPEAT;
END_IF;

End_function_block
 
... ich mußte ein bißchen suchen ... aber wieder der gleiche Fehler :
Code:
WHILE index1 [B][COLOR=red]>= 0[/COLOR][/B] DO
[COLOR=red][B]index1:=index1-1[/B][/COLOR];
FOR index2 := 6 TO 1 BY -1 DO 
index3 := index3-1; 
sortierpuffer[index3]:= Matrizze[index1,index2]; 
END_FOR;
END_WHILE;
index1 kann kleiner als "0" werden ...
Das ist in deinem ARRAY nicht definiert ...

Ich würde hier aber auf jeden Fall bei Schleifen bleiben und die indexe nicht einfach nur inkrementieren oder dekrementieren, sondern ausrechnen :
Code:
Index3 := Index2 + Index1 * 7 ;
Ist aber nur ein Vorschlag ...

Gruß
LL
 
Außerdem wären Einrückungen in deinem Code und Codetags hier im Forum nicht schlecht, das sieht dann so aus:

Code:
FUNCTION_BLOCK FB1

var_input
  zahl: DINT;
  Takt,Sortieren,sort: BOOL;
END_VAR

VAR_TEMP
  shrhilf1: DWORD;
  shrhilf2: DWORD;
  index3: INT;
  index4: DINT;
  index5: DINT;
  hilfs: DINT;
  tauschen: BOOL;
  puffer1,puffer2: WORD;
END_VAR

VAR
  Matrizze: ARRAY[0..6,0..6] OF DINT;
  sortierpuffer: ARRAY[0..48]OF DINT;
  index1: INT;
  index2: INT;
  hilf: BOOL:=false ;
  flanke: BOOL:=false;
END_VAR

BEGIN

IF Takt=true then
  IF hilf = false THEN
    hilf:= true;
  ELSE
    hilf:=false;
  END_IF;
  IF hilf = true THEN
    index1:=DINT_TO_INT(zahl);
  ELSE
    index2:=DINT_TO_INT(zahl);
    IF Matrizze[index1,index2] = 0 THEN
      index4:=INT_TO_DINT(index1);
      index5:=INT_TO_DINT(index2);
      shrhilf1:=DINT_TO_DWORD(index4); 
      shrhilf2:=DINT_TO_DWORD(index5) ;
      Matrizze[index1,index2]:=DWORD_TO_DINT(SHR(in:=shrhilf1, N:=16) OR SHR(in:=shrhilf2, N:=24));
    END_IF;
    Matrizze[index1,index2]:=Matrizze[index1,index2] + 1;
    index1:=index2;
    hilf:=true;
  END_IF;
END_IF;

IF Sortieren=true then
  index3:=49;
  index1:= 7;
  WHILE index1 >= 0 DO
    index1:=index1-1;
    FOR index2 := 6 TO 1 BY -1 DO
      index3 := index3-1;
      sortierpuffer[index3]:= Matrizze[index1,index2];
    END_FOR;
  END_WHILE;
END_IF;

IF sort=true THEN
  REPEAT
    tauschen:= false;
    FOR index3:=48 TO 1 BY -1 DO
      puffer1:=DINT_TO_DWORD(sortierpuffer[index3]);
      puffer2:=DINT_TO_DWORD(sortierpuffer[index3-1]);
      sortierpuffer[index3]:= DWORD_TO_DINT(puffer1 AND 16#0000FFFF);
      sortierpuffer[index3-1]:= DWORD_TO_DINT(puffer2 AND 16#0000FFFF);
      IF sortierpuffer[index3-1] > sortierpuffer[index3] THEN
        sortierpuffer[index3-1]:=DWORD_TO_DINT(puffer1);
        sortierpuffer[index3]:= DWORD_TO_DINT(puffer2);
        tauschen:= true;
      ELSE 
        sortierpuffer[index3]:= DWORD_TO_DINT(puffer1);
        sortierpuffer[index3-1]:=DWORD_TO_DINT(puffer2);
      END_IF;
    END_FOR;
  UNTIL NOT tauschen
  END_REPEAT;
END_IF;

End_function_block
 
Zuviel Werbung?
-> Hier kostenlos registrieren
danke, ich wollte noch fragen wie man einen DB in der Variablentabelle beobachtet bei mir zeigt es immer nur ungültiger Operand an.
Kann man einen ARRAY Wert auch auf ein MW oder AW legen.
 
DB beobachten geht genauso wie bei den anderen Variablen ...
Du schreibst in das Variablen-Feld z.B. "DB100.DBW10" ... geht auch bei einem I-DB ...
 
Hallo ich habe nochmal ein Problem, jetzt habe ich das Programm noch etwas umgeändert, Ausrechnen der prozentzualen Abweichung vom Mittelwert, und schreiben in einen DB, es zeigt jetzt wieder Bereichslängenfehler an
kann das mit den Negativen Werten zusammenhängen.


IF zaehler=5000 THEN
mittelwert:=5000/49;
index3:=0;
FOR index1 := 7 TO 2 BY -1 DO
FOR index2 := 7 TO 2 BY -1 DO
index3 := index3+1;
sortierpuffer1[index3]:=DINT_TO_DWORD(matrizze[index1,index2]);
sortierpuffer[index3]:=DWORD_TO_DINT(sortierpuffer1[index3] AND 16#0000FFFF);
sortierpuffer[index3]:=REAL_TO_DINT((DINT_TO_REAL(sortierpuffer[index3])-mittelwert/mittelwert)*100);
sortierpuffer[index3]:=DWORD_TO_DINT(SHR(IN:=((DINT_TO_DWORD(sortierpuffer[index3]))AND 16#F0000000),N:=16)
OR sortierpuffer1[index3] AND 16#FF000000);
WORD_TO_BLOCK_DB(5).DD[index3*4]:=DINT_TO_DWORD(sortierpuffer[index3]);
END_FOR;
END_FOR;
zaehler:=0;
END_IF;

END_FUNCTION_BLOCK
 
Zuviel Werbung?
-> Hier kostenlos registrieren
...an welcher Stelle in deinem Konstrukt entsteht den der Bereichslängenfehler ...? Das wäre vielleicht interessant zu wissen ...

Ansonsten ... wie groß sind denn die ARRAY's dimensioniert ? Das sollte man bei so etwas IMMER mit angeben. Einen negativen Index sehe ich erstmal nicht ...

Gruß
LL
 
danke für die schnelle Antwort, Bausteinadresse 148,instanz-DB Doppelwort- Zugriff , Zugriffsadresse 0.
Wie zählt man denn die Bausteinadresse, ist das Schieben des Vorzeichenbits
richtig
 
Hallo,
die Diagnose bringt dich auf Wunsch genau in die richtige Zeile (Baustein öffnen). In dem Fall würde ich aufgrund der Fehlermeldung aber auf die folgende Zeile tippen :
Code:
WORD_TO_BLOCK_DB(5).DD[index3*4]:=DINT_TO_DWORD(sortierpuffer[index3]);
Ist der DB5 den groß genug dimensioniert ? Gibt es darin mindestens 49 Doppelworte ? Das ist aber Spekulation (Meldung Instanz-DB ...).

Bitte teile doch noch die Deklaration deiner ARRAY's mit ...

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ist deine Variable Matrizze immer noch so definiert?

Code:
Matrizze : ARRAY[0..6,0..6] OF DINT;

In der Hilfe steht:

Beim Start der Schleife wird die Laufvariable auf den Startwert (Anfangszuweisung) gesetzt und nach jedem Schleifendurchlauf um die angegebene Schrittweite erhöht (positive Schrittweite) oder erniedrigt (negative Schrittweite), solange bis der Endwert erreicht ist.

Das würde dann heißen, beim ersten Schleifendurchlauf könnte es schon krachen, da Index1 und Index2 da auf 7 stehen.
 
Hallo,
die Diagnose bringt dich auf Wunsch genau in die richtige Zeile (Baustein öffnen). In dem Fall würde ich aufgrund der Fehlermeldung aber auf die folgende Zeile tippen :
Code:
WORD_TO_BLOCK_DB(5).DD[index3*4]:=DINT_TO_DWORD(sortierpuffer[index3]);
Ist der DB5 den groß genug dimensioniert ? Gibt es darin mindestens 49 Doppelworte ? Das ist aber Spekulation (Meldung Instanz-DB ...).

Bitte teile doch noch die Deklaration deiner ARRAY's mit ...

Gruß
LL

Und ist dein DB5 etwa dein Instanz-DB oder was ist das für einer? Die Fehlermeldung moniert ja den Zugriff auf den Instanz-DB.
 
da war ein Zeitstempel Konflikt mit dem IB, die ARRAYS habe ich umgeändert die stimmen, die Prozentberechnung geht nicht, es kommt 0 raus
also im sortierpuffer1 stehen nur die Vektoren, wie dimensioniert man einen
DB (global) muß man da die 100 Werte von Hand eingeben,
vielen Dank
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Was genau, soll das bewirken?

Code:
sortierpuffer[index3]:=DWORD_TO_DINT(SHR(IN:=((DINT_TO_DWORD(sortierpuffer[index3]))AND 16#F0000000),N:=16)

Global-DB:

1. von Hand
2. Array[1..100] of DInt
3. Array[1..100] of UDT1, wobei UDT1 eine Struktur oder eine beliebige Anordnung von Daten enthalten kann.
 
Zuletzt bearbeitet:
Das Verschieben des Vorzeichenbits, da ja nur die die ersten beiden Bytes
den Zahlenwert angeben und die oberen Bytes je ein Byte ein Vektor.
 
Aber dieser Teil hier:
Code:
((DINT_TO_DWORD(sortierpuffer[index3]))AND 16#F0000000)

sorgt doch dafür, daß nur noch 4 Bit da sind, die schiebst du dann 16 nach rechts. Ist das so gewollt?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja weil ich verknüpfe ja diesen Teil noch zweimal mit ODER( mit den Vektorenwerten und dem Zahlenwert)
und das war der Fehler ich habe wieder AND mit OR verwechselt und den Zahlenwert ganz vergessen,
die oberen 4 Bit sind doch nur mit dem Vorzeichenbit besetzt.
na ja, jetzt hab ich solange rumgebastelt bis mir die Geduld abhanden gekommen ist, aber wer suchet der findet
 
Zuletzt bearbeitet:
Ja danke der Nachfrage, ich habe jetzt die negativen Zahlen mit der 2er-komplementärbildung und dem Setzen des Vorzeichen Bits hinbekommen,
nun wollte ich noch fragen ob man ein Array auch Löschen kann, denn ich will alle 5000 Zyklen auswerten:

modul:=zaehler MOD 5000;
IF modul= 0 THEN
hilf3:=DINT_TO_REAL(zaehler);
mittelwert:=hilf3/49;
index3:=0;
FOR index1 := 7 TO 2 BY -1 DO
FOR index2 := 7 TO 2 BY -1 DO
index3 := index3+1;
hilf1:=DINT_TO_DWORD(matrizze[index1,index2]);
hilf2:=(hilf1 AND 16#0000FFFF);
hilf4:=DWORD_TO_DINT(hilf2);
hilf3:=DINT_TO_REAL(hilf4);
IF hilf3<mittelwert THEN
v_zeichen:=true;
hilf4:=REAL_TO_DINT(((mittelwert-hilf3)/mittelwert)*100);
hilf2:=DINT_TO_DWORD(hilf4+1); // +1 zur Ergänzung des 2er komplements
hilf2:=(NOT hilf2) AND 16#0000FFFF; //Komplementärbildung
sortierpuffer[index3]:=DWORD_TO_DINT(hilf2 OR (hilf1 AND 16#FFFF0000)
OR 2#1000000000000000); //setzen des Vorzeichenbits
puffer1:=hilf4;
ELSE
v_zeichen:=false;
hilf4:=REAL_TO_DINT(((hilf3-mittelwert)/mittelwert)*100);
hilf2:=DINT_TO_DWORD(hilf4);
sortierpuffer[index3]:=DWORD_TO_DINT(hilf2 OR hilf1 AND 16#FFFF0000);
puffer2:=hilf4;
END_IF;

WORD_TO_BLOCK_DB(5).DD[index3*4]:=DINT_TO_DWORD(sortierpuffer[index3]);
END_FOR;
END_FOR;
zaehler:=0;
END_IF;

END_FUNCTION_BLOCK


 
Zuletzt bearbeitet:
Zurück
Oben