Skip to content

Commit aa651b1

Browse files
authored
Merge pull request #47 from jepler/example-updates-background
enhance examples
2 parents 56b4872 + e55ff9b commit aa651b1

File tree

4 files changed

+478
-30
lines changed

4 files changed

+478
-30
lines changed

examples/pioasm_7seg.py

+178
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# SPDX-FileCopyrightText: 2022 Jeff Epler, written for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
"""Drive a 7-segment display entirely from the PIO peripheral
6+
7+
By updating the buffer being written to the display, the shown digits can be changed.
8+
9+
The main program repeatedly shows random digits which 'lock' after a short
10+
time. After all digits have locked, it blanks for a short time and then repeats.
11+
It also demonstrates the use of `asyncio` to perform multiple tasks.
12+
13+
This example is designed for a Raspberry Pi Pico and bare LED display. For
14+
simplicity, it is wired without any current limiting resistors, instead relying
15+
on a combination of the RP2040's pin drive strength and the 1/4 duty cycle to
16+
limit LED current to an acceptable level, and longevity of the display was not
17+
a priority.
18+
19+
Before integrating a variant of this example code in a project, evaluate
20+
whether your design needs to add current-limiting resistors.
21+
22+
https://www.adafruit.com/product/4864
23+
https://www.adafruit.com/product/865
24+
25+
Wiring:
26+
* Pico GP15 to LED matrix 1 (E SEG)
27+
* Pico GP14 to LED matrix 2 (D SEG)
28+
* Pico GP13 to LED matrix 3 (DP SEG)
29+
* Pico GP12 to LED matrix 4 (C SEG)
30+
* Pico GP11 to LED matrix 5 (G SEG)
31+
* Pico GP10 to LED matrix 6 (COM4)
32+
* Pico GP9 to LED matrix 7 (COLON COM)
33+
* Pico GP22 to LED matrix 8 (COLON SEG)
34+
* Pico GP21 to LED matrix 9 (B SEG)
35+
* Pico GP20 to LED matrix 10 (COM3)
36+
* Pico GP19 to LED matrix 11 (COM2)
37+
* Pico GP18 to LED matrix 12 (F SEG)
38+
* Pico GP17 to LED matrix 13 (A SEG)
39+
* Pico GP16 to LED matrix 14 (COM1)
40+
"""
41+
42+
import asyncio
43+
import random
44+
import array
45+
import board
46+
import rp2pio
47+
import adafruit_pioasm
48+
49+
_program = adafruit_pioasm.Program(
50+
"""
51+
out pins, 14 ; set the pins to their new state
52+
"""
53+
)
54+
55+
# Display Pins 1-7 are GP 15-9
56+
# Display Pins 8-12 are GP 22-16
57+
COM1_WT = 1 << 7
58+
COM2_WT = 1 << 10
59+
COM3_WT = 1 << 11
60+
COM4_WT = 1 << 1
61+
COMC_WT = 1 << 0
62+
63+
SEGA_WT = 1 << 8
64+
SEGB_WT = 1 << 12
65+
SEGC_WT = 1 << 3
66+
SEGD_WT = 1 << 5
67+
SEGE_WT = 1 << 6
68+
SEGF_WT = 1 << 9
69+
SEGG_WT = 1 << 2
70+
71+
SEGDP_WT = 1 << 4
72+
SEGCOL_WT = 1 << 13
73+
74+
ALL_COM = COM1_WT | COM2_WT | COM3_WT | COM4_WT | COMC_WT
75+
76+
SEG_WT = [
77+
SEGA_WT,
78+
SEGB_WT,
79+
SEGC_WT,
80+
SEGD_WT,
81+
SEGE_WT,
82+
SEGF_WT,
83+
SEGG_WT,
84+
SEGDP_WT,
85+
SEGCOL_WT,
86+
]
87+
COM_WT = [COM1_WT, COM2_WT, COM3_WT, COM4_WT, COMC_WT]
88+
89+
DIGITS = [
90+
0b0111111, # 0
91+
0b0000110, # 1
92+
0b1011011, # 2
93+
0b1001111, # 3
94+
0b1100110, # 4
95+
0b1101101, # 5
96+
0b1111100, # 6
97+
0b0000111, # 7
98+
0b1111111, # 8
99+
0b1101111, # 9
100+
]
101+
102+
103+
def make_digit_wt(v):
104+
val = ALL_COM
105+
seg = DIGITS[v]
106+
for i in range(8):
107+
if seg & (1 << i):
108+
val |= SEG_WT[i]
109+
return val
110+
111+
112+
DIGITS_WT = [make_digit_wt(i) for i in range(10)]
113+
114+
115+
class SMSevenSegment:
116+
def __init__(self, first_pin=board.GP9):
117+
self._buf = array.array("H", (DIGITS_WT[0] & ~COM_WT[i] for i in range(4)))
118+
self._sm = rp2pio.StateMachine(
119+
_program.assembled,
120+
frequency=2000,
121+
first_out_pin=first_pin,
122+
out_pin_count=14,
123+
auto_pull=True,
124+
pull_threshold=14,
125+
**_program.pio_kwargs,
126+
)
127+
self._sm.background_write(loop=self._buf)
128+
129+
def __enter__(self):
130+
return self
131+
132+
def __exit__(self, exc_type, exc_value, traceback):
133+
self.deinit()
134+
135+
def deinit(self):
136+
self._sm.deinit()
137+
138+
def __setitem__(self, i, v):
139+
if v is None:
140+
self._buf[i] = 0
141+
else:
142+
self._buf[i] = DIGITS_WT[v] & ~COM_WT[i]
143+
144+
145+
async def digit_locker(s, i, wait):
146+
delay = 30
147+
d = random.randint(0, 9)
148+
while delay < 300:
149+
d = (d + random.randint(1, 9)) % 10 # Tick to a new digit other than 'd'
150+
s[i] = d
151+
await asyncio.sleep(delay / 1000)
152+
if wait:
153+
wait -= 1
154+
else:
155+
delay = delay * 1.1
156+
157+
158+
def shuffle(seq):
159+
for i in range(len(seq) - 1):
160+
j = random.randrange(i + 1, len(seq))
161+
seq[i], seq[j] = seq[j], seq[i]
162+
163+
164+
async def main():
165+
waits = [100, 175, 225, 250]
166+
with SMSevenSegment(board.GP9) as s:
167+
while True:
168+
shuffle(waits)
169+
await asyncio.gather(
170+
*(digit_locker(s, i, di) for i, di in enumerate(waits))
171+
)
172+
await asyncio.sleep(1)
173+
for i in range(4):
174+
s[i] = None
175+
await asyncio.sleep(0.5)
176+
177+
178+
asyncio.run(main())

0 commit comments

Comments
 (0)