from machine import Pin
import utime
# Define shift register pins for segment control
SEG_DATA = Pin(0, Pin.OUT)
SEG_CLOCK = Pin(1, Pin.OUT)
SEG_LATCH = Pin(2, Pin.OUT)
# Define shift register pins for digit selection
DIGIT_DATA = Pin(3, Pin.OUT)
DIGIT_CLOCK = Pin(4, Pin.OUT)
DIGIT_LATCH = Pin(5, Pin.OUT)
# 7-segment display binary values (common cathode)
SEGMENT_MAP = {
'0': 0b00111111, '1': 0b00000110, '2': 0b01011011, '3': 0b01001111,
'4': 0b01100110, '5': 0b01101101, '6': 0b01111101, '7': 0b00000111,
'8': 0b01111111, '9': 0b01101111, ' ': 0b00000000
}
# Digit selection map (Active-Low, enables one digit at a time)
DIGIT_MAP = [0b1110, 0b1101, 0b1011, 0b0111] # Only one bit LOW at a time
def shift_out(value, data_pin, clock_pin):
"""Shift out 8-bit data to a shift register"""
for i in range(8):
bit = (value >> (7 - i)) & 1
data_pin.value(bit)
clock_pin.value(1)
utime.sleep_us(1)
clock_pin.value(0)
def latch(latch_pin):
"""Latch the data to output the bits"""
latch_pin.value(1)
utime.sleep_us(1)
latch_pin.value(0)
def display_digits(digits, duration=300):
"""Display a 4-digit number correctly using multiplexing"""
start_time = utime.ticks_ms()
while utime.ticks_ms() - start_time < duration: # Display for given duration
for i in range(4):
shift_out(0b00000000, SEG_DATA, SEG_CLOCK) # Clear segments
shift_out(0b1111, DIGIT_DATA, DIGIT_CLOCK) # Disable all digits
latch(SEG_LATCH)
latch(DIGIT_LATCH)
# Send new data
shift_out(SEGMENT_MAP[digits[i]], SEG_DATA, SEG_CLOCK) # Send segment data
shift_out(DIGIT_MAP[i], DIGIT_DATA, DIGIT_CLOCK) # Activate current digit
latch(SEG_LATCH) # Update segment display
latch(DIGIT_LATCH) # Update digit selection
utime.sleep_ms(5) # Short delay for multiplexing
def scroll_number(number, scroll_speed=300):
"""Scroll a number smoothly across the display"""
str_num = str(number) # Convert number to string
str_num = " " * 4 + str_num + " " * 4 # Add padding for smooth scroll
for i in range(len(str_num) - 3): # Shift through characters
display_digits(str_num[i:i+4], scroll_speed)
def zero_pad(num, digit, width=4):
"""Ensure the number is formatted as a 4-digit string"""
str_num = str(num)
if digit==True:
return "0" * (width - len(str_num)) + str_num
else:
return " " * (width - len(str_num)) + str_num
def display_number(number, disp=False, duration=1000):
"""Display a 4-digit number correctly using multiplexing"""
padded_num = zero_pad(number, disp, 4) # Ensure 4-digit format
start_time = utime.ticks_ms()
while utime.ticks_ms() - start_time < duration: # Display for given duration
for i in range(4):
shift_out(0b00000000, SEG_DATA, SEG_CLOCK) # Clear segments
shift_out(0b1111, DIGIT_DATA, DIGIT_CLOCK) # Disable all digits
latch(SEG_LATCH)
latch(DIGIT_LATCH)
# Send new data
shift_out(SEGMENT_MAP[padded_num[i]], SEG_DATA, SEG_CLOCK) # Send segment data
shift_out(DIGIT_MAP[i], DIGIT_DATA, DIGIT_CLOCK) # Activate current digit
latch(SEG_LATCH) # Update segment display
latch(DIGIT_LATCH) # Update digit selection
utime.sleep_ms(5) # Short delay for multiplexing
# Test cases: Display different numbers correctly
while True:
display_number(1234) # Show 1234 for 1 sec
display_number(5678) # Show 5678 for 1 sec
display_number(90) # Show 0090 for 1 sec
display_number(42) # Show 0042 for 1 sec
scroll_number(15479865646)