Bubble Display, Propeller
|HP 4-Digit Bubble Display (7-Segment LED)|
I used one of my spare eeZee Propellers to play around with the display and create driver code. I haven't played in Spin in awhile, so it was a good refresher. Here's what I did...
Propeller pins P16 - P19 are connected to Cathode 4 through 1, respectively. Pins P20 - P26 are connected to Anode A through G, respectively. The decimal point is hooked up to P27.
Driving 7-Segment Displays
You could simply drive the display one digit at a time, setting all the required anodes high and the corresponding cathode low.
A common cathode display is intended to be controlled with the cathodes. Use 4 resistors, one for each cathode, power each of the common anodes sequentially, and use the cathodes to individually turn segments on or off for each display digit position.
The display driver runs on a cog and displays digits stored in hub memory. The main cog simply counts from 0 to 9999 over and over again, extracting the 1's, 10's, 100's and 1000's place and storing the numbers for display, as follows, where b1, b2, b3, b4 are each of the digits.
PUB Start | i
b1 := b2 := b3 := b4 := 10 ' initial digit (>9 means off)
cognew(display, @stack) ' start display driver cog
repeat i from 0 to 9999
b4 := i // 10 ' ones
b3 := (i/10) // 10 ' tens
b2 := (i/100) // 10 ' hundreds
b1 := (i/1000) // 10 ' thousands
waitcnt(clkfreq/10+cnt) ' count at ~10Hz
I may refactor the program to use BCD; storing digits in each of the 4 bytes of a Propeller's 32-bit long int, but the code is more readable using one variable per digit.
Driver DetailsAs for the driver, a segment array, seg, stores the outa cathode pin bits required to turn on each segment (a through g) at each display digit position (1 through 4).
The main loop calls setdigit(digit, value) which sets the cathode bit in the seg array, for the specified display digit and the specified numeric value. For example, displaying "2" in position 3 requires the cathode for position 3 to be low (on) for segments a, b, d, e, g, and high (off) for segments c and f.
setdigit(1, b1) ' set 1's value
setdigit(2, b2) ' set 10's value
setdigit(3, b3) ' set 100's value
setdigit(4, b4) ' set 1000's value
bit := AN_A ' start with anode a
repeat s from A to G ' loop thru segments
outa := seg[s]|bit ' turn on cathodes, anode
bit <<= 1 ' next anode bit
Then, the main loop iterates over the array, seg[A..G], sets the cathode pins, simply with outa := seg[s] and raises the corresponding segment anode pin for each array element by ORing outa with bit, which is the bit corresponding to the current anode pin. How does the array get set with the right cathode?
The setdigit(digit, value) function converts the display digit into the appropriate cathode bit to activate (set low) or deactivate (set high).
It then uses the numeric value (0..9) in another case statement to select which segments should be on (seg[?] &= set) or off (seg[?] |= unset).
1: unset := CA_1
2: unset := CA_2
3: unset := CA_3
4: unset := CA_4
other: unset := 0
set := !unset & (CA_1|CA_2|CA_3|CA_4)
0: seg[A] &= set
seg[B] &= set
seg[C] &= set
seg[D] &= set
seg[E] &= set
seg[F] &= set
seg[G] |= unset
So, It's Been Awhile...You would have heard from me sooner, but alas, there has not been much time for tinkering or blogging lately.
My paucity of spare time can be blamed on work, filling Tindie orders, and gearing up for the crowd funding campaign for OpenMV Cam.