This is a dice testing machine (and random number generator) that works by throwing dice in a tube, and reading them from below through a plastic window. There are three dice in the tube, and one roll/read takes 4 seconds. After about an hour of testing dice you should have a histogram showing the distribution of outcomes that you can use to check if the dice are fair.
I have used Chessex dice, Vortex™ Bright Green/Black that came in a 12-die set during my testing. I have found them easy to work with, since they are not translucent and have black dots.
Electronicsand Frame
The tester has a Raspberry Pi 5 and a Pi Camera 2, I did some tests with the Pi Camera 3 but had problems getting the auto focus to work. Focus is manual on the Pi Camera 2, and only needs to be set once.
Most of the mechanism is made from PLA, and some from PETG. Both materials works fine, PETG is a bit more slippery and might be a better option in the long run.
In the top of the tube is a 50 mm acrylic window, 1, 5 mm thick. I got this from Amazon in a 25 pack, its attached with a window frame and some melting glue.
Drive mechanismTo rotate the tube there is a NEMA 17 stepper motor, 200 steps. Its rated at 12 volts and draws 450 mA, the stepper motor driver DRV8825 can handle a bit over 1 A so power isn't an issue. There are a few wires connecting the Raspberry Pi to the driver, pins for Reset, Enable, Sleep, Ground, and Direction, but only the "Step" pin is actively used. To get enough entropy the flip needs to be pretty quick, how quick it can be depends on the stepper motor. Initially I was worried that I needed to put a reduction gear on the stepper motor, but it works very nicely with a 1:1 ration(two 25 teeth module 2.5 gears made in Onshape)
Python Codeparams = cv2.SimpleBlobDetector_Params()
params.minThreshold = 5
params.maxThreshold = 200
params.thresholdStep = 5
params.filterByArea = True
params.minArea = 200
params.maxArea = 1200
params.filterByColor = True
params.blobColor = 0
params.filterByCircularity = True
params.minCircularity = 0.75
params.maxCircularity = 1.0
params.filterByConvexity = True
params.minConvexity = 0.6
params.filterByInertia = True
params.minInertiaRatio = 0.4Much of the code is created with ChatGPT or made from examples just adjusted and copied from other code. The program has two main functions, counting the blobs(pips on the dice) using the blobdetector in OpenCV, there are a bunch of different settings for the detector that makes it pretty easy to distinguish between artifacts from light and a dice being slightly slanted. Only blobs that are placed in the middle circle are counted.
Once the blobs are detected, they are grouped with DBSCAN to count what of them do belong to a dice. There is a value in the code that can be adjusted if too many blobs are counted to belong to the same dice.
To avoid getting errors in the results, a throw is invalid and not saved, in case there are more or less than three dice. If any dice has more than 6 dots, and if the total number of dots are more than 18, the throw will also be invalid. The image is still saved for trouble shooting, but named "invalid".
Once the results are passed the result is put into "result.txt" and the histogram image is updated. The histogram(created by using matplotlib) image and the latest image from a throw are then presented on a webpage, with a link to the results.txt. The Raspberry Pi has Apache2 installed, and the images and result files are placed in /var/www/html directory for access by Apache web server. This means that the Python Program needs to be run as root.
To avoid wear and tear on the mechanism, it uses a 5 mm stainless steel axle, with two bearings. The bottom of the tube is a 2 mm rubber pad. The insides of the tube should probably be coated with a liner of something slippery like Teflon tape to avoid wearing of the sides. Also a thicker tube might be a bit more quiet than this one.
Every image takes 72 kB of discspace, in 800 x 600 pixels. This creates somewhere around 60 MB of data every hour, or 1, 4 GB per day. With even a modest memory card in the Raspberry Pi, this wont be an issue.
Randomness and entropyOne dice throw creates 2, 585 bites of entropy, so with three dice there should be 116 bits per minute. A common key size for cipher keys are 256 bits for symmetric ciphers like AES, and 2048 bits for public key ciphers.
If the generated results are to be used as a random number generator there are a couple of methods that can be used to remove any bias that the dice(or the machine might have had). The Von Neumann extractor is one of these, it reduces bias at the cost of entropy, as much as half of the generated numbers will be removed.
To get good random numbers from dice throws that give a value of 1-6 you can use modulo, but there are things to avoid. If you need a random value from 0 to 27 you should throw one three dice(d1-d3) in an order, and do the following:
(d1 - 1) * 36 + (d2 - 1) * 6 + (d3 -1) * 1
If the value is above 196 throw the dice again and remove the numbers, other wise there will be a modulo bias in the results. After that you modulo the number with 28. Example:
- First dice thrown: 4
- Second dice thrown: 3
- Third dice thrown: 2











Comments