Siemens S7 V5.5 en arrays


High met Henk

Special Member

Ehhmm ik heb geen DI.

Gebruik AI en tel op met ca 0.5 mA.

Dan kan het nog steeds wel, maar met 128 timers en opslaan is het niet echt functioneel.

E = MC^2, dus de magnetische compatibiliteit doet kwadratisch mee???

Dan heb ik het niet helemaal goed gelezen. Maar je kan altijd een FC maken war je de timer met een systeempuls laat werken en dan telt. Echter die hoeveelheid timers maakt de PLC niks uit. Je hebt er ruim 500 tot je beschikking.

Ik heb nog eens gelezen wat als je een vergelijk maakt dus wat je nu meet en een seconde later en een timer triggert kan je dan je waarde actualiseren. 27567 / 16 = 1723 digit per 0,5ma
Door een actuele waarde met een deelfuntie DIV kan je dus ook waarde genereren van aantal kasten.

High met Henk

Special Member

Dat deel heb ik al.

Daar zit probleem niet in.

Maar om 21.30 ga ik waarschuwen dat we om 22.00 op alarm gaan.

Als ik om 21.30 10 kasten dicht heb..
En om 21.35 11 kasten.
En om 21.45 12 kasten.

Dan beveilig ik dus om 22.00 10 kasten
Om 22.05 zijn 11 kasten beveiligd
Om 22.15 zijn er 12 kasten beveiligd.

Ik houd dus in het array op de 2e index het aantal kasten bij. Die waarden moeten dus alleen maar oplopen.

Ik zoek gewoon uit hoe ik die indexen kan gebruiken.
Dat wil mij niet lukken in S7 V5.5

E = MC^2, dus de magnetische compatibiliteit doet kwadratisch mee???

Wordt er niet simpeler op. Arrays zijn niet helemaal mijn ding,succes

Kan je niet beter een array van UDT's aanmaken?

http://www.acro.be/Downloads/BasisPLC/Hoofdstuk%208_Databouwstenen.pdf

[Bericht gewijzigd door coldrestart op 1 november 2021 11:24:30 (15%)]

High met Henk

Special Member

Optellen van die 30 minuten in een UDT is lastiger.
Maar kan later evt nog.

Maar zit ik nog steeds met een array en indexen.
En dat wil ik ook wel, maar krijg het in S7 v5.5 niet aan de praat

[Bericht gewijzigd door High met Henk op 1 november 2021 12:24:30 (21%)]

E = MC^2, dus de magnetische compatibiliteit doet kwadratisch mee???

Arrays en indexeren/shiften zou ik zelf in SCL doen, dan is het een eitje.
AWL en pointers ben ik zelf niet zo'n fan van, het wordt al snel onduidelijk wat er precies gedaan wordt.

High met Henk

Special Member

Op 1 november 2021 12:27:18 schreef Jorn:
Arrays en indexeren/shiften zou ik zelf in SCL doen, dan is het een eitje.
AWL en pointers ben ik zelf niet zo'n fan van, het wordt al snel onduidelijk wat er precies gedaan wordt.

Dat is allemaal heel leuk ALS SCL (ST door mij foutief genoemd) zou kunnen in STEP 7 V5.5

En dat kan dus niet.

E = MC^2, dus de magnetische compatibiliteit doet kwadratisch mee???

Op 1 november 2021 16:38:44 schreef High met Henk:
[...]

Dat is allemaal heel leuk ALS SCL (ST door mij foutief genoemd) zou kunnen in STEP 7 V5.5

En dat kan dus niet.

Jawel, dat kan wel, maar moet je apart installeren als optie, en volgens mij ook apart een licentie voor hebben, maar zou ook gewoon als trial moeten werken.

Voor 5.6: https://support.industry.siemens.com/cs/document/109748118/where-do-yo…

[Bericht gewijzigd door Jorn op 1 november 2021 17:36:53 (18%)]

High met Henk

Special Member

Heb je daar dan ook een voorbeeld van hoe het werkt?

E = MC^2, dus de magnetische compatibiliteit doet kwadratisch mee???
GJ_

Moderator

Op 1 november 2021 12:27:18 schreef Jorn: AWL en pointers ben ik zelf niet zo'n fan van, het wordt al snel onduidelijk wat er precies gedaan wordt.

Ik vind het juist een eitje in AWL, net wat je gewent bent natuurlijk.

In scl mogelijkheden zat
zomaar even wat ingerost, ik doe nog zelden wat in 5.6 alles is al een paar jaar TiaPortal

code:


FUNCTION_BLOCK  FB77
TITLE   = 'Arraytest'
VERSION : '1.0'
AUTHOR  : Peter
FAMILY  : Arrays
VAR_INPUT


 
   
END_VAR
VAR

mxarr: INT;
anloginputvalue : INT;   //input value analog 4-20mA =  0-1000  every door offset 50 points 
IntArray : ARRAY [0..32] OF INT;
TimeArray: ARRAY [0..32] OF TIME;
//doubelarray
D_array: ARRAY[0..32] OF ARRAY[0..2] OF INT;
UdtArray: ARRAY[0..32] OF udt77;
END_VAR


VAR_TEMP



  i: INT;
  anlogincount: INT;


END_VAR    

BEGIN


FOR i := 0 TO mxarr DO
    intarray[i]:= i+30;
    timearray[i]:= dINT_TO_time(INT_TO_DINT( i*1000));
END_FOR;

//double array

D_array[2,1] := 1;
//udt array
//if analog inputvalue = xx.x mA then
udtarray[0].deurstatus := true;

//end if;

//scan all, add hysterese ?
 FOR anlogincount := 0 TO 1000 BY 50 do
   IF anlogincount = anloginputvalue THEN
     udtarray[0].deurstatus := true;
   ELSE
     udtarray[0].deurstatus := false;
   END_IF;
END_FOR;

END_FUNCTION_BLOCK

code:


TYPE UDT77
// header  
STRUCT
  DeurStatus : BOOL;  //open dicht
  DeurTijd : TIME; 
  tekst : STRING[30]:='' ;
 END_STRUCT;
 END_TYPE
High met Henk

Special Member

heb even ergens een mooie TIA portal geregeld en loop nu even te hannesen met date en time

ik wil op de Hmi in aparte velden de datum en tijd hebben.

echter ik krijg het niet voor elkaar om de datum goed te krijgen.

ik weet dat het date and time formaat 8 bytes is en ik

byte 0 moet hebben voor het jaar
Byte 1 voor de maand
byte 2 voor de dag

maar ik kan op 1 of ndere manier niet filteren.
AND operaties werken niet.
tijd aftrekken kan wel..

ik ben al aan het klooien geweest met fomules etc..

maar zo moeilijk moet het toch niet zijn??

HMI moet voor leken een tijd en datum kunnen instellen, dus aparte velden voor elke waarde

op de achtergrond wil ik ze weer samenvoegen tot een nieuwe DT
Voor de tijd heb ik e.e.a. al voor elkaar, maar de datum is echt erg lastig!

E = MC^2, dus de magnetische compatibiliteit doet kwadratisch mee???
High met Henk

Special Member

klein schopje...

niemand die weet hoe ik normaal dagen, maanden en jaren uit een datum kan trekken?

E = MC^2, dus de magnetische compatibiliteit doet kwadratisch mee???
GJ_

Moderator

Gewoon in een merkerdubbelwoord stoppen is het eenvoudigste natuurlijk. BV MD100En dan MB100 voor het jaar, MB101 voor de maand, enz
Of in de DB stoppen, bv BD100.DBD0. En dan het jaar uit MB100.DBB0 enz enz

Als je het moeilijk wil doen kun je ook schuiven en een AND er op loslaten of zo.
Genoeg mogelijkheden.

High met Henk

Special Member

In SCL is het dus niet zo makkelijk om over ladderof fbd maar te zwijgen.

Ik kan een date and time alleen in een int stoppen
Een and lukt ook niet op dit var type..

De int maakt er time in Ms sinds 1-1-1990 van

E = MC^2, dus de magnetische compatibiliteit doet kwadratisch mee???
GJ_

Moderator

Stop toch met SCL en ga fijn AWL programmeren, dan was je al klaar geweest >:-)

Zet het desnoods in een aparte bouwsteen en doe alleen die in AWL. Die mogelijkheid heb je, gebruik hem dan ook.

Als ik het goed begrijp wil je een date_and_time variabele uit elkaar trekken en opdelen in de afzonderlijke waarden?
Kan in SCL simpel door er met een AT instructie een masker van het gewenste type er overheen te leggen, in dit geval een struct met de losse waarden.

De losse velden zijn in mijn voorbeeld te benaderen als DateTimeStruct.Jaar bijvoorbeeld.

Onderstaande code maakt een unix time stamp
het stukje wat je nodig bent staat onder
"// read system time"
Wat voor HMI is het, de meeste kunnen datum en tijd gewoon weer geven in een singele i/o field.

code:


FUNCTION "UnixTimeStamp" : String
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_TEMP 
      Leapyears : Int;
      Days_from_1970 : DInt;
      days_from_BeginOfYear : Array[1..12] of Int;
      l_unixtime : DInt;
      sfc1_ret_val : Int;
      CDT_systemtime : Date_And_Time;
      systemtime AT CDT_systemtime : Struct
         Year_CDT : Byte;
         Month_CDT : Byte;
         Day_CDT : Byte;
         Hour_CDT : Byte;
         Minute_CDT : Byte;
         Second_CDT : Byte;
         MSec : Word;
      END_STRUCT;
      Year : Int;
      Month : Int;
      Day : Int;
      Hour : Int;
      Minute : Int;
      Second : Int;
      Msecs : Int;
   END_VAR


BEGIN
	// Convert system time to unix time
	// (seconds until 1970-01-01 00:00)
	
	
	
	
	
	#Leapyears := 0;
	#Days_from_1970 := 0;
	
	// days of current month without leap day
	
	#days_from_BeginOfYear[1] := 0;
	#days_from_BeginOfYear[2] := 31;
	#days_from_BeginOfYear[3] := 59;
	#days_from_BeginOfYear[4] := 90;
	#days_from_BeginOfYear[5] := 120;
	#days_from_BeginOfYear[6] := 151;
	#days_from_BeginOfYear[7] := 181;
	#days_from_BeginOfYear[8] := 212;
	#days_from_BeginOfYear[9] := 243;
	#days_from_BeginOfYear[10] := 273;
	#days_from_BeginOfYear[11] := 304;
	#days_from_BeginOfYear[12] := 334;
	
	
	// read system time
	#sfc1_ret_val := RD_SYS_T(#CDT_systemtime);
	#Year := BCD16_TO_INT(#systemtime.Year_CDT) + 2000;
	#Month := BCD16_TO_INT(#systemtime.Month_CDT);
	#Day := BCD16_TO_INT(#systemtime.Day_CDT);
	#Hour := BCD16_TO_INT(#systemtime.Hour_CDT);
	#Minute := BCD16_TO_INT(#systemtime.Minute_CDT);
	#Second := BCD16_TO_INT(#systemtime.Second_CDT);
	
	#Msecs := BCD16_TO_INT(SHR(IN := #systemtime.MSec, N := 4));
	
	// sum of leap years since 1979 (without current leap year)
	#Leapyears := ((#Year - 1) - 1968) / 4
	- ((#Year - 1) - 1900) / 100
	+ ((#Year - 1) - 1600) / 400;
	
	
	#Days_from_1970 := (#Year - 1970) * 365 + #Leapyears
	+ #days_from_BeginOfYear[#Month] + #Day - 1;
	
	IF ((#Month > 2) AND ((#Year MOD 4 = 0) AND ((#Year MOD 100 <> 0) OR (#Year MOD 400 = 0)))) THEN
	    #Days_from_1970 := #Days_from_1970 + 1; // + leap day, if year is leap year
	END_IF;
	
	// OUTPUT in s
	#l_unixtime := #Second + 60 * (#Minute + 60 * (#Hour + 24 * #Days_from_1970));
	
	
	// if error return 0
	IF #sfc1_ret_val <> 0 THEN
	    #UnixTimeStamp := '';
	ELSE
	    
	    CASE #Msecs OF
	        0..9:
	            #UnixTimeStamp := CONCAT(IN1 := DELETE(IN := DINT_TO_STRING(#l_unixtime), L := 1, P := 1),
	                                     IN2 := DELETE(IN := INT_TO_STRING(#Msecs), L := 1, P := 1), IN3 := '00000000');
	        10..99:
	            #UnixTimeStamp := CONCAT(IN1 := DELETE(IN := DINT_TO_STRING(#l_unixtime), L := 1, P := 1),
	                                     IN2 := DELETE(IN := INT_TO_STRING(#Msecs), L := 1, P := 1), IN3 := '0000000');
	        100..999:
	            #UnixTimeStamp := CONCAT(IN1 := DELETE(IN := DINT_TO_STRING(#l_unixtime), L := 1, P := 1),
	                                     IN2 := DELETE(IN := INT_TO_STRING(#Msecs), L := 1, P := 1), IN3 := '000000');
	            
	        ELSE
	            #UnixTimeStamp := '';
	    END_CASE;
	        
	        
	   
	END_IF;
	
	
	
END_FUNCTION
High met Henk

Special Member

Op 2 december 2021 17:12:22 schreef Jorn:
Als ik het goed begrijp wil je een date_and_time variabele uit elkaar trekken en opdelen in de afzonderlijke waarden?
Kan in SCL simpel door er met een AT instructie een masker van het gewenste type er overheen te leggen, in dit geval een struct met de losse waarden.

[bijlage]

De losse velden zijn in mijn voorbeeld te benaderen als DateTimeStruct.Jaar bijvoorbeeld.

Heb dit geprobeerd, maar zie het datatype AT niet en erbij tikken lukt niet

E = MC^2, dus de magnetische compatibiliteit doet kwadratisch mee???

Op 11 december 2021 16:07:14 schreef High met Henk:
[...]

Heb dit geprobeerd, maar zie het datatype AT niet en erbij tikken lukt niet

Waarschijnlijk heb je optimized block access aan staan?
Even rechtermuisknop op je fb/fc in het linker selectiescherm en dan properties, en optimized uitzetten.

https://www.youtube.com/watch?v=qHL1H0qsObk

High met Henk

Special Member

Dat filmpje heb ik gezien.
Optimized block access staat uit.
Let op is Tia Portal V14 en een cpu 314

E = MC^2, dus de magnetische compatibiliteit doet kwadratisch mee???

Importeer mijn voorbeeld en kijk of Tia het accepteert in je cpu.

[Bericht gewijzigd door Peter112 op 11 december 2021 21:29:08 (19%)]

Op 11 december 2021 21:13:09 schreef High met Henk:
Dat filmpje heb ik gezien.
Optimized block access staat uit.
Let op is Tia Portal V14 en een cpu 314

Klopt, mijn voorbeeld heb ik ook met een 314 CPU gemaakt omdat inderdaad een 300 serie niet alles kan wat met een 1500 wel kan.
Enige verschil is dat ik Tia Portal V17 gebruikt heb.