Arduino 32-bit Random

Overview

PyPi module N/A
git repository https://bitbucket.org/arrizza-public/arduino-32-bit-random
git command git clone git@bitbucket.org:arrizza-public/arduino-32-bit-random.git
Verification Report https://arrizza.com/web-ver/arduino-32-bit-random-report.html
Version Info
  • Ubuntu 20.04 focal, Python 3.10
  • Ubuntu 22.04 jammy, Python 3.10

Summary

How to generate 32-bit Random integers on an Arduino using random noise as the random number generator seed.

See One-at-a-Time Hash http://burtleburtle.net/bob/hash/doobs.html This is being used for calculating a unique random hash value. I use the A0 pin on the arduino to get random 10 bit values from the noise in the electronics. Then apply the One-at-a-Time Hash to convert that to a randomized 32-bit value. The assumption is that the A0 pin is unconnected.

And since the random sequence was available, I used it to double-check whether the random() function reporting actual random numbers. I use the mean and standard deviation of those values. See https://arrizza.com/on-the-fly-stats for calculating these values on the fly (in python). Those techniques came from:

Usage

  • To cause the seed to be recalculated, send an 'x' (click "Send" on CLion's Serial Monitor).
  • To set the seed to a specific value, send digits e.g. '10' will set it to 10.
  • To show a sequence of seeds, send 's'. To revert back to random values, send 's' again.

Statistics

The random values (1 - 10) are used to calculate the mean and standard deviation of the sequence. The mean should be 5.5 and the standard deviation should be 2.873 (or so). The counts of how many 1's, 2's etc. are found are shown as well. For example:

num:20000, mean:    5.529, stdev:    2.865, current val:         2
[1]: 1969  [2]: 1941  [3]: 1949  [4]: 2014  [5]: 2084  [6]: 2050  [7]: 1917  [8]: 2041  [9]: 1996 [10]: 2039 

shows there were 1969 1's. Given the total samples was 20,000, there should be an even distribution across 1 through 10, i.e. there should be 2000 1's.

These expected values can be double-checked using the check_stddev.py script on your PC. This currently runs 1_000_000 random() calls and checks stddev and mean. I've run it with 10_000_000 calls and the totals are very similar.

$ python3.10 check_stddev.py
Std : 2.872 exp = 2.873
mean: 5.500 exp = 5.500
[0, 100260, 99814, 99791, 100022, 99825, 100107, 100424, 99871, 100024, 99862]

Setup

Sets up the Serial port and does an initial seed of the random number generator.

Main Loop

Checks to see if there is any input and if so uses that to set the seed. Then spins as quickly as possible generating random values from 1 to 10. It calculates the stats and counts for that value.

Periodically it spits out the current values.

num: 4246000, mean:     5.498, stdev:     2.841, current val:          2
[1]:424365  [2]:425415  [3]:424662  [4]:424922  [5]:425128  [6]:423433  [7]:424607  [8]:425311  [9]:424562 [10]:423595 

Notes

  • the stats are only a double-check, not conclusive proof that random() is as random as it should be.

- John Arrizza