Random number - not random

wlie

Member
I wonder what is happening here.
Code:
#PICAXE 08M2
#No_Data

start0:
random w0
w1 = w0 // 2550 + 1
goto start0

start1:
random w2
w3 = w2 // 2550 + 1
goto start1
After each pass contains W0 always the same value as W2.
But if I insert a short break in one of the loops, the values are different.
Code:
#PICAXE 08M2
#No_Data

start0:
random w0
w1 = w0 // 2550 + 1
goto start0

start1:
pause 50
random w2
w3 = w2 // 2550 + 1
goto start1
What am I doing wrong?
 

inglewoodpete

Senior Member
Small microcontrollers are purely 'logical' devices, so there is nothing random about them. So, wherever possible, you need to provide a 'seed' value into the word register that you are using. The more variable (unpredictable) the seed value is, the better the pseudo-random number generated with the RANDOM command will be.

In the past, I have used whatever unpredictable input value I had available. Eg. the position of a servo motor using ADC; the position of a potentiometer that is regularly altered, using ADC; the value from ReadInternalTemp; the value of a Touch input; the delay between bootup and the first of a input key. Once seeded, it is a good idea the execute the Random command on every loop of your main program: this helps to keep the random number constantly changing.
 

oracacle

Senior Member
I was thinking about this the other day, I came to the conclusion the best way would be to start with 2 seeds, 254 and some other number (go for a prime number for fun), after the first random number production use the new number as the first see and keep the second number.

I ran this quickly, still needs work so that each successive random is so predictable
Code:
[color=Black]init:
      [/color][color=Blue]let [/color][color=Purple]b0 [/color][color=DarkCyan]= [/color][color=Navy]254
      [/color][color=Blue]let [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Navy]13
      [/color]
[color=Black]main:
      [/color][color=Blue]let [/color][color=Purple]b2 [/color][color=DarkCyan]= [/color][color=Purple]b0 [/color][color=DarkCyan]+ [/color][color=Purple]b1
      [/color][color=Blue]sertxd ([/color][color=Black]#[/color][color=Purple]b2[/color][color=Black], [/color][color=Navy]44[/color][color=Black], #[/color][color=Purple]b0[/color][color=Black], [/color][color=Navy]44[/color][color=Black], #[/color][color=Purple]b1[/color][color=Black], [/color][color=Navy]13[/color][color=Black], [/color][color=Navy]10[/color][color=Blue])
      let [/color][color=Purple]b0 [/color][color=DarkCyan]= [/color][color=Purple]b2
      [/color][color=Blue]let [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Purple]b2 [/color][color=DarkCyan]/ [/color][color=Navy]2
      [/color][color=Blue]if [/color][color=Purple]b2 [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=Blue]then
            [/color][color=Purple]b0 [/color][color=DarkCyan]= [/color][color=Navy]253
            [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Navy]13
      [/color][color=Blue]end if
      

      goto [/color][color=Black]main[/color]
try this and see how thing go
Code:
[color=Black]init:
      [/color][color=Blue]let [/color][color=Purple]b0 [/color][color=DarkCyan]= [/color][color=Navy]254
      [/color][color=Blue]let [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Navy]13
      [/color]
[color=Black]main:
      [/color][color=Blue]let [/color][color=Purple]b2 [/color][color=DarkCyan]= [/color][color=Purple]b0 [/color][color=DarkCyan]+ [/color][color=Purple]b1
      [/color][color=Blue]sertxd ([/color][color=Black]#[/color][color=Purple]b2[/color][color=Black], [/color][color=Navy]44[/color][color=Black], #[/color][color=Purple]b0[/color][color=Black], [/color][color=Navy]44[/color][color=Black], #[/color][color=Purple]b1[/color][color=Black], [/color][color=Navy]13[/color][color=Black], [/color][color=Navy]10[/color][color=Blue])
      random [/color][color=Purple]b3
      [/color][color=Blue]for [/color][color=Purple]b4 [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=Blue]to [/color][color=Purple]b3
            [/color][color=Blue]let [/color][color=Purple]b0 [/color][color=DarkCyan]= [/color][color=Purple]b2
            [/color][color=Blue]let [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Purple]b2 [/color][color=DarkCyan]/ [/color][color=Navy]2
            [/color][color=Blue]if [/color][color=Purple]b2 [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=Blue]then
                  [/color][color=Purple]b0 [/color][color=DarkCyan]= [/color][color=Navy]253
                  [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Navy]13
            [/color][color=Blue]end if
      next [/color][color=Purple]b4

      [/color][color=Blue]goto [/color][color=Black]main[/color]
 

oracacle

Senior Member
seemed to work fine in simulation, how ever it doesn't really matter, just sub out the appropriate byte variables for word variable, the programme will still function the same

Code:
[color=Black]init:
      [/color][color=Blue]let [/color][color=Purple]b0 [/color][color=DarkCyan]= [/color][color=Navy]254
      [/color][color=Blue]let [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Navy]13
      [/color]
[color=Black]main:
      [/color][color=Blue]let [/color][color=Purple]b2 [/color][color=DarkCyan]= [/color][color=Purple]b0 [/color][color=DarkCyan]+ [/color][color=Purple]b1
      [/color][color=Blue]sertxd ([/color][color=Black]#[/color][color=Purple]b2[/color][color=Black], [/color][color=Navy]44[/color][color=Black], #[/color][color=Purple]b0[/color][color=Black], [/color][color=Navy]44[/color][color=Black], #[/color][color=Purple]b1[/color][color=Black], [/color][color=Navy]13[/color][color=Black], [/color][color=Navy]10[/color][color=Blue])
      random [/color][color=Purple]w3
      [/color][color=Blue]for [/color][color=Purple]w4 [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=Blue]to [/color][color=Purple]w3
            [/color][color=Blue]let [/color][color=Purple]b0 [/color][color=DarkCyan]= [/color][color=Purple]b2
            [/color][color=Blue]let [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Purple]b2 [/color][color=DarkCyan]/ [/color][color=Navy]2
            [/color][color=Blue]if [/color][color=Purple]b2 [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=Blue]then
                  [/color][color=Purple]b0 [/color][color=DarkCyan]= [/color][color=Navy]253
                  [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Navy]13
            [/color][color=Blue]end if
      next [/color][color=Purple]w4

      [/color][color=Blue]goto [/color][color=Black]main[/color]
 

wlie

Member
I think I understand that it is difficult to achieve real random values, but I do not understand is why the values are similar in the two task. The Random command should be carried out in both task independent of each other.
 

lbenson

Senior Member
Not sure why the pause makes a difference. Since the seeds for random have the same initial value (0), the results will track, varying in principle because of the randomness of whether 1 or 0 is added to the "random" result as part of the randomization algorithm. This is the case when run on a real chip.

To start off different, initialize with different primes, e.g., "w0 = 2377", "w2 = 3391".
 
Last edited:

wlie

Member
By setting w0=2377 in task0 and w2=3391in task1 as suggested by Ibenson it looks much more randomized. But I still don't understand the diffence with the pause.
 

AllyCat

Senior Member
Hi William,

If you tale a "snapshot" of the two values, then they probably will be different because the start0 task will have completed more iterations during the pause in the start1 loop. But how are you seeing the values of w0 and w2 anyway, since your program doesn't have any "output" commands (sertxd or flashing a LED, etc)? Note that the PE5 and PE6 simulators behave differently and AFAIK neither is the same as a "real" PICaxe chip!

There are two fundamental issues with the PICaxe "random" routine. Firstly, as expalined above, the PICaxe itself does not have access to any random seed, so the Programmer must "find" one. But putting in an arbitrary fixed value will still produce the same results every time the program runs. Using another starting number (than the 0 to which all variables are initialised) does tend to "hide" the other issue: that the result from "random w0" (in a real chip) mainly involves a single left-shift of the bits, so the result is always either (2 * w0) or (2 * w0 + 1), but truncated to a word (16 bit) value.

If you want a really random value, then you should use a truly random seed (a "touch16,anyadcinputpin,wo" is probably the simplest) and then execute "random w0" more times than there are bits in your required subsequent random number (e.g. four times for a single decimal digit, eight for a byte, etc.).

Cheers, Alan.
 

wlie

Member
This was just a try to run programs in task, so my original program looks like this:
Code:
#PICAXE 08M2
#No_Data

start0:
random w0
w1 = w0 // 2550 + 1
pause w1
toggle 1
goto start0

start1:
random w2
w3 = w2 // 2550 + 1
pause w3
toggle 2
goto start1
[code]
After which I discovered that the two LED was blinking at the same rate.
Then I tried simulation by stepping through the program and here I saw the same value in W1 and W3. And by pause they change.

Anyway I was just playing to learn something new.
 

premelec

Senior Member
Probably leaving a pin 'floating' - say with 1 megohm and short wire antenna - use read ADC and RF noise in the commonly experienced environment would give pretty random readings - the upside of electromagnetic soup we live in!
 

120ThingsIn20Years

Senior Member
Probably leaving a pin 'floating' - say with 1 megohm and short wire antenna - use read ADC and RF noise in the commonly experienced environment would give pretty random readings - the upside of electromagnetic soup we live in!
Nice.

Quantum random number generator :)

some interaction between Temperature and Timer would probably work quite well as well. ie the last digit of the timer * temperature + the second to last digit of the timer or something.

Anything analogue should do it.

But my vote is for Floating ADC RF noise detection.

Awesome!
 
Top