BS1 question
Patrick D
Posts: 62
I would like to build a pretty simple circuit using he BS1. I have never used the BS1, but have used the BS2 many times...
I would like to have a single 7 segment display that would randomize 1-6 and display on the seven segment.
Then with 2 buttons, Increment or decrement the displayed value to 0-9.
I know I can do this easily w/ a BS2, but would I be able to do the same with a BS1? (going w/ BS1 for cost reasons).
for the 0-6 (dice roll) I was going to use code something like this:
RANDOM R
DIE = (R // 6) + 1
I would like to have a single 7 segment display that would randomize 1-6 and display on the seven segment.
Then with 2 buttons, Increment or decrement the displayed value to 0-9.
I know I can do this easily w/ a BS2, but would I be able to do the same with a BS1? (going w/ BS1 for cost reasons).
for the 0-6 (dice roll) I was going to use code something like this:
RANDOM R
DIE = (R // 6) + 1
Comments
The seven-segment display requires 7 pins, leaving just one unused pin for input.
But you could get tricky and multiplex one pin, making it both an input and an output. So timewise, that pin would mainly be an output, driving an LED segment, but you would have an input switch in parallel with that segment. A software loop occasionallly polls the switch to see if it's pressed. Worst case, you may force that LED segment on or off when you push that parallel switch.
Alternatively, you could add a 7-segment display driver IC, but I'd say you're so close with the BS1 that you "git 'er done" without it.
There are some examples in the BS1 application notes of ways to use the POT statement to determine which of two or more switches are closed using just one I/O pin. Essentially you've got 3 resistors in series and each switch shorts out one resistor when it's pushed. The 3rd resistor provides a minimum resistance if both switches are closed. If the resistors are roughly in a 1:2:4 relationship, it's easy to figure out which switch is closed.
So if I went with the display driver IC, would the MAX7219 work?
You'd not need the 10K pulldown resistors and you'd just connect the ABCD inputs to a group of 4 I/O pins on the BS1, either P0-3 or P4-7.
@Patrick: No driver needed if you go that route. A bit of code crunching and all you need is a BS1. Perfect application.
So - this is what I have so far - does this look like it will work?
PARTS AND MATERIALS
• 4511 BCD-to-7seg latch/decoder/driver
• Common-cathode 7-segment LED display
• Seven 470 Ω resistors
• Four 10k Ω resistors
• Four (or Three) momentary contact SPST switches
• Project Case
• Power: Could be wall transformer or 9V battery
• BASIC Stamp 1 Project Board
(see attached sample schematic)
• Will the 40 mA (Vdd) be enough to drive the 4511 and the 7 segment display?
again - this project is intended to simulate a single six sided dice roll. Pressing Roll (S1) will display a random 1-6. Pressing S2 will increment the displayed number by 1 until it reaches a max of 9. Pressing S3 will decrement the display by 1, with a minimum display of zero.
I was going to do something like this for the dice roll:
RANDOM R ' R is now 0 - 65,535
DIE_1 = (R // 6) + 1 ' roll die
I have an old BS Manual 2.0 and it looks like the BS1 will do both RANDOM and modulus, but as far as the rest I am stuck.
Can you please help me with the rest of the code? I am very rusty
=======================
Pseudo code (more like thinking out loud)
' {$STAMP BS1}
' {$PBASIC 1.0}
' define I/O
Set P0-P3 to outputs
Set P4-P7 to inputs
' declare variables
DICE
ROLL
' define display values (P0-P4)
Zero = 0,0,0,0
One = 0,0,0,1
Two = 0,0,1,0
Three = 0,0,1,1
Four = 0,1,0,0
Five = 0,1,0,1
Six = 0,1,1,0
Seven = 0,1,1,1
Eight = 1,0,0,0
Nine = 1,0,0,1
init Display - set to 0
[S1 goes high]
random roll
goto Display subroutine
[S2 goes high]
increment DICE by 1
goto Display subroutine
[S3 goes high]
decrement DICE by 1
goto Display subroutine
Subroutines:
Display
Show DICE value
Return
========================
Thanks in advance,
Patrick in Memphis, TN
First of all, the 4511 is CMOS, so it's current consumption is negligible and it seems like your only thing that uses a lot of current is the 7-segment display and the BS1. The BS1 uses 1 mA of current so using 40mA, you have 39mA to use on the display, if you display an 8 (The number that uses the most segments) you can, at most use 5.5mA a segment.
The design is the same - basically need this:
DESCRIPTION-
a single 7 segment display, 3 momentary contact buttons
SW1 - "rolls" a dice (6 sided) and displays value (random 1-6)
SW2 - Increments the display by one - to a max of 9 (any time switch is pressed after display reaches 9, the display just stays at 9)
SW3 - decrements the display by one - down to zero (any time switch is pressed after display reaches 0, the display just stays at 0)
Is the BS2 overkill? Could this be performed without? maybe using a 555?
Im not an engineer, and not have much luck with this. Its been a few years and just getting back into this project - ANY help with code or circuit ideas would be a help and greatly appreciated.
You can use the 7-segment display directly with a BS2 if you limit the current per segment to about 10mA. A 380 Ohm to 470 Ohm resistor would be fine. The 10K resistors for pullups for the switches would be fine too. I suggest you look at the "What's a Microcontroller?" tutorial for connection examples and code examples for both the pushbuttons and individual LEDs. Your 7-segment display is either a common anode or common cathode and the common lead would be connected to either Vdd (common anode) or Vss (common cathode). The resistors would be connected between the segments and the I/O pins. Use a group of 8 pins (0-7 or 8-15) for the display.
You can assign values to all 8 I/O pins in each group of 8. OUTH is I/O pins 8-15 while OUTL is I/O pins 0-7. Writing "OUTL = %00000001" would light up the segment attached to I/O pin 0 (with a common cathode display) while "OUTL = %11111010" would light up the segments attached to I/O pins 0 and 2 (with a common anode display). Work these examples on paper and compare what happens with the descriptions in "What's a Microcontroller?" for a single LED.
Experiment with combinations of lighted segments to find the patterns you need to show the digits. That takes the place of the 4511. I believe the 4511 datasheet shows what segments are used there for each digit. If you have a common cathode display and are using I/O pins 0-6 for the 7 segments (with I/O pin 7 being used for the decimal point if you want), you can light up all 7 segments to show an 8 with "OUTL = %01111111".
Stay out of the hardware loop for now and develop your idea/s by staying inside the IDE - using DEBUG for your display and DEBUGIN for your SW1, SW2, SW3.
to recap, this is the application:
a single 7 segment display, 3 momentary contact buttons
SW1 - "rolls" a dice (6 sided) and displays value (random 1-6)
SW2 - Increments the display by one - to a max of 9 (any time switch is pressed after display reaches 9, the display just stays at 9)
SW3 - decrements the display by one - down to zero (any time switch is pressed after display reaches 0, the display just stays at 0)
It's been a few years sonce I looked at PBASIC - can someone out there please push me in the right direction?
thank you - patrick
You probably want to have the display on I/O pins 0-6, skip pin 7 and put the pushbuttons on I/O pins 8-10 (and maybe the decimal point on pin 15). That way you can set all the segments with a single I/O statement (OUTL = %0000000 or some other value). You can use the decimal point for debugging if you want. You can use a LOOKUPZ statement to translate a number from 0-15 into one of 16 values used for the segments. Commonly, values from 10-15 are used for special characters like "-" or "r" or "c" or "U" or "E". "E" is often used to indicate an error.
One thing that isnt working right is how i am creating a random number 1-6. It does generate some numbers but unless i change the seed value eac time, the number sequences are similar, even with a reset.
the code below is stiched from the examples that were suggested - with a few things added (tried to make the LED's "roll" between each new number, etc)
is there any way i can be sure that each roll has 1/6 probability of cominng up?
the LED is connected to P8-15
'{$STAMP BS2}
'{$PBASIC 2.5}
' rolls a dice 100 times and displays results in debug and on 7-seg display
'=================================================================
rounds VAR Byte ' number of reps
numGen VAR Word ' random number holder
myNum VAR Byte ' random number, 1-6
' Patterns of 7-Segment Display to create letters
d1 CON %10000100
d2 CON %11010011
d3 CON %11010110
d4 CON %10110100
d5 CON %01110110
d6 CON %01110111
space CON %00000000
pinCounter VAR Nib
OUTH = %00000000 ' All off to start
DIRH = %11111111 ' All LEDs must be outputs
Setup:
numGen = 11508 ' initialize random "seed"
Main:
FOR rounds = 1 TO 100
DEBUG CLS, "Pick a number from 1 to 6", CR
GOSUB Pick_A_Number
GOSUB Display_Dice
DEBUG "My number was: ", DEC myNum ' show the number
PAUSE 1000
NEXT
DEBUG CLS, "Done"
numgen = numgen +1 ' put this here to help w randomizing seed but doent work
'GOTO main ' to loop
END ' end program
Pick_A_Number:
RANDOM numGen ' stir up the bits of NumGen.
DEBUG DEC ? numGen
myNum = numGen / 9000 MIN 1 ' scale to fit 1-6 range.
RETURN
Display_Dice:
FOR PINCounter = 8 TO 15 'make it look like a "roll"
HIGH pinCounter
PAUSE 100
LOW pinCounter
NEXT
LOOKUP myNum-1, [d1, d2, d3, d4, d5, d6, d6 ], OUTH '7's=6
DEBUG " ", DEC2 myNum, " ", BIN8 OUTH, CR
PAUSE 400 ' 400 ms between letters
RETURN
Yep.
I've used a CdS photocell and RCTIME, incorporating the result as basis for a "seed".