John Bradnam
Published © GPL3+

Arduino Electronic Dice System

An electronic five dice system built around an Arduino ATmega328 with 5 built-in dice games - Standard Dice, Poker, Craps, Yahtzee and Duel.

IntermediateFull instructions provided8 hours1,607
Arduino Electronic Dice System

Things used in this project

Hardware components

ATmega328
Microchip ATmega328
DIL-28 variant
×1
MAX7219 DIL IC
×1
Linear Regulator (7805)
Linear Regulator (7805)
78M05 SMD DPAK Variant
×1
Capacitor 100 nF
Capacitor 100 nF
1206 SMD package
×1
Capacitor 10 µF
Capacitor 10 µF
1206 Ceramic SMD package
×1
Capacitor 220 µF
Capacitor 220 µF
10V 7343 SMD package
×1
3 mm LED: Red
3 mm LED: Red
×35
3 mm LED: Green
3 mm LED: Green
×5
LED (generic)
LED (generic)
3mm Blue
×5
16Mhz CSTCR6M Crystal Filter
×1
TECHNIK SMD power socket
×1
12mm x 12mm Tactile switches
×7
Passive Buzzer 47
×1
IC & Component Socket, 14 Contacts
IC & Component Socket, 14 Contacts
1 x 24 Pin and 1 x 28 pin
×2
1206 Resistors
1 x 22K, 1 x 10K, 1 x 5K1, 1 x 4K7, 2 x 3K3, 2 x 2K7, 4 x 1K
×12

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)
Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Custom parts and enclosures

Case

Schematics

Schematic (300 dpi)

PCB

Eagle Files

Schematic and PCB in Eagle format

Code

DicerV2.ino

C/C++
/******************************************************************************
 * Program: DICER V2
 * Author: jbrad2089@gmail.com
 *****************************************************************************/

#include "buttons.h"
#include "leds.h"
#include "sound.h"

#define TOTAL_GAMES 5
enum GameEnum { DICE, POKER, CRAPS, YAHTZEE, DUEL };

int currentGame;    //Used to store current active game
byte buttonLeds;    //Used to hold current button LED state
int currentMode;    //Used by games to hold current position in game


void setup()
{
  //Serial.begin(9600);

  setupSound();
  setupButtons();
  setupLeds();
  
  buttonLeds = 0;
  currentGame = DICE;
  setGameLed(currentGame);
  initDice();
}

void loop()
{
  int button = buttonPressed();
  if (button != NO_BUTTON)
  {
    if (button == SELECT_BTN)
    {
      currentGame = (currentGame + 1) % TOTAL_GAMES;
      setGameLed(currentGame);
      switch (currentGame)
      {
        case DICE: initDice(); break;
        case POKER: initPoker(); break;
        case CRAPS: initCraps(); break;
        case YAHTZEE: initYahtzee(); break;
        case DUEL: initDuel(); break;
      }
      
    }
    else
    {
      switch (currentGame)
      {
        case DICE: playDice(button); break;
        case POKER: playPoker(button); break;
        case CRAPS: playCraps(button); break;
        case YAHTZEE: playYahtzee(button); break;
        case DUEL: playDuel(button); break;
      }
    }
  }
  delay(100);
}
  
//=================================================================================================
// DICE
//=================================================================================================

//Initialise the gane
void initDice()
{
  //default to TWO dice
  buttonLeds = S1_LED | S2_LED;
  setButtonLeds(buttonLeds);
  clearDiceLeds();
}

//Play game - 1st button has been pressed
// S1 - S5 ==> Sets the number of dice
// PLAY ==> Throws selected number of dice 
//Continue play until SELECT button is pressed again
void playDice(int button)
{
  while (button != SELECT_BTN)
  {
    if (button == PLAY_BTN)
    {
      roll(buttonLeds);
      playRolledTone();
    }
    else if (button != NO_BUTTON)
    {
      switch (button)
      {
        case S1_BTN: buttonLeds = S1_LED; break;
        case S2_BTN: buttonLeds = S1_LED | S2_LED; break;
        case S3_BTN: buttonLeds = S1_LED | S2_LED | S3_LED; break;
        case S4_BTN: buttonLeds = S1_LED | S2_LED | S3_LED | S4_LED; break;
        case S5_BTN: buttonLeds = S1_LED | S2_LED | S3_LED | S4_LED | S5_LED; break;
      }
      setButtonLeds(buttonLeds);
      clearDiceLeds();
    }
    button = buttonPressed();
  }
  //Close out the game
  initDice();
}

//=================================================================================================
// POKER
//=================================================================================================

int results[7];

//Initialise the gane
void initPoker()
{
  buttonLeds = 0;
  setButtonLeds(buttonLeds);
  clearDiceLeds();
  currentMode = 0;
}

//Play game - 1st button has been pressed
// S1 - S5 ==> Holds the dice
// PLAY ==> Throws dice not held - Flashes result.
// PLAY again throws all dice and clears HOLD
//Continue play until SELECT button is pressed again
void playPoker(int button)
{
  while (button != SELECT_BTN)
  {
    if (button == PLAY_BTN)
    {
      roll(~buttonLeds);
      playRolledTone();
      currentMode++;
      //Serial.println(currentMode);
      if (currentMode == 2)
      {
        //sprintf(temp, "Dice values are: %d, %d, %d, %d, %d", dice1, dice2, dice3, dice4, dice5);
        //Serial.println(temp);
        
        //Work out final hand
        for (int i=0; i < 7; i++)
        {
          results[i] = 0;
        }
        results[dice1]++;
        results[dice2]++;
        results[dice3]++;
        results[dice4]++;
        results[dice5]++;

        //sprintf(temp, "Results are: 1 = %d, 2 = %d, 3 = %d, 4 = %d, 5 = %d, 6 = %d", results[1], results[2], results[3], results[4], results[5], results[6]);
        //Serial.println(temp);
        
        if ((results[1] == 1 && results[2] == 1 && results[3] == 1 && results[4] == 1 && results[5] == 1) ||
            (results[2] == 1 && results[3] == 1 && results[4] == 1 && results[5] == 1 && results[6] == 1) ||
            (results[1] == 5 || results[2] == 5 || results[3] == 5 || results[4] == 5 || results[5] == 5 || results[6] == 5))
        {
          //straight or five of a kind
          flashDice(DICE_1 | DICE_2 | DICE_3 | DICE_4 | DICE_5);
        }
        else if (results[1] == 4 || results[2] == 4 || results[3] == 4 || results[4] == 4 || results[5] == 4 || results[6] == 4)
        {
          //four of a kind
          flashDice(getDiceMask(4));
        }
        else if (results[1] == 3 || results[2] == 3 || results[3] == 3 || results[4] == 3 || results[5] == 3 || results[6] == 3)
        {
          //full house or 3 of a kind - we don't need to break it down any further
          flashDice(getDiceMask(3) | getDiceMask(2));
        }
        else if (results[1] == 2 || results[2] == 2 || results[3] == 2 || results[4] == 2 || results[5] == 2 || results[6] == 2)
        {
          //two of a kind or two pair - we don't need to break it down any further
          flashDice(getDiceMask(2));
        }
        //Setup for a new game
        currentMode = 0;
        buttonLeds = 0;
        setButtonLeds(buttonLeds);
      }
    }
    else if (button != NO_BUTTON)
    {
      switch (button)
      {
        case S1_BTN: buttonLeds = buttonLeds ^ S1_LED; break;
        case S2_BTN: buttonLeds = buttonLeds ^ S2_LED; break;
        case S3_BTN: buttonLeds = buttonLeds ^ S3_LED; break;
        case S4_BTN: buttonLeds = buttonLeds ^ S4_LED; break;
        case S5_BTN: buttonLeds = buttonLeds ^ S5_LED; break;
      }
      setButtonLeds(buttonLeds);
    }
    button = buttonPressed();
  }
  //Close out the game
}

//Returns the mask of dice that have a face value that matches the count
//returns DICE_X mask
byte getDiceMask(int count)
{
  byte diceMask = 0;
  for(int v = 1; v <= 6; v++)
  {
    if (results[v] == count)
    {
      if (dice1 == v) { diceMask |= DICE_1; }
      if (dice2 == v) { diceMask |= DICE_2; }
      if (dice3 == v) { diceMask |= DICE_3; }
      if (dice4 == v) { diceMask |= DICE_4; }
      if (dice5 == v) { diceMask |= DICE_5; }
    }
  }
  return diceMask;
}

//=================================================================================================
// CRAPS
//=================================================================================================

//Initialise the gane
void initCraps()
{
  buttonLeds = 0;
  setButtonLeds(buttonLeds);
  clearDiceLeds();
  currentMode = 1;
}

//Play Game
//Throws first TWO dice
//7 or 11 - Automatic WIN
//2 or 3 or 12 - Automatic LOSS
//4, 5, 6, 8, 9, and 10 - Throws Last two dice
//  - If match player winds
//  - If 7, player losses
//  - Otherwise player throws last two dice again
void playCraps(int button)
{
  int firstThrow;
  int lastThrow;
  
  while (button != SELECT_BTN)
  {
    if (button == PLAY_BTN)
    {
      if (currentMode == 1)
      {
        //Throw first two dice
        setButtonLeds(0);
        clearDiceLeds();
        roll(S1_LED | S2_LED);
        firstThrow = dice1 + dice2;
        if (firstThrow == 7 || firstThrow == 11)
        {
          //Automatic win
          playWinMusic();
        }
        else if (firstThrow == 2 || firstThrow == 3 || firstThrow == 12)
        {
          //Automatic loss
          playLoseMusic();
        }
        else
        {
          //throw again
          playRethrowTone();
          currentMode = 2;
          setButtonLeds(S4_LED | S5_LED);
          flashButtonLeds(S4_LED | S5_LED);
        }
      }
      else
      {
        //Keep throwing until  match or 7
        roll(S4_LED | S5_LED);
        lastThrow = dice4 + dice5;
        if (lastThrow == firstThrow)
        {
          //Win
          playWinMusic();
          setButtonLeds(0);
          currentMode = 1;
        }
        else if (lastThrow == 7)
        {
          //Loss
          currentMode = 1;
          setButtonLeds(0);
          playLoseMusic();
        }
        else
        {
          //throw again
          playRethrowTone();
        }
      }
    }
    button = buttonPressed();
  }
  //Close out the game
  initCraps();
}

//=================================================================================================
// YATHZEE
//=================================================================================================

//Initialise the gane
void initYahtzee()
{
  //clear LEDs
  buttonLeds = 0;
  setButtonLeds(buttonLeds);
  clearDiceLeds();
  currentMode = 0;
}

//Play game - 1st button has been pressed
// S1 - S5 ==> Holds the dice
// PLAY ==> Throws dice not held.
//Continue play until SELECT button is pressed again
void playYahtzee(int button)
{
  while (button != SELECT_BTN)
  {
    if (button == PLAY_BTN)
    {
      currentMode++;
      if (currentMode == 4)
      {
        //Only allowed a maximum of three throws in Yahtzee
        initYahtzee();
      }
      roll(~buttonLeds);
      playRolledTone();
    }
    else if (button != NO_BUTTON)
    {
      switch (button)
      {
        case S1_BTN: buttonLeds = buttonLeds ^ S1_LED; break;
        case S2_BTN: buttonLeds = buttonLeds ^ S2_LED; break;
        case S3_BTN: buttonLeds = buttonLeds ^ S3_LED; break;
        case S4_BTN: buttonLeds = buttonLeds ^ S4_LED; break;
        case S5_BTN: buttonLeds = buttonLeds ^ S5_LED; break;
      }
      setButtonLeds(buttonLeds);
    }
    button = buttonPressed();
  }
  //Close out the game
  initYahtzee();
}

//=================================================================================================
// DUEL
//=================================================================================================

//Initialise the gane
void initDuel()
{
  buttonLeds = 0;
  setButtonLeds(buttonLeds);
  clearDiceLeds();
}

//Play Game
//Player 1 has left two dice
//Player 2 has right two dice
//Highest player moves their car by the difference between the players dice throws.
void playDuel(int button)
{
  while (button != SELECT_BTN)
  {
    if (button == PLAY_BTN)
    {
      clearDiceLeds();
      roll(S1_LED | S2_LED | S4_LED | S5_LED);
      int player1 = dice1 + dice2;
      int player2 = dice4 + dice5;
      if (player1 > player2)
      {
        flashDice(S1_LED | S2_LED);
        playWinTone();
      }
      else if (player1 < player2)
      {
        flashDice(S4_LED | S5_LED);
        playWinTone();
      }
      else
      {  
        //throw again
        playLossTone();
      }
    }
    button = buttonPressed();
  }
  //Close out the game
  initDuel();
}

buttons.h

C/C++
#pragma once
/*
Button handler for Dicer

A0 - SELECT - 1K0 - 2.5V - 512
A0 - S1 - 2K7 - 1.35V - 276
A0 - S2 - 3K3 - 1.16V - 237
A0 - S3 - 5K1 - 0.82V - 167
A1 - S4 - 1K0 - 2.5V - 512
A1 - S5 - 2K7 - 1.35V - 276
A1 - PLAY - 3K3 - 1.16V - 237

*/

enum ButtonEnum { NO_BUTTON, SELECT_BTN, S1_BTN, S2_BTN, S3_BTN, S4_BTN, S5_BTN, PLAY_BTN };
typedef struct 
{
	int btn;
	int pin;
	int low;
	int high;
} button_type;

#define TOTAL_BUTTON_VALUES 7
button_type buttonValues[TOTAL_BUTTON_VALUES] = {
	{SELECT_BTN,A0,300,600},
	{S1_BTN,A0,250,300},
	{S2_BTN,A0,200,250},
	{S3_BTN,A0,100,200},
	{S4_BTN,A1,300,600},
	{S5_BTN,A1,250,300},
	{PLAY_BTN,A1,200,250}
};

void setupButtons()
{
	pinMode(A0, INPUT);
	pinMode(A1, INPUT);
}

//Tests if any of the buttons have been pressed and released
//  returns the button that was pressed
ButtonEnum buttonPressed()
{
	ButtonEnum button = NO_BUTTON;

	int i = 0;
	while (i < TOTAL_BUTTON_VALUES && button == NO_BUTTON)
	{
		int btn = buttonValues[i].btn;
		int pin = buttonValues[i].pin;
		int lowRange = buttonValues[i].low;
		int highRange = buttonValues[i].high;
		int value = analogRead(pin);
		if (value >= lowRange && value < highRange)
		{
			_delay_ms(10);
			if (analogRead(pin) >= lowRange && analogRead(pin) < highRange)
			{
				while (analogRead(pin) >= lowRange && analogRead(pin) < highRange)
				{
				}
				button = btn;
			}
		}
		i++;
	}
	return button;
}

leds.h

C/C++
#pragma once
/*
LED handler for Dicer

Digits are the rows
Segments are the columns
Segment order for each row is SEG_DP, SEG_A, SEG_B, SEG_C, SEG_D, SEG_E, SEG_F, SEG_G

PB3 - MOSI - LOAD - D11
PB4 - MISO - DATA - D12
PB5 - SCK - CLOCK - D13

DICE LAYOUT
===========
        DIG_0                 DIG_1                 DIG_2                 DIG_3                 DIG_4         
+-------------------+ +-------------------+ +-------------------+ +-------------------+ +-------------------+ 
| SEG_F       SEG_A | | SEG_F       SEG_A | | SEG_F       SEG_A | | SEG_F       SEG_A | | SEG_F       SEG_A | 
| SEG_E SEG_G SEG_B | | SEG_E SEG_G SEG_B | | SEG_E SEG_G SEG_B | | SEG_E SEG_G SEG_B | | SEG_E SEG_G SEG_B | 
| SEG_D       SEG_C | | SEG_D       SEG_C | | SEG_D       SEG_C | | SEG_D       SEG_C | | SEG_D       SEG_C | 
+-------------------+ +-------------------+ +-------------------+ +-------------------+ +-------------------+ 


GREEN GAME LEDS
===============
				  DIG_5
| SEG_A | SEG_B | SEG_C | SEG_D | SEG_E |
| Game1 | Game2 | Game3 | Game4 | Game5 |


BLUE SWITCH LEDS
================
                  DIG_6
| SEG_A | SEG_B | SEG_C | SEG_D | SEG_E |
| S1    | S2    | S3    | S4    | S5    |

*/
#include <LedControl.h>
#include "Sound.h"

#define MAX7219_LOAD 11
#define MAX7219_DATA 12
#define MAX7219_CLOCK 13
LedControl lc=LedControl(MAX7219_DATA,MAX7219_CLOCK,MAX7219_LOAD,1);

//Column values for each face on dice
byte diceColumns[] = {B00000000,B00000001,B01001000,B01001001,B01011010,B01011011,B01111110};
//Dice masks (must match switch LED masks)
#define DICE_1 B01000000
#define DICE_2 B00100000
#define DICE_3 B00010000
#define DICE_4 B00001000
#define DICE_5 B00000100
//Button switches
#define SWITCH_ROW 6
byte switchMask = 0;
#define S1_LED B01000000
#define S2_LED B00100000
#define S3_LED B00010000
#define S4_LED B00001000
#define S5_LED B00000100
//Game LEDs
#define GAME_ROW 5
byte gameColumns[] = {B01000000,B00100000,B00010000,B00001000,B00000100};
//LED states - stores the current value of each digit
byte ledStates[7];
//LED flash enable - 0 = not flashing, 1 = flashing
byte ledFlash[7];
//Whether flash is on or off
bool flashState = false;
// Delay between each interrupt - eg: 1 sec ==> (16*10^6) / (1*1024) - 1 (must be <65536) (8Mhz)
#define FLASH_SPEED 7820
//Current dice values
int dice1;
int dice2;
int dice3;
int dice4;
int dice5;

void setupLeds() 
{
  /*
  The MAX72XX is in power-saving mode on startup,
  we have to do a wakeup call
  */
  lc.shutdown(0,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,1);
  /* and clear the display */
  lc.clearDisplay(0);
  
  /* Set up timer for background flashing */
  cli();  //stop interrupts
  //set timer1 interrupt for flash
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  // set compare match register for 1hz increments
  OCR1A = FLASH_SPEED;
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS10 and CS12 bits for 1024 prescaler
  TCCR1B |= (1 << CS12) | (1 << CS10);  
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);    
  // allow interrupts
  sei();

  //Get random seed from noise on unused analog pin
  randomSeed(analogRead(A3));
}

//timer1 interrupt 1Hz toggles flashing of LEDs
ISR(TIMER1_COMPA_vect)
{
  //generates pulse wave of frequency 1Hz/2 = 0.5kHz (takes two cycles for full wave- toggle high then toggle low)
  for (int i = 0; i < 7; i++)
  {
    if (flashState)
    {
      //turn on LEDs
      lc.setRow(0, i, ledStates[i]);
    }
    else
    {
      //turn off LEDs that have flash enabled
      lc.setRow(0, i, ledStates[i] & ~ledFlash[i]);
    }
  }
  flashState = !flashState;
}

//Set the game LED
//game - GameEnum (0 - 4)
void setGameLed(int game)
{
  lc.setRow(0, GAME_ROW, gameColumns[game]);
  ledStates[GAME_ROW] = gameColumns[game];
  ledFlash[GAME_ROW] = (byte)0;
}

//Flash the game LED
//game - GameEnum (0 - 4)
void flashGameLed(int game)
{
  ledFlash[GAME_ROW] = gameColumns[game];
}

//Set the switch LEDs
//leds - combination of S1_LED to S5_LED
void setButtonLeds(byte leds)
{
	lc.setRow(0, SWITCH_ROW, leds);
  ledStates[SWITCH_ROW] = leds;
  ledFlash[SWITCH_ROW] = (byte)0;
}

//Flash the switch LEDs
//leds - combination of S1_LED to S5_LED
void flashButtonLeds(byte leds)
{
  ledFlash[SWITCH_ROW] = leds;
}

//Set the dice LEDs
//dice - 0 to 4
//value - 1 to 6
void setDiceLeds(int dice, int value)
{
	lc.setRow(0, dice, diceColumns[value]);
  ledStates[dice] = diceColumns[value];
  ledFlash[dice] = (byte)0; //Turn off flash
}

//Flashes the dice LEDs
//dice - 0 to 4
//value - 1 to 6
void flashDiceLeds(int dice, int value)
{
  ledFlash[dice] = diceColumns[value];
}

//Flash current dice value
//diceMask is one or more DICE_X constants
void flashDice(byte diceMask)
{
  if (diceMask & DICE_1)
  {
    ledFlash[0] = ledStates[0];
  }
  if (diceMask & DICE_2)
  {
    ledFlash[1] = ledStates[1];
  }
  if (diceMask & DICE_3)
  {
    ledFlash[2] = ledStates[2];
  }
  if (diceMask & DICE_4)
  {
    ledFlash[3] = ledStates[3];
  }
  if (diceMask & DICE_5)
  {
    ledFlash[4] = ledStates[4];
  }
}

//Clear all LEDs and remove any flashing
void clearDiceLeds()
{
  for (int i = 0; i < 5; i++)
  {
    lc.setRow(0, i, (byte)0);
    ledStates[i] = (byte)0;
    ledFlash[i] = (byte)0;
  }
}

//Get a random roll that isn't the same as the last value
//lastRoll is current dice value
//returns new roll
int newRoll(int lastRoll)
{
  int roll = lastRoll;
  while (roll == lastRoll)
  {
    roll = random(1, 7);
  }
  return roll;
}

//Roll the dice
//diceMask is one or more DICE_X constants
void roll(byte diceMask)
{
  int d = 0;
  for (int i = 0; i < (random(7, 30)); i++) 
  {

    if (diceMask & DICE_1)
    {
      dice1 = newRoll(dice1);
      setDiceLeds(0, dice1);
    }
    if (diceMask & DICE_2)
    {
      dice2 = newRoll(dice2);
      setDiceLeds(1, dice2);
    }
    if (diceMask & DICE_3)
    {
      dice3 = newRoll(dice3);
      setDiceLeds(2, dice3);
    }
    if (diceMask & DICE_4)
    {
      dice4 = newRoll(dice4);
      setDiceLeds(3, dice4);
    }
    if (diceMask & DICE_5)
    {
      dice5 = newRoll(dice5);
      setDiceLeds(4, dice5);
    }
    
    playRollTone();
    delay(d);
    d = d + 50;
  }
}

sound.h

C/C++
#pragma once
/*
Sound handler for Dicer
*/

//Pin that has Piezo electric buzzer
#define SOUND_PIN A2

void setupSound() 
{
  pinMode(SOUND_PIN, OUTPUT);
}

void playSound(double freqHz, int durationMs)
{
  //Calculate the period in microseconds
  int periodMicro = int((1/freqHz)*1000000);
  int halfPeriod = periodMicro/2;
   
  //store start time
  long startTime = millis();
   
  //(millis() - startTime) is elapsed play time
  while((millis() - startTime) < durationMs)
  {
    digitalWrite(SOUND_PIN, HIGH);
    delayMicroseconds(halfPeriod);
    digitalWrite(SOUND_PIN, LOW);
    delayMicroseconds(halfPeriod);
  }
}

void playRollTone()
{
  playSound(300,50); 
}

void playRolledTone()
{
  playSound(600, 150);
}

void playWinTone()
{
  playSound(800, 150);
}

void playRethrowTone()
{
  playSound(400, 150);
}

void playLossTone()
{
  playSound(100, 150);
}

void playLoseMusic()
{
	delay(400);
	//wah wah wah wahwahwahwahwahwah
	for(double wah=0; wah<4; wah+=6.541)
	{
	  playSound(440+wah, 50);
	}
	playSound(466.164, 100);
	delay(80);
	for(double wah=0; wah<5; wah+=4.939)
	{
	  playSound(415.305+wah, 50);
	}
	playSound(440.000, 100);
	delay(80);
	for(double wah=0; wah<5; wah+=4.662)
	{
	  playSound(391.995+wah, 50);
	}
	playSound(415.305, 100);
	delay(80);
	for(int j=0; j<7; j++)
	{
	  playSound(391.995, 70);
	  playSound(415.305, 70);
	}
	delay(400);
}

void playWinMusic()
{
  playSound(880,100); //A5
  playSound(988,100); //B5
  playSound(523,100); //C5
  playSound(988,100); //B5
  playSound(523,100); //C5
  playSound(587,100); //D5
  playSound(523,100); //C5
  playSound(587,100); //D5
  playSound(659,100); //E5
  playSound(587,100); //D5
  playSound(659,100); //E5
  playSound(659,100); //E5
  playSound(880,100); //A5
  playSound(988,100); //B5
  playSound(523,100); //C5
  playSound(988,100); //B5
  playSound(523,100); //C5
  playSound(587,100); //D5
  playSound(523,100); //C5
  playSound(587,100); //D5
  playSound(659,100); //E5
  playSound(587,100); //D5
  playSound(659,100); //E5
  playSound(659,100); //E5
  delay(250);
}

Credits

John Bradnam

John Bradnam

145 projects • 178 followers
Thanks to mbedni.

Comments