[?]: Random number generator

SIMATIC S7-200/300/400, Step7, PCS7, CFC, SFC, PDM, PLCSIM,
SCL, Graph, SPS-VISU S5/S7, IBHsoftec, LOGO ...
dlsdls2
Posts: 2
Joined: Thu Aug 27, 2009 3:38 pm
Location: Vietnam

[?]: Random number generator

Post by dlsdls2 »

Hello,
I am looking for a rnadom number generator with min and max limites.

Maybe somone have the zip from this adresse:
http://support.automation.siemens.com/W ... n/29851674

Thank's
sventek
Posts: 56
Joined: Sun Jul 13, 2008 10:48 am
Location: Europe

Post by sventek »

Hi dlsdls2,

look at http://www.oscat.de!

You can download a library where you can find a function for a "random number generator".

greetings
sventek
Schtiel
Site Admin
Posts: 1122
Joined: Wed Sep 06, 2006 12:03 pm
Location: CIS

Post by Schtiel »

Try this function:
viewtopic.php?p=28980#28980
Coyote
Posts: 41
Joined: Wed Sep 06, 2006 10:07 am
Location: Slovenia

Post by Coyote »

Code: Select all

function Sqrt(val:real):real; 
  var
    flag: bool;
    i: int;
    diff: real;
    dx: real;
    xx: real;
  var_end;

  begin
    
          xx := val/10.0;
    
          flag := 0;
          if (val == 0 ) then
             xx := 0;
          else
            i:=0;
            while ( (i<20) and !flag ) do
    
        	       dx := (val - (xx*xx)) / (2.0 * xx);
        	       xx := xx + dx;
        	       diff := val - (xx*xx);
    
        	       if (abs(diff) <= 0.001) then
                        flag := 1;
        	       end_if;
    
                 i:=i+1;
    
            end_while;
    
          end_if;
    
          result:=xx;
    
  end;

  function abs(arg:real):real; 

  begin
         if arg>=0 then
            result:=arg;
         else
            result:=-arg;
         end_if;
    
  end;

  function Sin(rad:real):real;
 
  var
    app: real;
    diff: real;
    inc: int;
  var_end;

  begin
    
          inc := 1;
          while (rad > 2*PI) do
        	  rad := rad - 2*PI;
          end_while;
    
          while (rad < -2*PI) do
            rad := rad + 2*PI;
          end_while;
    
          app := rad;
          diff:= rad;
          diff := (diff * (-(rad*rad))) / ((2.0 * inc) * (2.0 * inc + 1.0));
          app := app + diff;
          inc:=inc+1;
    
          while(abs(diff) >= 0.001) do
            diff := (diff * (-(rad*rad))) / ((2.0 * inc) * (2.0 * inc + 1.0));
            app := app + diff;
            inc:=inc+1;
          end_while;
    
          result:=app;
    
  end;

  function Log(arg:real):real; 

  var constant
    log2 = 0.693147180559945309;
    sqrto2 = 0.707106781186547524;
    p0 = -24.013917955921051;
    p1 = 30.9572928215376501;
    p2 = -9.63769093368686593;
    p3 = 0.421087371217979714;
    q0 = -12.0069589779605255;
    q1 = 19.4809660700889731;
    q2 = -8.911109027983123371;
  var_end;

  var
    z: real;
    zsq: real;
    temp: real;
    expo: int;
  var_end;

  begin
    /*
    	log returns the natural logarithm of its floating
    	point argument.
    
    	The coefficients are #2705 from Hart & Cheney. (19.38D)
    
    */
    
    
    	if (arg <= 0.0) then
    
    		result:=-1;
    
      else
          	expo := 0;
    	      if(arg>1.0) then
    		                  while (arg>1) do
    			                      expo := expo+1;
    			                      arg := arg/2;
    		                  end_while;
    	      elsif(arg<0.5) then
                         while (arg<0.5) do
    			                      expo := expo-1;
    			                      arg := 2*arg;
    		                 end_while;
            end_if;
    
    
    	    while (arg<0.5) do
    		      arg := arg*2;
    		      expo := expo-1;
    	    end_while;
    
    	    if (arg<sqrto2) then
    		     arg := 2*arg;
    		     expo := expo-1;
    	    end_if;
    
    	    z := (arg-1)/(arg+1);
    	    zsq := z*z;
    	    temp := ((p3*zsq + p2)*zsq + p1)*zsq + p0;
    	    temp := temp/(((1.0*zsq + q2)*zsq + q1)*zsq + q0);
    	    temp := temp*z + expo*log2;
    	    result:=temp;
    
      end_if;
    
  function RandGauss:real;
  
  var static
    r1: real;
    r2: real;
  var_end;

  var
    w: real;
    x1: real;
    x2: real;
  var_end;

  begin
    
    
    r1 := -2.0*log(1-rand());
    r2 :=  2.0*pi*rand();
    r1 :=  sqrt(r1);
    result := r1*sin(r2);
    
    
  end;
 
 function Rand:real;
 
  var static
    ir1: int; default=11;
    jr1: int; default=222;
    kr1: int; default=333;
  var_end;

  var
    t: real;
  var_end;

  begin
    /* first generator  */
           ir1:= 171 * (ir1%177) - 2 * (ir1/177);
           if ( ir1<0 ) then
              ir1 := ir1 + 30269;
           end_if;
    
    /* second generator */
           jr1:= 172 * (jr1%176) - 35 * (jr1/176);
           if ( jr1<0 ) then
              jr1 := jr1 + 30307;
           end_if;
    
    /* third generator  */
           kr1:= 170 * (kr1%178) - 63 * (kr1/178);
           if ( kr1<0 ) then
              kr1 := kr1 + 30323;
           end_if;
    
    /* combine them to give really random value */
           t:= ir1/30269.0 +jr1/30307.0 +kr1/30323.0;
    
           result:=t - int(t);
    
  end;

This is my code for Random Gaussisan number generator for PLC. It is used for testing a sorting algorithm for sorting machine. The language is some derivatitive of IEC 61131. Maybe you need only the last function Rand() its a pseudorandom number generator and variables ir1,jr1,kr1 are static - it means they should be stored each new random hit, the next random number depends on those stored numbers (pseudo random technique). All other functions (abs(),Sqrt(), Log(), Sin()) are needed to transform those random numbers in Gauss shaped random form if your PLC doesnt support these functions yet itself.
Coyote
Posts: 41
Joined: Wed Sep 06, 2006 10:07 am
Location: Slovenia

Post by Coyote »

Code: Select all


FUNCTION_BLOCK FB100

VAR_OUTPUT
  OUT: REAL;
END_VAR
VAR
    ir1: INT :=111; 
    jr1: INT :=222; 
    kr1: INT :=333; 
END_VAR
VAR_TEMP
    t: REAL; 
END_VAR

    BEGIN 
    //* first generator  */ 
            ir1:= 171 * (ir1 MOD  177) - 2 * (ir1/177); 
            IF ( ir1<0 ) THEN 
              ir1 := ir1 + 30269; 
            END_IF; 
    
    //* second generator */ 
            jr1:= 172 * (jr1 MOD 176) - 35 * (jr1/176); 
            IF ( jr1<0 ) THEN 
              jr1 := jr1 + 30307; 
            END_IF; 
    
    //* third generator  */ 
            kr1:= 170 * (kr1 MOD 178) - 63 * (kr1/178); 
            IF ( kr1<0 ) THEN 
              kr1 := kr1 + 30323; 
            END_IF; 
    
    //* combine them to give really random value */ 
            t:= ir1/30269.0 +jr1/30307.0 +kr1/30323.0; 
    
           OUT:=t - TRUNC(t); 

END_FUNCTION_BLOCK;

This code is for Simatic SCL. It gives a random number in interval [0,1]. The probability is equal for all numbers between specified interval, there are no favorites numbers. You can offset and scale the interval to get the desired output.
Janosch07
Posts: 19
Joined: Sun Oct 22, 2006 9:12 am

Random Number

Post by Janosch07 »

Try this


FUNCTION "Random Number" : VOID
TITLE =Random Number Generator
//This Function Block uses SFC64
//
//The random number is generated according to the following formula:
//
//V[n+1]=(A*V[n]+B) mod M
//
//"Numerical Recipes"
//A=1664525
//B=1013904223
//M=2^32 (Because its not possible the following number was used:
// 2147483647 (2^31 -1)
AUTHOR : JAN
FAMILY : INT
NAME : RNDNUM
VERSION : 0.1


VAR_INPUT
H_Limit : DINT ;
L_Limit : DINT ;
END_VAR
VAR_OUTPUT
Random_DI : DINT ;
Random_R : REAL ;
END_VAR
VAR_TEMP
A : DINT ; //1664525 dec = 0019660D hex
B : DINT ; //1013904223 dec = 3C6EF35F hex
M : REAL ; //2147483647 dec = 7FFFFFFF hex
rest : DINT ;
RetVal : TIME ;
Temp1 : DINT ;
END_VAR
BEGIN
NETWORK
TITLE =

CALL "TIME_TCK" (
RET_VAL := #RetVal);
L L#1664525;
T #A;
L L#1013904223;
T #B;
L L#2147483647;
T #M;
L #H_Limit;
L #L_Limit;
-D ;
T #Temp1;
L #A;
L #RetVal;
*D ;
L #B;
+D ;
L #M;
MOD ;
DTR ;
ABS ;
L L#2147483647;
DTR ;
/R ;
L #Temp1;
DTR ;
*R ;
LAR1 ;
RND ;
L #L_Limit;
+D ;
T #Random_DI;
L #L_Limit;
DTR ;
TAR1 ;
+R ;
T #Random_R;

END_FUNCTION

cheers