Multiplexing 7 segment displays with a single 20X2 and i2c

Memran

Member
Hello again!

I've got a mini project on the go, where I am trying to use a 20X2 to drive some 7 segment displays from i2c input, but I am getting "ghost digits".

For simplicity of the code on the 20X2 during testing, the bytes received contain the data for the 7 segment abcdefg LEDs and not actual numbers.
I am using outpinsC (0,1,2,3,4,5,7) (6 is input only) for the abcdefg outputs, and outpinsB (0,1) for the common of the displays. (if/when I get this working, I'll add more digits).

I think the crux of my problem is that I need to set outpinsB and outpinsC at the same time but the only thing I can do is set them sequentially.

Code:
init: 
	let dirsB = %00001111
	let dirsC = %11111111
	
	hi2csetup i2cslave, %10100000
	setintflags %01000000,%01000000 'set up i2c interrupt
	
do
	'digit #1
	let outpinsC = b1
	let outpinsB = %00000010
	pause 5
	'digit #2
	let outpinsC = b0
	let outpinsB = %00000001
	pause 5
loop
	
interrupt:
	hi2cflag = 0 'reset flag
	'get digits from scratch
	get 0,b0
	get 1,b1
	setintflags %01000000,%01000000 'reset i2c interrupt
	return
The i2c receive and interrupt are working as expected, and the correct digits are clearly visible, but the "ghost digits" from the multiplexing are causing me problems.
ghost digits: a fainter version of the another digit is visible on top of the desired digit.

Using another IC, such as a BCD to 7 segment decoder still has issues because I'd need 4 pins for the BCD, and that only leaves 2 or 3 pins for the multiplexing (2 used from B for i2c, and C.6 is input only). So if I want to run more than 3 digits (I do) I will have the same issue of trying to set B and C simultaneously.

Is there some way to set outpinsB and outpinsC at the same time?
Failing that, is there some other strategy to minimise the impact of the sequential outpins assignments?

Thanks :D

ps. I know there are modules available which do exactly what I want, but where is the fun in that? ;)
 

westaust55

Moderator
Try adding blanking to turn off the LEDs just before establishing the next digit to avoid the flicker. See lines in red below


Code:
init: 
	let dirsB = %00001111
	let dirsC = %11111111
	
	hi2csetup i2cslave, %10100000
	setintflags %01000000,%01000000 'set up i2c interrupt
	
do
	'digit #1
	let outpinsC = b1
	let outpinsB = %00000010
	pause 5
	[COLOR="#FF0000"]let outpinsB = %00000000[/COLOR]
	'digit #2
	let outpinsC = b0
	let outpinsB = %00000001
	pause 5
	[COLOR="#FF0000"]let outpinsB = %00000000[/COLOR]
             loop

	
interrupt:
	hi2cflag = 0 'reset flag
	'get digits from scratch
	get 0,b0
	get 1,b1
	setintflags %01000000,%01000000 'reset i2c interrupt
	return
 
Top