Circuits with LEDs and switches are a great way to get to grip with the basics of PIC programming. This project is a simple electronic dice using a baseline 12F508/509 PIC micro-controller.

I've been meaning to make a PCB for this circuit for a while but as I keep all my etching equipment in the garage and the temperature out there is freezing, I thought I'd take a warmer option and use strip board.
The Hardware
If you take a look at the schematic you'll see just how simple this circuit is. The seven LEDs used to display the dice roll are connected to four pins on the micro-controller. Only the central LED is controlled individually, the other six are paired such that one pin controls either two opposite corners or the two middle LEDs.
Each LED has its own current limiting resistor. In the schematic I have suggested 330R resistors with red LEDs but in my prototype I used 220R resistors as I find that yellow LEDs are usually dimmer than red and need a smaller valued load resistor.
A single CR2032 3V coin cell battery powers the circuit. The 12F508/509 can operate on its internal 4Mhz oscillator provided it is powered by at least 2V. Its good design practice to include a 100nF decoupling capacitor in the circuit to smooth out power fluctuations. On the strip board it has been positioned immediately next to the micro-controller.
The only remaining component to be discussed is the momentary 'push to make' tactile switch which shorts GP3 (pin 4) to ground when pressed. When the circuit is operating the micro-controller will use an internal 'weak pull up' resistor to that the pin appears to be in a 'HI' state when it is read. Pushing the switch will make it change to a 'LO' state until the switch is released.
The Firmware
As with many PIC based circuits the magic happens in the firmware. I won't go through it line by line but here are some pointers as to how its works.
Time Delays
The code uses the micro-controllers 8-bit timer (TMR0) to generate delays. The TMR0 register is incremented periodically by the controller, how often it does this depends on two factors; the instruction cycle frequency (e.g. the oscillator frequency divided by 4) and the timer0 prescaler setting.
The length of time it takes a timer to 'roll over' (e.g. increment the timer count value until it reaches zero) can be calculated as:
time = count * 1 / instruction_frequency * prescaler
The code uses 1/100 sec delay as the basis for its timing, often counting multiples of this to create longer delays (e.g. 30x for a 0.3 second delay). As the controller is using its internal 4Mhz oscillator and the prescaler is set to 128 this gives:
0.01 = count * 1 / (4000000 / 4) * 128 = count * 1 / 1000000 * 128
Solving for count:
count = 0.01 * 1000000 / 128 = 78.125
In the source code this expression is written a little differently with the required time expressed as frequency in Hertz but the result is the same.
count = (oscillator_frequency / 4) / (timer_frequency * prescaler)
As timers increment the code loads a negative count value into the TMR0 register. After 'count' increments the timer will contain a zero value.
Random Numbers
Generating a random number is actually a very difficult thing to do so the firmware cheats and uses the user as the random element.
When the switch is pressed the code goes into a loop that debounces the switch. While it is in this loop it continually increments the next dice roll value. The time spent in this loop depends on how long the user keeps the switch pressed and as the dice roll value is updated hundred of thousands of times per second during this period the result is an apparently random dice value.
Low Power Sleep
The circuit does not contain a switch to isolate the battery from the micro-controller so it is permanently powered on. In order to stop the battery being drained after a few hours the controller turns off all the LEDs and puts itself into a low power sleep state if it is not used for 15 seconds. Pressing the switch causes the controller to wake up and restart.
You can download the detailed project materials here:
| Schematic: | dice-schematic.pdf |
| PCB: | dice-pcb.pdf |
| Eagle Files: | dice-eagle.zip |
| MPLAB Project: | dice-project-2009-12-29.zip |
| HEX File: | dice-12F508.hex dice-12F509.hex |





