This post details a project I recently finished, an electronic dice roller. My goal for this device was to display the result of a simulated “dice roll”, allowing for easy and quick generation of the sum of random numbers from 1 to n, where n is chosen by the user. This can be helpful in many role-playing games such as Dungeons and Dragons, where there are many times you need to roll something like two six sided dice (2d6), one twenty-sided dice (1d20), or three eight-sided dice for example (3d8).
Layout and Planning
After a few iterations of different screen designs and button layouts, I settled on a final design.
Preliminary design sketches/ideas:
(click to enlarge images)
My finalized design employed the use of a 128×64 pixel OLED display, mainly because of its flexibility: I could easily change my graphical interface as opposed to, say, seven-segment LED displays which severely limit the number of digits that can be displayed. They also are more complicated to use because you need many output pins and therefore would be forced to add extra components such as shift registers to make it work with a microcontroller of a limited number of pins.
The screen I got on Amazon also is dual color, in the sense that the first 16 rows are yellow, and the rest blue. This was perfect for my application because it fits my graphical layout (number of dice rolled at top in yellow, and blue for the larger text result). Plus, it just looks nicer than a single-color screen.
Apart from viewing the screen, the user interacts with the dice roller by pressing the “roll” button (the red upper button) which rolls the selected number of dice with the selected number of sides, or the “add” button (the yellow lower button) which adds a new roll to the number already displayed on the screen. The number of dice and modifier can be seen at the top yellow portion of the screen, and the roll result in a blue larger font at the bottom. If the result is greater than three digits, an error message is shown, as only three digits can fit on the screen.
The values for number of dice rolled, number of sides, and the modifier added or subtracted can be easily changed by using the knob: when pressed, it cycles which area is highlighted, and the value can be modified by turning the knob clockwise or counterclockwise. This makes changing settings quick and intuitive, and allows for very quick rolling of various amounts of dice.
Now I had to program my Arduino to do what I needed it to: interface with a screen, read the input from two buttons, and adjust values based on a rotary encoder.
Luckily, communicating with the screen was made quick and simple because of Adafruit’s Libraries. (SSD1306 for interfacing with the driver chip for the screen, and their GFX library for quickly and easily adding text or shapes to the display.)
The rotary encoder used external interrupts, which are a very useful feature that the ATMega328 has and the Arduino IDE has support for. It allows code to be ran only when a pin changes, and otherwise will not slow down the main loop() program by polling with the digitalRead() function. You can read more about this useful feature here: http://playground.arduino.cc/Code/Interrupts
After prototyping my design with my Arduino Uno and a breadboard, I arranged each part on a proto board. I also decided to use a bare ATMega328 chip because of its ease of use from prototyping on my Uno and integrating it into my final circuit. Because it is the chip that runs my Arduino, putting it in my final circuit is as easy as popping the chip out, soldering the connections in place, adding a 16Mhz crystal oscillator and 22pF capacitors, and adding a pull-up resistor to stop the reset from activating.
From the beginning, I wanted this project to run on an external battery, and a 9V battery seemed perfect for this task. I used a 5V linear voltage regulator to supply the microcontroller and display with the correct voltage. I added a 10uF capacitor on the output because it needs it for stability reasons, and a 0.1uF decoupling capacitor, though this is probably not necessary.
Finally I added the screen, which partially covers the voltage regulator and microchip to keep the device as compact as possible. After that was done (and after testing to make sure it all actually worked), I cut the extra protoboard to size, to make it fit better inside a case.
I also connected a power switch in series with the battery source to allow it to be turned on and off. And finally it works! A small, compact self-contained package that now does exactly what I want: to roll dice. All I need to do is build a case to house my newly-soldered electronics.
Instead of using a generic black box housing, I wanted to make my own unique case. I also liked the idea of making it out of metal and luckily I had some scrap laying around from taking apart an old fax machine.
To shape the metal to the case, I started by using calipers to measure my electronics, and made a 2d CAD image of the screen, knob, and button layout in SolidWorks to aid in cutting in the right spots. Next, I printed this on a piece of paper at 1:1 scale, cut the paper to shape, and taped my image onto the metal sheet. After using a marker to transfer the cutout shapes over, I had a template to cut holes for the case that were placed in the exact right spots.
I then used a dremel with a cutting wheel attachment to make the hole for the buttons and screen, and a large drill bit to make the circle for the knob. If I were to redo this step, I would have drilled out my button holes as well, as it is very difficult to make square holes of the size I needed, and I ended up using round LEDs to reach the buttons anyway. Oh well, now I know how to do it better next time.
After I cut the holes in the front plate of the case, I also cut a piece for the back and used my dremel with a different attachment to sand away the metal and change the finish from a matte look to a snazzier brushed metal look.
After I cut the metal to size for the front and back, I needed to find something to reach the buttons, and needed some sort of spacer to stop the whole thing from squishing together too much, at least enough so the buttons would not be pressed continuously.
As you already know, I used red and yellow LEDs not as a source of light, but to reach the momentary buttons soldered to the board. These actually worked astonishingly well, after some modifications. First I cut off their leads and added athin ring of hot glue around their base as a way to prevent the LEDs from sliding out of the case when it was fully assembled. One thing I actually could have done is make the buttons themselves light up when pressed, but at this point in the project I just wanted to have a finished project. Maybe I’ll make some cool light-up buttons on the next thing I make.
I made the spacers out of fairly small aluminum tubing, and hot glued them in place. This isn’t the most rugged case, but it should do for my purposes. I spaced the back far enough to easily fit a 9V battery, hot glued the switch to the front side of the case, and closed it all up with black gaffer’s tape.
And, now it’s done!
I’ll leave you with some more images of the device. Thanks for reading!
- 5V Linear Voltage Regulator (LM317?)
- 2 x 22pF Capacitors
- 16Mhz Crystal Oscillator
- 10 uF Capacitor
- 2 x Momentary push buttons
- Atmega 328 Microcontroller
- 1 x Rotary Encoder with integrated pushbutton
- Knob for Rotary Encoder
- 3 x 10 kOhm Resistors
- 128×64 pixel OLED display
- Solder and wire for connections
- Prototype Board
- 9V Battery snap leads
- On/Off switch (SPST)
- Hot glue
- Dremel for cutting protoboard and creating case
- Scrap metal for case
- Black tape
- Thin tubing for spacers