Random Seeds and Random Numbers

What is the best (read: less likely to repeat over time) random-number generator that I can get on my arduino? I have a project in which I want the "random" start conditions to be different every time. analogRead()ing a floating pin seems to be the accepted practice, however, these values often repeat: I took about 20,000 samples on an unconnected pin; all of them fell between 300 and 550. Would digitalRead()ing an unconnected pin be better? Also: I don't really care about time as long as the computation doesn't take some hideously long amount of time. Under a second or so is fine.

Thanks a lot!

baum

Would digitalRead()ing an unconnected pin be better?

What range of values would you expect?

Just reading an analog input won't do it. We've talked about accumulating the LSB of consecutive analogRead()s in the past. That works OK but still has clumping of values.

Have a search for this on the forum, there are a couple of mega threads about it and several suggested algorithms.


Rob

I've ran across tinkerit's TrueRandom library. Maybe that will give you better results?
http://code.google.com/p/tinkerit/wiki/TrueRandom

Disclaimer: I am in no way, shape, or form, neither physically, nor mentally, related, linked, or otherwise part of the tinkerit team. I just happen to stumble across that library one day. I have not had a chance to test it out either.

Would digitalRead()ing an unconnected pin be better?

What range of values would you expect?

Assume I need an int: then I would get 16 readings and combine them. Also, a binary method may be more random as a floating analog pin may have a reading of, say, 500, no such value exists in the digital realm, hopefully causing the random-ish-ness that we would like.

I looked at TrueRandom, but it uses analog readings...

baum

Have a look at this thread

http://arduino.cc/forum/index.php/topic,66206.15.html

Plenty of info there about using analog and other methods.

then I would get 16 readings and combine them

Better off taking a lot more and using a "whitening" technique to smooth out the runs of 1s and 0s.


Rob

Random number generators aren't.

You could try using a Geiger counter and radiation source like maybe from a smoke detector.

Yep. Bottom line it that without an external entropy source there appears to be no way to get true random on an Arduino.

For many applications the "accumulating the LSB of several analogReads" does pretty well, it depends on just how important it is to have true random.


Rob

If avoiding repetition is your main concern, the easiest thing to do is to store a random seed in eeprom. The logic goes something like this:

  • Startup
  • Read number from eeprom and use it to seed the random() function
  • Use random() to generate a new seed for next time
  • Check that the new seed is not the same as the previous, and save it in eeprom
  • Run the rest of the program

That is still not random, the pattern is totally predictable and will be the same for every Arduino running the code, unless you seed the EEPROM with a genuine random number, maybe from the PC when you burn the chip.


Rob

Hold on.... Would this be of any use?

Or what if I tied one inverter's input to its output? ----> high freq. oscillation!!!!

I was thinking of the eeprom, but, as Rob pointed out, it will repeat across many arduinos.

Any ideas?

baum

I've ran across tinkerit's TrueRandom library. Maybe that will give you better results?

No. It has at least two serious flaws.

This is reliable...

Store an initial random seed in the EEPROM. The following are a good source for the initial seed(s)...

baum:
Hold on.... Would this be of any use?

Intel’s New Way Of Creating Randomness From Digital Orderliness | Hackaday

Or what if I tied one inverter's input to its output? ----> high freq. oscillation!!!!

I was thinking of the eeprom, but, as Rob pointed out, it will repeat across many arduinos.

Any ideas?

baum

If the running sketch allows then new value(s) could be stored to EEPROM. Use the low-order digits from the stock market report for instance and maybe have the PC communicating the new data modify those using date-time digits if the one isn't enough. OTOH without a PC, waving the thing around to gather light level data combined with capacitance or sound readings might do.

But couldn't a high-freq oscillating inverter be read as a random-ish source? Not too much hardware/software needed. (propogation time of the inverter: ~10ns on 7404, so ~100MHz)

baum

Heh guys;

I read in one of my electronics magazines is to use a transistor circuit which is a "noise generator" transistor circuit. So connect the output to one of the analog input pins, you may have the choice of reading between 0 to 1024 ( between 0 to 5V ).

To bad I can not find that schematic.

My idea...

Yep there are methods that use diode-junction noise, presumably the signal has to be amplified but that's all a bit analog for me :slight_smile:

As for the '04 oscillator, I really don't know, might work. Technically the oscillator and Arduino are still in sync but you don't need much of a change at 100MHz to get a different reading. Maybe if you feed the read value back into the oscillator to vary it just a tad. Say use the bit read as an output that is connected to the '04 through a 1M/10M resistor or some such.

Both these need external hardware though.


Rob

If non-deterministic randomness is needed as well as non-repeating randomness, you'll need a proper noise generator such as like this one from Mixed-signal and digital signal processing ICs | Analog Devices

We don't need the higher frequencies (>10kHz), so filter them out before the first amplifier. You don't have to use those particular amplifiers, any decent op-amp will do. Connect the output to an analogue pin and ensure that the amplitude of the resulting waveform is much larger than the ADC resolution, but still comfortably within the ADC's input range.

To generate an n-bit random number: read the adc n-times (with a few ms pause between each read) and keep the LSBs of each readout.

My first thought was why use an LNA, then I read the posts on that appnote

Q: Why use a low-noise amp when you want nose?
A: Because nobody makes a high-noise amp.

Good point :slight_smile:


Rob

Something like this: RNG Version 2 ?

maybe I'll take a look at that.

I believe there is a minimum voltage (more than 5V) for the circuit to work correctly. The author calls for a "12v DC Adapter". The motivating design also calls for 12 volts.

There is no evaluation of the data quality. Data that looks random is often not. If you are building something that requires good quality data, you should perform the evaluation. Given the references to "aging", occasionally reevaluating the quality may be necessary.

I suspect component (or board) aging was the culprit.

...indicates that the circuit may eventually become unreliable.