An automated system for measuring dice fairness — capturing thousands of rolls, detecting face values with a trained YOLO model, and running chi-square statistics to find out how random your dice really are.
Dice can be subtly biased from manufacturing imperfections — a slightly heavier face, off-centre pips, or a non-uniform resin pour. Detecting this by hand would take thousands of manual rolls.
Automate everything. A servo rolls the die on command, a global-shutter camera captures each result, and a trained YOLO model reads the face value — all without human involvement.
Results are stored in a database and tested against a chi-square distribution. A fair die should show each face roughly equally across a large sample.
Five stages, fully automated — from rolling to reporting.
A Raspberry Pi Pico 2 generates a precise 333 Hz PWM signal to a servo motor that physically rolls the die inside the capture chamber.
An Arducam IMX296 global-shutter USB3 camera frames the resting die through a folded optical path (first-surface mirror at 45°). Cross-polarisation optics on both the light path and the camera lens eliminate acrylic glare.
A YOLO model — trained on thousands of labelled captures in Label Studio — reads the face value from the image. Separate models handle numeric faces and pip counting.
Each roll result (value, timestamp, confidence) is persisted to a local database alongside the raw image, enabling full re-analysis if the model is updated.
Chi-square testing over the accumulated sample tells you whether face-frequency deviations are within expected statistical noise or indicate genuine bias.
Built around a Jetson-class SBC for sustained vision workloads with a dedicated coprocessor for deterministic motor control.
High-end Jetson-class SBC with 256 GB NVMe, dual-band WiFi, and active cooling. Runs vision inference, the capture UI, and the database.
1.58 MP global-shutter sensor with a 6 mm CS-mount manual-focus lens. Global shutter eliminates rolling-shutter artefacts when capturing fast die motion. Connected via single USB 3 cable.
Dedicated MCU generating deterministic 333 Hz PWM for the servo. Removes timing jitter that an SBC running Linux could introduce. Connected to the Jetson via USB serial.
A 45° first-surface mirror routes the image horizontally to reduce enclosure height. A linear polariser on the light output and a rotatable polariser on the lens suppress specular reflections from the acrylic cap.
1920×1200 IPS display connected via HDMI for video and USB-C for capacitive touch input. Provides the operator interface for session control and live results.
One external 12 V / 10 A supply feeds the whole system. Internal buck converters step down to 5 V for the servo rail. Provides clean, consolidated power with no wall-wart cluster.
Pure Python, built for the Jetson. All major components are modular and independently testable.
Custom-trained models for both pips and numeric faces. Trained with images captured and labelled using Label Studio.
Camera control via the UVC interface. Manual exposure, gain, and white balance locked for session repeatability.
The motor module sends roll commands to the Pico over USB serial, keeping timing-critical PWM off the Jetson.
Lightweight local storage for roll results. Raw images are retained alongside metadata to allow full batch re-analysis after model updates.
Accumulated roll counts tested against a uniform distribution. Produces a pass/fail fairness verdict with a configurable significance threshold.
Unit and integration tests for the motor, vision, and data modules. Runs with pytest from the project root.
# Clone the repo
git clone https://github.com/G-IV/Dice_Tester.git
cd Dice_Tester
# Create and activate a virtual environment
python3 -m venv venv
source venv/bin/activate
# Install in editable mode
pip install -e .
# Run the tests
pytest
Follow the full design journey — from early enclosure sketches to the current folded-optical-path build — with interactive 3D models at each stage.
Open the Devlog →