├── LICENSE ├── README.md ├── documentation ├── TinyDice_pic1.jpg ├── TinyDice_pic2.jpg ├── TinyDice_pic3.jpg ├── TinyDice_pic4.jpg └── TinyDice_wiring.png ├── hardware ├── tinyDice_BOM_v1.0.tsv ├── tinyDice_gerber_v1.0.zip └── tinyDice_schematic_v1.0.pdf └── software ├── TinyDice.ino ├── makefile └── tinydice.hex /LICENSE: -------------------------------------------------------------------------------- 1 | This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. 2 | To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send 3 | a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TinyDice - Electronic Dice based on ATtiny13A 2 | TinyDice is a tiny (35mm * 17mm) electronic dice powered by ATtiny13A. 3 | 4 | - Project Video (YouTube): https://youtu.be/Zr3TuCeP4eM 5 | - Design Files (EasyEDA): https://easyeda.com/wagiminator/attiny10-tinydice-smd 6 | 7 | ![pic1.jpg](https://raw.githubusercontent.com/wagiminator/ATtiny13-TinyDice/master/documentation/TinyDice_pic1.jpg) 8 | 9 | # Hardware 10 | The wiring is pretty simple: 11 | 12 | ![wiring.png](https://raw.githubusercontent.com/wagiminator/ATtiny13-TinyDice/master/documentation/TinyDice_wiring.png) 13 | 14 | The fact that the opposite pairs of dots on a dice always appear together was used for the circuit diagram. This means that there is no need for Multi or Charlieplexing. However, the supply voltage must be at least twice as high as the forward voltage of the LEDs. Therefore only red LEDs and the rechargeable LIR2032 li-ion batteries should be used. 15 | 16 | # Software 17 | ## Implementation 18 | Timer0 is used to constantly change the number of pips in the background. Chance is created by the uncertainty of the moment the button is pressed by the user, which brings the current number of pips to display. As long as nothing else needs to be done, the ATtiny remains in IDLE and only wakes up when you press a button (pin change interrupt). Then it rolls the dice, in which a series of numbers are shown on the dice with increasing time interval. Finally, the last number shown remains and the ATtiny changes back to IDLE. The number of pips shown on the dice corresponds to the respective variable pips, which is constantly changed by the timer overflow interrupt. A simple matrix is used to control the LEDs, with which the respective number is converted into the values for the PORTB register. 19 | 20 | ```c 21 | // Libraries 22 | #include // for GPIO 23 | #include // for sleep mode 24 | #include // for interrupts 25 | #include // for delays 26 | 27 | // Global variables 28 | volatile uint8_t pips = 0; // current number of pips 29 | 30 | // Main function 31 | int main(void) { 32 | // Local variables 33 | uint8_t matrix[] = {0b00110001, // 1 34 | 0b00110100, // 2 35 | 0b00110011, // 3 36 | 0b00110110, // 4 37 | 0b00110111, // 5 38 | 0b00111110};// 6 - for converting pips to pins 39 | 40 | // Setup pins 41 | DDRB = 0b00001111; // PB0 - PB3 as output, PB4 input 42 | PORTB = 0b00110001; // pull-up for PB4/5; LED7 on 43 | 44 | // Setup timer/counter 45 | TCCR0A = 0b00000000; // no output 46 | TCCR0B = 0b00000011; // set prescaler to 64 47 | TIMSK0 = 0b00000010; // enable timer overflow interrupt 48 | 49 | // Setup pin change interrupt 50 | GIMSK = 0b00100000; // turn on pin change interrupts 51 | PCMSK = 0b00010000; // pin change interrupt on button pin 52 | SREG |= 0b10000000; // enable global interrupts 53 | 54 | // Disable unused peripherals and set sleep mode to save power 55 | ACSR = 0b10000000; // disable analog comperator 56 | PRR = 0b00000001; // shut down ADC 57 | set_sleep_mode(SLEEP_MODE_IDLE);// set sleep mode to IDLE 58 | 59 | // Loop 60 | while(1) { 61 | sleep_mode(); // go to sleep 62 | if(~PINB & 0b00010000) { // if button pressed: 63 | for(uint8_t i = 0; i < 16; i++) { // roll the dice 64 | uint8_t del = (i << 4); // increasing delay between pip-shows 65 | while(del--) _delay_ms(1); // set the delay 66 | PORTB = matrix[pips]; // show current number of pips 67 | } 68 | while(~PINB & 0b00010000); // wait for button released 69 | _delay_ms(10); // debounce 70 | } 71 | } 72 | } 73 | 74 | // Timer0 overflow interrupt service routine 75 | ISR(TIM0_OVF_vect) { 76 | if(++pips > 5) pips = 0; // cycle number of pips on every timer overflow 77 | } 78 | 79 | // Pin change interrupt service routine 80 | EMPTY_INTERRUPT(PCINT0_vect); // nothing to be done here, just wake up from sleep 81 | ``` 82 | 83 | ## Compiling and Uploading 84 | Since there is no ICSP header on the board, you have to program the ATtiny either before soldering using an [SOP adapter](https://aliexpress.com/wholesale?SearchText=sop-8+150mil+adapter), or after soldering using an [EEPROM clip](https://aliexpress.com/wholesale?SearchText=sop8+eeprom+programming+clip). The [AVR Programmer Adapter](https://github.com/wagiminator/AVR-Programmer/tree/master/AVR_Programmer_Adapter) can help with this. 85 | 86 | ### If using the Arduino IDE 87 | - Make sure you have installed [MicroCore](https://github.com/MCUdude/MicroCore). 88 | - Go to **Tools -> Board -> MicroCore** and select **ATtiny13**. 89 | - Go to **Tools** and choose the following board options: 90 | - **Clock:** 1.2 MHz internal osc. 91 | - **BOD:** BOD disabled 92 | - **Timing:** Micros disabled 93 | - Connect your programmer to your PC and to the ATtiny. 94 | - Go to **Tools -> Programmer** and select your ISP programmer (e.g. [USBasp](https://aliexpress.com/wholesale?SearchText=usbasp)). 95 | - Go to **Tools -> Burn Bootloader** to burn the fuses. 96 | - Open TinyDice.ino and click **Upload**. 97 | 98 | ### If using the precompiled hex-file 99 | - Make sure you have installed [avrdude](https://learn.adafruit.com/usbtinyisp/avrdude). 100 | - Connect your programmer to your PC and to the ATtiny. 101 | - Open a terminal. 102 | - Navigate to the folder with the hex-file. 103 | - Execute the following command (if necessary replace "usbasp" with the programmer you use): 104 | ``` 105 | avrdude -c usbasp -p t13 -U lfuse:w:0x2a:m -U hfuse:w:0xff:m -U flash:w:tinydice.hex 106 | ``` 107 | 108 | ### If using the makefile (Linux/Mac) 109 | - Make sure you have installed [avr-gcc toolchain and avrdude](http://maxembedded.com/2015/06/setting-up-avr-gcc-toolchain-on-linux-and-mac-os-x/). 110 | - Connect your programmer to your PC and to the ATtiny. 111 | - Open a terminal. 112 | - Navigate to the folder with the makefile and sketch. 113 | - Run `PROGRMR=usbasp make install` to compile, burn the fuses and upload the firmware (change PROGRMR accordingly). 114 | 115 | # References, Links and Notes 116 | 1. [ATtiny13A Datasheet](http://ww1.microchip.com/downloads/en/DeviceDoc/doc8126.pdf) 117 | 118 | ![pic3.jpg](https://raw.githubusercontent.com/wagiminator/ATtiny13-TinyDice/master/documentation/TinyDice_pic3.jpg) 119 | ![pic4.jpg](https://raw.githubusercontent.com/wagiminator/ATtiny13-TinyDice/master/documentation/TinyDice_pic4.jpg) 120 | 121 | # License 122 | ![license.png](https://i.creativecommons.org/l/by-sa/3.0/88x31.png) 123 | 124 | This work is licensed under Creative Commons Attribution-ShareAlike 3.0 Unported License. 125 | (http://creativecommons.org/licenses/by-sa/3.0/) 126 | -------------------------------------------------------------------------------- /documentation/TinyDice_pic1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/ATtiny13-TinyDice/8047d367f60a2e84074dcadcc05a3d5c99952aef/documentation/TinyDice_pic1.jpg -------------------------------------------------------------------------------- /documentation/TinyDice_pic2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/ATtiny13-TinyDice/8047d367f60a2e84074dcadcc05a3d5c99952aef/documentation/TinyDice_pic2.jpg -------------------------------------------------------------------------------- /documentation/TinyDice_pic3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/ATtiny13-TinyDice/8047d367f60a2e84074dcadcc05a3d5c99952aef/documentation/TinyDice_pic3.jpg -------------------------------------------------------------------------------- /documentation/TinyDice_pic4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/ATtiny13-TinyDice/8047d367f60a2e84074dcadcc05a3d5c99952aef/documentation/TinyDice_pic4.jpg -------------------------------------------------------------------------------- /documentation/TinyDice_wiring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/ATtiny13-TinyDice/8047d367f60a2e84074dcadcc05a3d5c99952aef/documentation/TinyDice_wiring.png -------------------------------------------------------------------------------- /hardware/tinyDice_BOM_v1.0.tsv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/ATtiny13-TinyDice/8047d367f60a2e84074dcadcc05a3d5c99952aef/hardware/tinyDice_BOM_v1.0.tsv -------------------------------------------------------------------------------- /hardware/tinyDice_gerber_v1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/ATtiny13-TinyDice/8047d367f60a2e84074dcadcc05a3d5c99952aef/hardware/tinyDice_gerber_v1.0.zip -------------------------------------------------------------------------------- /hardware/tinyDice_schematic_v1.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wagiminator/ATtiny13-TinyDice/8047d367f60a2e84074dcadcc05a3d5c99952aef/hardware/tinyDice_schematic_v1.0.pdf -------------------------------------------------------------------------------- /software/TinyDice.ino: -------------------------------------------------------------------------------- 1 | // =================================================================================== 2 | // Project: TinyDice - Electronic Dice based on ATtiny13A 3 | // Version: v1.0 4 | // Year: 2020 5 | // Author: Stefan Wagner 6 | // Github: https://github.com/wagiminator 7 | // EasyEDA: https://easyeda.com/wagiminator 8 | // License: http://creativecommons.org/licenses/by-sa/3.0/ 9 | // =================================================================================== 10 | // 11 | // Description: 12 | // ------------ 13 | // A tiny electronic dice powered by ATtiny13A. Timer0 is used to 14 | // constantly change the number of pips. Chance is created by the 15 | // uncertainty of the moment the button is pressed by the user. 16 | // 17 | // Wiring: 18 | // ------- 19 | // +-\/-+ 20 | // --- RST ADC0 PB5 1|° |8 Vcc 21 | // LED2/5 ------- ADC3 PB3 2| |7 PB2 ADC1 -------- LED1/4 22 | // Button ------- ADC2 PB4 3| |6 PB1 AIN1 OC0B --- LED3/6 23 | // GND 4| |5 PB0 AIN0 OC0A --- LED7 24 | // +----+ 25 | // Dice 26 | // +------------------+ 27 | // | LED1 LED6 | 28 | // | | 29 | // | LED2 LED7 LED5 | 30 | // | | 31 | // | LED3 LED4 | 32 | // +------------------+ 33 | // 34 | // Compilation Settings: 35 | // --------------------- 36 | // Controller: ATtiny13A 37 | // Core: MicroCore (https://github.com/MCUdude/MicroCore) 38 | // Clockspeed: 1.2 MHz internal 39 | // BOD: BOD disabled 40 | // Timing: Micros disabled 41 | // 42 | // Leave the rest on default settings. Don't forget to "Burn bootloader"! 43 | // No Arduino core functions or libraries are used. Use the makefile if 44 | // you want to compile without Arduino IDE. 45 | // 46 | // Fuse settings: -U lfuse:w:0x2a:m -U hfuse:w:0xff:m 47 | 48 | 49 | // =================================================================================== 50 | // Libraries and Definitions 51 | // =================================================================================== 52 | 53 | // Libraries 54 | #include // for GPIO 55 | #include // for sleep mode 56 | #include // for interrupts 57 | #include // for delays 58 | 59 | // Global variables 60 | volatile uint8_t pips = 0; // current number of pips 61 | 62 | // =================================================================================== 63 | // Main Function 64 | // =================================================================================== 65 | 66 | int main(void) { 67 | // Local variables 68 | uint8_t matrix[] = {0b00110001, // 1 69 | 0b00110100, // 2 70 | 0b00110011, // 3 71 | 0b00110110, // 4 72 | 0b00110111, // 5 73 | 0b00111110};// 6 - for converting pips to pins 74 | 75 | // Setup pins 76 | DDRB = 0b00001111; // PB0 - PB3 as output, PB4 input 77 | PORTB = 0b00110001; // pull-up for PB4/5; LED7 on 78 | 79 | // Setup timer/counter 80 | TCCR0A = 0b00000000; // no output 81 | TCCR0B = 0b00000011; // set prescaler to 64 82 | TIMSK0 = 0b00000010; // enable timer overflow interrupt 83 | 84 | // Setup pin change interrupt 85 | GIMSK = 0b00100000; // turn on pin change interrupts 86 | PCMSK = 0b00010000; // pin change interrupt on button pin 87 | SREG |= 0b10000000; // enable global interrupts 88 | 89 | // Disable unused peripherals and set sleep mode to save power 90 | ACSR = 0b10000000; // disable analog comperator 91 | PRR = 0b00000001; // shut down ADC 92 | set_sleep_mode(SLEEP_MODE_IDLE);// set sleep mode to IDLE 93 | 94 | // Loop 95 | while(1) { 96 | sleep_mode(); // go to sleep 97 | if(~PINB & 0b00010000) { // if button pressed: 98 | for(uint8_t i = 0; i < 16; i++) { // roll the dice 99 | uint8_t del = (i << 4); // increasing delay between pip-shows 100 | while(del--) _delay_ms(1); // set the delay 101 | PORTB = matrix[pips]; // show current number of pips 102 | } 103 | while(~PINB & 0b00010000); // wait for button released 104 | _delay_ms(10); // debounce 105 | } 106 | } 107 | } 108 | 109 | // =================================================================================== 110 | // Interrupt Service Routines 111 | // =================================================================================== 112 | 113 | // Timer0 overflow interrupt service routine 114 | ISR(TIM0_OVF_vect) { 115 | if(++pips > 5) pips = 0; // cycle number of pips on every timer overflow 116 | } 117 | 118 | // Pin change interrupt service routine 119 | EMPTY_INTERRUPT(PCINT0_vect); // nothing to be done here, just wake up from sleep 120 | -------------------------------------------------------------------------------- /software/makefile: -------------------------------------------------------------------------------- 1 | # =================================================================================== 2 | # Project: tinyDice 3 | # Author: Stefan Wagner 4 | # Year: 2020 5 | # URL: https://github.com/wagiminator 6 | # =================================================================================== 7 | # Type "make help" in the command line. 8 | # =================================================================================== 9 | 10 | # Input and Output File Names 11 | SKETCH = TinyDice.ino 12 | TARGET = tinydice 13 | 14 | # Microcontroller Settings 15 | DEVICE = attiny13a 16 | CLOCK = 1200000 17 | LFUSE = 0x2a 18 | HFUSE = 0xff 19 | 20 | # Programmer Settings 21 | PROGRMR ?= usbasp 22 | TGTDEV = attiny13 23 | 24 | # Toolchain 25 | CC = avr-gcc 26 | OBJCOPY = avr-objcopy 27 | OBJDUMP = avr-objdump 28 | AVRSIZE = avr-size 29 | AVRDUDE = avrdude -c $(PROGRMR) -p $(TGTDEV) 30 | CLEAN = rm -f *.lst *.obj *.cof *.list *.map *.eep.hex *.o *.s *.d 31 | 32 | # Compiler Flags 33 | CFLAGS = -Wall -Os -flto -mmcu=$(DEVICE) -DF_CPU=$(CLOCK) -x c++ 34 | 35 | # Symbolic Targets 36 | help: 37 | @echo "Use the following commands:" 38 | @echo "make all compile and build $(TARGET).elf/.bin/.hex/.asm for $(DEVICE)" 39 | @echo "make hex compile and build $(TARGET).hex for $(DEVICE)" 40 | @echo "make asm compile and disassemble to $(TARGET).asm for $(DEVICE)" 41 | @echo "make bin compile and build $(TARGET).bin for $(DEVICE)" 42 | @echo "make upload compile and upload to $(DEVICE) using $(PROGRMR)" 43 | @echo "make fuses burn fuses of $(DEVICE) using $(PROGRMR) programmer" 44 | @echo "make install compile, upload and burn fuses for $(DEVICE)" 45 | @echo "make clean remove all build files" 46 | 47 | all: buildelf buildbin buildhex buildasm removetemp size 48 | 49 | elf: buildelf removetemp size 50 | 51 | bin: buildelf buildbin removetemp size removeelf 52 | 53 | hex: buildelf buildhex removetemp size removeelf 54 | 55 | asm: buildelf buildasm removetemp size removeelf 56 | 57 | flash: upload fuses 58 | 59 | install: upload fuses 60 | 61 | upload: hex 62 | @echo "Uploading $(TARGET).hex to $(DEVICE) using $(PROGRMR) ..." 63 | @$(AVRDUDE) -U flash:w:$(TARGET).hex:i 64 | 65 | fuses: 66 | @echo "Burning fuses of $(DEVICE) ..." 67 | @$(AVRDUDE) -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m 68 | 69 | clean: 70 | @echo "Cleaning all up ..." 71 | @$(CLEAN) 72 | @rm -f $(TARGET).elf $(TARGET).bin $(TARGET).hex $(TARGET).asm 73 | 74 | buildelf: 75 | @echo "Compiling $(SKETCH) for $(DEVICE) @ $(CLOCK)Hz ..." 76 | @$(CC) $(CFLAGS) $(SKETCH) -o $(TARGET).elf 77 | 78 | buildbin: 79 | @echo "Building $(TARGET).bin ..." 80 | @$(OBJCOPY) -O binary -R .eeprom $(TARGET).elf $(TARGET).bin 81 | 82 | buildhex: 83 | @echo "Building $(TARGET).hex ..." 84 | @$(OBJCOPY) -j .text -j .data -O ihex $(TARGET).elf $(TARGET).hex 85 | 86 | buildasm: 87 | @echo "Disassembling to $(TARGET).asm ..." 88 | @$(OBJDUMP) -d $(TARGET).elf > $(TARGET).asm 89 | 90 | size: 91 | @echo "------------------" 92 | @echo "FLASH: $(shell $(AVRSIZE) -d $(TARGET).elf | awk '/[0-9]/ {print $$1 + $$2}') bytes" 93 | @echo "SRAM: $(shell $(AVRSIZE) -d $(TARGET).elf | awk '/[0-9]/ {print $$2 + $$3}') bytes" 94 | @echo "------------------" 95 | 96 | removetemp: 97 | @echo "Removing temporary files ..." 98 | @$(CLEAN) 99 | 100 | removeelf: 101 | @echo "Removing $(TARGET).elf ..." 102 | @rm -f $(TARGET).elf 103 | -------------------------------------------------------------------------------- /software/tinydice.hex: -------------------------------------------------------------------------------- 1 | :1000000009C021C021C021C01EC01DC01CC01BC012 2 | :100010001AC019C011241FBECFE9CDBF10E0A0E661 3 | :10002000B0E0ECE1F1E002C005900D92A636B10718 4 | :10003000D9F720E0A6E6B0E001C01D92A736B207CE 5 | :10004000E1F718D069C0DCCF18951F920F920FB658 6 | :100050000F9211248F93809166008F5F80936600CA 7 | :10006000863010F0109266008F910F900FBE0F90A7 8 | :100070001F901895CF93DF93CDB7DD27C650CDBF26 9 | :1000800086E0E0E6F0E0DE01119601900D928A959F 10 | :10009000E1F78FE087BB81E388BB1FBC83E083BFB0 11 | :1000A00082E089BF80E28BBF80E185BB8FB780682B 12 | :1000B0008FBF80E888B981E085BD85B7877E85BF21 13 | :1000C00085B7806285BF889585B78F7D85BFB499D8 14 | :1000D000F7CF80E0982F9295907F915038F0EBE227 15 | :1000E000F1E03197F1F700C00000F7CF9091660082 16 | :1000F000E1E0F0E0EC0FFD1FE90FF11D908198BBEE 17 | :100100008F5F803139F7B49BFECF87EB9BE001977F 18 | :0C011000F1F700C00000D4CFF894FFCF3E 19 | :06011C0031343336373E9A 20 | :00000001FF 21 | --------------------------------------------------------------------------------