Pages: [1] 2   Go Down
Author Topic: Re: Random()  (Read 1075 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


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.
« Last Edit: November 19, 2012, 09:44:16 pm by Coding Badly » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 39
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm not sure if I completely understand what you are saying... I'm a real newbie w/ the arduino IDE.
Logged

Anaheim CA.
Offline Offline
Faraday Member
**
Karma: 46
Posts: 2865
...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

He doesn't either or he would have offered his opinion... FWIW.

Bob
Logged

--> 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

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I'm not sure if I completely understand what you are saying

google rand() srand().

The approach I outlined will provide a truly random number.
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
  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.
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8472
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is the 1st ~2000 of adc data, using myanalogRead():

Code:
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;
}

I had it fixed on adc0.



* adc rand.PNG (27.64 KB, 578x424 - viewed 11 times.)
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

First 2500+ data points using the stock analogRead():



* adc rand analogRead.PNG (19.45 KB, 578x431 - viewed 11 times.)
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

myanalogRead(), over 4500 samples.



* adc rand 4500.PNG (31.18 KB, 580x432 - viewed 9 times.)
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Looks pretty random to me.
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8472
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 199
Posts: 12767
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
1023
1023
1023
1023
1023
1023
1023
...
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.
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

With the stock analogRead(), here are the top value counts after about 2500*8 samples:

Code:
value  count
0 107
84 96
42 89
21 89
10 81
64 79
80 78
8 78
85 77
2 77
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Maybe the /16 div factor you're using,

That's not done without reason, smiley

Quote
They seem to use 2.

smiley
Logged

Pages: [1] 2   Go Up
Jump to: