***********************************
* PIC MINI DICE (C) Rickard Gunée *
***********************************
This text is mostly a copy of the Video Pong page on my homepage:
http://www.rickard.gunee.com/projects/mixed/dice
--- Introduction ---
This file describes a PIC10F200-based electronic dice. The reason I made this
was that I got a small corner left over when ordering a panel with a couple
of other PCBs and thought I would rather use the corner for something fun than
leave it unused, so I made a dice. The PCB is quite small, so it is hard to
etch yourself even the layout is available in the zip-file if you want to try,
so to make it easier for you I've made it possible for you to buy PCBs, pre-
programmed chips, and of course complete kits from me in my web shop.
Even though this is a very simple project, it requires some surface mount
soldering skills, proper tools, and a steady hand as it is built with surface
mounted components only. But it might be a good start if you have experience
in hole mounted soldering and want to try surface mount soldering.
--- Hardware ---
The standard solution for a power supply is to use a 7805 but I could not
find any 7805 in a sot-23 or smaller capsule so I used an LP2985 that is
available in a 5-pin sot-23 capsule with 5v/150mA output. I use a 100nF cap
on both input and output side of the regulator to get rid of noise etc. I'm
using a standard 9v battery to supply the circuit. In the PCB-layout there
is also a hole for the cable to remove mechanical tension from the soldering
point of the cable.
The PIC controlling the dice is a PIC10F20X, but it is also possible to use a
PIC10F22X (that is what is sold in my web shop. as it is almost the same price
so I use the 10F222 to get fewer chips in stock as other projects use the
10F222), both are microcontrollers with very limited RAM and ROM, 16b/256w of
RAM/ROM but there are versions with up to 24b/512w, the 10F22X series also has
an ADC but that is not needed in this project. Same .hex-file can be used for
both the PIC10F200 and the PIC10F222 as the later is set into compatible mode
and only disables the 10F222 specific functions in the beginning of the program
which has no effect on a 10F200 chip. Two of the six pins are used for power
supply, there is one reset (or input only) pin and three IO-pins. The switch
is connected to the reset pin that is configured as an input. The three IO-
pins left is used to drive a 2x2 matrix configuration of the seven LEDs. The
LEDs are connected in series and lit in three sets of two LEDs on opposite
sides in series and one single LED in the center. The 2x2 matrix configuration
is created with three pins only by putting diodes in both directions so when
the common line is "0" LEDs are lit by "1" and when the common is "1" LEDs are
lit by "0". This leads to that only two sets of LEDs can be lit at one time,
either the LEDs in the corners or the ones in the middle. When changing fast
(100Hz) between lighting the different LEDs it look like they are all lit at
the same time thanks to the persistence of vision effect. There are of course
some resistors in series with the LEDs as the system runs on 5v and the LEDs
have a voltage drop of about 2v each
One nice feature of the PIC10F-series is the current consumption, especially
in sleep mode. This removes the need of an on/off switch as the dice only uses
0.4uA in standby, so it can be in standby for many years without discharging
the battery.
--- Software ---
The software is very simple, not very good looking and not very optimized but
the 16 bytes of RAM and 256 words of ROM is more than enough so there is no
need for optimizations (except for the optimizations that are fun to do). It
has a main loop lights half the LEDs delays and lights the second half then
another delay and then runs the state engine that controls the output. The
state engine has four states IDLE,WAIT,ROLL and SHOW. When in the idle state
the PIC is set to sleep state and is woken up on pin change (when the switch
is pushed). In the wait state, a roll pattern is shown and a counter is gene-
rating a random number based on how long time the user pushes the button (not
very good random generator but if the button is pushed longer than the
mechanically shortest possible time it is quite ok). In the ROLL state the
roll animation is shown for two additional seconds just to make it more
exciting ;) Finally in the SHOW state the result is shown for 3.5s before
getting back to IDLE, unless the button is pushed and it starts another roll.
;******************************************************************************* ;* PIC10F2XX-based mini dice (C) Rickard Gunée 2007 * ;******************************************************************************* ;* This is the software for a small electronic dice based on a PIC10F2XX * ;* The dice is built with seven LEDs placed like this: * ;* * ;* D1 D5 * ;* D2 D4 D6 * ;* D3 D7 * ;* * ;* The leds are multiplexed in four groups according * ;* to the schematic below:;******************************************************************************* #include p10f222.inc list r=dec __CONFIG _CP_OFF & _WDT_OFF & _IOFSCS_4MHZ & _MCLRE_OFF ; udata ;temp0 res 1 ;temp1 res 1 VDA0 equ 1 VDA1 equ 2 sndbit equ 0 lpl equ 1 rpl equ 2 scrpart equ 3 close equ 4 serve equ 6 screen equ 7 temp0 equ 0x10 temp1 equ 0x11 temp2 equ 0x12 digit equ 0x13 state equ 0x14 time_l equ 0x15 time_h equ 0x16 number equ 0x17 S_IDLE equ 0x00 S_WAIT equ 0x01 S_ROLL equ 0x02 S_SHOW equ 0x03 ;rst code 0x00 ;Reset Vector movwf OSCCAL goto Start ;Jump to Start code ; Table with digits and graphics for roll ; Note that order of numbers doesn't matter ; because they are shown randomly so the ; table has been rolled to make roll table ; and digit table overlap thus saving one ; byte in the table, a lot of memory left ; so it is just to show off ;) digits andlw 7 addwf PCL,F retlw B'1001' ;4 retlw B'0001' ;5 retlw B'1011' ;6 retlw B'0100' ;1 retlw B'1000' ;2 retlw B'0000' ;3 \ retlw B'0101' ;/ retlw B'0110' ;- ; big delay loop to create a delay of about w*3cc bigdelay movwf temp1 bigdelay_l0 movlw 0xFF movwf temp0 bigdelay_l1 decfsz temp0,F goto bigdelay_l1 decfsz temp1,F goto bigdelay_l0 retlw 0 ; Tnitialize ports etc Start movlw B'1000' ; set leds as outputs and switch as input tris GPIO clrf ADCON0 ; disable ADC on PIC10F22X movlw B'00000000' option clrf time_l ;clear time clrf time_h main: ;display phase 1 movfw digit ;for a given digit call digits ;get on/off values for the four LED sets movwf temp2 ;store in temp2 for phase 2 andlw B'0011' ;mask out lower 2 bits movwf GPIO ;output to LEDs (also setting common to low) movlw 3 call bigdelay ;wait for 1/200 second ;display phase 2 rrf temp2,F ;shift down upper two bits rrf temp2,W xorlw B'0100' ;set common line bit to high movwf GPIO ;output to LEDs movlw 3 call bigdelay ;wait for 1/200 second ;handle timer incf time_l,f ;increase timer low byte skpnz ;if overflow incf time_h,f ;then increase timer high byte ;handle main state machine movfw state ;switch on state andlw 0x03 ;prevent illegal jump to be safe addwf PCL,F ;jump to state jump (one of the four lines below) goto state_idle goto state_wait goto state_roll ;"fall through" to show state below ;-------------------------------------------------------- ;- Show state, shows the result state_show movlw S_WAIT btfss GPIO,3 ;if button is pressed movwf state ;set state to WAIT to make another roll movfw time_h ;check if time = 512 main loop cycles xorlw 0x2 skpz goto main ;if not get back to main and keep waiting clrf state ;otherwise: set idle state clrf GPIO ;turn of leds sleep ;go to sleep ;-------------------------------------------------------- ; this is the state where the system wakes up state_idle btfsc GPIO,3 ;if button was not pressed sleep ;then power down movlw S_WAIT movwf state ;otherwise set state to wait goto main ;-------------------------------------------------------- ;- Wait for button to be released and decrease number ;- to get user pressing time to generate a random value state_wait movlw S_ROLL btfss GPIO,3 ;if button is released goto state_wait_j0 movwf state ;set state to roll clrf time_l ;and clear time clrf time_h state_wait_j0 decfsz number,F ;decrease number goto state_wait_j1 movlw 6 ;restart at 6 if zero movwf number ;resulting in a "random" number of 0..5 state_wait_j1 goto spin ;show spin effect ;-------------------------------------------------------- ;- Roll state, this is just to get som tensions, rolling ;- for a couple of extra seconds state_roll movfw time_h xorlw 0x1 ;check if time = 256 main loop cycles skpz goto spin; ;if not get show spin effect before getting ;back to main and keep waiting movlw S_SHOW ;otherwise, set state = show movwf state clrf time_l ;clear time clrf time_h decf number,w ;set digit to number-1 (result of roll) movwf digit goto main ;get back to main and start showing the result ;-------------------------------------------------------- ;- Spin effect, shows a rolling sequence of \/- spin movfw time_l ;get low part of time andlw 0x1F ;check lower 4 bits skpz ;if nonzero goto main ;then continue ;the following is done every 16 display cycles incf digit,w ;else increase digit andlw 0x03 ;keep below upper limit skpnz ;and check for zero movlw 0x01 ;additional increase if zero xorlw 0x04 ;keep above lower limit movwf digit ;store back to digit goto main ;get back to main loop end
PIC MINI DICE © Rickard Gunée. You may do what ever you want with the information in this zip-file, as long as you refer to the original author
(by name and link to authors homepage), don't do it for profit and don't
hurt or harm anyone or anything with it. The author can not be held responsible
for any damage caused by any of the information related to this project.