Go Down

### Topic: Re: Random() (Read 2670 times)previous topic - next topic

#### dhenry

##### Nov 18, 2012, 01:31 amLast Edit: Nov 20, 2012, 03:44 am by Coding Badly Reason: 1

Off-topic posts split from...
http://arduino.cc/forum/index.php/topic,132949.0.html

Seed the random number generator with your adc: adc a spare pin and get its lowest bit for as many times as you need - 8 times if your seed is an 8-bit type and 32-times if your seed is a 32-bit type.

#### iluvplanes

#1
##### Nov 18, 2012, 01:32 am
I'm not sure if I completely understand what you are saying... I'm a real newbie w/ the arduino IDE.

#### Docedison

#2
##### Nov 18, 2012, 01:39 am
He doesn't either or he would have offered his opinion... FWIW.

Bob
--> WA7EMS <--
"The solution of every problem is another problem." -Johann Wolfgang von Goethe
I do answer technical questions PM'd to me with whatever is in my clipboard

#### dhenry

#3
##### Nov 18, 2012, 02:56 am
Quote
I'm not sure if I completely understand what you are saying

The approach I outlined will provide a truly random number.

#### dhenry

#4
##### Nov 18, 2012, 01:10 pm
That looks good.

One suggestion: you want to seed the random number generator with a truly random number. So do successive fills with the adc's lowest bit.

Code: [Select]
`  unsigned long tmp = 0x01, rseed=0;  //create a 32-bit random number  do {    if (analogRead(1) & 0x01) rseed |= tmp; //test bit 0    else rseed |= 0x00;    tmp = tmp << 1; //left shift the mask  while (tmp);    randomSeed(tmp); //seed the random number generator`

I would actually use rand() and srand() for their portability.

#### dhenry

#5
##### Nov 18, 2012, 01:11 pm
You can actually use this approach to generate a truly random number (vs. the pesudo random number from rand() or random()), but it takes a lot more time.

#6
##### Nov 18, 2012, 02:41 pm
Using the LSB of an ADC reading can give pretty good results, but even with whitening it's not truly random.

There's a mega thread around where I (and others) tried it, when you graph the results you get definite banding.

It's well good enough for most applications though.

_____
Rob
Rob Gray aka the GRAYnomad www.robgray.com

#### dhenry

#7
##### Nov 18, 2012, 04:05 pm

Code: [Select]
`unsigned short myanalogRead(unsigned char pin) {  ADMUX = 0x00;  //Vref = DEFAULT, adc on adc0, right justified  ADCSRA =  (1<<ADEN) |    //enable adc            (0<<ADSC) |    //don't start the adc yet            (0<<ADATE) |  //no auto sampling            (1<<ADIF) |    //clear adc flag by writing 1 to it            (0<<ADIE) |    //no adc interrupt            (1<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);  //1/16 adc prescaler  ADCSRA |= (1<<ADSC);      //start the conversion  while (ADCSRA & (1<<ADSC)) continue; //wait for the conversion to end      return ADC;}`

#### dhenry

#8
##### Nov 18, 2012, 04:09 pm
First 2500+ data points using the stock analogRead():

#9

#### dhenry

#10
##### Nov 18, 2012, 04:21 pm
Looks pretty random to me.

#11
##### Nov 18, 2012, 05:13 pm
Yes it does. I used analogRead() IIRC, interesting difference I wonder why. Maybe the /16 div factor you're using, They seem to use 2.

_____
Rob
Rob Gray aka the GRAYnomad www.robgray.com

#12
##### Nov 18, 2012, 09:47 pm
google rand() srand().  The approach I outlined will provide a truly random number.

No, it doesn't.  Using your function, I get a steady stream of...

Code: [Select]
`1023102310231023102310231023...1023`

I'll give you a hint, @dhenry, making a claim that something provides "truly random numbers" requires a mathematical proof.  Posting a single function with one person's casual observations is not even close.

#### dhenry

#13
##### Nov 18, 2012, 10:46 pm
With the stock analogRead(), here are the top value counts after about 2500*8 samples:

Code: [Select]
`value  count0 10784 9642 8921 8910 8164 7980 788 7885 772 77`

#### dhenry

#14
##### Nov 18, 2012, 10:55 pm
Quote
Maybe the /16 div factor you're using,

That's not done without reason,

Quote
They seem to use 2.

Go Up

Please enter a valid email to subscribe