# Re: Random()

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.

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

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

Bob

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

The approach I outlined will provide a truly random number.

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.

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

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.

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

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

``````unsigned short myanalogRead(unsigned char pin) {
ADMUX = 0x00;  //Vref = DEFAULT, adc on adc0, right justified
(0<<ADSC) |    //don't start the adc yet
(0<<ADATE) |  //no auto sampling
(1<<ADIF) |    //clear adc flag by writing 1 to it
while (ADCSRA & (1<<ADSC)) continue; //wait for the conversion to end

}
``````

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

myanalogRead(), over 4500 samples.

Looks pretty random to me.

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

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

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

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

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

Maybe the /16 div factor you're using,

That's not done without reason, :)

They seem to use 2.

:)

dhenry doesn't need facts, he has an opinion about [u]everything[/u] and he IS NEVER wrong. Just ask him...

Bob

If you want true randomness, try biasing a diode near the "knee" of the I-V curve (around 0.7V for a silicon diode). The current will fluctuate randomly due to thermal noise.

73, NV1T

You already have that diode, in some mcus with a temperature sensor;

But the thermal noise is too small to produce a truly random figure by the onboard adc.

Yeah, you might need to amplify it with an op-amp circuit. I built one of these many moons ago. Y'all should read this informative article: http://en.wikipedia.org/wiki/Hardware_random_number_generator

73, NV1T

There is an easier way: reverse connect a npn to form an esaki diode. Power that up via a capacitor + a low. It will form a flasher. The period of its flashes is random and can be easily measured by a timer.