Random number seed

Any recommendations as to what can be used for seeding the pRNG ? Is there any semi-random value that can be used after startup? I was thinking about using analogRead from some unconnected port but I don't know if that value is going to be sufficiently random every time I start the chip.

Using analogRead from an unconnected port is commonly done. I don't know for sure how effective it is (always been a bit curious) but it's commonly used, and easy to test how effective it is by printing it.

I've used liberlab to monitor 4 channels of analog inputs from the Arduino. I would say it is not a great source for random seed as while there is noise all the disconnected analog values are under 5% or so of full scale. If there is a valid analog voltage wired to any one of the pins the other pins tend to raise somewhat, most likely from small amount of capacitance coupling between the floating inputs and the valid wired input. So maybe of some value for a seed value but I would look for something better. Isn't there some free running counter register that one could read instead?

Lefty

I've read somewhere something about big capacitors being used for the electrical noise they make.

Correct me if I'm wrong : white noise is a true random noise because each frequency of the spectrum is equally present. so, a white noise generator would be a good source of random number, wouldn't it ?

Here's what I found :
http://www.ciphersbyritter.com/NOISE/NOISRC.HTM
http://www.musicfromouterspace.com/analogsynth/multinoisemodule_exp.html

And an interesting source for randomness :

IF -- and that's a capital IF -- your application receives input at an unpredictable amount of time after it starts up, then millis() can be an excellent seed for random(). For example, I have a little toy I made for my son. To play, he plugs it in, and anytime after the several seconds of startup stuff is finished, he presses a button indicating he wants to play. I use the value of millis() to seed the random() at that time.

The advantage is that the range of possible seed values is several thousand (or possibly much more depending on when he pushes the button) compared to the maximum of 1024 that you could get in theory -- in practice much less -- from analogRead. The microsecond counter might be much better.

However, this technique might not be appropriate for your application. It certainly would NOT be appropriate to use millis() at some fixed point in your setup() function.

I've often thought that analogReading two different pins and combining their values might be an improvement, but I have never tried this:

 long seed = analogRead(pin1) + 1024 * analogRead(pin2);

Mikal

I have not had a chance to read out the values, but instead looked at results posted on the wiring forum. It seems like there is some suitable randomness on floating analog pins, but that the values hover around 0v. Something like this: 0 0 0 71 24 56 0 0 3 34 0 0 0 62 1 8

I am wondering if writing do (value=analogRead) while value!=0 would do the trick. The seed is required prior to user interaction otherwise waiting for a button press would be a nice solution.

With the do while statement, if you're unlucky, you can experience some really long hang times. Might work but not really good.

I just thought of the best seed idea ever! At setup() time, read a 2-byte (or 4 depending on which version of rand/random you're using) seed from, say, offset 496 of the EEPROM. Then immediately call rand (or random) and write the resulting 2 (or 4) bytes back at the same offset. Then you'll be guaranteed a nice random seed every time you power up your Arduino.

Mikal

mikalhart, that makes it persistent, but it does have the (very small) risk of wearing out that cell in the EEPROM. Power-ups happen far more often than sketch uploads, in some situations. I would definitely write at least four bytes, maybe more, and XOR longer seeds together.