Hmm. I'm guessing the circuit of the board is something like ...I'll need to have a read of the 74HC595 datasheet.
.------------------------------------------------------------.
| |
.|. | | | | | | | | | | | | | | | | |
|_| .-^-^-^-^-^-^-^-^-. .-^-^-^-^-^-^-^-^-. |
| | 0 1 2 3 4 5 6 7 | | 0 1 2 3 4 5 6 7 | |
| | | | | |
DIO <>----^------>| DIN DOUT |------------>| DIN DOUT |--'
.--------->| CLK | .--------->| CLK |
| .------>| LATCH | | .------>| LATCH |
| | -.- | | | | -.- | |
| | `-->| RESET\ | | | `-->| RESET\ |
| | .-->| OE\ | | | .-->| OE\ |
| | _|_ `-----------------' | | _|_ `-----------------'
| | | |
SCK >--^--|----------------------------' |
| |
RCK >-----^-------------------------------'
Oops, and thanks. It seems I missed that.The MR pin of a 74HC595 is active low, so needs to be pulled high to run.
Symbol DIO = B.0
Symbol SCK = B.1
Symbol RCK = B.2
Symbol CLOCK = SCK
Symbol LATCH = RCK
Symbol reserveW0 = w0 ; b1:b0
Symbol digit = b2
Symbol segments = b3
PowerOnReset:
Low CLOCK
Low LATCH
MainLoop:
Do
; Test digits and segments
digit = 1
Do
segments = digit
Gosub SetDigitSegments
digit = digit * 2
Loop Until digit = 0
; Test digits
digit = 1
segments = 1
Do
Gosub SetDigitSegments
digit = digit * 2
Loop Until digit = 0
; Test segments
digit = 1
segments = 1
Do
Gosub SetDigitSegments
segments = segments * 2
Loop Until segments = 0
; All off
digit = 0
segments = 0
Gosub SetDigitSegments
Pause 4000
Loop
SetDigitSegments:
b0 = digit : Gosub ClockOutB0_MsbFirst
b0 = segments : Gosub ClockOutB0_MsbFirst
High LATCH
Low LATCH
Pause 1000
Return
ClockOutB0_MsbFirst:
For b1 = 0 To 7
If bit7 = 0 Then
Low DIO
Else
High DIO
End If
High CLOCK
Low CLOCK
b0 = b0 * 2
Next
Return
It's a bit odd, if they aren't joined, that both ends of the board are labelled "DIO" rather than "DIN" and "DOUT" to make it clear which end data should be fed in to or taken out from. Then again I find it odd they used "SCK" and "RCK" rather than CLOCK and LATCH or something which made it more obvious what each does..Unless it is obvious that the DIOs are linked together on the board, then the DIO (out) from one board goes to the DIO (in) on the next board to achieve the daisy-chaining.
Thanks to Jacks excellent sleuthing it should be possible. Untested but I think this should convert digit order so digit 1 is on the left, 8 is on the right, and only one segment is lit at a time ...I tried your code @hippy and it does give me some sort of display but it is jumbled, is it easy to convert as per Jacks suggestion ?
SetDigitSegments:
; Convert 'digit' bit setting to digit number
LookDown digit, (0, 1, 2, 4, 8, 16, 32, 64, 128), b1
; Our b1 digit value : 0 1 2 3 4 5 6 7 8
; Display digit order : 4 3 2 1 8 7 6 5
; Display select bits : 0 8 4 2 1 128 64 32 16
LookUp b1, (0, 8, 4, 2, 1, 128, 64, 32, 16), b1
b0 = b1 : Gosub ClockOutB0_MsbFirst
b0 = segments ^ $FF : Gosub ClockOutB0_MsbFirst
High LATCH
Low LATCH
Pause 1000
Return
b0 = b1 ^ $FF : Gosub ClockOutB0_MsbFirst
b0 = segments : Gosub ClockOutB0_MsbFirst
Thanks for that video - At least it's workingI have attached a video clip link to show you what i am getting as im struggling to make sense of the result.......
SetDigitSegments:
b0 = segments : Gosub ClockOutB0_MsbFirst
b0 = digit ^ $FF : Gosub ClockOutB0_MsbFirst
High LATCH
Low LATCH
Pause 1000
Return
SetDigitSegments:
b0 = segments : Gosub ClockOutB0_MsbFirst
; Convert 'digit' bit setting to digit number
LookDown digit, (0, 1, 2, 4, 8, 16, 32, 64, 128), b1
; Our b1 digit value : 0 1 2 3 4 5 6 7 8
; Display digit order : 4 3 2 1 8 7 6 5
; Display select bits : 0 8 4 2 1 128 64 32 16
LookUp b1, (0, 8, 4, 2, 1, 128, 64, 32, 16), b1
b0 = b1 ^ $FF : Gosub ClockOutB0_MsbFirst
High LATCH
Low LATCH
Pause 1000
Return
[0,0,0,0,1,0,0,0], # Position 0 / 8th display
[0,0,0,0,0,1,0,0], # Position 1 / 7th display
[0,0,0,0,0,0,1,0], # Position 2 / 6th display
[0,0,0,0,0,0,0,1], # Position 3 / 5th display
[1,0,0,0,0,0,0,0], # Position 4 / 4th display
[0,1,0,0,0,0,0,0], # Position 5 / 3rd display
[0,0,1,0,0,0,0,0], # Position 6 / 2nd display
[0,0,0,1,0,0,0,0] # Position 7 / 1st display
; bits 7 6 5 4 3 2 1 0
"0": [1,1,0,0,0,0,0,0], segments:
"1": [1,1,1,1,1,0,0,1], --0--
"2": [1,0,1,0,0,1,0,0], 5 1
"3": [1,0,1,1,0,0,0,0], --6--
"4": [1,0,0,1,1,0,0,1], 4 2
"5": [1,0,0,1,0,0,1,0], --3--
"6": [1,0,0,0,0,0,1,0], 7 (dp)
"7": [1,1,1,1,1,0,0,0],
"8": [1,0,0,0,0,0,0,0],
"9": [1,0,0,1,0,0,0,0],
"A": [1,0,0,0,1,0,0,0],
"B": [1,0,0,0,0,0,1,1],
"C": [1,1,0,0,0,1,1,0],
"D": [1,0,1,0,0,0,0,1],
"E": [1,0,0,0,0,1,1,0],
"F": [1,0,0,0,1,1,1,0],
"G": [1,1,0,0,0,0,1,0],
"H": [1,0,0,0,1,0,0,1],
"I": [1,1,0,0,1,1,1,1],
"J": [1,1,1,1,0,0,0,1],
"K": [1,0,0,0,1,0,1,0],
"L": [1,1,0,0,0,1,1,1],
"M": [1,1,0,1,0,1,0,0],
"N": [1,1,0,0,1,0,0,0],
"O": [1,1,0,0,0,0,0,0],
"P": [1,0,0,0,1,1,0,0],
"Q": [1,0,0,1,1,0,0,0],
"R": [1,1,0,0,1,1,1,0],
"S": [1,0,0,1,0,0,1,0],
"T": [1,0,0,0,0,1,1,1],
"U": [1,1,0,0,0,0,0,1],
"V": [1,1,0,1,0,0,0,1],
"W": [1,1,1,0,0,0,1,0],
"X": [1,0,1,1,0,1,1,0],
"Y": [1,0,0,1,0,0,0,1],
"Z": [1,0,1,0,0,1,0,0],
" ": [1,1,1,1,1,1,1,1],
"-": [1,0,1,1,1,1,1,1],
"_": [1,1,1,1,0,1,1,1]
SetDigitSegments:
b0 = segments : Gosub ClockOutB0_MsbFirst
; Convert 'digit' bit setting to digit number
LookDown digit, (0, 1, 2, 4, 8, 16, 32, 64, 128), b1
; Our b1 digit value : 0 1 2 3 4 5 6 7 8
; Display digit order : 4 3 2 1 8 7 6 5
; Display select bits : 0 8 4 2 1 128 64 32 16
LookUp b1, (0, 8, 4, 2, 1, 128, 64, 32, 16), b1
b0 = b1 ^ $FF : Gosub ClockOutB0_MsbFirst
High LATCH
Low LATCH
Pause 1000
Return
Yes, I think we've been mislead by the "Demo Program" because it's showing the same digit on all the displays (except one which is "disabled"). A real "live" display will need to be updated continuously about every 2-3 milliseconds (usually by a timer interrupt). I don't believe that's even possible with a PICaxe, except by using its on-chip SPI Hardware, a feature that I would like to investigate sometime (using an M2 with POKESFR commands, not an X2 chip), but probably not now......., other than to reduce the pins needed to connect to the display(s). In order to have eight 7 segment displays lit up won't the PicAxe be running flat out trying to maintain a flicker free display?
Thanks; it's so much easier when one can see what's happening. I think we are just one step away from having it working ...Any ideas ? I am beginning to think this module is a real oddball
SetDigitSegments:
b0 = segments ^ $FF : Gosub ClockOutB0_MsbFirst
; Convert 'digit' bit setting to digit number
LookDown digit, (0, 1, 2, 4, 8, 16, 32, 64, 128), b1
; Our b1 digit value : 0 1 2 3 4 5 6 7 8
; Display digit order : 4 3 2 1 8 7 6 5
; Display select bits : 0 8 4 2 1 128 64 32 16
LookUp b1, (0, 8, 4, 2, 1, 128, 64, 32, 16), b1
b0 = b1 : Gosub ClockOutB0_MsbFirst
High LATCH
Low LATCH
Pause 1000
Return
LookDown digit, (0, 128, 64, 32, 16, 8, 4, 2, 1), b1
That is my presumption. It may be possible because I did manage to bit-bang an 8-digit 7-segment display a segment at a time and get that flicker-free but that did require highly optimised code and there wasn't much time for anything else.To my mind, the board described would seem to need constant refreshing in order to display multiple digits at once ... In order to have eight 7 segment displays lit up won't the PicAxe be running flat out trying to maintain a flicker free display?
Symbol DIO = B.0
Symbol SCK = B.1
Symbol RCK = B.2
Symbol CLOCK = SCK
Symbol LATCH = RCK
; .GFEDCBA
Symbol BLANK = $FF ^ %00000000 ; AAA
Symbol ONE = $FF ^ %00000110 ; F B
Symbol TWO = $FF ^ %01011011 ; F B
Symbol THREE = $FF ^ %01001111 ; GGG
Symbol FOUR = $FF ^ %01100110 ; E C
Symbol FIVE = $FF ^ %01101101 ; E C
Symbol SIX = $FF ^ %01111101 ; DDD o
Symbol SEVEN = $FF ^ %00000111
Symbol EIGHT = $FF ^ %01111111
Symbol NINE = $FF ^ %01101111
Symbol DP = $FF ^ %10000000
Symbol reserveW0 = w0 ; b1:b0
Symbol digitBit = b2
Symbol digit4 = b10
Symbol digit3 = b11
Symbol digit2 = b12
Symbol digit1 = b13
Symbol digit8 = b14
Symbol digit7 = b15
Symbol digit6 = b16
Symbol digit5 = b17
PowerOnReset:
SetFreq M32
Low CLOCK
Low LATCH
MainLoop:
digit1 = ONE ; Display 1234.5678
digit2 = TWO
digit3 = THREE
digit4 = FOUR & DP
digit5 = FIVE
digit6 = SIX
digit7 = SEVEN
digit8 = EIGHT
Do
Gosub UpdateDisplay
Loop
UpdateDisplay:
digitBit = 1
bPtr = 10
Do
b0 = @bPtrInc : Gosub ClockOutB0_MsbFirst
b0 = digitBit : Gosub ClockOutB0_MsbFirst
High LATCH
Low LATCH
digitBit = digitBit + digitBit
Loop Until digitBit = 0
Return
ClockOutB0_MsbFirst:
For b1 = 0 To 7
If bit7 = 0 Then
Low DIO
Else
High DIO
End If
High CLOCK
Low CLOCK
b0 = b0 * 2
Next
Return
Actually it's a bit more involved than that. In order to make persistence of vision work, the entire display must be updated at a 50 Hz or better rate and, digit at a time means, selecting a new digit for display every 2ms or so as AllyCat notes.By moving to hardware SPI things can probably be made fast enough to be flicker free.
No that's exactly how it should beThe plot thickens .........
D'Oh! ...The code in post 21 gives a completely blank display....
UpdateDisplay:
digitBit = 0
UpdateDisplay:
digitBit = 1
Not quite sure how you mean but this should show an incrementing number on the display -They are flickering as per the video, at least we now have the correct format.
Is it simple to get the updates to just be a simple number step thru a digit at a time ?
Symbol DIO = B.0
Symbol SCK = B.1
Symbol RCK = B.2
Symbol CLOCK = SCK
Symbol LATCH = RCK
; .GFEDCBA
Symbol BLANK = $FF ^ %00000000 ; AAA
Symbol ZERO = $FF ^ %00111111 ; F B
Symbol ONE = $FF ^ %00000110 ; F B
Symbol TWO = $FF ^ %01011011 ; GGG
Symbol THREE = $FF ^ %01001111 ; E C
Symbol FOUR = $FF ^ %01100110 ; E C
Symbol FIVE = $FF ^ %01101101 ; DDD o
Symbol SIX = $FF ^ %01111101
Symbol SEVEN = $FF ^ %00000111
Symbol EIGHT = $FF ^ %01111111
Symbol NINE = $FF ^ %01101111
Symbol DP = $FF ^ %10000000
Symbol reserveW0 = w0 ; b1:b0
Symbol counter = w1 ; b3:b2
Symbol digitBit = b2
Symbol digit4 = b10
Symbol digit3 = b11
Symbol digit2 = b12
Symbol digit1 = b13
Symbol digit8 = b14
Symbol digit7 = b15
Symbol digit6 = b16
Symbol digit5 = b17
PowerOnReset:
SetFreq M32
Low CLOCK
Low LATCH
MainLoop:
counter = 0
Do
Gosub SetCounterDigits
Gosub UpdateDisplay
counter = counter + 1
Loop
SetCounterDigits:
; Split the 16-bit counter into numeric digit values 0-9
digit5 = counter / 10000
digit4 = counter / 1000 % 10
digit3 = counter / 100 % 10
digit2 = counter / 10 % 10
digit1 = counter % 10
; Blank leading zeroes, blank digit value = 10
If digit5 = 0 Then
digit5 = 10
If digit4 = 0 Then
digit4 = 10
If digit3 = 0 Then
digit3 = 10
If digit2 = 0 Then
digit2 = 10
End If
End If
End If
End If
; Convert numeric digit values into display segments
LookUp digit5, (ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, BLANK), digit5
LookUp digit4, (ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, BLANK), digit4
LookUp digit3, (ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, BLANK), digit3
LookUp digit2, (ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, BLANK), digit2
LookUp digit1, (ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE ), digit1
Return
UpdateDisplay:
digitBit = 0
bPtr = 10
Do
b0 = @bPtrInc : Gosub ClockOutB0_MsbFirst
b0 = digitBit : Gosub ClockOutB0_MsbFirst
High LATCH
Low LATCH
digitBit = digitBit + digitBit
Loop Until digitBit = 0
Return
ClockOutB0_MsbFirst:
For b1 = 0 To 7
If bit7 = 0 Then
Low DIO
Else
High DIO
End If
High CLOCK
Low CLOCK
b0 = b0 * 2
Next
Return
Having one 74HC595 per display should be easy enough, simpler than what we are doing here, and that appears to be how tmfkan has done it. Send eight bytes of digit data, setting the segments for each digit, activate LATCH, and the display will be set and stay flicker-free until the next data is written.The reason for learning the 74HC595 was to test banks of eight of them each driving a single seven segment display.
I guess I misunderstood how you were intending to use the display board. If you just want to use a single digit sou can test setting segments on that it can be as simple as -Update, i now have it without the flickering by slowing the setfreq down to setfreqM1 and its now working in a way that i can cope with without having a fit
Symbol DIO = B.0
Symbol SCK = B.1
Symbol RCK = B.2
Symbol CLOCK = SCK
Symbol LATCH = RCK
; .GFEDCBA
Symbol BLANK = %00000000 ; AAA
Symbol ZERO = %00111111 ; F B
Symbol ONE = %00000110 ; F B
Symbol TWO = %01011011 ; GGG
Symbol THREE = %01001111 ; E C
Symbol FOUR = %01100110 ; E C
Symbol FIVE = %01101101 ; DDD o
Symbol SIX = %01111101
Symbol SEVEN = %00000111
Symbol EIGHT = %01111111
Symbol NINE = %01101111
Symbol DP = %10000000
Symbol reserveW0 = w0 ; b1:b0
PowerOnReset:
Low CLOCK
Low LATCH
MainLoop:
Do
b0 = FOUR ; Change this to the segments you want to set
Gosub SetDigit
Loop
SetDigit:
b0 = b0 ^ $FF : Gosub ClockOutB0_MsbFirst
b0 = 1 : Gosub ClockOutB0_MsbFirst
High LATCH
Low LATCH
Return
ClockOutB0_MsbFirst:
For b1 = 0 To 7
If bit7 = 0 Then
Low DIO
Else
High DIO
End If
High CLOCK
Low CLOCK
b0 = b0 * 2
Next
Return
If you are driving each 7-segment Common Cathode display with its own 595 register it might be possible to modify your PCB to make it work.Is it possible to make the TPIC6B595 drive the common cathode displays or am i simply better off just starting a new layout with common Anode ?
.----. __ ............
| |---|__|---:--|>|--. :
| |---|__|---:--|>|--{ :
: : __ : : :
| |---|__|---:--|>|--{ :
| |---|__|---:--|>|--^--:---.
`----' :..........: _|_ 0V
--.-.---.-.-- 5V
.|.|. .|.|.
|_|_| |_|_|
.----. | | | | ............
| |---^-|---|-|---:--|>|--. :
| |-----^---|-|---:--|>|--{ :
: : | | : : :
| |---------^-|---:--|>|--{ :
| |-----------^---:--|>|--^--:---.
`----' :..........: _|_ 0V
That makes sense. If I have read that right you have a board similar to below which you need to test -The TPIC IC's on the PCB are prone to failure and this test jig is meant to give me a quick indication of which device is faulty, they are all SMD so its not a quick swap out if you suspect one to be faulty etc.
_____________________ _ _ _________
......|_____________________ _ _ _________|...
: |||| |||| |||| :
: .-^^^^-. .-^^^^-. .-^^^^-. :
DAT --:---->| |---->| |- - - ->| | :
: .->| | .->| | .->| | :
: | `------' | `------' | `------' :
CLK --:--^------------^----------- - -' :
:............................................: