Random Numbers with Picaxe chips

kando

Senior Member
Hi,
How does anyone do random numbers with Picaxe chips?
I have this method which seems to work but has anyone got a straight forward way of writing a snippet of program to do this on a Picaxe.
I'm looking for something to seed the random before I use it but not using outside the chip stuff.

Wouldn't it be nice to just have X=RND(6+1)

Here is a way that works but it is still outside the chip for seeding.

Code:
[color=Green];Random numbers by kando
;Run in the simulator to see it. (Version 6 beta) (neat IR sim handset)
;press a button on the handset to start..[/color]
[color=Blue]settimer [/color][color=Navy]63455[/color][color=Green]; seems to work well with this number!
;i've used irin and a sky remote handset[/color]
[color=Black]main:[/color]
[color=Blue]irin [PLAIN][[/PLAIN][/color][color=Navy]1000[/color][color=Black],main[/color][color=Blue][PLAIN]][/PLAIN][/color][color=Black],[/color][color=Blue]C.3[/color][color=Black],[/color][color=Purple]b0 [/color][color=Green];wait for button press on IR pin use to seed random[/color]
[color=Purple]w12[/color][color=DarkCyan]=[/color][color=Purple]timer[/color][color=Green];collect time when button pressed into w12[/color]
[color=Purple]w0[/color][color=DarkCyan]=[/color][color=Purple]w0[/color][color=DarkCyan]-[/color][color=Purple]w12[/color][color=Green]; (w0 = b0,b1)(w12 = b24 ,b25)[/color]
[color=Blue]for [/color][color=Purple]b5[/color][color=DarkCyan]=[/color][color=Navy]1 [/color][color=Blue]to [/color][color=Navy]27[/color]
[color=Blue]DO
   RANDOM [/color][color=Purple]w0
   b2 [/color][color=DarkCyan]= [/color][color=Purple]w0 [/color][color=DarkCyan]/ [/color][color=Navy]199 [/color][color=DarkCyan]// [/color][color=Navy]9 [/color][color=DarkCyan]+ [/color][color=Navy]1[/color][color=Green]; 9 because  random x9 change to 6 for dice[/color]
[color=Blue]LOOP UNTIL [/color][color=Purple]b2 [/color][color=DarkCyan]<> [/color][color=Purple]b3
b3 [/color][color=DarkCyan]= [/color][color=Purple]b2[/color]

[color=Blue]sertxd ([/color][color=Black]#[/color][color=Purple]b3[/color][color=Black],[/color][color=Blue]cr[/color][color=Black],[/color][color=Blue]lf)[/color][color=Green];to see results for testing [/color]
[color=Blue]next [/color][color=Purple]b5[/color]
[color=Blue]end[/color]
For comments.
Kando
 

srnet

Senior Member
Its been discussed a few times on here, put 'random seed' into the forum search to see is there is anything relevant.

And do bear in mind, that even when seeded, the random function will only ever do pseudo random numbers, there will be a sequence.
 

AllyCat

Senior Member
Hi,

The general design aim of a computer/controller is to be deterministic, which does make you rather dependent on some form of external influence. The most obvious are light level (using an external sensor), temperature, supply voltage and stray capacitance ("touch" hardware), the last three all having PICaxe internal sensing capability.

But if you assume that the chip is running from a regulated supply rail, in a thermally-stable, Faraday-screened, Black box, with no User-Interaction, then you do indeed have a problem. ;) So, I would choose as my "seed" whichever of the aforementioned parameters is NOT likely to be completely stable in practice.

Cheers, Alan.
 

rossko57

Senior Member
Or in this case there is a push button ... the time between power-up and button press will be a vague human factor. What's wrong with that, do you need a version with no button?
 

hippy

Technical Support
Staff member
Timer should be usable for seeding when there is user interaction. It is also possible to store the last random number used in Eeprom memory so, when the program restarts, it will continue the sequence where it left off rather than starting from its usual initial value.

The PRNG sequence may become quite obvious in some cases and may be nowhere near as random as required. That can be made less obvious by using RANDOM on w0 ( or w1 ) and then building a new number from bitN variables in a variety of combinations.

All tricks suggested for seeding and randomising the actual sequence can be piled onto each other to disrupt what would be the normal random sequence.

There is a fair bit of discussion on random numbers in the forums including 'what is random'; a quite fundamental question as what's required is often not something which is truly random.
 

kando

Senior Member
Timer should be usable for seeding when there is user interaction. It is also possible to store the last random number used in Eeprom memory so, when the program restarts, it will continue the sequence where it left off rather than starting from its usual initial value.

The PRNG sequence may become quite obvious in some cases and may be nowhere near as random as required. That can be made less obvious by using RANDOM on w0 ( or w1 ) and then building a new number from bitN variables in a variety of combinations.

All tricks suggested for seeding and randomising the actual sequence can be piled onto each other to disrupt what would be the normal random sequence.

There is a fair bit of discussion on random numbers in the forums including 'what is random'; a quite fundamental question as what's required is often not something which is truly random.
Perfectly true and thank you Hippy. (what is PRNG? is it pseudo random number Gsomething? (brain gone))
My search continues for the elusive Picaxe pseudo random numbers without external help.
 

Dartmoor

Member
Kando's original post makes reference to a dice as an example.
Most of us are probably looking for a 'random' selection from a limited range of options (eg dice or roulette wheel), rather than an entirely random number (eg lottery numbers)?
We could have one loop running that is dedicated to providing a value (1-6) for a variable eg: A=1; short pause; A=2; short pause; A=3; short pause; A=4; short pause; A=5; short pause; A=6; short pause; return. This starts running (at a number of loops per second) from the moment the picaxe is powered up.
A second loop (main program?) then reads the value at the instant the IR button is pressed, or some other decision point is reached, and performs the appropriate action depending on the value of the variable at that instant?
As a Picaxe novice, I mainly use the Logicator for programming Picaxe & have a rather simplistic view of Picaxe life. To me, this is seems easier than creating a long number & perfoming maths to get the value required?
As a novice, I expect to get shot down in flames!
 

srnet

Senior Member
How would you ensure that the 'loop' spent exactly the same amount of time on 1,2,3,4,5,6 ?

If you dont there would be a (small) bias towards one number.
 

hippy

Technical Support
Staff member
The looping idea is possible, and may be very usable with the M2's using multitasking ...

Code:
[color=Navy]#Picaxe [/color][color=Black]08M2[/color]

[color=Blue]Start0:
  Do
    [/color][color=Purple]w1 [/color][color=DarkCyan]= [/color][color=Purple]w0 [/color][color=DarkCyan]+ [/color][color=Navy]1
    [/color][color=Blue]SerTxd([/color][color=Black]#[/color][color=Purple]w1[/color][color=Black],[/color][color=Red]" "[/color][color=Blue])
    Pause [/color][color=Navy]1000
  [/color][color=Blue]Loop
  
Start1:
  Do
    [/color][color=Purple]w0 [/color][color=DarkCyan]= [/color][color=Purple]w0 [/color][color=DarkCyan]+ [/color][color=Navy]1 [/color][color=DarkCyan]// [/color][color=Navy]6
  [/color][color=Blue]Loop [/color]
 

lbenson

Senior Member
I wonder why the timer variable is not available on the M2 devices. The following program uses a peeksfr $15 to get the value of timer upon pressing and releasing a button on pin c.4 on an 08M2. Randomization is provided by the time delays between button presses.
Code:
#picaxe 08M2

main:
  do
    do while pinc.4 = 0 : loop ' wait for button press
'    w13 = timer ' timer only available on x1,x2
    PeekSFR $15, w13 ' get timer value 
    random w13
    b25 = w13 // 6 + "1"
    sertxd(b25)
    do while pinc.4 = 1 : loop ' wait for button release
  loop
This is the result over 97 button presses: 2211166552135334524445425335353432342352662412343616346135554263465551546212344315314551524313234

It breaks down as follows:
# Instances
1 13
2 15
3 21
4 18
5 20
6 10

Not great. The two most frequently occurring numbers (3 and 5) are twice as likely to come up as the least (6). I don't know how this would work out over multiple trials.

This was on a real chip. This works in simulation with PE5, but returns only "3"s with PE6. PE5 simulation returned "1,3,4,3,3,1,1,1,1,4,2,5,1,6,6,3,2,3,5,4,6,2,1,4,6,2,5,1,6,4,2,3,2,6,2,4,4,4,6,2,6,2,4,4,4,3,6,3,1,4,3,3,3,1,4,6,1,1,1,5,6,4".
 

hippy

Technical Support
Staff member
I wonder why the timer variable is not available on the M2 devices. The following program uses a peeksfr $15 to get the value of timer upon pressing and releasing a button on pin c.4 on an 08M2.
The answer to that is likely that, while PEEKSFR $15 gets an altering with time value, it does not have the equivalent functionality of 'timer' on the X1 and X2. While it may be usable by way of an equivalent there is no guarantee that it always will be in all circumstances.
 

Technical

Technical Support
Staff member
This works in simulation with PE5, but returns only "3"s with PE6. PE5 simulation returned "1,3,4,3,3,1,1,1,1,4,2,5,1,6,6,3,2,3,5,4,6,2,1,4,6,2,5,1,6,4,2,3,2,6,2,4,4,4,6,2,6,2,4,4,4,3,6,3,1,4,3,3,3,1,4,6,1,1,1,5,6,4".

Strange as it sounds it is actually PE6 that has a more accurate random simulation! Peeksfr commands of internal PIC registers are not simulated fully in either PE5 or PE6, but the random command simulation in PE5 always uses a computer seed and hence gives the different values you see (ignoring the word variable seed value). However this is not an accurate use of the seed as in a real PICAXE chip.

PE6 simulation of random command is identical to real-life PICAXE, hence is normally more consistent with a real part in most programs. However here, as peeksfr is not simulated, you always get an identical seed, hence the random result is a consistent 3.
 

Phil bee

Member
Hi Folks, here is my solution to the requirement for a random number hope this helps.

Code:
random w0			'Load W0 with random number
 let b4=b0/4 min 43 max 64		'Divide B0 by 4 and filter out any number below 43 or above 64
 let b7=b0/3/5 min 43 max 64	'Divide B0 by 3 then by 5 and filter out any number below 43 or above 64
 

hippy

Technical Support
Staff member
Hi Folks, here is my solution to the requirement for a random number hope this helps.
I think you might have some transcription error in your posted code ...

let b7=b0/3/5 min 43 max 64

b0/3/5 will only ever deliver a result of 0 to 17, which will then always be upped to a minimum of 43. You would only ever see a value of 43 in 'b7'

let b4=b0/4 min 43 max 64

b0/4 does better, delivering a result 0 to 63, but 67% of the time the 'b4' result will be 43.
 
Top