Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

a simple electronic dice for PIC basic

Status
Not open for further replies.

techmanx

New Member
This was one of my early projects using pics, and I hope it will be helpful for any newbees. The programme is written in Mikrobasic, but should be easily changed to suit other basics.


program dice3
'simple dice programme, 6 leds are arranged in the normal dice pattern
'The leds are all strobed on at high speed, actually going throgh all the 6 possibilities but
'effectively looking as though they are all on .
'Pushing the button halts the leds at whatever number they were at when the button was pushed.
'The leds are then displayed flasing on and off for a few seconds, the flash rate
'gradually increases to indicate to the dice thrower that the leds will shortly finish
'with the number display and go back to waiting for a button press for the next
'throw.
'Written for pic16F684 but can be used on other pics, with possible port-letter changes


dim i,n,tim as byte


sub function throwc(dim numc as word) as word 'here the led combinations are set up
select case numc 'using both ports.

case 1 result = %11111110 'Bit patterns for port
case 2 result = %11111111
case 3 result = %11111110
case 4 result = %11110001
case 5 result = %11110000
case 6 result = %11110001
end select
end sub

sub function throwa(dim numa as word) as word
select case numa

case 1 result = %11111111
case 2 result = %11101001
case 3 result = %11101001
case 4 result = %11101110
case 5 result = %11101110
case 6 result = %11101000
end select
end sub



main:
intcon =0
trisa =%00001000
ansel =%00001000
trisc =0
portc =0
porta =0

loop:

for i = 1 to 6 'dice possibilities 1 to 6
if adc_read (3) < 60 then 'look for button push
gosub clearports 'clear the leds
tim = 60 'set the decaying blink rate timer
for n = 0 to 20
vdelay_ms(tim)
gosub clearports
vdelay_ms(tim)
porta = throwa(i) rem call the led pattern according to (I)
portc =throwc(i) rem call the led pattern according to (I)
tim = tim - 3
next n
gosub clearports
delay_ms(200)
end if
porta =throwa(i)
portc =throwc(i)
delay_us(50)
next i
goto loop
clearports: 'clears ports to no leds lit
porta = 0
portc = 0
return
end.
Rem, I must include a timer that switches off the display when not used for
' some time!
 

Attachments

  • CIMG0007.JPE
    CIMG0007.JPE
    29.9 KB · Views: 463
I wonder how loaded the dice routine is? What's the A/D routine for?

I remember working on a 12F629 Dice kit I was going to sell.
**broken link removed**
 
Last edited:
I wonder how loaded the dice routine is? What's the A/D routine for?

I remember working on a 12F629 Dice kit I was going to sell.
**broken link removed**

A/D routine is only a cheap way of reading the keypress, by looking for a volt drop rather than messing about with de-bouncer routines.
 
Ahh, well I was looking over your code and the die would appear to be "weighted" as rolling loop is not same the number of instructions when resetting the die counter.
This is a common problem with computer dice, the solution I found was to run TMR2 as a modulo 6, 36, 216 etc... counter as the rolls would be fair. Just like your version I left it to the human element as the random part.
I've written some test code in Swordfish BASIC for the 18F, I'd be happy to post it if you're interested.
 
Last edited:
Code:
    Dim A As Byte
    Dim Dice As Byte
    TRISC.0 = 1
    TRISB = 0
    PORTB = 0
Main:
    A = A + 1    
    If A > 5 Then A =0
    DelayMS 10
    If PORTC.0 = 1 Then GoSub display
    GoTo Main
    
display:      '  1   2   3   4   5   6
    LookUpL A, [$20,$48,$38,$59,$79,$7F],Dice
	PORTB = Dice
	Return
 
Code:
    Dim A As Byte
    Dim Dice As Byte
    TRISC.0 = 1
    TRISB = 0
    PORTB = 0
Main:
    A = A + 1    
    If A > 5 Then A =0
    DelayMS 10
    If PORTC.0 = 1 Then GoSub display
    GoTo Main
    
display:      '  1   2   3   4   5   6
    LookUpL A, [$20,$48,$38,$59,$79,$7F],Dice
	PORTB = Dice
	Return

Thats smart for another form of basic and another Pic. Its even easier with a 4011 and 4017 one doesnt need to write anything!
Cheers
 
Code:
    Dim A As Byte
    Dim Dice As Byte
    TRISC.0 = 1
    TRISB = 0
    PORTB = 0
Main:
    A = A + 1    
    If A > 5 Then A =0
    DelayMS 10
    If PORTC.0 = 1 Then GoSub display
    GoTo Main
    
display:      '  1   2   3   4   5   6
    LookUpL A, [$20,$48,$38,$59,$79,$7F],Dice
    PORTB = Dice
    Return

It's still a loaded die roll. The problem is very similar to clearing a timer when building an RTC.
 
If an external switch debouncer is used surely you could get rid of that delay, and make it minimally loaded?
 
Last edited:
The program rolls (loops) hundreds if not thousands of times between button presses. The loading is caused by an asymmetrical loop, it's impossible to fix using loops in a high level language. You could fix it with an assembly loop and adding padding where needed to make every count execute with the same number of instructions.
The other method uses a self-resetting free running timer (compare)
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top