What is the smallest and simplest seed for a random number generator?

Put a parallel resistor and capacitor between the A/D pin and ground. Make the resistor fairly high, preferably well above the input signal impedance requirement for the A/D. Make the RC time constant maybe around 10 µs. For example, 100 kΩ and 100 pF sounds like a good combination.

To get a value with some randomness, drive the pin high for a while, then set it to high impedance and take a A/D reading a few µs later. Particularly if you properly abuse the A/D acquisition time, the voltage it will see will be dependent on the R and C values, the pin leakage current, other nearby noise, and temperature.

Grab the low bit or the low two bits and repeat as necessary to get any number of random bits.

For a more random pattern, perform this procedure occasionally and inject the low bit of the A/D result into the random number generator you are already using.


Some possible options:

  1. Pre-program a unique serial address for each device. If you have a good enough RNG algorithm, then even a sequential list of serial addresses will produce wildly different results.

  2. Depending on your MCU/setup, you might have two different clock sources available for the system clock and the watchdog timer/timer counter input. If one/both of these have significant variance, you can use this to generate a suitably different seed. Here is an example I wrote which uses an Arduino's internal watchdog timer and an external XTAL system clock.

  3. Use a BJT transistor and build a highly beta dependent amplifier. This can be read from an ADC for the seed.

  4. Capacitors/inductors are typically specified to a much worse tolerance than resistors. You could build some kind of filter circuit (RC, RL, LC) with these and measure the output with the ADC.


What I did for a MP3 player with random capability is to just use a different sequential seed at every power on. I started at 1 and stored this in the EEPROM so that at the next power cycle I used 2 etc. This was on an ATMEGA168. As helloworld922 noted even a simple sequential seed will generate completely different pseudo random sequences.

I used one of the linear congruent random sequence generators, this gives a uniform distribution.

int i;
seed = seed * 2053 + 13849;
i = (seed % max) + 1;  // max is the maximum value I want out of the function

Of course if you want multiple units to have different sequences even though they may have had the same number of power cycles then you need something to start out randomly.

This could be done by any of the methods proposed by the other posters - One method I can think of could use the AC zero crossing going into the processor if you have it (for lamp phase control for example)? This could be used to sample the timer on the first crossing following power-up and then used as the seed.

Are there any push-buttons on the unit to select mode etc? If so you can sample the counter the very first time the button is pushed after the MCU is programmed you can generate a random seed initially and store it in EEPROM. Every Power-up after this point would use the stored seed.