Arduino Electrical Dice

by Selawen in Circuits > Arduino

310 Views, 2 Favorites, 0 Comments

Arduino Electrical Dice

IMG_20210809_062424703.jpg
ITTT Dice Roller

In this project I make an electrical dice roller in the shape of a 20 sided die.

The dice roller can be set to roll a 4, 6, 8, 10, 12, 20, and 100 sided die when shaken.

Supplies

Electrical components:

  • Arduino UNO
  • 4 pin I2C LCD
  • Rotary Potentiometer
  • Tilt switch
  • LED (optional)
  • 220 Ohm resistor (optional)
  • 9V battery (optional)

For the casing:

  • a lasercutter + wood
  • Wood glue

Wiring the Arduino

dice roller_fritzing.png
final wiring.jpg

Connect all wires as shown in the image.

For the LCD display:

  • GND to ground
  • VCC to 5V
  • SDA to A4
  • SCL to A5

For the Potentiometer:

  • Middle pin to A1
  • Outer pins to 3.3V and Ground, it doesn't matter which goes where

For the Tilt sensor:

  • Short pin to pin 4
  • Long pin to 5V

For the LED:

  • Short pin to pin 5 through the 220 Ohm resistor
  • Long pin to Ground

For the Battery:

  • Live wire to Vin
  • Neutral wire to Ground

The LED is optional and the battery can be swapped for another power source if desired

Downloading Libraries

For the code to work you're going to need two additional Arduino libraries.

The first is LiquidCrystal_I2C by Marco Schwartz, this one can be downloaded through the Arduino IDE or from the GitHub repository.

The second is New-LiquidCristal, which cannot be found through the IDE. To download this library go to this repository. From here you download the zip, and extract this into your Arduino libraries folder.

The Code

Load this code snippet into your Arduino.

//declare lcd
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

//i2c pins
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 
const int tiltSensor = 4;
const int dial = A1;
const int led1 = 5;

int dialValue;
int chosenDie;
boolean rolling = false;
long rollResult;

void setup() {

  Serial.begin(9600);               //initiaise contact laptop

  //define the LCD, 16 columns and 2 rows
  lcd.begin(16,2);
  lcd.backlight();//Power on the back light

  //declare the tilt sensor as an INPUT
  pinMode(tiltSensor, INPUT);
  randomSeed(analogRead(A0));

  //declare the leds as an OUTPUT
  pinMode(led1, OUTPUT);
}

void loop() {
  int dialRaw = analogRead(dial);
  int dialPosition = map(dialRaw, 0, 590, 0, 6);
  Serial.println(dialRaw);
  switch (dialPosition){
    case 0:
    {
      if(chosenDie != 4){
        lcd.clear();//Clean the screen
        lcd.setCursor(0,0); //we start writing from the first row first column
        lcd.print("roll d4");
        chosenDie = 4;
        Serial.println("d4");
      }
      break;
    }
    case 1:
    {
      if(chosenDie != 6){
        lcd.clear();//Clean the screen
        lcd.setCursor(0,0); //we start writing from the first row first column
        lcd.print("roll d6");
        chosenDie = 6;
        Serial.println("d6");
      }
      break;
    }
    case 2:
    {   
      if(chosenDie != 8){
        lcd.clear();//Clean the screen
        lcd.setCursor(0,0); //we start writing from the first row first column
        lcd.print("roll d8");   
        chosenDie = 8;
        //Serial.println("d8");
      }
      break;
    }
    case 3:
    {
      if(chosenDie != 10){
        lcd.clear();//Clean the screen
        lcd.setCursor(0,0); //we start writing from the first row first column
        lcd.print("roll d10");
        chosenDie = 10;
        //Serial.println("d10");
      }
      break;
    }
    case 4:
    {
      if(chosenDie != 12){
        lcd.clear();//Clean the screen
        lcd.setCursor(0,0); //we start writing from the first row first column
        lcd.print("roll d12");
        chosenDie = 12;
       //Serial.println("d12");
      }
      break;
    }
    case 5:
    {
      if(chosenDie != 20){
        lcd.clear();//Clean the screen
        lcd.setCursor(0,0); //we start writing from the first row first column
        lcd.print("roll d20");
        chosenDie = 20;
        //Serial.println("d20");
      }
      break;
    }
    case 6:
    {
      if(chosenDie != 100){
        lcd.clear();//Clean the screen
        lcd.setCursor(0,0); //we start writing from the first row first column
        lcd.print("roll d100");
        chosenDie = 100;
        //Serial.println("d100");
      }
      break;
    }
    }
  //delay(500);                       // waits 500ms

  //roll the die if shaking is detected and it's not rolling already
  if (digitalRead(tiltSensor)==1 && !rolling){
    rolling = true;
    Roll();
  }

void Roll(){
  rollResult = random(1, (chosenDie+1)); //generate random number between 1 and the selected die
  lcd.clear();//Clean the screen
  lcd.setCursor(0,0); //we start writing from the first row first column
  lcd.print("rolling d");
  lcd.print(chosenDie);


  //Blink
  for (int i=0; i<10; i++){
  digitalWrite(led1, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(100);                       // wait 100ms
  digitalWrite(led1, LOW);    // turn the LED off by making the voltage LOW
  delay(100);  		      // wait for 100ms 
  }                      

  lcd.setCursor(0,1); //write result on second row
  lcd.print(rollResult);<br>  //Serial.print("rolling d");
  //Serial.println(chosenDie);
  //Serial.println(rollResult);
  delay(1000); //wait 1 sec before allowing rerolls
  rolling = false;
}

Making the Casing (optional)

IMG_20210809_062709266.jpg

Use a lasercutter to cut the casing.

After lasercutting you should have:

  • 18 solid faces
  • 1 face with a 6 mm diameter hole for the potentiometer
  • 1 face with a cutout for the LCD panel
  • 30 edge pieces

First, attach the potentiometer and the LCD panel to their faces.

Now assemble the rest of the faces to form a regular icosahedron (or d20)

Before adding the potentiometer and LCD faces add padding to protect the electronics when shaken.

Finally, add in the electronics and close the shape off with the last two faces.

Downloads