"""
012345678901234567890123456789012345678901234567890123456789
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Raspberry Pi Pico 7-Segment Counter 4 Digit (MicroPython)┃
┃ Project name: 7-Segment_Counter_Parallel. ┃
┃ (My Wokwi.com project) ┃
┃ Filename: 7-Segment_Counter_v22.py (spell checked) ┃
┃ ┃
┃ Purpose: A program to demonstrate the use of 4 digit ┃
┃ seven-segment LEDs to display a running count while, and ┃
┃ too demonstrate blinking digits while using the ┃
┃ multitasking technique to display each digit one at a ┃
┃ time using an 8-bit parallel port. ┃
┃ ┃
┃ This is for developing a simple and efficient function ┃
┃ to display up to four 7-segment LEDs, along with using ┃
┃ attribute flag bits to control each digit's on/off state.┃
┃ Buttons control blink. ┃
┃ ┃
┃ Status/ Rev: designing / ver 2.2d ┃
┃ Date: 2023-05-01 ┃
┃ By: Phil. N ┃
┃ License: GNU General Public License (GNU GPL). ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
https://docs.micropython.org/en/latest/library/machine.Pin.html
Notes:
All 8-Segments including DP connects to GPIO 0 to GPIO 7.
GP0 = SegA, GP1 = SegB, GP2 = SegC... GP6 = SegG, GP7 = DP.
Common of each digit connects to GPIO 8 to GPIO 11.
GP8 = Dig1, GP9 = Dig2, GP10 = Dig3, GP11 = Dig4.
| en | Digit Select: | Display Segments: |
GPIO = | 12 | 11 10 09 08 | 07 06 05 04 03 02 01 00 |
| en | D4 D3 D2 D1 | DP SG SF SE SD SC SB SA |
V2.0 Need to implement Digits Memory (digitsMem) into current program:
V2.1 Need to finish setting up programming for the two (2) button matrix:
GPIO-13 (orange wire) is always an input tied to an interrupt, and is Row-0.
GPIO-14/15 are columns Col-0 and Col-1.
The ISR checks which button or buttons are pressed by placing a 1 or 0 on
each column while checking Row-0's input. If Row-0 is low while a column
is also low, then button is pressed.
"""
# ******* I N C L U D E S ***********************************************
# *** Place any imported Modules here!
from machine import Pin
from time import sleep
from rp2 import PIO, StateMachine, asm_pio
# ****** I N T E R R U P T V E C T O R S ******************************
# *** Place IRQ here!
# ******* V A R I A B L E S *********************************************
# *** Define variable values and input/output pins here!
counter = 0 # Counter for displaying a number.
digitSeg = 0 # Digit Segments.
pins = [
Pin(0, Pin.OUT), # A
Pin(1, Pin.OUT), # B
Pin(2, Pin.OUT), # C
Pin(3, Pin.OUT), # D
Pin(4, Pin.OUT), # E
Pin(5, Pin.OUT), # F
Pin(6, Pin.OUT), # G
Pin(7, Pin.OUT) # DP (not connected)
]
digNum = [
Pin(8, Pin.OUT), # Digit 1
Pin(9, Pin.OUT), # Digit 2
Pin(10, Pin.OUT), # Digit 3
Pin(11, Pin.OUT) # Digit 4
]
'''
7-segment display layout
A
-----
F | G | B
-----
E | | C
----- o Dp
D
| Display Segments: |
| MSN | LSN |
| 07 06 05 04 | 03 02 01 00 |
| Dp G F E | D C B A |
'''
# 7-segment display digit patterns
# Seg-Pattern: Character: Array number:
SegmentPattern = [
0x3F, # 0 0
0x06, # 1 1
0x5B, # 2 2
0x4F, # 3 3
0x66, # 4 4
0x6D, # 5 5
0x7D, # 6 6
0x07, # 7 7
0x7F, # 8 8
0x6F, # 9 9
0x77, # A 10
0x7C, # b 11
0x39, # C 12
0x5E, # d 13
0x79, # E 14
0x71, # F 15
0x00, # Off 16
0x80, # . 17 (Dp)
0x76, # H 18
0x1E, # J 19
0x38, # L 20
0x5C, # o 21
0x73, # P 22
0x3E, # U 23
0xFF, # Test 24 (All on)
0x20, # | 25 (Vertical bar)
0x22, # || 26 (2 Vertical bars)
0x40, # - 27 (Dash)
0x08, # _ 28 (Lower-Horizontal)
0x88, # _. 29 (Lower-Horizontal Dp)
]
maxNum = 29 # Maximum displayable characters.
# Need to implement Digits Memory (digitsMem) into current program.
# Decide whether to store a value or segment pattern.
digitsMem = [
#digX=0 1 2 3 # Y
[1, 2, 3, 4], # mem0 1 2 3 4
[2, 6, 0, 0], # mem1 2 6 0 0
[0xA, 0xB, 0xC, 0xD], # mem2 A B C D
[0x10, 4, 0xDB, 9], # mem3 off 4 2. H
]
memY = 0
digX = 0
aDigit = digitsMem[memY][digX]
led = Pin(21, Pin.OUT) # LED.
en_led = Pin(12, Pin.OUT) # Enable LED going to future 5801 chip.
# Setup interrupt pin for the two (2) buttons.
intPin = Pin(13, Pin.IN, Pin.PULL_UP)
# Both buttons always outputs, and need to be set to a low value to cause an interrupt.
# Green button.
col0_pb = Pin(14, Pin.OUT)
# Red button.
col1_pb = Pin(15, Pin.OUT)
redpbState = 0 # Not yet used, need to get interrupt handler working first.
greenpbState = 0 # Not yet used, need to get interrupt handler working first.
ledValue = 1 # Note this variable does work, and changes LED state.
en_ledValue = 1 # Note this variable does work, and changes LED state.
# ****** F U N C T I O N S ***********************************************
# *** Place any functions here!
''' ***********************************************************************
* Function : reset()
* Date / Ver : 04-18-2023 / V2.1d
* PreCondition : None
* Input : None
* Output : None
* Side Effects : None
* Note : Turns off all segments on the 7-segment display.
* Then turns off all digit control lines.
* Defaults col0_pb / col1_pb to low for interrupt detection.
********************************************************************** '''
def reset():
for pin in pins:
pin.value(1)
for pin in digNum:
pin.value(0)
col0_pb.value(0)
col1_pb.value(0)
''' ***********************************************************************
* Function : alert()
* Date / Ver : 04-18-2023 / V1.0d
* PreCondition : None
* Input : None
* Output : None
* Side Effects : None
* Note : Interrupt handler function.
********************************************************************** '''
# interrupt handler function
def alert(intPin):
global en_ledValue # Make variable global so it can be changed within function.
global ledValue
en_ledValue = 0 # Note: indicates interrupt handler is not being called.
ledValue = 0 # because these leds stay no, they should go off.
# ******* D E C L A R A T I O N S ***************************************
# ** Declare executable instructions here(!)
# attach the interrupt to the intPin, and will call the function "alert".
# RISING or FALLING
intPin.irq(trigger = Pin.IRQ_FALLING, handler = alert)
reset()
digitSel = 0b000100000000
@asm_pio(out_init=(rp2.PIO.OUT_HIGH,) * 12, out_shiftdir=PIO.SHIFT_RIGHT,
autopull=True, pull_thresh=16)
def paral_prog():
pull()
out(pins, 12)
parallelPort = StateMachine(0, paral_prog, freq=10000000, out_base=Pin(0))
parallelPort.active(1)
# ******** Main Processing Loop *************
# *** Round and around the Mobius loop...
while True:
if counter > maxNum:
counter = 0
if digitSel > 0b100000000000:
digitSel = 0b000100000000
# digitSeg = SegmentPattern[counter] # Use this for common cathode 7-segment display.
digitSeg = ~SegmentPattern[counter] # Use this for common anode 7-segment display.
digitSeg = digitSeg & 0b000011111111
portWrt = digitSel | digitSeg
parallelPort.put(portWrt)
counter += 1
digitSel = digitSel << 1
sleep(0.75)
led.value(ledValue)
en_led.value(en_ledValue)