Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Need Simple Random Function

Status
Not open for further replies.

GreyHairOldGuy

New Member
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.....

Tks in advance

Mike
 
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.
https://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.
 
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
 
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.
 
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:
//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.
 
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:
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:
Try changing it to,
Code:
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.
 
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:
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:
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:
If you want it between 1 and 36 then do,
Code:
'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.
 
A more random sequence can be had using the feedback polynomial x8 + x6 + x5 + x4 + 1. See LFSR.

Code:
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.
 
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.
 
As you have seed defined as a word you may as well use the longer sequence,
Code:
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.
 
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!
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top