Added snowman file
[pi-xmas.git] / xmas_tree / tree.py
1 # Example code for [charlieplexed] GPIO Xmas Tree for
2 # Raspberry Pi by Andrew Gale.
3
4 import RPi.GPIO as GPIO
5 import time
6
7 # The tree connects to the 6 GPIO pins furthest away from the
8 # corner of Raspberry Pi i.e. *physical* pin numbers 21-26 on
9 # the model A or B and 35-40 on the B+.
10
11 # Some Kickstarter supporters opted to receive a 'bi-colour'
12 # LED as their stretch goal reward. This fits in the top
13 # LED position (i.e. LED_0) but actually contains a second
14 # LED that we shall call LED_7
15
16 # Bicolour LED fitted or not?
17 # bicolour_fitted = False # the default is False
18 bicolour_fitted = True # the default is False
19
20 # The time for which each LED is illuminated.
21 # This is the place to tweak the brightness of the bicolour
22 # LEDs by altering their illumination time.
23 illumination_time_bicolour_green = 0.004 # the ON time for the bicolour green LED
24 illumination_time_bicolour_red = 0.004 # the ON time for the bicolour red LED
25 illumination_time_default = 0.001 # the ON time for all the other LEDs
26
27 # The following constants will be configured by tree.setup()
28 # but we will set them to -1 for now.
29 A, B, C, D = -1, -1, -1, -1 # The four Charlieplexing nodes
30 total_illumination_time = -1 # Time for one whole cycle
31
32 # The following code to detect which version of Raspberry Pi
33 # you are using is courtesy of Matt Hawkins at
34 # http://www.raspberrypi-spy.co.uk
35
36 def getrevision():
37 # Extract board revision from cpuinfo file
38 myrevision = "0000"
39 try:
40 f = open('/proc/cpuinfo','r')
41 for line in f:
42 if line[0:8]=='Revision':
43 length=len(line)
44 myrevision = line[11:length-1]
45 f.close()
46 except:
47 myrevision = "0000"
48
49 return myrevision
50
51
52
53 def single_led_on(n):
54 if (A==-1):
55 print "***********************************************"
56 print "** **"
57 print "** ERROR: you MUST call tree.setup() first!! **"
58 print "** **"
59 print "***********************************************"
60 raise Exception('You MUST call tree.setup() first!!')
61
62 # First, set all the nodes to be input (effectively
63 # 'disconnecting' them from the Raspberry Pi)
64 GPIO.setup(A, GPIO.IN)
65 GPIO.setup(B, GPIO.IN)
66 GPIO.setup(C, GPIO.IN)
67 GPIO.setup(D, GPIO.IN)
68 GPIO.setup(A2, GPIO.IN)
69 GPIO.setup(B2, GPIO.IN)
70 GPIO.setup(C2, GPIO.IN)
71 GPIO.setup(D2, GPIO.IN)
72
73 # Now determine which nodes are connected to the anode
74 # and cathode for this LED
75 if (n==1): anode, cathode = C, A
76 elif (n==2): anode, cathode = C, D
77 elif (n==4): anode, cathode = D, C
78 elif (n==8): anode, cathode = D, B
79 elif (n==16): anode, cathode = B, D
80 elif (n==32): anode, cathode = A, B
81 elif (n==64): anode, cathode = B, A
82 elif (n==128): anode, cathode = A, C
83 elif (n==(256+1)): anode, cathode = C2, A2
84 elif (n==(256+2)): anode, cathode = C2, D2
85 elif (n==(256+4)): anode, cathode = D2, C2
86 elif (n==(256+8)): anode, cathode = D2, B2
87 elif (n==(256+16)): anode, cathode = B2, D2
88 elif (n==(256+32)): anode, cathode = A2, B2
89 elif (n==(256+64)): anode, cathode = B2, A2
90 elif (n==(256+128)): anode, cathode = A2, C2
91 else: return # invalid LED number
92
93 # Configure the anode and cathode nodes to be outputs
94 GPIO.setup(anode, GPIO.OUT)
95 GPIO.setup(cathode, GPIO.OUT)
96
97 # Make the anode high (+3.3v) and the cathode low (0v)
98 GPIO.output(anode, GPIO.HIGH)
99 GPIO.output(cathode, GPIO.LOW)
100
101
102 def leds_on_and_wait(leds, wait_time):
103 # This routine is passed an 8-bit value (in the "leds"
104 # parameter) with one bit representing each LED. This routine
105 # checks each bit in turn and, if it's set to '1' then it
106 # turns the LED on for 0.001 seconds (or whatever is defined
107 # in the constants at the top). The whole routine
108 # loops around as many times as it can in the time specified
109 # in the "wait_time" parameter, thereby creating the illusion
110 # that all LEDs are on simultaneously (due to persistence
111 # of vision) when, in reality, only one is on at a time.
112
113 # When used with a bicolour LED at the top of the tree, this
114 # routine is passed a 9-bit value.
115 # Bit 7 is for the red LED in the bicolour LED.
116 # Bit 8 is for the green LED in the bicolour LED.
117 # Bit 0: to maintain compatibility with code for a non-bicolour version of
118 # the tree, if bit 0 is set then we want the bicolour LED to light BOTH LEDs
119 # to mimic the yellow of the non-bicolour version of the tree.
120
121 if (bicolour_fitted):
122 bicolour_leds = 0
123 if (leds & 1):
124 # bit 0 is set, so display bicolour as amber/yellow
125 #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits
126 bicolour_leds |= (128+1) # enable the red and green bicolour LEDs
127 if (leds & 128):
128 # bit 7 is set so display bicolour as red
129 #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits
130 bicolour_leds |= 128 # enable the red bicolour LEDs
131 if (leds & 256):
132 # bit 8 is set so display bicolour as green
133 #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits
134 bicolour_leds |= 1 # enable the green bicolour LEDs
135 if (leds & 2**9):
136 # bit 9 is set, so display second bicolour as amber/yellow
137 #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits
138 bicolour_leds |= (2**15+2**8) # enable the red and green bicolour LEDs
139 if (leds & 2**16):
140 # bit 16 is set so display bicolour as red
141 #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits
142 bicolour_leds |= 2**15 # enable the red bicolour LEDs
143 if (leds & 2*17):
144 # bit 8 is set so display bicolour as green
145 #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits
146 bicolour_leds |= 2**8 # enable the green bicolour LEDs
147 leds = (leds & 0b00111111001111110) # preserve the 6 standard red LED bits
148 leds = leds | bicolour_leds
149 print '{:017b}'.format(leds)
150
151 for j in range(int(wait_time/total_illumination_time)):
152 for i in range(16):
153 single_led_on(leds & (1<<i))
154
155 if (bicolour_fitted and (i==0 or i == 8)):
156 time.sleep(illumination_time_bicolour_green)
157 elif (bicolour_fitted and (i==7 or i == 16)):
158 time.sleep(illumination_time_bicolour_red)
159 else:
160 time.sleep(illumination_time_default)
161
162
163 def all_leds_off():
164 single_led_on(0)
165
166 def setup():
167 global A
168 global B
169 global C
170 global D
171 global A2
172 global B2
173 global C2
174 global D2
175 global total_illumination_time
176
177 GPIO.setmode(GPIO.BCM)
178
179 # choose the correct GPIO pins depending on model
180 revision = getrevision()
181 print "** revision: ", revision
182 if ((revision == "0010") or (revision == "0012")):
183 print "Model B+ or A+"
184 A, B, C, D = 21, 19, 26, 20
185 else:
186 print "Other model, probably Model A or Model B"
187 print "Pi 2"
188 # A, B, C, D = 7, 9, 11, 8
189 A, B, C, D = 15, 3, 4, 14 # near corner
190 A2, B2, C2, D2 = 21, 19, 26, 20 # near USB
191
192
193 if (bicolour_fitted):
194 total_illumination_time = 6 * illumination_time_default
195 total_illumination_time += illumination_time_bicolour_green
196 total_illumination_time += illumination_time_bicolour_red
197 else:
198 total_illumination_time = 8 * illumination_time_default
199
200 #print "total_illumination_time: ", total_illumination_time
201
202 def cleanup():
203 GPIO.cleanup()
204