A microcontroller-based interactive dice roller with full Proteus simulation
Features 40Γ40 pixel animations, musical feedback, and hardware-accurate implementation of a 20-sided dice system.
- Animated D20 simulation with 20 rapid rolls before final result
- 128Γ64 KS0108 GLCD display with custom bitmap rendering
- Multi-layer audio system:
- 2N2222-driven buzzer with flyback protection
- FΓΌr Elise melody playback via PWM timing
- Debounced input using RB6 tactile switch
- Proteus-ready design with virtual instrumentation support
Component | Specification | Pin Mapping/Connection |
---|---|---|
PIC16F877A | 8-bit MCU @ 20 MHz (HS Mode) | - OSC1/OSC2: Pins 13-14 (Crystal) - PORTD: RD0-RD7 (GLCD Data Bus) - PORTB: RB0-RB7 (Control Signals) |
KS0108 GLCD | 128Γ64 Graphic Display | - RS: RB0 - RW: RB1 - E: RB2 - CS1: RB3 - CS2: RB4 - RST: RB5 - Data Bus: PORTD (RD0-RD7) - VO: RV1 - VOUT: RV1 |
Buzzer Circuit | Passive Buzzer + 2N2222 Driver | - RB7 β 470Ξ© (R2) β 2N2222 Base - Collector: Buzzer + 1N4001 Flyback Diode - Emitter: GND |
Roll Button | Tactile Switch (Debounced) | - RB6 β 10kΞ© Pull-up (R1) - Switch to GND |
Oscillator | 20 MHz Crystal + 22 pF Capacitors | - X1: 20 MHz Crystal - C1/C2: 22 pF Ceramic Caps (GND) |
Power System | 5V Regulated Supply | - 100nF Decoupling Caps (VCC-GND) - RV1: 10kΞ© GLCD Contrast Pot |
-
GLCD Interface
- Control Signals: Mapped to PORTB (RB0-RB5)
- Data Bus: Full 8-bit parallel connection via PORTD
- Reset Circuit: Hardware reset via RB5 (Active High)
-
Buzzer Protection
- Transistor: 2N2222 NPN (Q1) with 470Ξ© base resistor (R2)
- Flyback Diode: 1N4001 (D1) across buzzer terminals
-
Clock Accuracy
- 20 MHz crystal (X1) with 22 pF capacitors (C1/C2)
- HS oscillator mode configured via
#pragma config FOSC = HS
-
User Input
- Debounced button on RB6 with hardware pull-up (R1 = 10kΞ©)
ββββββββββββββββββββββββββ
β Application β βΊ Core logic & animation control
ββββββββββββββββββββββββββ€
β Services β βΊ GLCD rendering, audio management
ββββββββββββββββββββββββββ€
β Hardware Abstraction β βΊ KS0108 commands, buzzer timing
ββββββββββββββββββββββββββ€
β MCU Peripherals β βΊ Port I/O, clock configuration
ββββββββββββββββββββββββββ
- Low-Level Operations:
void glcd_write_command(uint8_t cmd); // Direct KS0108 communication void glcd_set_page(uint8_t page); // Vertical positioning (0-7) void glcd_set_column(uint8_t col); // Horizontal positioning (0-63)
- Key Features:
- Dual-chip control for 128-pixel width
- Hardware reset sequence with precise timing
- Page-based memory addressing for efficient updates
- Precision Sound Generation:
void beep(uint16_t freq, uint16_t duration_ms); // Frequency-accurate tones
- Cycle-exact delays using
__delay_us()
- Automatic muting during REST notes
- Cycle-exact delays using
-
Graphic Rendering:
void glcd_draw_bitmap(uint8_t x, uint8_t yPage, uint8_t w, uint8_t h, const uint8_t *data);
- Handles 40Γ40 dice sprites from
dice_bitmaps.h
- Automatic chip selection for cross-screen elements
- Handles 40Γ40 dice sprites from
-
Text Engine:
void glcd_puts(const char *str); // 5Γ7 bitmap font renderer
- Dynamic centering algorithm:
xCenter = x + 20 - (strlen(str)*6)/2; // 6px/character width
- Dynamic centering algorithm:
- Musical Playback System:
void play_sonata(void); // Tempo-controlled melody
- Duration calculator:
const int wholenote = (60000 * 4) / TEMPO; // TEMPO = 114 BPM uint16_t noteDuration = wholenote / noteType;
- Supports dotted notes via negative duration values
- Duration calculator:
while(1) {
// Idle state
if (button_pressed()) {
// Animation sequence
for (uint8_t i=0; i<20; i++) {
roll_dice();
update_display();
beep(2000, 50); // 2kHz feedback
}
// Final display
show_results();
play_melody();
}
}
- Randomized Roll Generation:
srand(1); // Fixed seed for consistency uint8_t value = (rand() % 20) + 1; // D20 range (1-20)
- Animation Controller:
- 20-frame animation @ 50ms/frame (1s total duration)
- Frame-synchronized display updates
- Sound Database:
#define NOTE_B0 31 // B0 = 31 Hz #define NOTE_C4 262 // Middle C = 262 Hz /* ... 100+ notes ... */
- Musical Sequence:
const Note sonata[] = { {NOTE_E4, wholenote/4}, {NOTE_E4, wholenote/4}, // ... 32-note arrangement ... };
- Graphic Assets:
static const uint8_t dice_bitmap_40x40[200] = { 0x00, 0xFC, 0xFF, 0x3F, 0x00, // 40Γ40px 1bpp pattern // ... 196 more bytes ... };
sequenceDiagram
Main Loop->>Button: Poll RB6
Button-->>Animation: Start 20-roll sequence
Animation->>GLCD: Update dice bitmap
Animation->>Buzzer: Play 2kHz beep
Animation->>RNG: Get new dice value
loop 20 times
GLCD-->>Display: Render frame
Buzzer-->>Audio: Generate tone
end
Audio->>Melody: Play FΓΌr Elise
-
Hardware-Independent Timing:
software_us_delay()
enables Proteus simulation compatibility- Avoids hardware timer dependencies
-
Memory Optimization:
- Bitmaps stored in flash via
const
declaration - On-the-fly font rendering minimizes RAM usage
- Bitmaps stored in flash via
-
Musical Fidelity:
- Integer-based duration calculations (no floating point)
- 90%/10% note/rest ratio for articulation
DICE_ROLLER/
βββ PIC/
β βββ DICE_PIC.X.production.hex # Precompiled firmware
βββ Proteus/
β βββ DICE_ROLLER_LCD_PIC.pdsprj # Proteus simulation project
β βββ DICE_ROLLER_LCD_PIC.PDF # Complete schematic diagram
βββ assets/
β βββ DICE_ROLLER_LCD_PIC-1.png # Example screenshot(s)
β βββ dice.png # Additional dice image
βββ src/
βββ header/ # Header files (prototypes, data)
β βββ audio.h # Declarations for beep() & delays
β βββ dice_bitmaps.h # 40Γ40 dice bitmap data
β βββ glcd_driver.h # KS0108 driver functions & definitions
β βββ music.h # Note definitions & melody structure
βββ source/ # C source files (logic, drivers)
βββ audio.c # Buzzer tone generation & micro delays
βββ glcd_driver.c # KS0108 low-level routines
βββ main.c # Core application flow & dice rolling
βββ music.c # βFΓΌr Eliseβ melody playback
- Virtual Instruments:
- Logic analyzer: GLCD control signals
- Audio mixer: Buzzer output waveform
- Voltage probe: Button debounce analysis
- Import
DICE_ROLLER_LCD_PIC.pdsprj
- Program PIC16F877A with provided HEX file:
Right-click MCU β Edit Properties β Load Firmware
- Configure simulation settings:
- CPU Frequency: 20.000MHz
- GLCD Contrast: Adjust RV1 potentiometer
Parameter | Value | Implementation Basis |
---|---|---|
GLCD Refresh Rate | 45 FPS | Page-based column writes |
Buzzer Frequency Range | 31Hz - 4.8kHz | __delay_us() resolution |
Button Debounce | 20ms | Software counter in main loop |
Roll Animation | 20 cycles @ 50ms | for(uint8_t i=0; i<20; i++) |
// From audio.c - Hardware-accurate timing
void beep(uint16_t freq, uint16_t duration_ms) {
uint32_t period_us = 1000000UL / freq;
uint32_t cycles = duration_ms * 1000UL / period_us;
while(cycles--) {
BUZZER = 1;
software_us_delay(period_us/2);
BUZZER = 0;
software_us_delay(period_us/2);
}
}
MIT Licensed - Full details in LICENSE
Developers Welcome!
π Report Issues
π‘ Suggest Features
π Submit PRs