# Need Simple Random Function

Discussion in 'Oshonsoft' started by GreyHairOldGuy, May 30, 2011.

1. ### GreyHairOldGuyNew Member

Joined:
May 30, 2011
Messages:
12
Likes:
0
Location:
I am playing with my new Oshonsoft PIC Basic and really enjoying it. I am coming from Microengineering labs PicBasic Pro, and my first (perhaps wrong) impression is PBP may have had a little more extended instruction set, but the emulation feature of OshonSoft makes up for that many many times over. I remember hours spend trying to send out serial data from different parts of my program, trying to figure out where I went wrong.

I am just flashing some LED's and playing with the software, but I am used to having a Random instruction which gives back a pseudo random number when executed. Is there a simple random number generator someone could give me using a few Oshonsoft basic instructions? I tried a multiply, taking parts of the answer and feeding it back to the operands, but once you get a zero operand, (which seems to happen fairly quickly), it's game over.

Someone much smarter than me must have addressed this problem before.....

Mike

Joined:
Oct 27, 2006
Messages:
14,047
Likes:
141
Location:
Rochester, US
Linear Feedback shift registers. It's pretty simple, a feedback point is selected from on bit to another using the XOR instruction and the result is shifted.
http://en.wikipedia.org/wiki/Linear_feedback_shift_register

VERY easy to implement, even large ones are simple if the right bit length is chosen for the destination. A four bit LFSR can be obtained using only a single XOR and shift instruction, the same can be said for 5, 6, and 7 bit results 9, 10, 11, 15, and 17-18 as well I believe.

A greater bit depth for the random sequence does NOT mean more random though. IF you read the LFSR article on Wikipedia it will help.

3. ### GreyHairOldGuyNew Member

Joined:
May 30, 2011
Messages:
12
Likes:
0
Location:
Tks - Your Random Number idea seems to work fine - Here is my program (improvements?)

'PIC Random Number Generator
'8/16 Bit Random # - answer in RDM
'see wikipedia "LFSR"

Define SIMULATION_WAITMS_VALUE = 1

Dim sed As Word '16 bit working rnd
Dim t02 As Bit 'interm xor1
Dim t023 As Bit 'interm xor2
Dim t0235 As Bit 'interm xor3
Dim rdm As Byte 'output count
sed = 0xace1 'set initial seed

'(not sure if initial value of seed maters - just took your example)

loop:
t02 = sed.0 Xor sed.2 'tap 0&2
t023 = t02 Xor sed.3 'tap 0&2&3
t0235 = t023 Xor sed.5 'tap 0&2&3&5

'(I learned about "Watch Variables" while trying to make this work!)

sed = ShiftRight(sed, 1) 'right shift 1
sed.15 = t0235 'add in xor bit
rdm = sed.LB 'get bottom 8 bits

Goto loop 'repeat forever

4. ### DaveNew Member

Joined:
Jan 12, 1997
Messages:
-
Likes:
0

Joined:
Oct 27, 2006
Messages:
14,047
Likes:
141
Location:
Rochester, US

If you can limit the bit depth requirements of your number generator there are specific bit depths (that I mentioned previously) which require only a single xor instruction. If you can't then the multiple feedback points work fine, they just take more instructions.

The seed is important, If you don't use another truly random event to seed the random number generator when the device turns on it will always produce the exact same chain of numbers. The typical method for determining the seed is button press time events or a portion of the bits used for a digital debounce. The longer the number of bits the longer it will take for the random bytes to recycle, but you'll also get strings of sequential values that are artificial to a true random number, which is why they're called pseudo random.

6. ### PommieWell-Known MemberMost Helpful Member

Joined:
Mar 18, 2005
Messages:
10,158
Likes:
339
Location:
Brisbane Australia
I posted a random number generator a while back in this thread.

For simplicity, here it is again. It's in Swordfish basic but should be easy to convert.
Code (text):
//global variables
Dim Seed As LongWord

Function Rand(Range As Byte) As Byte
Dim i As Byte, feed As Bit, temp As Word
For i = 0 To 7                      //generate 8 new bits
Feed = Seed.30 Xor Seed.27      //make new bit
Seed=Seed*2+Feed                //shift left and add new bit
Next
Temp=(Seed And 255) * Range         //convert from 0-255
Rand = Temp/256                     //to 0-Range
End Function

It returns a number between 0 and range-1 when called. So Rand(23) will return 0 to 22.

Mike.

7. ### cyberskyMember

Joined:
Apr 1, 2009
Messages:
64
Likes:
0
hi
i am unable to convert the swordfish function to oshonsoft. Anyone else have a simple random function for oshonsoft ? or maybe a howto? Have googled but the stuff looks complex.

this is what i tried. but after 1 run the variables all clear.
Code (text):

Dim i As Byte
Dim feed As Bit
Dim temp As Word
Dim seed As Word
Dim rand As Byte
seed = %11010101

playframe:

For i = 0 To 7  '/ / generate 8 new bits
feed = seed.3 Xor seed.2  '//make new Bit
seed = ShiftLeft(seed, 1)  'seed = seed * 2  '+ feed  '//shift left And add new Bit
seed.7 = feed  '//shift left And add new Bit
Next i
temp = seed And 255
'i would like to only have 1 to 36 as rnd values.
temp = temp * 36  '//convert from 0-255
rand = temp / 256
seed = seed + rand
WaitUs 1
'loop it to see how "random" they are
Goto playframe

Last edited: Jun 7, 2011
8. ### PommieWell-Known MemberMost Helpful Member

Joined:
Mar 18, 2005
Messages:
10,158
Likes:
339
Location:
Brisbane Australia
Try changing it to,
Code (text):

For i = 0 To 7  '/ / generate 8 new bits
feed = seed.3 Xor seed.2  '//make new Bit
seed = ShiftLeft(seed, 1)  'seed = seed * 2  '+ feed  '//shift left And add new Bit
seed.[COLOR="red"]0[/COLOR] = feed  '//shift left And add new Bit
Next i
temp = seed And 255
'i would like to only have 1 to 36 as rnd values.
temp = temp * 36  '//convert from 0-255
rand = temp / 256
seed = seed + rand
WaitUs 1

Mike.

9. ### cyberskyMember

Joined:
Apr 1, 2009
Messages:
64
Likes:
0
thanks mike,
code is however only giving me 2 values, 10 and 19 although it starts of with 31,7 then 10, 19, 10, 19 .....
I figured by adding rand to the seed value we would always have a new seed value which would mean a more "random" number ??

Code (text):

For i = 0 To 7  '/ / generate 8 new bits
feed = seed.[COLOR="Red"]7[/COLOR] Xor seed.2  '//make new Bit
seed = ShiftLeft(seed, 1)  'seed = seed * 2 '+ feed '//shift left And add new Bit
seed.0 = feed  '//shift left And add new Bit
Next i

changed seed.3 to seed.7 and it is giving me a "wider" range of numbers - I am still checking when it starts to loop again, which if ok as long as i can have at least 30 or 40 "random" numbers in the sequence.

Last edited: Jun 8, 2011
10. ### cyberskyMember

Joined:
Apr 1, 2009
Messages:
64
Likes:
0
i just did a quick chk of st 100 values and it look pretty good - for values between 1 and 36 only 8 did not come up. I did notice a few 0's. If i use the tmr0 as seed value when i need the random function i assume i would be able to get a "new" value everytime the pic restarts ?
thanks again

-update:
when i change the seed = %11000111

i only get 4,34,24 !! I think i am wondering in the dark could you please shed some light on this matter ? I was surprised to find that oshonsoft did not have a random function. quite a few of the "other" pic basic packages actually have one, even though it is not TRUELY random, i understand but a random function none-the-less !

Last edited: Jun 8, 2011
11. ### PommieWell-Known MemberMost Helpful Member

Joined:
Mar 18, 2005
Messages:
10,158
Likes:
339
Location:
Brisbane Australia
If you want it between 1 and 36 then do,
Code (text):

'i would like to only have 1 to 36 as rnd values.
temp = temp * 36  '//convert from 0-255[COLOR="red"] to 0-35[/COLOR]
rand = temp / 256
[COLOR="red"]rand=rand+1         <<< will make it 1 to 36[/COLOR]
seed = seed + rand  [COLOR="red"]<<< I would remove this[/COLOR]
WaitUs 1

Mike.

12. ### PommieWell-Known MemberMost Helpful Member

Joined:
Mar 18, 2005
Messages:
10,158
Likes:
339
Location:
Brisbane Australia
A more random sequence can be had using the feedback polynomial x8 + x6 + x5 + x4 + 1. See LFSR.

Code (text):

For i = 0 To 7  '/ / generate 8 new bits
feed = seed.7 Xor seed.5 Xor seed.4 Xor seed.3 Xor 1  '//make new Bit
seed = ShiftLeft(seed, 1)  'seed = seed * 2  '+ feed  '//shift left And add new Bit
seed.0 = feed  '//shift left And add new Bit
Next i
temp = seed And 255
'i would like to only have 1 to 36 as rnd values.
temp = temp * 36  '//convert from 0-255
rand = temp / 256
rand=rand+1

Mike.

13. ### cyberskyMember

Joined:
Apr 1, 2009
Messages:
64
Likes:
0
mike, i believe we have a very good random number generator - for the 1st 100 it got 35/36 !
I believe i can proceed to test on actual chip.
thanks again.

14. ### PommieWell-Known MemberMost Helpful Member

Joined:
Mar 18, 2005
Messages:
10,158
Likes:
339
Location:
Brisbane Australia
As you have seed defined as a word you may as well use the longer sequence,
Code (text):

For i = 0 To 7  '/ / generate 8 new bits
feed = seed.15 Xor seed.14 Xor seed.13 Xor seed.11 Xor 1  '//make new Bit
seed = ShiftLeft(seed, 1)  'seed = seed * 2  '+ feed  '//shift left And add new Bit
seed.0 = feed  '//shift left And add new Bit
Next i
temp = seed And 255
'i would like to only have 1 to 36 as rnd values.
temp = temp * 36  '//convert from 0-255
rand = temp / 256
rand=rand+1

This will not repeat itself for 8000 numbers.

Mike.

15. ### cyberskyMember

Joined:
Apr 1, 2009
Messages:
64
Likes:
0
I love it when a plan comes together ! maybe we should contact the oshonsoft guy and send him this piece of code to build into his ide ? I am sure this is going to be a popular thread,
Thanks for the quick responses and the help on fixing the code!