Skip to content

Instantly share code, notes, and snippets.

@turnipsoup
Created January 28, 2024 20:28
Show Gist options
  • Save turnipsoup/c5ca00fc8157414484f2cbf142032a6b to your computer and use it in GitHub Desktop.
Save turnipsoup/c5ca00fc8157414484f2cbf142032a6b to your computer and use it in GitHub Desktop.
Scripts for controlling a quad 7-segment display via a Rasyberry Pi Pico using Micropython. Both Direct GPIO and via shift registers.
from machine import Pin
import time
import _thread
display_number = 0
padding = True
dataPIN1 = 18
dataPIN2 = 20
latchPIN2 = 19
latchPIN1 = 17
clockPIN = 16
clockPIN=Pin(clockPIN, Pin.OUT)
dataPIN1=Pin(dataPIN1, Pin.OUT)
latchPIN1=Pin(latchPIN1, Pin.OUT)
dataPIN2=Pin(dataPIN2, Pin.OUT)
latchPIN2=Pin(latchPIN2, Pin.OUT)
numbers = {
"0": "11111100",
"1": "01100000",
"2": "11011010",
"3": "11110010",
"4": "01100110",
"5": "10110110",
"6": "10111110",
"7": "11100000",
"8": "11111110",
"9": "11100110"
}
coms = ["01111111", "10111111", "11011111", "11101111", "11110111"]
# Thanks to https://peppe8o.com/how-to-use-74hc595-shift-register-with-raspberry-pi-pico-and-micropython/
def shift_update(input,data,clock,latch):
"""
Send update to shift register
"""
#put latch down to start data sending
clock.value(0)
latch.value(0)
clock.value(1)
#load data in reverse order
for i in range(7, -1, -1):
clock.value(0)
data.value(int(input[i]))
clock.value(1)
#put latch up to store data on register
clock.value(0)
latch.value(1)
clock.value(1)
def display_number_led(num: int, padding=False):
"""
Displays a four digit number on the 7 segment display
Padding=true will pre-pend zeroes.
"""
n = str(num)
# Pad with zeroes if requested
if padding:
if len(n) < 4:
t = 4 - len(n)
for i in range(t):
n = "0" + n
# Display the number
for i in range(4):
shift_update(numbers[n[i]],dataPIN1,clockPIN,latchPIN1)
time.sleep(0.001)
shift_update(coms[i],dataPIN2,clockPIN,latchPIN2)
# Clear the display to "update" a bit slower for the human eyes
shift_update("11111111",dataPIN2,clockPIN,latchPIN2)
def display_number_thread():
"""
Displays a four digit number on the 7 segment display
Padding=true will pre-pend zeroes.
"""
from machine import Pin
while True:
display_number_led(display_number, padding=padding)
if __name__ == "__main__":
# Start the display thread
second_thread = _thread.start_new_thread(display_number_thread, ())
count = 0
while True:
display_number = count
count += 1
if count > 9999:
count = 0
time.sleep(0.1)
from machine import Pin
import time
import _thread
##########
led = Pin("LED", Pin.OUT)
# Top, Top-Right, Bottom-Right, Bottom, Bottom-Left, Top-Left, Middle, Dot, Colon
# A, B, C, D, E, F, G, DP
# Pico GP pins
LED_pins = [9, 7, 26, 28, 5, 8, 22, 27]
COLON_pin = 6
COLON_enable = False
LED_mappings = {"A": 9, "B": 7, "C": 26, "D": 28, "E": 5, "F": 8, "G": 22, "DP": 27}
LED_names = LED_mappings.keys()
numbers = {
0: ["A", "B", "C", "D", "E", "F"],
1: ["B", "C"],
2: ["A", "B", "D", "E", "G"],
3: ["A", "B", "C", "D", "G"],
4: ["B", "C", "F", "G"],
5: ["A", "C", "D", "F", "G"],
6: ["A", "C", "D", "E", "F", "G"],
7: ["A", "B", "C"],
8: ["A", "B", "C", "D", "E", "F", "G"],
9: ["A", "B", "C", "F", "G"],
}
# Digit 1, Digit 2, Digit 3, Digit 4, Colon
# Pico GP pins
COM_pins = [15, 14, 13, 11, 12]
display_digit = [1, 2, 3, 4]
##########
def disable_all_compins() -> None:
"""
Disables all COM pins
"""
for pin in COM_pins:
Pin(pin, Pin.OUT).value(1)
def disable_other_compins(digit: int) -> None:
"""
Disables all COM pins except the one specified
"""
for pin in COM_pins:
if pin != COM_pins[digit]:
Pin(pin, Pin.OUT).value(1)
else:
Pin(pin, Pin.OUT).value(0)
def clear_digit(digit: int) -> None:
"""
Clears the digit by turning off all LEDs
"""
# Enable Digit requested by tying Digit COM PIN to LOW
Pin(COM_pins[digit], Pin.OUT).value(0)
for num in LED_pins:
Pin(num, Pin.OUT).value(0)
def clear_all_digits() -> None:
"""
Clears all digits by turning off all LEDs
"""
for digit in range(4):
clear_digit(digit)
disable_all_compins()
def enable_colon() -> None:
"""
Enables the colon by tying the COLON pin to LOW
"""
Pin(COM_pins[-1], Pin.OUT).value(0)
Pin(COLON_pin, Pin.OUT).value(1)
def disable_colon() -> None:
"""
Disables the colon by tying the COLON pin to HIGH
"""
Pin(COM_pins[-1], Pin.OUT).value(1)
Pin(COLON_pin, Pin.OUT).value(0)
def draw_number_on_digit(number: int, digit: int, dot: bool = False) -> None:
"""
Draws a number on a single digit by tying the COM pin to LOW
And drawing the number on the LEDs
"""
# Disable all other digits
disable_other_compins(digit)
# Clear the digit so we dont get weirdness
Pin(COM_pins[digit], Pin.OUT).value(0)
for num in numbers[number]:
Pin(LED_mappings[num], Pin.OUT).value(1)
if dot:
Pin(LED_mappings["DP"], Pin.OUT).value(1)
def draw_number_four_digits(
number: list[int],
dots: list[bool] = [False, False, False, False],
colon: bool = False,
) -> None:
"""
Takes a four digit integer and draws it on the display
"""
# Draw each digit
for i in range(4):
draw_number_on_digit(number[i], i, dots[i])
clear_digit(i)
if colon:
enable_colon()
disable_colon()
else:
disable_colon()
def draw_four_thread() -> None:
"""
Takes a four digit integer and draws it on the display
"""
from machine import Pin
while True:
draw_number_four_digits(
display_digit, dots=[False, False, False, False], colon=COLON_enable
)
##########
if __name__ == "__main__":
# Enable LED to show that something is happening
led = Pin("LED", Pin.OUT)
led.value(1)
# Start the display thread
second_thread = _thread.start_new_thread(draw_four_thread, ())
count = 0
while True:
c = str(count)
if len(c) < 4:
t = 4 - len(c)
for i in range(t):
c = "0" + c
display_digit = [int(i) for i in c]
# draw_number_four_digits(display_digit)
count += 1
if count >= 9999:
count = 0
time.sleep(0.1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment