Lösungsmöglichkeit

Zuviel Werbung?
-> Hier kostenlos registrieren
Also z.B. Wert1=1 und Wert2=3 =>Lampe3
Wert1=2 und Wert2=1=>Lampe11

Daraus ergibt sich für mich die folgende Berechnung der Lampen-Nr.:
(Wert1-1) * 10 + Wert2
Wenn Wert1 = 1...100 ist und Wert2 = 0...9, dann kann man damit 1000 Lampen ansprechen.

Damit ergibt sich dann der folgende Code für die Lampen:
Code:
U DB100.dbx3.0 // 1 im Byte 3
FP M 0.1 // pos. Flanke "Lampe an"
 
U DB100.dbx3.0 // 1 im Byte 3
FN M 0.0 // pos. Flanke "Lampe aus"
 
UN M0.0
UN M0.1
SPB WEIT
 
L DB100.DBB1 // Wert1
+ -1
L 10
*I
L DB100.DBB2 // Wert2
+I
T MW 2 // Nummer der Lampe
 
L MW 2
L 8
/I
T MW 4 // ByteNummer
 
L MW2
MOD 8
T MW 6 // BitNummer
 
L MW 4
SLD 3
L MW 6
+D   // Pointer bestehend aus Byte.Bit
LAR1 // isn Adressregister
 
U DB100.DBX3.0 // Lampe (1=AN, 0=AUS)
AUF DB 200
= DBX[AR1,p#0.0] // Bit Lampe zuweisen
 
WEIT: NOP 0

Ich hoffe es hilft Dir weiter (und ich hab' keine Fehler drin).

Grüße
Gebs

[EDIT]
Hab' doch ein paar Fehler drin gehabt.
[/EDIT]
 
Zuletzt bearbeitet:
statt der modulo-operation gefällt mir das hier besser:

Code:
*
      L     #iBitNumber
      L     8
      /I    
      T     #dTemp

      L     P##dTemp
      LAR1  

      L     W [AR1,P#2.0]
      SLD   3
      L     W [AR1,P#0.0]
      +D    
      LAR1  

      AUF   #DbByNumber
      U     #xSet
      S     DBX [AR1,P#0.0]
 
..SCL habe ich leider nicht :(
Das ist schade. In SCL würde es sich mit einem zweidimesionalem Array schön einfach gestalten. In AWL ist es auf diese Art etwas schwieriger. Man müsste den Code in AWL zumindest noch etwas kommentieren.

SCL
Code:
FUNCTION TAUSENDLAMPEN : void
VAR_INPUT
   WERT_A                      : INT; // 1..10
   WERT_B                      : INT; // 1..100
   WERT_C                      : INT; 
END_VAR
VAR_IN_OUT
   LAMPE                       : ARRAY[1..10, 1..100] OF BOOL;
END_VAR
BEGIN
  IF WERT_A < 1 OR WERT_A > 10 OR WERT_B < 1 OR WERT_B > 100
    THEN RETURN;
  END_IF;
  IF WERT_C = 1 THEN
      LAMPE[WERT_A, WERT_B] := true;
  END_IF;
  IF WERT_C = 0 THEN
      LAMPE[WERT_A, WERT_B] := false;
  END_IF;
END_FUNCTION

übersetzer Code in AWL
Code:
      SET   
      SAVE  
      =     L      0.1
      L     #WERT_A
      L     1
      <I    
      L     #WERT_A
      L     10
      =     L      0.2
      >I    
      O     L      0.2
      L     #WERT_B
      L     1
      =     L      0.2
      <I    
      O     L      0.2
      L     #WERT_B
      L     100
      =     L      0.2
      >I    
      O     L      0.2
      SPBN  A7d0
      U     L      0.1
      SAVE  
      BEA   
A7d0: L     #WERT_C
      L     1
      ==I   
      SPBN  A7d1
      L     #WERT_A
      ITD   
      L     L#-1
      +D    
      L     L#104
      *D    
      L     #WERT_B
      ITD   
      TAK   
      T     LD     2
      TAK   
      L     L#1
      -D    
      L     L#1
      *D    
      L     LD     2
      +D    
      SET   
      L     P##LAMPE
      LAR1  
      TAK   
      T     LD     2
      TAK   
      L     W [AR1,P#0.0]
      T     LW     6
      AUF   DB [LW 6]
      L     D [AR1,P#2.0]
      L     LD     2
      +D    
      LAR1  
      =      [AR1,P#0.0]
A7d1: L     #WERT_C
      L     0
      ==I   
      SPBN  A7d2
      L     #WERT_A
      ITD   
      L     L#-1
      +D    
      L     L#104
      *D    
      L     #WERT_B
      ITD   
      TAK   
      T     LD     2
      TAK   
      L     L#1
      -D    
      L     L#1
      *D    
      L     LD     2
      +D    
      CLR   
      L     P##LAMPE
      LAR1  
      TAK   
      T     LD     2
      TAK   
      L     W [AR1,P#0.0]
      T     LW     6
      AUF   DB [LW 6]
      L     D [AR1,P#2.0]
      L     LD     2
      +D    
      LAR1  
      =      [AR1,P#0.0]
A7d2: CLR   
      U     L      0.1
      SAVE  
      BE

DB mit ARRAY
Code:
LAMPE ARRAY[1..10,1..100]   
 BOOL

OB1
Code:
      CALL  "TAUSENDLAMPEN"
       WERT_A:=MW100
       WERT_B:=MW102
       WERT_C:=MW104
       LAMPE :="L".LAMPE
 
      CALL  "BLKMOV"
       SRCBLK :="L".LAMPE
       RET_VAL:=#TEMP_INT
       DSTBLK :=P#A 0.0 BYTE 130

Ok, Blockmove verschenkt ein paar Ausgänge, ..müsste man in mehrere Blöcke aufteilen.


Gruß, Onkel
 
Zuletzt bearbeitet:
Scheint in SCL wirklich deutlich einfacher und übersichtlicher zu sein.

naja ... also gebs weg mit einigen code-optimierungen und onkel dagoberts scl-variante hätte ich dann doch gern noch im zykluszeitvergleich gesehen ... ich finde es in AWL äußerst übersichtlich, auch wenn man nicht indiziert zugreifen kann...
 
Die AWL-Variante würde ich auch bevorzugen. Auf das bisschen Zykluszeit sei zwar gesch.., aber bei der SCL-ARRAY-Lösung bleiben Lücken im Datenbereich. Und das ist u.U. sehr nachteilig.


Gruß, Onkel
 
Zurück
Oben