Rechnen mit BYTE in SCL geht nicht ?

noeppkes

Level-1
Beiträge
150
Reaktionspunkte
5
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich versuch mit einer als BYTE definierte temp_var zu rechne und zwar folgendermaßen:

Code:
VAR_TEMP
  multidata_10 : BYTE;
END_VAR
 
// ...
 
// db20.dbb17 = ARRAY of CHAR
multidata_10 := db20.dbb17 - 48;  // - 48 geht nicht. Unzulässige Operandentypen

// 57 geht auch nicht. Unzulässige Operandentypen.
IF multidata_10 > 57 THEN multidata_10 := multidata_10 - 7; END_IF;

Kann mir hier jemand helfen ?

noeppkes ...
 
Hallo noeppkes,

ja geht ganz einfach mit BYTE_TO_INT(x) x steht für die Byte Variable.

Bsp.
Code:
multidata_10 := INT_TO_BYTE(BYTE_TO_INT(db20.dbb17) - 48);
MfG
Daniel
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mit BYTE in SCL rechnen

Danke für deine Antwort.
Das funktioniert auch.

Aber ich wollte nicht in INT rechnen sondern in BYTE.

Code:
  VAR_TEMP
    multidata_10 : INT;
    b_multidata_10 AT multidata_10 : ARRAY[0..15] OF BOOL;
  END_VAR
 
  // Das hier funktioniert über INT.
  multidata_10 := BYTE_TO_INT(db20.dbb17) - 48;
  IF multidata_10 > 9 THEN multidata_10 := multidata_10 - 7; END_IF;
 
  // Hier wollte ich die untersten Bits des DB20.DBB17 auswerten
  // warum 8 .. 11 und nicht 0 .. 3 ??????
  IF (b_multidata_10[8]) THEN ...
  IF (b_multidata_10[9]) THEN ...
  IF (b_multidata_10[10]) THEN ...
  IF (b_multidata_10[11]) THEN ...

Aber eigentlich wollte aber gerne mit BYTE rechnen
in etwa so:
Code:
  VAR_TEMP
    multidata_10 : BYTE;
    b_multidata_10 AT multidata_10 : ARRAY[0..7] OF BOOL;
  END_VAR
 
 
  multidata_10 := CHAR_TO_BYTE(db20.dbb17) - 48;
  IF multidata_10 > 9 THEN multidata_10 := multidata_10 - 7; END_IF;
 
  // Hier wollte ich die untersten Bits des DB20.DBB17 auswerten
  // warum 8 .. 11 und nicht 0 .. 3 ??????
  IF (b_multidata_10[0]) THEN ...
  IF (b_multidata_10[1]) THEN ...
  IF (b_multidata_10[2]) THEN ...
  IF (b_multidata_10[3]) THEN ...

Kann mir jemand zum Verständnis helfen ?

noeppkes ...
 
Ohne es getestet zu haben, übersetzen läßt es sich so:

Code:
VAR_TEMP
    multidata_10 : Byte;
    b_multidata_10 AT multidata_10 : ARRAY[0..7] OF BOOL;
    A: INT;
END_VAR

  // Das hier funktioniert über Byte-Int-Int-Byte-Wandlung.
  multidata_10 := Int_To_Byte(BYTE_TO_INT(db20.dbb17) - 48);
  IF BYTE_TO_INT(multidata_10) > 9 THEN multidata_10 := INT_TO_BYTE(BYTE_TO_INT(multidata_10) - 7); END_IF;
 
  // Hier wollte ich die untersten Bits des DB20.DBB17 auswerten
  // warum 8 .. 11 und nicht 0 .. 3 ??????
  IF (b_multidata_10[0]) THEN A := 1; END_IF;
  IF (b_multidata_10[1]) THEN A := 2; END_IF;
  IF (b_multidata_10[2]) THEN A := 3; END_IF;
  IF (b_multidata_10[3]) THEN A := 4; END_IF;
 
Rechnen mit BYTE in SCL

Hallo Ralle,

danke für die Nachricht.

Versteh ich das richtig, ein Vergleich wie z.B multidata_10 > 57 then ...
ist immer Integer.
Ein BYTE-Vergleich geht nciht direkt ?

noeppkes ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mit INT,DINT und REAL gehen alle Vergleichsfunktionen (=,<>,>0,<0,>,<), mit BYTE,WORD und DWORD nur = und <>.

Siehe Kapitel 11.8 im Anhang.
 

Anhänge

  • SCL_d.pdf
    2,2 MB · Aufrufe: 89
Rechnen mi-Wert folgendermaßen abfragen möchtret BYTE in SCL

Hallo,
danke für die Antwort.
Wie aber sieht es mit AND Verknüfungen aus.

Es funktioniert anscheinend auch nicht, wenn ich ein INT folgendermaßen

multidata_10 : INT;

if multidata_10 AND 2 then ...
Das funktioniert nicht ?

Muss ich immer über die Sicht (AT) gehen

multidata_10 : INT;
b_multidata_10 AT multidata_10 ARRAY [0..15] of BOOL; // Hoffe ich habe es richtig geschrieben.

if b_multidata_10[1] then ...

Warum so umständlich ?

noeppkes ...
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Anwendung Konvertierungsfunktionen

Hallo Leute,

ich bin gerade auf der Suche nach einer
Konvertierungsfunktionen mit der sich BYTE in INT konvertieren lässt (Jahr aus DATE_AND_TIME). Laut Siemens-Handbuch (
S7-SCL V5.3 für S7-300/400) gibt es dafür wohl die
Konvertierungsfunktionen Klasse B ( BYTE_TO_INT oder BCD_TO_INT(x) ). Wenn ich diese Funktionen aber in mein Prog kopiere zeigt er mir ein Fehler an oder die Jahreszahl ist nach der Umwandlung geändert. Kann mir vieleicht jemand einen Tip geben wie sich das Problem beheben lässt?

Gruß

Mario
 
Siehe Larry.
BCD_TO_INT will ja ein WORD, also sollte das in etwa so aussehen:

iJahr := BCD_TO_INT(BYTE_TO_WORD(bcdJahr));


wobei bcdJahr das Byte 0 aus dem Datentyp DATE_AND_TIME ist.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Konvertierungsfunktionen

... anbei hab ich mal den Code angehängt. Wie gesagt das Problem liegt beim auslesen und umwandeln der Jahreszahl.


[/CODE]TITLE = 'Tageszahl'

VERSION : '1.0'
AUTHOR :
NAME : name
FAMILY : family
FUNCTION Tageszahl_SCL: VOID

// Variablendeklartion
VAR_OUTPUT
Tageszahl: INT; // Aktuelle Tageszahl
TageImJahr:INT; // 365 oder 366 Tage???
Jahreszahl:INT;
END_VAR
VAR_TEMP
Tag:INT;
Monat:INT;
Date_Time:INT;
IstEinSchaltjahr:BOOL;
Jahr:INT;
Zaehler:INT;
END_VAR
VAR
TageImMonat: ARRAY[1..12] OF INT;
SPS_Datum_Uhrzeit : DATE_AND_TIME ;
a_Datum_Uhrzeit AT SPS_Datum_Uhrzeit : ARRAY [0..7] OF BYTE;
END_VAR

BEGIN

// Auslesen der der SPS Zeit und der Datumsangaben
Date_Time := READ_CLK (CDT:= SPS_Datum_Uhrzeit);

// Datum mit vierstelliger Jahreszahl aus Systemdatum ermitteln
Jahr:= WORD_TO_INT(BYTE_TO_WORD(a_Datum_Uhrzeit[0]));//
// Beim auslesen von BYTE 0 ist vor der konvertierung die reichtige Jahreszahl angezeigt,
// bei Jahreszahlen ab 2010 wird nach der Konverterung eine größere Zahl angezeigtnach.


Monat:= WORD_TO_INT(BYTE_TO_WORD(a_Datum_Uhrzeit[1]));
Tag:= WORD_TO_INT(BYTE_TO_WORD(a_Datum_Uhrzeit[2]));
IF Date_Time >= 90
THEN Jahreszahl := Jahr + 1900;
ELSE Jahreszahl := Jahr + 2000;
END_IF;

// Ist ein Schaltjahr???
// Die Regel lautet: Alles, was durch 4 teilbar ist, ist ein Schaltjahr.
// Es sei denn, das Jahr ist durch 100 teilbar, dann ist es keins.
// Aber wenn es durch 400 teilbar ist, ist es doch wieder eins.
IF (Jahreszahl MOD 400 = 0) OR
(Jahreszahl MOD 4 = 0) AND
(Jahreszahl MOD 100 <> 0)
THEN IstEinSchaltjahr := true;
ELSE IstEinSchaltjahr := false;
END_IF;

// Bestimmung der Anzahl Tage im Jahr in Abhängigkeit vom Schaltjahr
IF IstEinSchaltjahr = true
THEN TageImJahr:=366;
ELSE TageImJahr:=365;
END_IF;

// Berchnung der Tageszahl
//
// Wertezuweisung Array TageImMonat
TageImMonat [1]:= 31; // Januar
TageImMonat [2]:= 28; // Februar
TageImMonat [3]:= 31; // März
TageImMonat [4]:= 30; // April
TageImMonat [5]:= 31; // Mai
TageImMonat [6]:= 30; // Juni
TageImMonat [7]:= 31; // Juli
TageImMonat [8]:= 31; // August
TageImMonat [9]:= 30; // September
TageImMonat [10]:= 31; // Oktober
TageImMonat [11]:= 30; // November
TageImMonat [12]:= 31; // Dezember
// Anfangswerte setzen
Tageszahl := 0; // Tageszahl auf Anfangswert 0
Zaehler:=1; // Zähler auf Anfangswert 1

IF Monat > 1 AND Monat <=18 THEN // IST Monat größer 1(Jan.) und kleiner-gleich 12 (Dez.) DANN
FOR Zaehler := 1 TO Monat-1 BY 1 DO // SOLL über FOR-Schleife von 1 bis Monat-1
Tageszahl := Tageszahl+TageImMonat[Zaehler]; // die Tageszahlen aufsummiert werden
Zaehler:= Zaehler +1; // Zähler wird pro Durchlauf um 1 erhöht
END_FOR;
Tageszahl:= Tageszahl+Tag;
ELSE Tageszahl := Tag;

END_IF;

END_FUNCTION
 
Konvertierungsfunktion

Hallo Ralle,

wenn ich den Code,

Jahr := BCD_TO_INT(BYTE_TO_WORD(a_Datum_Uhrzeit[0]));

wie beschrieben einfüge wird BCD_TO_INT nicht als Funktion angezeigt und als Fehlermeldung bekomme ich angezeigt, dass der Baustein nicht gefunden oder kopiert werden konnte. Muss ich vielleicht noch eine Einstellung vornehmen?

Gruß

Mario
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich hab den Code in meinen SCL-Editor kopiert und es hat leider nicht funktioniert. Normalerweise müsste doch auch die Anweisung BCD_TO_INT in BLAU erscheinen oder? Beim compilieren werden mir dann noch 2 Fehlermeldungen (siehe Anhang) ausgegeben. Muss ich vielleicht noch eine Einstellung ändern oder kann es an der Prog.version liegen?

Gruß

Mario
 

Anhänge

  • Screenshot.pdf
    72,3 KB · Aufrufe: 11
Zuviel Werbung?
-> Hier kostenlos registrieren
... kann ich leider nicht nachstellen. Ich habe gleiche Version mit SP4 (also 5.3.4.0) installiert. Bei mir gibt es die Abweisung und so wie du es geschrieben hast in deinem Code (PDF) ist es auch korrekt. Vielleicht lädst du dir mal das aktuelle SP bei Siemens herunter ...
Leider habe ich den Link nicht mehr ...

Gruß
LL
 
Was ist neu in Version V5.3 SP1?

Spracherweiterungen
S7-SCL V5.3 SP1 wurde um Sprachmittel erweitert, die die IEC 61131-3 definiert:
  • Funktionen zur Verarbeitung von Zahlenwerten als interne SCL-Funktionen (SEL, MAX, MIN, LIMIT, MUX)
  • Unterstützung der BCD-Darstellung von Ganzzahlen durch Konvertierungsfunktionen (BCD_TO_INT, INT_TO_BCD, etc.)
  • Zuweisungsoperator => für Ausgangsparameter von Funktionen
  • Feld-Initialisierung mit Klammerung
  • Neue Konvertierungsfunktionen (BYTE_TO_INT, INT_TO_BYTE, etc.)

Du brauchst also mind. V5.3. SP1
 
Zurück
Oben