0

I have an 8-digit LED display board, but I'm getting odd results. Line 21 defines which segments are lit AND which displays are used. So [1,0,0,0,1,0,0,0] turns off the 1st and 5th segments and lights the 4th and 8th displays (displays are in the order 4, 3, 2, 1, 8, 7, 6, 5). So the first 1 in the list on Line 24 turns off the decimal point and illuminates the fourth display. The 5th 1 turns off the bottom segment and illuminates the eighth display.

8 digit seven-segment display

What I would like is to be able to specify which display to use and which segments of that display to light / unlight.

Here is the Python 3 code:

import RPi.GPIO as IO
import time

# Ignore warnings
IO.setwarnings(False)

# Set pinouts
dataPin  = 11
latchPin = 15
clockPin = 13

IO.setmode (IO.BOARD)
IO.setup(dataPin, IO.OUT)
IO.setup(clockPin, IO.OUT)
IO.setup(latchPin, IO.OUT)

# 7-segment displays are in the following
# order:   4 3 2 1 8 7 6 5

# Segments to light (0 = on / 1 = off)
segsLit = [1,0,0,0,1,0,0,0] # Line 21

# Iterate through 7-seg displays
for j in range(8):
  IO.output(latchPin, 0)

  # Iterate through list1 to light segments
  for i in range(8):
    IO.output(clockPin, 0)
    IO.output(dataPin, segsLit[i])
    IO.output(clockPin, 1)
  IO.output(latchPin, 1)

IO.cleanup()

print("Done")

I've found a couple of guides, but they are for driving only a single display or just 8 LEDs. There are lots of guides for the Arduino, which I've tried to convert, but I just keep getting similar issues with the wrong digits displaying.

wibbleface
  • 119
  • 14
  • After reading your question, I'm unclear what the problem is. Are the incorrect segments lighting up? – larsks Jul 25 '21 at 17:51
  • The incorrect 7-seg displays are lighting up and those which do light up all show the same. Looking on the photo I added, you can see that displays 1 and 5 are both showing 'A'. I'd like to be able to display different information on each display, specifying what will be displayed on each. E.g. '1234ABCD' across the eight displays – wibbleface Jul 25 '21 at 18:57
  • presumably all your serial chips are daisy chained, so there is no need to turn the latchPin off and on for each cycle. Plus you have 8 digits times 7 segments, so you should have 56 segment values in your table. If you have one chip per display, you will probably have an 8th bit as well per digit. I'll probably add a guessing answer below. – RufusVS Jul 25 '21 at 19:28
  • I was wrong in my prior comment. I looked up the board, and it appears to be multiplexed, which also means it must be continuously refreshed. One chip handles the segment and decimal point, the other one appears to be the digit position enable. So you would need to do 16 shifts per update . – RufusVS Jul 25 '21 at 19:53
  • @RufusVS You've pointed me in the right direction -- thanks. I should be sending 16 bits of data. The first 8 bits are for which segments to light, the second are for the position of the displays to use. I'll post a solution. – wibbleface Jul 26 '21 at 08:07
  • I'm surprised, I must have misread the schematic [here] (https://robotdyn.com/pub/media/0G-00004875==Mod-LED-Display-8D-74HC595/DOCS/Schematic==0G-00004875==Mod-LED-Display-8D-74HC595.pdf])because it looked like bits got shifted serially first into the segments chip then through to the position select chip (SDO of segments was tied to SDI of position). Which would mean position select should be sent first. – RufusVS Jul 26 '21 at 13:34

2 Answers2

0

Based on a schematic I found for your board, it looks like to drive 8 leds you'd need a program similar to this. The main idea is the led's have to be continuously refreshed to display multiple digits. only one segment pattern will be enabled per shifting cycle (though you COULD make it appear on multiple digits, which would be an unusual application for sure.)

I didn't bother to try to get the digit positions and segment positions all correct, that's up to you. Also digit select polarity might need to be reversed. But this edit to your code should get you closer:

import RPi.GPIO as IO

REFRESH_NS = 1_000_000_000 / 30 / 8  # refresh 30 times per second, 8 digits

# Ignore warnings
IO.setwarnings(False)

# Set pinouts
dataPin  = 11
latchPin = 15
clockPin = 13

IO.setmode (IO.BOARD)
IO.setup(dataPin, IO.OUT)
IO.setup(clockPin, IO.OUT)
IO.setup(latchPin, IO.OUT)

# 7-segment displays are in the following
# order:   4 3 2 1 8 7 6 5

# Segments to light (0 = on / 1 = off)
segsLit = 
[
[1,0,0,0,0,0,0,0],
[0,1,0,0,0,0,0,0],
[0,0,1,0,0,0,0,0],
[0,0,0,1,0,0,0,0],
[0,0,0,0,1,0,0,0],
[0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,1,0],
[0,0,0,0,0,0,0,1],
]

update_time = time.monotonic_ns()

# Iterate through 7-seg displays (8 bits with decimal point)
while True:
    IO.output(latchPin, 0) # start shift operation
    
    for digit in range(8):

        # digit select shifts out first
        for pos in range(8):
            IO.output(clockPin, 0)
            IO.output(dataPin, 1 if pos==digit else 0)
            IO.output(clockPin, 1)

        # Iterate through to light segments
        for seg in range(8):
            IO.output(clockPin, 0)
            IO.output(dataPin, segsLit[digit][seg])
            IO.output(clockPin, 1)


    IO.output(latchPin, 1) # end shift operation
    
    while time.monotonic_ns() < update_time + REFRESH_NS: # delay to energize led
        pass # spin loop
    
    update_time = time.monotonic_ns() # prepare for next update
    
IO.cleanup()

print("Done")
RufusVS
  • 4,008
  • 3
  • 29
  • 40
0

16 bits of data needed to be sent to the board. The first 8 bits are to light specific segments, the subsequent 8 bits are to indicate which display(s) to use.

In the updated code below, the 8th (right-most) display will show the letter 'A'.

import RPi.GPIO as IO
import time

# Ignore warnings
IO.setwarnings(False)

# Set pinouts
dataPin  = 11
latchPin = 15
clockPin = 13

IO.setmode (IO.BOARD)
IO.setup(dataPin, IO.OUT)
IO.setup(clockPin, IO.OUT)
IO.setup(latchPin, IO.OUT)

# 7-segment displays are in the following
# order:   4 3 2 1 8 7 6 5

# First 8 bits = segments to light // Second 8 bits = position
segsLit = [1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0] # Line 21

# Iterate through 7-seg displays
IO.output(latchPin, 0)

# Iterate through list1 to light segments
for i in range(16):
  IO.output(clockPin, 0)
  IO.output(dataPin, segsLit[i])
  IO.output(clockPin, 1)
IO.output(latchPin, 1)

IO.cleanup()

print("Done")
wibbleface
  • 119
  • 14