ATtiny85/45/25 LED Dice (Super Simple and CHEAP!)

71,089

200

32

About: I'm a big Arduino fan. I'm always looking for new and exciting things to do with electronics and Arduino. I also like video gaming on my PC and Xbox. I also ride my bike almost every day, and sometimes swim/...

If you have looked at my 5 LED ATtiny85 POV display, we programmed the ATtiny with the Arduino. (If you haven't seen it, click here) We will be doing the same thing for this LED Dice project.

The total parts cost for this project is about $5-$10. (Not including the Arduino board and the tools.)

It is super simple to make, so don't worry if you don't have a lot of programming/ electronics experience.

This is a contest entry for the LED Contest with Elemental LED, so don't forget to vote for me! ;)


Step 1: Parts List

Here's all the stuff you need. You can get it all for 5-10 bucks if you buy from Mouser/Digi-Key.

Parts:
1x ATtiny85/45/25 (8 pin DIP)
1x 8 pin DIP socket
1x Tactile pushbutton switch
1x 10K Ohm resistor
7x LEDs (I used clear, high-brightness red. We will be powering this with a 3 volt battery pack, so make sure you choose something that can handle that much power)
1x 2 AA/AAA battery pack (could also be a 3 volt CR2032 coin cell battery, just make sure whatever pack you choose that it's 3 volts)
Some perfboard
Batteries that go with your battery pack
Some wire

Tools:
Arduino board (for programming the ATtiny)
USB A-B cable (for plugging in the Arduino)
Soldering iron
Thin solder
Helping hands (optional, but very helpful for soldering)
Something to cut down the perfboard to size (I used my Dremel)

Step 2: How It Works

At this point, you might be thinking that the ATtiny85 does not have enough input/output pins to drive 7 LEDs and read the input of a pushbutton.

If you thought this, you would be right, but there is a way around this.

If you look at a 6 sided die, you might notice that there are never 2 dots that aren't diagonal or across from each other that are not there at the same time (except for the middle one). That means that we can connect the top left LED to the bottom right LED, the middle left LED to the middle right LED, and the bottom left LED to the top right LED.

So now we only need 4 pins to control all of the LEDs (the 3 pairs of LEDs and the single middle one). That means we have one pin left over to read the push button. Perfect!

Step 3: Program the ATtiny MCU

If you read my Instructable on the 5 LED POV display, they you probably already know how to do this. For those of you that don't, here is a guide.

This is the code that you need to upload to the ATtiny:

int pinLeds1 = 3;
int pinLeds2 = 2;
int pinLeds3 = 1;
int pinLed4 = 0;
int buttonPin = 4;
int buttonState;
long ran;
int time = 2000;

void setup ()
{
  pinMode (pinLeds1, OUTPUT);
  pinMode (pinLeds2, OUTPUT);
  pinMode (pinLeds3, OUTPUT);
  pinMode (pinLed4, OUTPUT);
  pinMode (buttonPin, INPUT);
  randomSeed(analogRead(0));
}

void loop()
{
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH){
    ran = random(1, 7);
    if (ran == 1){
      digitalWrite (pinLed4, HIGH);
      delay (time);
    }
    if (ran == 2){
      digitalWrite (pinLeds1, HIGH);
      delay (time);
    }
    if (ran == 3){
      digitalWrite (pinLeds3, HIGH);
      digitalWrite (pinLed4, HIGH);
      delay (time);
    }
    if (ran == 4){
      digitalWrite (pinLeds1, HIGH);
      digitalWrite (pinLeds3, HIGH);
      delay (time);
    }
    if (ran == 5){
      digitalWrite (pinLeds1, HIGH);
      digitalWrite (pinLeds3, HIGH);
      digitalWrite (pinLed4, HIGH);
      delay (time);
   }
   if (ran == 6){
      digitalWrite (pinLeds1, HIGH);
      digitalWrite (pinLeds2, HIGH);
      digitalWrite (pinLeds3, HIGH);
      delay (time);
   }
  }
  digitalWrite (pinLeds1, LOW);
  digitalWrite (pinLeds2, LOW);
  digitalWrite (pinLeds3, LOW);
  digitalWrite (pinLed4, LOW);
}

Step 4: Breadboard It!

Now put it all on a breadboard and test it out. You can power it with any 3 volt power source. Make sure that the LEDs are arranged correctly!

Step 5: Solder It!

Now you can solder it onto your perfboard, if you would like. Be careful though, it gets kind of trick with all the LED wires/leads crossing, make sure they are not touching, or else your dice will not work.

Also, make absolutely sure that you connect/arrange the LEDs correctly, or else the LEDs will not light up the right way.

Sorry I couldn't take pictures of the soldering process, I made this Instructable after I completely finished the dice.

Step 6: Make It Look Nice!

I cut down the perfboard with my Dremel, and then used the sander bit to round off the edges. Then I hot glued the battery pack to the back of the perfboard.

Now it looks nice!

Step 7: Use It!

Push the button to make a random dice number between 1 and 6 appear on the LEDs.

Congratulations! You're done!

2 People Made This Project!

Recommendations

  • First Time Author

    First Time Author
  • Make it Glow Contest 2018

    Make it Glow Contest 2018
  • Big and Small Contest

    Big and Small Contest

32 Discussions

0
None
mboroff

4 years ago on Introduction

So I thought it would be neat to build two of these on one board. After all most games use two dice. Anyway I have one double DPDT switch turn the power on both circuits at the same time. Well it turns out that both dice seem to almost always show the same value when you hit the switch to display a number. Since there is no clock or anything unique to make one randomize different from the other. So other than modifying one die with a variation on the random number generation, anybody got any ideas would be appreciated.

dice.JPG
2 replies
0
None
drededmboroff

Reply 3 years ago on Introduction

the code above tries to make a random seed by reading from ADC(0) with the line randomSeed(analogRead(0)); but there is two issues with this... I don't think the ATTiny45/85 has a correlating AnalogPin 0 in the Arduino IDE so this would need to be randomSeed(analogRead(1)); to read ATTINY pin7... but that still wont work to well because there is a connection on Pin7(aka arduino digital pin2) so its not floating and you wont get a very random value... but I would try that first and see what happens but you most likely will need to do something tricky and put the switch and the DigitalPin2 LED onto DigitalPin4(by switching the pin to an input checking for a button press then back to an output to display LED over and over again) so you can leave Analog Pin 1 floating so it will get random noise from the environment.

0
None
annekh510dreded

Reply 6 weeks ago

My guess is that if they have a shared switch to turn them on then they'll be running the setup at the same time and will get the same reading for the analogRead, as long as that input is left floating stick a slight time delay in the setup and hopefully you get two different seeds.

0
None
annekh510

6 weeks ago

I took the idea but started from scratch with both the circuit and the code.
I put resistors in for the LEDs and even worked out the relative sizes of the one for the single LED vs two LEDs so they all had the same current and thus brightness. The one major thing I found was that a 3V battery would not power two LEDs, I didn't try every colour/size I had on hand and I can't remember if I tried without a resistor, but my doodles suggest each LED needs 2V, so two in series need 4V. Your circuit diagram fried my brain, so I've only just realised it works by doing it in series. However this did lead to me finding some really nifty battery holders that take two coin cells and have an on/off switch, I haven't found anything I like as much that takes a single battery.
I found I needed to debounce the button. To make the code a bit clearer I stuck the dice rolling code into a separate function. Having done that I figured I might as well play and added a function that flashed the lights going round in a circle to build up some tension whilst the dice got rolled.
It's still on a breadboard at the moment, I might try a 2 dice version, but I can't figure out a way to do it with a single ATtiny85, I don't have much experience with it and I don't think enough pins can do PWM and I'm not sure if it has enough processing power to implement that in software.

0
None

I had to change over some of the pins in your code, This is what I had:
int pinLeds1 = 4;
int pinLeds2 = 1;
int pinLeds3 = 0;
int pinLed4 = 3;
int buttonPin = 2;
Works good.

DSC_0392.JPG
5 replies
0
None
xBaconUnusualTravis

Reply 6 years ago on Introduction

Thats a pic of the one you made? Nice! I always like to run things on a smaller battery so its more compact, so i like how you did that.

0
None
UnusualTravisxBacon

Reply 6 years ago on Introduction

This little guy works great but I revisited this last night, I found that the battery life wasn't as good as it could be due to the chip always ON even when not in use, now my code puts the attiny85 into a "sleep" mode and wakes up when you press the button, the button has to be wired differently, the Switch must pull the attiny85 LOW instead. Batteries can last a much longer now. but now I need a new PCB :)

0
None
drededUnusualTravis

Reply 3 years ago on Introduction

using a high precision multimeter I measured 1mA on the original circuit so about 8 days of battery on a CR2032(not going to sleep) I then put the attiny85 into sleep mode but was still measuring .25mA(about 30 days on the battery) so I then looked into how to make the attiny use even less power and found out I need to disable the ADC's etc so then we now have a battery life of 15+yrs assuming you push the button an average of 2x per hour every hour.. I also added a 10k resistors to each LED pair and re-wrote the code to be non blocking(no use of delay) and be MUCH MUCH more random... so with my code you hold the button down and the dice visually rolls(extremely quickly goes through all 6 sides randomly) then when you release the button it will display the rolled number for either 2 seconds or until you press the button again(so you could re-roll immediately after seeing number)

[code]

#include <avr/sleep.h>

#include <avr/power.h>

int pinLeds1 = 1;

int pinLeds2 = 4;

int pinLeds3 = 0;

int pinLed4 = 3;

int buttonPin = 2;

int buttonState;

long ran;

int time = 2000;

unsigned long lastmillis;

int i = 0;

typedef void (* NumFuncPTR) ();

NumFuncPTR number[6] = {One,Two,Three,Four,Five,Six};

void pin2Interrupt(void)

{

/* This will bring us back from sleep. */

/* We detach the interrupt to stop it from

* continuously firing while the interrupt pin

* is low.

*/

detachInterrupt(0);

}

void enterSleep(void)

{

/* Setup pin2 as an interrupt and attach handler. */

attachInterrupt(0, pin2Interrupt, LOW);

delay(100);

set_sleep_mode(SLEEP_MODE_PWR_DOWN);

sleep_enable();

sleep_mode();

/* The program will continue from here. */

/* First thing to do is disable sleep. */

sleep_disable();

}

void Blink(){ //was written for debugging but I left it in.

digitalWrite(pinLed4,HIGH);

delay(500);

digitalWrite(pinLed4,LOW);

delay(500);

}

void setup ()

{

//Disable stuff we dont need so we can entire extreme low power sleep(.1uA)

// Disable the ADC by setting the ADEN bit (bit 7) to zero.

ADCSRA = ADCSRA & B01111111;

// Disable the analog comparator by setting the ACD bit (bit 7) to one.

ACSR = B10000000;

randomSeed(analogRead(1));

pinMode (pinLeds1, OUTPUT);

pinMode (pinLeds2, OUTPUT);

pinMode (pinLeds3, OUTPUT);

pinMode (pinLed4, OUTPUT);

pinMode (buttonPin, INPUT_PULLUP);

lastmillis = millis();

}

void loop()

{

buttonState = digitalRead(buttonPin);

while (buttonState == LOW){

buttonState = digitalRead(buttonPin);

time = 2000;

lastmillis = millis();

reset();

number[random(1,6)]();

delay(30);

}

if (lastmillis + time <= millis()){

reset();

enterSleep();

}

}

void One(){

digitalWrite (pinLed4, HIGH);

};

void Two(){

digitalWrite (pinLeds1, HIGH);

};

void Three(){

digitalWrite (pinLeds3, HIGH);

digitalWrite (pinLed4, HIGH);

};

void Four(){

digitalWrite (pinLeds2, HIGH);

digitalWrite (pinLeds3, HIGH);

};

void Five(){

digitalWrite (pinLeds2, HIGH);

digitalWrite (pinLeds3, HIGH);

digitalWrite (pinLed4, HIGH);

};

void Six(){

digitalWrite (pinLeds1, HIGH);

digitalWrite (pinLeds2, HIGH);

digitalWrite (pinLeds3, HIGH);

};

void reset(){

digitalWrite (pinLeds1, LOW);

digitalWrite (pinLeds2, LOW);

digitalWrite (pinLeds3, LOW);

digitalWrite (pinLed4, LOW);

}

[/code]

0
None
Basd15dreded

Reply 8 months ago

hello, i have a question about your code, when i'm using the code for my ATTINY25. it keeps saying that " NumFuncPTR number[6] = {One,Two,Three,Four,Five,Six}; " was not declayerd in this code

maybe you got a solution for this, cause i don't kno wit any more

0
None
Basd15dreded

Reply 10 months ago

Love your code and solution!!. Do you have a schematic for what you did with the leds and everything?

0
None
vkannan1

2 years ago

Hi nice

0
None
Yngel

3 years ago on Step 7

This looks like a geat little project. I've never used the ATtiny before, and now I've ordered 10. This'll be the first project I'll use it for.

0
None
zombiemom42

6 years ago on Introduction

ok so i mad emy own version of this before i even saw this one and i seems to be the same pretty much, I used an ATtiny 85. if tried 3 different sketches and none of them work, is one only flashes a 3. Please help!?

Hi, I also made an LED dice out of an Attiny25, you may wanna look at my code, as mine makes the chip go to sleep after it finishes with the numbers and so the batery can last up to 80 YEARS!
you may wanna add some sleep functions to your code, I managed to get the power consumption to less than 0.1 microAmps!

3 replies

yeah, thst's true, the actual self discharge of the battery is more tha the power needed by the chip itself, of course, what takes most of the battery's energy is the LEDs when they are ON.

Oh yeah, emihackr97, when i tried your code it messed up my ATtiny. It wouldn't let me upload any sketches to it but when it did it just didn't display any numbers when i pressed the button...