-
Notifications
You must be signed in to change notification settings - Fork 0
/
PDP8Lights.py
154 lines (124 loc) · 4.78 KB
/
PDP8Lights.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/python3
#
# BlinkenLights for the PiDP-8
#
# I like the PiDP-8, but the frenetic appearance of the lights
# when emulating the '8 is a bit distracting. Rather than
# leave it dark, this code lets you do arbitrary blinking.
#
# No support for PWM (not sure it's possible in Python?)
#
# J. Peterson, Dec 2019
#
import RPi.GPIO as GPIO # sudo apt-get install python3-dev
from time import sleep
import sys
# These are the RasPI board pin numbers on the 40 pin header.
# Now, beware of the 1-based indexing from the schematic, vs.
# the zero based indexing Python likes. Also note the PiDP-8
# schematic shows col 1,2 as pins 3,5 but on my unit
# they're pins 8 and 10.
# 1 2 3 4 5 6 7 8 9 10 11 12
col = [0, 8, 10, 7, 29, 31, 26, 24, 21, 19, 23, 32, 33]
led = [0, 38, 40, 15, 16, 18, 22, 37, 13]
row = [0, 36, 11, 12] # Used to access the switches
# Number of LEDs in each LED row. Zero-based
# 1 2 3 4 5 6 7 8
numLEDsInRow = [12, 12, 12, 12, 12, 12, 10, 7]
numLEDrows = len(numLEDsInRow)
# Timing (in seconds)
rowDelay = 0.0005 # Time to display lights in each row
frameDelay = 1/20.0 # Time per animation frame
scriptRestartTime = 30 * 60 # Runtime before the script gets restarted
totalFrameTime = rowDelay * numLEDrows + frameDelay
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
def lightSetup():
GPIO.setup(col[1:], GPIO.IN)
GPIO.setup(col[1:], GPIO.OUT)
GPIO.setup(led[1:], GPIO.OUT)
# Read one switch value
def readSwitch( rowNum, colNum ):
GPIO.setup(col[colNum], GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(led[1:], GPIO.IN) # This needs to be left input
GPIO.setup(row[rowNum], GPIO.OUT)
GPIO.output( row[rowNum], 0 )
result = GPIO.input( col[colNum] )
GPIO.output( row[rowNum], 1 );
lightSetup() # Resume output to LED mode
return result
# Seconds is the time to display the frame, pattern
# is an array of ints describing the bit patterns for the LED rows
def showFrame(seconds, pattern):
for i in range( int( seconds / (numLEDrows * rowDelay)) ):
for ledrow in range(0, numLEDrows):
# To turn on an LED i,j, send the led[i] line
# high, and the col[j] line low
wordlen = numLEDsInRow[ledrow]
GPIO.output( led[ledrow+1], 1 )
bits = pattern[ledrow]
bitList = [1-((bits & (1<<i))>>i) for i in range(wordlen-1, -1, -1)]
GPIO.output( col[1:wordlen+1], bitList )
sleep(rowDelay)
GPIO.output( col[1:wordlen+1], 1 )
GPIO.output( led[ledrow+1], 0 )
# From geeksforgeeks.org/rotate-bits-of-an-integer/
# "d" is the shift distance
def leftRotate1(n, numBits):
d=1
return (n << d) | (n >> (numBits-d))
def rightRotate1(n, numBits):
d=1
return (n >> d) | (n << (numBits-d)) & 0xFFF
# This is a very simple display loop, just rotating patterns in
# each of the LED rows.
def showDisplay():
lightSetup()
patterns = [0b111100001111, 0b111100001111, 0b111111000000, 0b111000111000,
0b111111000000, 0b100000001000, 0b1000010001, 0b1110000]
elapsedTime = 0;
totalTime = 0
# Exit the outerloop every scriptRestartTime, so RunLights.py
# can restart it. Otherwise, some creeping leak bloats
# and slows the app to the point where the display flickers
while totalTime < scriptRestartTime:
showFrame( frameDelay, patterns )
for i in range(len(patterns)):
if (i % 2) == 0:
patterns[i] = leftRotate1( patterns[i], numLEDsInRow[i] )
else:
patterns[i] = rightRotate1( patterns[i], numLEDsInRow[i] )
elapsedTime += totalFrameTime
# Every 2 seconds, check for the stop switch pushed down
if (elapsedTime > 2):
totalTime += elapsedTime
elapsedTime = 0
stopSwitch = readSwitch( 3, 6 ) # Momemtary Stop switch, 3rd from right
if stopSwitch == 0:
GPIO.cleanup()
sys.exit(0)
GPIO.cleanup()
showDisplay()
# Test code to read all the switches
# Reports "1" when the top of the switch is pushed in.
def readRow():
GPIO.setup(col[1:], GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(led[1:], GPIO.IN)
GPIO.setup(row[1:], GPIO.OUT)
rowMax = [0, 12, 6, 8]
off = 1
on = 0
lastValues = []
for i in range(20):
values = []
GPIO.output( row[1:], off )
for rowval in [2,1,3]:
GPIO.output( row[rowval], on)
for colval in range(1, rowMax[rowval]+1):
values.append( GPIO.input(col[colval]) )
GPIO.output( row[rowval], off)
if (values != lastValues):
print(values)
lastValues = values
sleep(1)
#readRow()