If I understand correctly what you are trying to do then there is a simple software solution.
The following Python code should update multiplexed 7-segment LCDs in a flicker free way.
For testing purposes each LCD is updated for 100000 µs in turn. In a practical application a value like 1000 µs should be used. The period
is set by the REFRESH constant.
The code assumes that a segment is switched on by setting a gpio high. Similarly a LCD is enabled by setting a gpio high. You'd need to invert the logic if your segments/LCD are wired differently.
#!/usr/bin/env python
# _7_segment.py
# 2015-08-07
# Public Domain
import time
import pigpio # http://abyz.me.uk/rpi/pigpio/python.html
# For testing purposes each LCD is refreshed (REFRESH) for
# 100000 microseconds. In a practical application you probably
# want to use a figure in the region of 1000 microseconds.
REFRESH=100000
CHARSET={
' ': 0b00000000,
'0': 0b11111100,
'1': 0b01100000,
'2': 0b11011010,
'3': 0b11110010,
'4': 0b01100110,
'5': 0b10110110,
'6': 0b00111110,
'7': 0b11100000,
'8': 0b11111110,
'9': 0b11100110,
'A': 0b11101110,
'b': 0b00111110,
'C': 0b10011100,
'c': 0b00011010,
'd': 0b01111010,
'E': 0b10011110,
'F': 0b10001110,
'H': 0b01101110,
'h': 0b00101110,
'L': 0b00011100,
'l': 0b01100000,
'O': 0b11111100,
'o': 0b00111010,
'P': 0b11001110,
'S': 0b10110110,
}
# This defines which gpios are connected to which segments
# a b c d e f g dp
SEG2GPIO=[ 4, 17, 18, 22, 23, 10, 24, 9]
# This defines the gpio used to switch on a LCD
# 1 2 3 4 5
LCD2GPIO=[ 5, 6, 7, 8, 11]
wid = None
showing = [0]*len(LCD2GPIO)
CHARS=len(CHARSET)
def display(lcd, char):
if char in CHARSET:
showing[lcd] = CHARSET[char]
else:
showing[lcd] = 0
def update_display():
global wid
wf = []
for lcd in range(len(LCD2GPIO)):
segments = showing[lcd] # segments on for current LCD
on = 0 # gpios to switch on
off = 0 # gpios to switch off
# set this LCD on, others off
for L in range(len(LCD2GPIO)):
if L == lcd:
on |= 1<<LCD2GPIO[L] # switch LCD on
else:
off |= 1<<LCD2GPIO[L] # switch LCD off
# set used segments on, unused segments off
for b in range(8):
if segments & 1<<(7-b):
on |= 1<<SEG2GPIO[b] # switch segment on
else:
off |= 1<<SEG2GPIO[b] # switch segment off
wf.append(pigpio.pulse(on, off, REFRESH))
print(on, off, REFRESH) # debugging only
pi.wave_add_generic(wf) # add pulses to waveform
new_wid = pi.wave_create() # commit waveform
pi.wave_send_repeat(new_wid) # transmit waveform repeatedly
if wid is not None:
pi.wave_delete(wid) # delete no longer used waveform
print("wid", wid, "new_wid", new_wid)
wid = new_wid
pi = pigpio.pi()
# Set all used gpios as outputs.
for segment in SEG2GPIO:
pi.set_mode(segment, pigpio.OUTPUT)
for lcd in LCD2GPIO:
pi.set_mode(lcd, pigpio.OUTPUT)
char=0
ck = CHARSET.keys()
while True:
# To test loop over character set.
for d in range(len(LCD2GPIO)):
display(d, ck[(d+char)%CHARS])
update_display()
char += 1
time.sleep(2)
pi.wave_delete(wid)
pi.stop()
segmentdisplay.print(23)
(outputs 0023
) ? – Basj Mar 25 '15 at 7:20