Go Down

Topic: Re: Random() (Read 1 time) previous topic - next topic

dhenry

Nov 18, 2012, 01:31 am Last 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

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

Docedison

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

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.

dhenry

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

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.

Graynomad

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

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

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


I had it fixed on adc0.


dhenry

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


dhenry

myanalogRead(), over 4500 samples.


dhenry

Looks pretty random to me.

Graynomad

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

Coding Badly

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

dhenry

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

Code: [Select]

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


dhenry

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

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy