Projects Research & Design Hub

Machine Vision Random Number Generator – Using the Raspberry Pi

Written by Dev Gualtieri

Computers seem good at random number generation. But in truth their random numbers are merely pseudorandom because computer programs are inherently deterministic. Here, Dev presents a random number generator that uses machine vision to acquire true randomness from a physical source.

  • How build a machine vision-based random number generator

  • What are different electronics alternatives for creating random numbers?

  • How does machine vision randomness work?

  • How to integrated Raspberry PI SBC and other components in a small enclosure

  • How in implement an interface board design with voltage-level shifting

  • How to set up the Raspberry PI OS

  • How to set up your image capture system

  • How to write an random number processing program

  • How to design the display and web browser interface

  • How to test your randomness results

  • Raspberry PI SBC

  • Raspberry Pi OS

  • YoLuke HD Webcam

  • LED light source

  • LCD display

  • 2N7000 MOSFET

  • Anjuta IDE

  • PCF8574 interface board

  • Python programming language

  • a mirror

  • acrylic spray paint

In the time before computers (BC), our ancestors used simple methods, such as throwing dice, to generate random numbers. Although our computers seem to be capable of spewing random numbers at a much higher rate, these numbers are not random, they’re pseudorandom. Computer programs are deterministic algorithms that are completely predictable at some base level. In this article, I share my design of a random number generator based on the Raspberry Pi that uses machine vision to harvest true randomness from a physical source.

An important part of my childhood education was frequent trips to the public library. Our city with a population of 100,000 had a huge public library that was well stocked with books and periodicals. I enjoyed randomly browsing the stacks—the yesteryear equivalent of evoking the random page feature on Wikipedia [1]. In my adventures among the stacks, I chanced upon an article that described an early attempt at using random numbers to generate poetry using a computer. This work was done at Bell Labs, where random numbers were likewise used to create art and computer music.

Reading that article was one of several things that sparked my interest in random numbers and random number generation that continued throughout my career. In the days of impact printing, I used random numbers to program the daisy wheel printer in my office in a simulation that made it sound as if I was hard at work typing when my office door was closed. In that case, the randomness was 1/f noise—a type of noise that’s less random than white noise.

Human culture has embraced randomness in such activities as reading tea leaves and flipping Tarot cards for predicting the future. Throwing dice in gaming has been done for millennia, and randomness is built into our modern slot machines. There are non-gaming uses of randomness in computer simulation, such as the Monte Carlo method used in physics, statistical sampling and statistical analysis of experiments.

Most computer applications will perform adequately using simple random number generators, but due care must be taken in the generation of cryptographic quality random numbers—the ones that are used to encode secret communications against technologically advanced adversaries. Just as an individual would be unwise to use “1234” as a PIN number, cryptographers want to “seed” their random number generators with unique starting values to produce better randomness.

Programming languages have always had random number functions, and these have improved over the decades. The earliest of these used a simple algorithm called a linear congruential generator (LCG). The GNU C compiler uses an improved version of this generator, but LCGs should not be used when good quality random numbers are needed. Many of today’s languages, including Python and PHP, use a much more complicated algorithm called the Mersenne Twister, which, as its name implies, involves the Mersenne primes [2].

Aside from its being a generalized feedback shift register, it’s somewhat hard to describe. It’s used as the random number generator not only in Python and PHP, but also the popular Mathworks MATLAB environment, the R statistical package and some other programming languages. It has a 32-bit implementation, called MT19937, based on the 24th Mersenne prime, that has a period 219937 – 1. There is also a 64-bit version called MT19937-64 [3].

As computer pioneer, John von Neumann, so famously stated in 1951: “Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin.” He realized that computers just follow some algorithm to generate their random numbers, so these apparently random numbers are completely predictable if the algorithm and its initial state is known. That didn’t stop him from using such random numbers for mathematical modeling of complex systems, since they’re good enough for such things. However, their potential predictability makes them not well suited for cryptography. That’s why sources of true randomness are important.

Nature has given us many sources of true randomness. In 1926, John B. Johnson of Bell Labs discovered that any resistor at temperatures above absolute zero has a random voltage noise across its terminals. Harry Nyquist, a colleague of his at Bell Labs, was able to explain this phenomenon, and we now call it Johnson-Nyquist noise. This noise is very small. A 1kΩ resistor at room temperature—measured over a 10kHz bandwidth—has an RMS (root mean square) noise voltage of just 400nV, but it can be amplified and used to generate random numbers.

Although the primary purpose of a Zener diode is to act as a voltage reference or voltage limiter, a reverse-biased Zener diode will produce a noise voltage far greater than that of a resistor. A basic circuit is shown in Figure 1, and two amplifiers are usually cascaded to produce volt-level signals. Zener diodes with higher breakdown voltage will produce stronger noise signals, so circuits with high supply voltage (12V rather than 5V) are preferred. The analog voltage noise produced by Zener diodes and resistors can be converted into a digital bitstream with additional circuitry.

Figure 1
A Zener diode noise source. The amplification needs to be large, and this leads to the addition of amplifier noise to the signal. While truly random noise (“white noise”) is independent of frequency, amplifier noise has a frequency dependence. Amplifier noise is “1/f noise” also called “flicker noise.”


Advertise Here

Heisenberg’s uncertainty principle is a well known feature of quantum mechanics, and uncertainty is a source of randomness. This sentiment was echoed by Einstein, who wrote that quantum mechanics was like “God playing dice with the world.” Radioactive decay in the tick-tick of a Geiger counter can be a source of random numbers, because the time interval between ticks is random. Since Geiger counters should click very slowly, scientists at the National Institute of Standards and Technology (NIST) developed a quantum voltage noise source (QVNS) in 1999. Their QVNS uses a superconducting junction based on a quantum mechanical effect known as the Josephson effect.

It’s unlikely that you will stock QVNS chips in your electronics parts bin, given that they only work at cryogenic temperatures. However, NIST has an online Randomness Beacon ( that produces a 512-bit random number every minute—together with a timestamp of its creation—and a hash with the previous value. The Beacon website does have one caveat: The random numbers should not be used as cryptographic keys.

One novel physical random number generator, created in the late 1990s by Silicon Graphics, is Lavarand. Lavarand generated random numbers from images of active lava lamps. The images are random, since the behavior of the bubbles of simulated lava is not predictable (Figure 2). The method of creating random numbers from images is described in US Patent No. 5,732,138, “Method for seeding a pseudo-random number generator with a cryptographic hash of a digitization of a chaotic system [4].” There was once a Lavarand website that served-up random numbers, but Silicon Graphics is now defunct, and so is the web site.

Figure 2
This lava lamp was purchased about 20 years ago, and it was in storage for most of that time. When I plugged it in, it still worked. The lava lamp was invented in the 1960s. Heat from an incandescent light bulb at the base reduces the density of a modified parafin material, so it floats to the top. It’s cooler at the top, so its density increases, and it returns to the base.While the original lava lamp patent (US Patent No. 3,387,396) has long since expired, the compositions of the “lava” materials are kept as trade secrets by manufacturers. The original lava, as listed in the patent, could contain carbon tetrachloride—a nasty chemical.

The lava lamp idea has been picked up by the website-security company, Cloudflare, which has a Wall of Entropy at its San Francisco offices [5]. The Wall of Entropy has multiple rows of lava lamps that are imaged to produce random numbers. These numbers are combined with random numbers from other sources of randomness to produce random numbers presumed to be cryptographically secure. Cloudflare has joined with other international randomness creators to form a “League of Entropy” to distribute random numbers on the Internet [6].

A wall of lava lamps would be a decorative addition to my home office, but there are less expensive ways to produce physical randomness. I searched craft stores and supermarket shelves looking for some suitable candidates. Shown in Figure 3 are 50:50 mixtures of easily obtained black and white components. High contrast between black and white is preferred.

Figure 3
Household sources of image randomness. (a) Black and clear plastic craft beads. (b) Black dyed and white pearled couscous pasta. (c) Black and white microbeads used as fingernail decoration. (c) Oriental black rice and white rice.

The contrast of the black and clear craft beads shown in Figure 3a is passable. The pearled couscous pasta in Figure 3b has great contrast, but the image granularity is somewhat large since the diameter of each pearl is about 4mm. Black dying of the couscous was accomplished using an acetone extraction of the ink from a black permanent marker. It’s interesting to note that black in such markers is actually a very dark blue.


Advertise Here

Figure 3c shows a much better option. These are 0.6mm microbeads used in fingernail art, not stocked in any of my local stores, but available online. The material that’s easiest to find is rice. I learned from a restaurant visit several years ago that there’s such a thing as black rice, and this rice is found in any oriental grocery store. Mixing the black rice with a white rice produces an excellent random image noise source, since the rice grains have a matte finish that doesn’t reflect light. A quick shake of any of these sources produces a new random image.

I’ve run Linux on my desktop computers for about two decades, so I quickly bought the first version of the Raspberry Pi microcomputer when it was introduced. The Raspberry Pi has gone through many versions since that time, and the present Raspberry Pi 3B+ version has much to recommend itself. The integrated HDMI video interface and the plethora of USB ports makes for easy software development and attachment of peripherals. The GPIO header allows interface to outboard digital devices for creation of embedded systems. My only complaints are the lack of a way to power the board other than a micro USB connector, and the fact that the 3.3V GPIO interface needs additional voltage level shifters to connect to the more common 5V world.

Machine vision is simplified by the presence of USB ports on the Raspberry Pi and the availability of inexpensive USB interfaced video cameras. These cameras, typically used for video conferencing, produce high-definition color video images and they operate over a large range of light levels. Our basic machine vision physical random number generator is built around the Raspberry Pi, one of these cameras (a YoLuke HD Webcam), an LED light source and a liquid crystal character display connected to the I2C capable GPIO pins of the Raspberry Pi. Linux—in the form of the popular Raspberry Pi OS operating system (previously called Raspbian)—has utilities that simplify stitching these hardware components together with software [7].

Our first problem is trying to stuff all these components into a small, elegant enclosure. The camera needs a reasonably large offset from the plane of the random elements to focus and image the entire area. To accomplish this, I used a folded optical system in which a mirror bends the image from the top of the device through 90-degrees to a side-looking camera (Figure 4). The random elements are contained in a 2″ square plastic cube that’s placed at the top of the enclosure. There’s a leaf switch at the top that detects when the cube is removed, presumably shaken and then replaced.

Figure 4
Mechanical layout of the machine vision physical random number generator. Fortunately, the video camera could easily focus down to the necessary 4″ optical path length. The micro USB power connector for the Raspberry Pi was attached to a short adapter cable with a standard USB receptacle for connection at the rear of the enclosure for the power source.


Advertise Here

Finding the right project enclosure is often a problem. In some cases, I’ve needed to combine two smaller enclosures into a larger one of the proper dimensions. For this project, I built an enclosure from scratch, using bits and pieces of plastic sheeting and bare circuit board stock. The enclosure dimensions were 4-1/2″ high, 7″ wide and 4-1/2″ deep. This resulted in a tight fit for the interior components, so I would recommend a slightly larger size.

While the Raspberry Pi gives an easy way to acquire a digital image, we still need to get a signal from the leaf switch and present the random numbers to the outside world. In this random number generator, communication is accomplished in two ways. First, there’s an interface board the converts the 3.3V GPIO signals of the Raspberry Pi to the 5V signals needed by an LCD display on the front panel. Inexpensive character displays with an I2C digital interface are available from many sources, and a backlit display was used in this project. Since the Raspberry Pi has a built-in Wi-Fi interface, the random numbers are also served as a webpage on your home network. Figure 5 shows the circuit diagram for the interface board, and Figure 6 is a component side view of the circuit board showing the connections.

Figure 5
Circuit diagram for the interface board. This board provides voltage level-shifting from the 3.3V logic of the Raspberry Pi to the 5V logic needed for the LCD display. It also powers the illumination LEDs, the LCD backlight, interfaces to the leaf switch that indicates when the cube of random material has been removed and replaced and a push-button power-off switch explained in the text. Connect “A” to “A” and “B” to “B”.

Figure 6
Component side view of the interface board showing the various connections. The Raspberry Pi can be configured to have a power-off switch, as explained in the text. The resistors for the illumination LEDs are external.

The voltage-shifting circuit involving the 2N7000 MOSFET is a simple and common solution to this problem. 2N7000 MOSFETs are available from a variety of manufacturers, including ON Semiconductor. It’s so common that there are inexpensive (about a dollar each) modules that contain four of these bi-directional logic level converters on a 15mm × 15mm board done with surface mount components. These have a row of six SIP connections on each end for connection to the logic signals and ground, so it would be easy to use these a plug-in modules for the interface board. To simplify connections, the current-limiting resistors for the illumination LEDs are soldered at the LEDs.

The first order of business in getting the Raspberry Pi up and running is to burn an image of the Raspberry Pi OS onto an SD card. Since Raspberry Pi OS is used just for this project’s software, you don’t need a card larger than 16GB. Since solid-state memory is becoming cheaper and cheaper, it might not be possible to buy an SD card of such low capacity, but any size above 16GB will do. Download the Raspberry Pi OS image and use the proper utility for your desktop operating system to copy the image onto the card using instructions on the Internet. In my desktop Linux system, I use the dd utility, making certain that I specify the proper sdx device so as to not overwrite my hard drive. Double-check your source and destination to avoid trouble.

Insert the SD card into the Raspberry Pi, plug a keyboard and mouse into the available USB connectors and attach an HDMI monitor. After the first boot process, you’ll have a desktop development environment for installation of additional helper programs. After development, the Raspberry Pi will function without having any of these peripherals connected. While this article gives a few instructions relevant to this application, there’s a lot of information needed to manage a Linux system, so look to the Internet to explain such things as establishing a network connection. Some basic information on network connection follows.

The wireless network interface is configured using Network Options in the graphical configuration utility obtained with the terminal command sudo raspi-config. After that, you can get the Raspberry Pi IP address by executing ifconfig from the command line, or using the nmap command on another Linux machine on your home network. In my case, this command was nmap -sn The two methods will output something like the following, from which I found the IP address of my Raspberry Pi:

wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet netmask broadcast
Nmap scan report for raspberrypi.fios-router.home (
Host is up (0.011s latency).

You can set a static IP address if you want, although that takes some effort. However, I’ve found that the assigned IP address of my Raspberry Pi doesn’t change, which is a likely consequence of the circuit being on all the time, and the router giving its connections a long lease life.

With a network connection established, it’s now time to download some necessary software and edit configuration files. Among the programs you need to install are the Apache2 web server, its PHP interface and an additional PHP module that allows executing a PHP program from the command line to make for easier development.

sudo apt-get update
sudo apt-get install apache2
sudo apt-get install libapache2-mod-php
sudo apt-get install php5-cli

While you can use any text editor to edit configuration files, I use kwrite, which highlights the language syntax when editing source code for most programming languages. In order to use the power-off button connected at GPIO pin 37, you need to add the following line to the /boot/config.txt file:

dtoverlay=gpio-shutdown, gpio-pin=26

No, that’s not an error. Because there’s some internal translation involved on the Raspberry Pi, pin-26 here is actually our intended GPIO pin-37. Although Linux systems are usually robust against removal of power, this off switch allows a gentle shutdown of the Raspberry Pi.

File permission is a common problem that novices have when using Linux. If you can’t create, read, or write some file or folder, it’s because you aren’t permitted, but you can change permissions as the root user by prefixing commands with sudo. More about file permission can be found on the Internet and later in this article. One easy way to edit files and change file permission is by opening a file manager as the administrative user. The Raspberry Pi OS graphical file manager can be invoked from the command line as follows:

sudo pcmanfm

Right clicking on a file or folder will give you a way to change its permissions, and you can also open a file in the text editor the same way.

Now that you have a stable Raspberry Pi OS environment, you can verify operation of the USB camera using the webcam application cheese. I also use this simple video application to digitize VHS tapes using a USB analog video adapter. You can use cheese to facilitate camera alignment and focusing. For a more detailed look at your camera’s capabilities, you can use execute lsusb at the command line to find its location. For my camera, I get: Bus 003 Device 008: ID 0bda:58b0 Realtek Semiconductor Corp. Then, executing lsusb -s 003:008 -v | egrep “Width|Height” gives a long list of camera modes that includes its default mode (1920×1080), and also:

wWidth                320
wHeight               240

which is the mode we’ll use.

The image capture by the main program, described later, is done by the very useful Linux utility ffmpeg. The images are captured as grayscale pgm files whose data format makes them very easy to process. PGM signifies Portable GrayMap, and these files give intensity values from 0–255. The command to acquire such an image from our video source is:

ffmpeg -f video4linux2 -s 320x240 -i /dev/video0 -ss 2 -frames 1 out.pgm

The -s option sets the image size, which is 320×240, the -i option specifies the input stream, and the -frames 1 option says that we want a single frame. The option -ss 2 tells ffmpeg to wait about two seconds into the stream before getting the frame. Video cameras have an AGC feature that automatically adjusts for light level, which is an important feature for ease-of-use. It takes a little time for this adjustment to take effect, so the two second wait allows for this. This ffmpeg command is called from the main program to acquire an image for subsequent analysis.

I wrote the main program for this application in C, and this program calls ffmpeg to acquire the image. While I used the Anjuta IDE to create this program, the source code can also be edited with a text editor and compiled on a command line using the available gcc compiler. A typical command line for this is:

gcc -Wall my_program.c -o myprogram

in which my_program.c is the source code, and the -o option specifies the name of the executable, in this case, myprogram. The -Wall option presents a list of program warnings and errors that need attention. I used C language for the main program because it facilitates the image processing and conversion of the physical randomness of the image. Python is a better language for controlling the I2C display interface and the other GPIO pins. For that reason, the main program calls a Python helper program to accomplish such tasks. The main program likewise produces a data file that’s used to present the random numbers on a web page.

It’s straightforward getting the image data into a numerical array for extraction of the random numbers, but creation of quality randomness takes a little effort. Because the image data is represented by pixel values in the range of 0-255, we can set a mid-range value of 127 and generate a “1” bit for values at that point and larger, and a “0” bit for numbers less than that.

The resultant bitstream is somewhat random, but it’s biased in several ways. For example, the white and black elements might have a slightly different electrostatic attraction to each other, and they might clump. Also, as in the case of using the black and white rice, the individual elements extend over many pixels, so there’s some correlation. For these reasons, we select pixels randomly using the random function of our programming language and go through a “whitening” step. Using software randomness in this case is allowed, since our physical system is unpredictable.

Whitening is a means of extracting randomness from a slightly biased random source, such as loaded dice, and a simple whitening method was invented by computer pioneer, John von Neumann. This von Neumann Whitening operates on two successive bits at a time, and maps them to a random stream as follows: (0,1) gives a 0, (1,0) gives a 1, and (0,0) or (1,1) gives a result that’s ignored. The random number in our machine vision system is created by randomly fetching pixels from the image, applying the threshold function to give a 0 or 1, whitening this bit stream and extracting a 64-bit hexadecimal number.

A 2 line by 16-character LCD display with an I2C serial interface is used to display the random numbers. The display chosen uses a Hitachi HD44780 compatible controller, as does nearly every such display. To make such displays I2C displays, they have an additional Texas Instruments (TI) PCF8574 chip that acts as a serial to parallel converter. Connection to the rest of the circuitry is through just four pins for +5Vt power, ground and the I2C SDA and SCL data lines (Figure 7). The display I used has a blue backlight, white characters and a potentiometer for contrast adjustment. The backlight can be connected through a jumper to the +5V supply, but I connected switched power from the GPIO interface board to the LED terminal of the jumper pins. This allows a power-off of the display backlight when the device is inactive.

Figure 7
Component side view of the LCD display. It’s always nice when a manufacturer clearly labels connections. The PCF8574 interface board had a bright LED on it that interfered with the video capture. I covered it with a blob of opaque silicone.

The I2C port needs to be enabled in Raspberry Pi OS before it can be used. You can enable it by using the graphical configuration utility, executed by the terminal command sudo raspi-config, then use the down arrow to select and enable I2C in “Interfacing Options.” If you’re asked about automatically loading the kernel module, select “yes,” then finish and reboot.

The I2C device address for the display is usually fixed at 0x27, but it’s sometimes 0x3F, so it’s important to verify its address by installing the i2c-tools and using the detect command:

sudo apt-get install i2c-tools
sudo i2cdetect -y 1

The python script,, which is called by the main program, will also function on its own for testing purposes:

sudo python {mode=0,1,2, 3, 4 or 5} {"diplayed string"}

in which mode = 0 initializes the display, mode = 1 writes a string to line 1, mode = 2 writes a string to line 2, mode = 3 reads the state of the leaf switch at GPIO pin 40, mode = 4 sets GPIO pin 38 to a 1 to light the illumination LEDs and mode = 5 sets GPIO pin 38 to a 0 to extinguish the illumination LEDs. Python needs a library to enable I2C access, so we need to run this command before everything works:

sudo apt-get install python-smbus

All program files are placed in the directory PRNG that we’ve created at /home/pi/. Because we want the prng main program executable to run on the Raspberry Pi whenever the device is powered on, we must add the following to the end of the /etc/rc.local file before its exit command:

sudo apt-get install python-smbus

Since we’re calling the PRNG program from a directory (/etc) that’s different from its location (/home/pi/), all file references in the supervisory program must have an absolute file path. After application of power, it takes about half a minute for Raspberry Pi OS to load, at which time the device is operational.

The only way to communicate the state of the switch that indicates whether the cube of random material has been removed from its platform and replaced is to transfer data from the python helper program to the main program written in C is through use of a file. The python program writes data to a file, and the C program reads it. To prevent excessive wear on the Raspberry Pi solid-state memory card, we use a memory-mapped file.

On the Raspberry Pi, the file folder /dev/shm is a temporary file storage filesystem (tmpf), that uses RAM for data storage, so it’s an efficient means of passing data between programs in Linux. The only drawback, as the temporary in its name indicates, is that all its data is lost between reboots. This is not a problem in our application.

The Raspberry Pi has built-in Wi-Fi connectivity, so it’s easy to program a web interface to view the random numbers on a home network. In fact, some might decide to forego the LCD display and just use the web interface. The built-in Wi-Fi connectivity, the installed the Apache web server and PHP allows a web interface to view the random numbers on a home network with just one additional program. Web pages are served from the /var/www/html/prng/ folder, where the PHP source file, prng_log.php, is placed.

Since this file is in the /var/www/html/prng/ folder, and our program is run from /home/pi/prng/, the php program copies the data file and the camera image between directories (home/pi/prng/data.txt to /var/www/html/prng/data.txt, and home/pi/prng/data.jpg to /var/www/html/prng/data.jpg). Note that proper file permissions are needed for this to be successful. A summary of the file permissions on my Raspberry Pi system is listed in Table 1, which might serve as a reference if you’re having trouble. After all that, the webpage is visible on any web browser on your home network at A screenshot of the web page is seen in Figure 8.

Table 1
Summary of the file permissions on my Raspberry Pi system

Figure 8
Web browser interface, accessed on my home network at The image is the image from which the latest random number is derived. The column entitled Von Neumann Trials indicates the quality of the raw data. On average, a 64-bit number will require 128 acquisitions of raw bit data for whitening. A good method for creating pin numbers is to select some middle decimal digits.

While it’s easiest to use the web browser interface that I’ve written, you can access the data as a text file on the Raspberry Pi using the secure shell, ssh, from a terminal. For my system with my IP address, this is accomplished in Linux with the following command:

ssh -X -l pi

Once you’ve connected with the Raspberry Pi, you can open a graphical interface of the file manager by typing pcmanfm. I’ve always found that graphical interfaces make life a lot easier, but you can also copy the data file to your desktop with a command such as this:

scp pi@ /home/drdev/Desktop/data.txt

Random numbers are uniformly distributed, but the appearance of a uniform distribution is not a good test of randomness. That’s because a list of numbers in serial order, which is definitely not random, would produce a uniform distribution. Other non-random sequences, such as all even numbers followed by all odd numbers, and other not so obvious arrangement of numbers, will also show a uniform distribution while not being random.

The Diehard Test Suite, a collection of programs initially developed by computer scientist George Marsaglia is the acknowledged method for testing randomness. This updated test suit, now known as Dieharder, is maintained by Robert G. Brown of the Duke University Physics Department and his colleagues [8]. It’s freely available from the Linux repositories, but don’t run it on the Raspberry Pi! You need a fast desktop computer with a lot of memory for this!

Dieharder needs many random numbers for a valid test. I used 10 million for my randomness checks. Because it’s not possible to shake the cube of random material 10 million times to snap its image, I took the shortcut of doing these tests with one static image, so the results might be considered a worst-case effort. Also, Dieharder looks at 32-bit numbers. I modified the program to produce a simulation program to produce a file of 10 million random 32-bit decimal numbers, 10M_data.txt, with the proper header, and executed the following command to run the test suite:

dieharder -a -g 202 -f data_10M.txt

For each test, Dieharder generates a p-value, which is a statistical measure of the rejection of the “null hypothesis” that the numbers aren’t random. The usual—and often misused measure—is that the null hypothesis is rejected when the p-value is greater than 0.05. Dieharder will also state plainly whether your numbers have passed the test. The results for my simulation are shown in Figure 9. Dieharder automatically runs two of the “runs” and “craps” tests. You can get an explanation of a certain test by executing:

Figure 9
Summary of the Dieharder randomness tests. All passed without comment, except for parking lot, which was noted as “weak.” In the parking lot test, unit circles are randomly placed in a 100×100 square. A circle is successfully parked if it does not overlap an existing successfully parked one. After 12,000 tries, the number of successfully parked circles should follow a certain normal distribution.

dieharder -d {n} -h

in which {n} is the test number, which is listed on Brown’s website [8]. For an explanation of the craps test, you would run:

dieharder -d 16 -h

As every circuit experimenter knows, unexpected problems present themselves in the development of most electronic devices. One problem I had a difficult time in diagnosis was stray light reflections that reduced the contrast at one edge of the cube of random material. The light that produced the glare obviously originated from the illumination LEDs, so I tried moving their position inside the box. This didn’t really help. The eventual fix was to mask most of the area of the mirror, because reflection of the LED light from the over-sized mirror was the cause of the problem (Figure 10). There was still plenty of mirror left for proper imaging.

Figure 10
Positions of the illumination LEDs and the mirror mask that solved the stray light problem. While I used a piece of thin black foam, black paper would work just as well, or the surface of the mirror can be painted with matte black paint.

I use a decal transfer paper with my toner-based printer to add a personalized touch to my projects. The paper I use was originally intended for (not too accurate) transfer of resist patterns onto copper foil circuit boards. I overcoat the printed sheets with several thin layers of clear acrylic spray paint, slide the decals from the sheets in a water bath, apply them to panels, then overcoat with another clear acrylic spray. Technology has advanced to the point at which there are better transfer options, as an Internet search will reveal. My finished project can be seen in Figure 11

Figure 11
The finished project, displaying the two most recent 64-bit random numbers on the LCD display. The panel marking was done using a decal transfer process, as described in the text.


[1] Random page feature on Wikipedia (
[2] M. Matsumoto and T. Nishimura, “Mersenne Twister: A 623-Dimensionally Equidistributed Uniform Pseudo-Random Number Generator”, ACM Transactions on Modeling and Computer Simulation, vol. 8, no. 1 (January, 1998), pp 3-30, doi:10.1145/272991.272995.
[3] Takuji Nishimura, “A C-program for MT19937: Integer version,” April 6, 1998.
[4] Landon Curt Noll, Robert G. Mende and Sanjeev Sisodiya, “Method for seeding a pseudo-random number generator with a cryptographic hash of a digitization of a chaotic system,” US Patent No. 5,732,138, March 24, 1998 ( )
[5] Joshua Liebow-Feeser, “Randomness 101: LavaRand in Production,” Cloudflare Web Site ( ).
[6] Dina Kozlov, “League of Entropy: Not All Heroes Wear Capes,” Cloudflare Web Site ( ).
[7] Raspian Download Page ( ).
[8] Dieharder: A Random Number Test Suite at Robert G. Brown’s General Tools Page ( ).

Appendix I – List of Source Code Files for the Raspberry Pi Machine Vision Random Number Generator

1.  prng.c (c source code for main program)

2. (python source code for I2C interface)

3.  prng_log.php (web browser interface program)

ON Semiconductor|
Raspberry Pi Ltd. |
Texas Instruments (TI) |


Keep up-to-date with our FREE Weekly Newsletter!

Don't miss out on upcoming issues of Circuit Cellar.

Note: We’ve made the Dec 2022 issue of Circuit Cellar available as a free sample issue. In it, you’ll find a rich variety of the kinds of articles and information that exemplify a typical issue of the current magazine.

Would you like to write for Circuit Cellar? We are always accepting articles/posts from the technical community. Get in touch with us and let's discuss your ideas.

Sponsor this Article
Website | + posts

Dev Gualtieri received his PhD. in Solid State Science and Technology from Syracuse University in 1974. He had a 30-year career in research and technology at a major aerospace company and is now retired. Dr. Gualtieri writes a science and technology blog at He is the author of three science fiction novels, and books about science and mathematics. See for details.

Supporting Companies

Upcoming Events

Copyright © KCK Media Corp.
All Rights Reserved

Copyright © 2024 KCK Media Corp.

Machine Vision Random Number Generator – Using the Raspberr…

by Dev Gualtieri time to read: 25 min