From 014dc3f191db69e580dfb7c87e968ea66020b26d Mon Sep 17 00:00:00 2001 From: Neil Smith <neil.git@njae.me.uk> Date: Sun, 13 Dec 2015 16:01:30 +0000 Subject: [PATCH] Initial commit of Xmas tree --- .gitignore | 47 ++++++++ xmas_tree/README.txt | 19 +++ xmas_tree/example_1.py | 32 +++++ xmas_tree/example_2.py | 35 ++++++ xmas_tree/example_3.py | 32 +++++ xmas_tree/example_4.py | 35 ++++++ xmas_tree/example_5.py | 42 +++++++ xmas_tree/example_bicolour.py | 36 ++++++ xmas_tree/example_twin.py | 28 +++++ xmas_tree/tree.py | 204 ++++++++++++++++++++++++++++++++ xmas_tree/tree.pyc | Bin 0 -> 3999 bytes xmas_tree/tree2.py | 212 ++++++++++++++++++++++++++++++++++ xmas_tree/tree2.pyc | Bin 0 -> 4340 bytes xmas_tree/twin_random.py | 19 +++ 14 files changed, 741 insertions(+) create mode 100644 .gitignore create mode 100644 xmas_tree/README.txt create mode 100644 xmas_tree/example_1.py create mode 100644 xmas_tree/example_2.py create mode 100644 xmas_tree/example_3.py create mode 100644 xmas_tree/example_4.py create mode 100644 xmas_tree/example_5.py create mode 100644 xmas_tree/example_bicolour.py create mode 100644 xmas_tree/example_twin.py create mode 100644 xmas_tree/tree.py create mode 100644 xmas_tree/tree.pyc create mode 100644 xmas_tree/tree2.py create mode 100644 xmas_tree/tree2.pyc create mode 100644 xmas_tree/twin_random.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3d99462 --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ +*~ + +*.py[cod] + +# C extensions +*.so + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg +lib +lib64 +__pycache__ + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox +nosetests.xml + +# Translations +*.mo + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject + +# IPython +.ipynb* + +# Sublime text +*.sublime-workspace + +# Logs +*.log diff --git a/xmas_tree/README.txt b/xmas_tree/README.txt new file mode 100644 index 0000000..27ea5fa --- /dev/null +++ b/xmas_tree/README.txt @@ -0,0 +1,19 @@ +To get started with your GPIO Xmas Tree for the +Raspberry Pi, type the following at the command prompt: + +sudo python example_1.py + +You can then try the other examples: + +example_1.py : each LED on in turn +example_2.py : several LEDs on at once +example_3.py : one LED off each time, all the others on +example_4.py : all LEDs flashing on and off simultaneously +example_5.py : random LEDs +example_bicolour : an example with the Kickstarter bicolour LED + +For bicolour example, make sure you edit tree.py and set +bicolour_fitted to True. + +Please share your own code! Go to www.pocketmoneytronics.co.uk +or follow us on Twitter @pocketmoneytron diff --git a/xmas_tree/example_1.py b/xmas_tree/example_1.py new file mode 100644 index 0000000..7ea6708 --- /dev/null +++ b/xmas_tree/example_1.py @@ -0,0 +1,32 @@ +import tree + +# Some constants to identify each LED +L0 = 1 +L1 = 2 +L2 = 4 +L3 = 8 +L4 = 16 +L5 = 32 +L6 = 64 +ALL = 1+2+4+8+16+32+64 +NO_LEDS = 0 + +tree.setup() # you must always call setup() first! + +# Pattern: flash each LED in turn + +for i in range(5): # repeat 5 times + tree.leds_on_and_wait(L0, 0.3) # LED 0 on for 0.3 seconds + tree.leds_on_and_wait(L1, 0.3) # LED 1 on for 0.3 seconds + tree.leds_on_and_wait(L2, 0.3) # etc. + tree.leds_on_and_wait(L3, 0.3) + tree.leds_on_and_wait(L4, 0.3) + tree.leds_on_and_wait(L5, 0.3) + tree.leds_on_and_wait(L6, 0.3) + + +tree.all_leds_off() # extinguish all LEDs + +# All done! +tree.cleanup() # call cleanup() at the end + diff --git a/xmas_tree/example_2.py b/xmas_tree/example_2.py new file mode 100644 index 0000000..c8297f6 --- /dev/null +++ b/xmas_tree/example_2.py @@ -0,0 +1,35 @@ +import tree + +# Some constants to identify each LED +L0 = 1 +L1 = 2 +L2 = 4 +L3 = 8 +L4 = 16 +L5 = 32 +L6 = 64 +ALL = 1+2+4+8+16+32+64 +NO_LEDS = 0 + +tree.setup() # you must always call setup() first! + +# Pattern: two or three LEDs are on at the same time. +# Note that each pair is on for 0.4 seconds + +for i in range(7): # repeat the pattern 7 times + tree.leds_on_and_wait(L1+L4, 0.4) # LED 1 and LED 4 + tree.leds_on_and_wait(L5+L3+L0, 0.4) # LEDs 5, 3 and 0 + tree.leds_on_and_wait(L2+L6, 0.4) # LEDs 2 and 6 + tree.leds_on_and_wait(L5+L3+L0, 0.4) # LEDs 5, 3 and 0 + + +tree.all_leds_off() # extinguish all LEDs + +# All done! +tree.cleanup() # call cleanup() at the end + + + + + + diff --git a/xmas_tree/example_3.py b/xmas_tree/example_3.py new file mode 100644 index 0000000..a02222e --- /dev/null +++ b/xmas_tree/example_3.py @@ -0,0 +1,32 @@ +import tree + +# Some constants to identify each LED +L0 = 1 +L1 = 2 +L2 = 4 +L3 = 8 +L4 = 16 +L5 = 32 +L6 = 64 +ALL = 1+2+4+8+16+32+64 +NO_LEDS = 0 + +tree.setup() # you must always call setup() first! + +# Pattern: all LEDs illuminated except for one each time + +for i in range(3): # repeat 3 times + tree.leds_on_and_wait(ALL-L0, 0.5) # all on except for LED 0 + tree.leds_on_and_wait(ALL-L1, 0.5) # all on except for LED 1 + tree.leds_on_and_wait(ALL-L2, 0.5) # etc. + tree.leds_on_and_wait(ALL-L3, 0.5) + tree.leds_on_and_wait(ALL-L4, 0.5) + tree.leds_on_and_wait(ALL-L5, 0.5) + tree.leds_on_and_wait(ALL-L6, 0.5) + + +tree.all_leds_off() # extinguish all LEDs + +# All done! +tree.cleanup() # call cleanup() at the end + diff --git a/xmas_tree/example_4.py b/xmas_tree/example_4.py new file mode 100644 index 0000000..40d5571 --- /dev/null +++ b/xmas_tree/example_4.py @@ -0,0 +1,35 @@ +import tree +import time + +# Some constants to identify each LED +L0 = 1 +L1 = 2 +L2 = 4 +L3 = 8 +L4 = 16 +L5 = 32 +L6 = 64 +ALL = 1+2+4+8+16+32+64 +NO_LEDS = 0 + +tree.setup() # you must always call setup() first! + +# Two slightly different ways of flashing *all* LEDs on and off. + +# Way 1 +for i in range(3): # repeat 3 times + tree.leds_on_and_wait(ALL, 0.5) # all on for 0.5s + tree.leds_on_and_wait(NO_LEDS, 0.5) # all off for 0.5s + +# Way 2 +for i in range(3): # repeat 3 times + tree.leds_on_and_wait(ALL, 0.5) # all on for 0.5s + tree.all_leds_off() # extinguish all LEDs + time.sleep(0.5) # wait for 0.5s + + +tree.all_leds_off() # extinguish all LEDs + +# All done! +tree.cleanup() # call cleanup() at the end + diff --git a/xmas_tree/example_5.py b/xmas_tree/example_5.py new file mode 100644 index 0000000..843ce74 --- /dev/null +++ b/xmas_tree/example_5.py @@ -0,0 +1,42 @@ +import tree +import random + +# Some constants to identify each LED +L0 = 1 +L1 = 2 +L2 = 4 +L3 = 8 +L4 = 16 +L5 = 32 +L6 = 64 +ALL = 1+2+4+8+16+32+64 +NO_LEDS = 0 + +tree.setup() # you must always call setup() first! + +# Two ways of randomly illuminating LEDs (they do the +# same thing but Way 1 is easier to understand whilst +# Way 2 is a shorter piece of code). + +# Way 1 +for i in range(100): # repeat 100 times + random_led = random.randint(0, 6) + if (random_led == 0): tree.leds_on_and_wait(L0, 0.2) # D0 on for 0.2s + elif (random_led == 1): tree.leds_on_and_wait(L1, 0.2) # D1 on for 0.2s + elif (random_led == 2): tree.leds_on_and_wait(L2, 0.2) # D2 on for 0.2s + elif (random_led == 3): tree.leds_on_and_wait(L3, 0.2) # D3 on for 0.2s + elif (random_led == 4): tree.leds_on_and_wait(L4, 0.2) # D4 on for 0.2s + elif (random_led == 5): tree.leds_on_and_wait(L5, 0.2) # D5 on for 0.2s + elif (random_led == 6): tree.leds_on_and_wait(L6, 0.2) # D6 on for 0.2s + +# Way 2 +for i in range(100): # repeat 100 times + random_led = random.randint(0, 6) + tree.leds_on_and_wait(1<<random_led, 0.5) # randomly selected LED on for 0.2s + + +tree.all_leds_off() # extinguish all LEDs + +# All done! +tree.cleanup() # call cleanup() at the end + diff --git a/xmas_tree/example_bicolour.py b/xmas_tree/example_bicolour.py new file mode 100644 index 0000000..4426ffc --- /dev/null +++ b/xmas_tree/example_bicolour.py @@ -0,0 +1,36 @@ +import tree + +# some constants to identify each LED +L1 = 2 +L2 = 4 +L3 = 8 +L4 = 16 +L5 = 32 +L6 = 64 +AMBER = 1 # LED 0 = amber +RED = 128 # LED 0 = red +GREEN = 256 # LED 0 = green +NO_LEDS = 0 +BOTTOM6 = 2+4+8+16+32+64 # the 6 standard red LEDs + +# note that we must tell setup() that we have a bicolour LED +tree.setup() # you must always call setup() first! + +# All the red LEDs will be permanently illuminated and we rotate +# between the various colours for the bicolour LED at the top. +for i in range(7): # repeat 7 times + tree.leds_on_and_wait(BOTTOM6, 0.8) # top LED off + tree.leds_on_and_wait(BOTTOM6 + GREEN, 0.8) # top LED green + tree.leds_on_and_wait(BOTTOM6 + RED, 0.8) # top LED red + tree.leds_on_and_wait(BOTTOM6 + AMBER, 0.8) # top LED amber + + tree.leds_on_and_wait(NO_LEDS, 0.8) # all LEDs off + tree.leds_on_and_wait(GREEN, 0.8) # top LED green + tree.leds_on_and_wait(RED, 0.8) # top LED red + tree.leds_on_and_wait(AMBER, 0.8) # top LED amber + +tree.all_leds_off() # extinguish all LEDs + +# All done! +tree.cleanup() # call cleanup() at the end + diff --git a/xmas_tree/example_twin.py b/xmas_tree/example_twin.py new file mode 100644 index 0000000..2e0afd6 --- /dev/null +++ b/xmas_tree/example_twin.py @@ -0,0 +1,28 @@ +import tree2 + +bottom_right_reds = [tree2.RR1, tree2.RR2, tree2.RR3, tree2.RR4, tree2.RR5, tree2.RR6] +bottom_left_reds = [tree2.LR1, tree2.LR2, tree2.LR3, tree2.LR4, tree2.LR5, tree2.LR6] + +# note that we must tell setup() that we have a bicolour LED +tree2.setup() # you must always call setup() first! + +# All the red LEDs will be permanently illuminated and we rotate +# between the various colours for the bicolour LED at the top. +for i in range(1): # repeat 7 times + tree2.leds_on_and_wait(bottom_right_reds, 0.8) # top LED off + tree2.leds_on_and_wait(bottom_right_reds + [tree2.LBG], 0.8) # top LED green + tree2.leds_on_and_wait(bottom_right_reds + [tree2.LBR], 0.8) # top LED green + tree2.leds_on_and_wait(bottom_right_reds + [tree2.LBA], 0.8) # top LED green + + tree2.leds_on_and_wait([], 0.8) # all LEDs off + + tree2.leds_on_and_wait(bottom_left_reds, 0.8) # top LED off + tree2.leds_on_and_wait(bottom_left_reds + [tree2.RBG], 0.8) # top LED green + tree2.leds_on_and_wait(bottom_left_reds + [tree2.RBR], 0.8) # top LED green + tree2.leds_on_and_wait(bottom_left_reds + [tree2.RBA], 0.8) # top LED green + +tree2.all_leds_off() # extinguish all LEDs + +# All done! +tree2.cleanup() # call cleanup() at the end + diff --git a/xmas_tree/tree.py b/xmas_tree/tree.py new file mode 100644 index 0000000..2f0c6c7 --- /dev/null +++ b/xmas_tree/tree.py @@ -0,0 +1,204 @@ +# Example code for [charlieplexed] GPIO Xmas Tree for +# Raspberry Pi by Andrew Gale. + +import RPi.GPIO as GPIO +import time + +# The tree connects to the 6 GPIO pins furthest away from the +# corner of Raspberry Pi i.e. *physical* pin numbers 21-26 on +# the model A or B and 35-40 on the B+. + +# Some Kickstarter supporters opted to receive a 'bi-colour' +# LED as their stretch goal reward. This fits in the top +# LED position (i.e. LED_0) but actually contains a second +# LED that we shall call LED_7 + +# Bicolour LED fitted or not? +# bicolour_fitted = False # the default is False +bicolour_fitted = True # the default is False + +# The time for which each LED is illuminated. +# This is the place to tweak the brightness of the bicolour +# LEDs by altering their illumination time. +illumination_time_bicolour_green = 0.004 # the ON time for the bicolour green LED +illumination_time_bicolour_red = 0.004 # the ON time for the bicolour red LED +illumination_time_default = 0.001 # the ON time for all the other LEDs + +# The following constants will be configured by tree.setup() +# but we will set them to -1 for now. +A, B, C, D = -1, -1, -1, -1 # The four Charlieplexing nodes +total_illumination_time = -1 # Time for one whole cycle + +# The following code to detect which version of Raspberry Pi +# you are using is courtesy of Matt Hawkins at +# http://www.raspberrypi-spy.co.uk + +def getrevision(): + # Extract board revision from cpuinfo file + myrevision = "0000" + try: + f = open('/proc/cpuinfo','r') + for line in f: + if line[0:8]=='Revision': + length=len(line) + myrevision = line[11:length-1] + f.close() + except: + myrevision = "0000" + + return myrevision + + + +def single_led_on(n): + if (A==-1): + print "***********************************************" + print "** **" + print "** ERROR: you MUST call tree.setup() first!! **" + print "** **" + print "***********************************************" + raise Exception('You MUST call tree.setup() first!!') + + # First, set all the nodes to be input (effectively + # 'disconnecting' them from the Raspberry Pi) + GPIO.setup(A, GPIO.IN) + GPIO.setup(B, GPIO.IN) + GPIO.setup(C, GPIO.IN) + GPIO.setup(D, GPIO.IN) + GPIO.setup(A2, GPIO.IN) + GPIO.setup(B2, GPIO.IN) + GPIO.setup(C2, GPIO.IN) + GPIO.setup(D2, GPIO.IN) + + # Now determine which nodes are connected to the anode + # and cathode for this LED + if (n==1): anode, cathode = C, A + elif (n==2): anode, cathode = C, D + elif (n==4): anode, cathode = D, C + elif (n==8): anode, cathode = D, B + elif (n==16): anode, cathode = B, D + elif (n==32): anode, cathode = A, B + elif (n==64): anode, cathode = B, A + elif (n==128): anode, cathode = A, C + elif (n==(256+1)): anode, cathode = C2, A2 + elif (n==(256+2)): anode, cathode = C2, D2 + elif (n==(256+4)): anode, cathode = D2, C2 + elif (n==(256+8)): anode, cathode = D2, B2 + elif (n==(256+16)): anode, cathode = B2, D2 + elif (n==(256+32)): anode, cathode = A2, B2 + elif (n==(256+64)): anode, cathode = B2, A2 + elif (n==(256+128)): anode, cathode = A2, C2 + else: return # invalid LED number + + # Configure the anode and cathode nodes to be outputs + GPIO.setup(anode, GPIO.OUT) + GPIO.setup(cathode, GPIO.OUT) + + # Make the anode high (+3.3v) and the cathode low (0v) + GPIO.output(anode, GPIO.HIGH) + GPIO.output(cathode, GPIO.LOW) + + +def leds_on_and_wait(leds, wait_time): + # This routine is passed an 8-bit value (in the "leds" + # parameter) with one bit representing each LED. This routine + # checks each bit in turn and, if it's set to '1' then it + # turns the LED on for 0.001 seconds (or whatever is defined + # in the constants at the top). The whole routine + # loops around as many times as it can in the time specified + # in the "wait_time" parameter, thereby creating the illusion + # that all LEDs are on simultaneously (due to persistence + # of vision) when, in reality, only one is on at a time. + + # When used with a bicolour LED at the top of the tree, this + # routine is passed a 9-bit value. + # Bit 7 is for the red LED in the bicolour LED. + # Bit 8 is for the green LED in the bicolour LED. + # Bit 0: to maintain compatibility with code for a non-bicolour version of + # the tree, if bit 0 is set then we want the bicolour LED to light BOTH LEDs + # to mimic the yellow of the non-bicolour version of the tree. + + if (bicolour_fitted): + bicolour_leds = 0 + if (leds & 1): + # bit 0 is set, so display bicolour as amber/yellow + #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits + bicolour_leds |= (128+1) # enable the red and green bicolour LEDs + if (leds & 128): + # bit 7 is set so display bicolour as red + #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits + bicolour_leds |= 128 # enable the red bicolour LEDs + if (leds & 256): + # bit 8 is set so display bicolour as green + #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits + bicolour_leds |= 1 # enable the green bicolour LEDs + if (leds & 2**9): + # bit 9 is set, so display second bicolour as amber/yellow + #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits + bicolour_leds |= (2**15+2**8) # enable the red and green bicolour LEDs + if (leds & 2**16): + # bit 16 is set so display bicolour as red + #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits + bicolour_leds |= 2**15 # enable the red bicolour LEDs + if (leds & 2*17): + # bit 8 is set so display bicolour as green + #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits + bicolour_leds |= 2**8 # enable the green bicolour LEDs + leds = (leds & 0b00111111001111110) # preserve the 6 standard red LED bits + leds = leds | bicolour_leds + print '{:017b}'.format(leds) + + for j in range(int(wait_time/total_illumination_time)): + for i in range(16): + single_led_on(leds & (1<<i)) + + if (bicolour_fitted and (i==0 or i == 8)): + time.sleep(illumination_time_bicolour_green) + elif (bicolour_fitted and (i==7 or i == 16)): + time.sleep(illumination_time_bicolour_red) + else: + time.sleep(illumination_time_default) + + +def all_leds_off(): + single_led_on(0) + +def setup(): + global A + global B + global C + global D + global A2 + global B2 + global C2 + global D2 + global total_illumination_time + + GPIO.setmode(GPIO.BCM) + + # choose the correct GPIO pins depending on model + revision = getrevision() + print "** revision: ", revision + if ((revision == "0010") or (revision == "0012")): + print "Model B+ or A+" + A, B, C, D = 21, 19, 26, 20 + else: + print "Other model, probably Model A or Model B" + print "Pi 2" + # A, B, C, D = 7, 9, 11, 8 + A, B, C, D = 15, 3, 4, 14 # near corner + A2, B2, C2, D2 = 21, 19, 26, 20 # near USB + + + if (bicolour_fitted): + total_illumination_time = 6 * illumination_time_default + total_illumination_time += illumination_time_bicolour_green + total_illumination_time += illumination_time_bicolour_red + else: + total_illumination_time = 8 * illumination_time_default + + #print "total_illumination_time: ", total_illumination_time + +def cleanup(): + GPIO.cleanup() + diff --git a/xmas_tree/tree.pyc b/xmas_tree/tree.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ea2ca6a7c8bb48b29ab31ddcfe36d6cff2c6e0cd GIT binary patch literal 3999 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 literal 0 HcmV?d00001 diff --git a/xmas_tree/tree2.py b/xmas_tree/tree2.py new file mode 100644 index 0000000..15f6f5d --- /dev/null +++ b/xmas_tree/tree2.py @@ -0,0 +1,212 @@ +# Example code for [charlieplexed] GPIO Xmas Tree for +# Raspberry Pi by Andrew Gale. + +import RPi.GPIO as GPIO +import time + +# The tree connects to the 6 GPIO pins furthest away from the +# corner of Raspberry Pi i.e. *physical* pin numbers 21-26 on +# the model A or B and 35-40 on the B+. + +# Some Kickstarter supporters opted to receive a 'bi-colour' +# LED as their stretch goal reward. This fits in the top +# LED position (i.e. LED_0) but actually contains a second +# LED that we shall call LED_7 + +# Bicolour LED fitted or not? +# bicolour_fitted = False # the default is False +bicolour_fitted = True # the default is False + +# The time for which each LED is illuminated. +# This is the place to tweak the brightness of the bicolour +# LEDs by altering their illumination time. +illumination_time_bicolour_green = 0.004 # the ON time for the bicolour green LED +illumination_time_bicolour_red = 0.004 # the ON time for the bicolour red LED +illumination_time_default = 0.001 # the ON time for all the other LEDs + +# The following constants will be configured by tree.setup() +# but we will set them to -1 for now. +A, B, C, D = -1, -1, -1, -1 # The four Charlieplexing nodes +total_illumination_time = -1 # Time for one whole cycle + +RR1 = 1 # Red LEDs on right tree +RR2 = 2 +RR3 = 3 +RR4 = 4 +RR5 = 5 +RR6 = 6 +RBA = 7 # Right bicolour amber +RBG = 8 # Right bicolour green +RBR = 9 # Right bicolour red + +LR1 = 11 # Red LEDs on right tree +LR2 = 12 +LR3 = 13 +LR4 = 14 +LR5 = 15 +LR6 = 16 +LBA = 17 # Right bicolour amber +LBG = 18 # Right bicolour green +LBR = 19 # Right bicolour red + +POSSIBLE_LEDS = [RR1, RR2, RR3, RR4, RR5, RR6, RBG, RBR, + LR1, LR2, LR3, LR4, LR5, LR6, LBG, LBR] + + +# The following code to detect which version of Raspberry Pi +# you are using is courtesy of Matt Hawkins at +# http://www.raspberrypi-spy.co.uk + +def getrevision(): + # Extract board revision from cpuinfo file + myrevision = "0000" + try: + f = open('/proc/cpuinfo','r') + for line in f: + if line[0:8]=='Revision': + length=len(line) + myrevision = line[11:length-1] + f.close() + except: + myrevision = "0000" + + return myrevision + + + +def single_led_on(n): + if (A==-1): + print "***********************************************" + print "** **" + print "** ERROR: you MUST call tree.setup() first!! **" + print "** **" + print "***********************************************" + raise Exception('You MUST call tree.setup() first!!') + + # First, set all the nodes to be input (effectively + # 'disconnecting' them from the Raspberry Pi) + GPIO.setup(A, GPIO.IN) + GPIO.setup(B, GPIO.IN) + GPIO.setup(C, GPIO.IN) + GPIO.setup(D, GPIO.IN) + GPIO.setup(A2, GPIO.IN) + GPIO.setup(B2, GPIO.IN) + GPIO.setup(C2, GPIO.IN) + GPIO.setup(D2, GPIO.IN) + + # Now determine which nodes are connected to the anode + # and cathode for this LED + if (n==RBG): anode, cathode = C, A + elif (n==RR1): anode, cathode = C, D + elif (n==RR2): anode, cathode = D, C + elif (n==RR3): anode, cathode = D, B + elif (n==RR4): anode, cathode = B, D + elif (n==RR5): anode, cathode = A, B + elif (n==RR6): anode, cathode = B, A + elif (n==RBR): anode, cathode = A, C + elif (n==LBG): anode, cathode = C2, A2 + elif (n==LR1): anode, cathode = C2, D2 + elif (n==LR2): anode, cathode = D2, C2 + elif (n==LR3): anode, cathode = D2, B2 + elif (n==LR4): anode, cathode = B2, D2 + elif (n==LR5): anode, cathode = A2, B2 + elif (n==LR6): anode, cathode = B2, A2 + elif (n==LBR): anode, cathode = A2, C2 + else: return # invalid LED number + + # Configure the anode and cathode nodes to be outputs + GPIO.setup(anode, GPIO.OUT) + GPIO.setup(cathode, GPIO.OUT) + + # Make the anode high (+3.3v) and the cathode low (0v) + GPIO.output(anode, GPIO.HIGH) + GPIO.output(cathode, GPIO.LOW) + + +def leds_on_and_wait(leds, wait_time): + # This routine is passed a list of LEDs to illumnate. + # The whole routine + # loops around as many times as it can in the time specified + # in the "wait_time" parameter, thereby creating the illusion + # that all LEDs are on simultaneously (due to persistence + # of vision) when, in reality, only one is on at a time. + + # When used with a bicolour LED at the top of the tree, this + # routine is passed a 9-bit value. + # Bit 7 is for the red LED in the bicolour LED. + # Bit 8 is for the green LED in the bicolour LED. + # Bit 0: to maintain compatibility with code for a non-bicolour version of + # the tree, if bit 0 is set then we want the bicolour LED to light BOTH LEDs + # to mimic the yellow of the non-bicolour version of the tree. + + led_set = set(leds) + if RBA in led_set: + led_set.discard(RBA) + led_set.add(RBG) + led_set.add(RBR) + if LBA in led_set: + led_set.discard(LBA) + led_set.add(LBG) + led_set.add(LBR) + + if led_set & set(POSSIBLE_LEDS): + elapsed = 0 + while elapsed < wait_time: + for i in led_set: + single_led_on(i) + + if (bicolour_fitted and (i == RBG or i == LBG)): + this_wait = illumination_time_bicolour_green + elif (bicolour_fitted and (i == RBR or i == LBR)): + this_wait = illumination_time_bicolour_red + else: + this_wait = illumination_time_default + elapsed += this_wait + time.sleep(this_wait) + else: + all_leds_off() + time.sleep(wait_time) + + +def all_leds_off(): + single_led_on(0) + +def setup(): + global A + global B + global C + global D + global A2 + global B2 + global C2 + global D2 + global total_illumination_time + + GPIO.setmode(GPIO.BCM) + + # choose the correct GPIO pins depending on model + revision = getrevision() + print "** revision: ", revision + if ((revision == "0010") or (revision == "0012")): + print "Model B+ or A+" + A, B, C, D = 21, 19, 26, 20 + else: + print "Other model, probably Model A or Model B" + print "Pi 2" + # A, B, C, D = 7, 9, 11, 8 + A, B, C, D = 15, 3, 4, 14 # near corner + A2, B2, C2, D2 = 21, 19, 26, 20 # near USB + + + if (bicolour_fitted): + total_illumination_time = 6 * illumination_time_default + total_illumination_time += illumination_time_bicolour_green + total_illumination_time += illumination_time_bicolour_red + else: + total_illumination_time = 8 * illumination_time_default + + #print "total_illumination_time: ", total_illumination_time + +def cleanup(): + GPIO.cleanup() + diff --git a/xmas_tree/tree2.pyc b/xmas_tree/tree2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a5468e2bf949eee0ba3adc2e57ee2b44ff7fb6c3 GIT binary patch literal 4340 zcmbtXOLH5?5$;*M2#_Gb_fzCjmK}tSNs5*&Sy9C%NEO8@@KH-TRJP(mt*}FKC2#>@ z7YSJ=bBJ<_56*wcA+9*N<}diHt1mhDkgLn5RHZ8EuXh2^q7qq^1-7@RAM@zx?&(Q< zm(R`q{^aLXik||1KjJs|ks@;Wuc$`!Sdp#TO@nNMbb{<8xs0a-rpaYWhTIwYWs;m8 za<b&)$mxZa(?@QS>^!+Cvir$RlRZFghU@~lJ!B7(n<aaQ+#K1%<o1$1LT(?~qvYnv z9wWD(>~V4j$etj#K=vfLgJe&UJ4E(0xx-}7kUK*5HF8JEo+X_p-A{Uebb<6B=^@f1 zq(@1Qksc>KL3)z(6zOTw*GSLO5%)Pq?il@!$TrCx7i6B?2|=!tJ1NK;<W324gWPFB z-h_Sjir3g+-oN?TKKj=e-#*`Z)c7z)c0cskj^r5t34kO(3Lp)T0q6n90`vm(0ptPt z0R{lDFWw-)5Wp}4*)w#9-q!dHK4riYx*$4pC}iBgt~@j7Lec3eohw@Z<O8}e=$sk6 zdnuady?A0!bB;m<>ND0(2s=aP3GB|qJa_kW4*vu0;4#Y(sRKVxN~vftU(v&JVmn|7 z+aad3%uj$NEH#?->Qc4Q^8CX(k3rP*7({Chv2aWO$_u=@AFUk{MHouDsW-GAqE+KB zmRYUU16{-jVUEGcSu@s_t`9}2=J`5=aarjoJT5Xu0)lDAmX7Nuda2<pot`*BC2VTF z1hBH$I16F@BhAfdM)$ZGj4>c1trBWL<<+q2QxmG6TREeOxngp7*Z2+o&f5&LE3xS< z*ni^z?*M~j2Lp{~%f@G8|5lODItD#XKodw38>V7X>MALHm6W+k>bXkFUM1zOl6o(Z zcvHhZS<63&Ey@!#*pt|Q{68u1^1@3h@G>3VXTs|jo~f9@?6zJ*cmu+_C%jaLw=cYc z@E$7O?n`~%5#FHiLIq28^=5=OB)rc>uRBi?-mvh#6us_Tz9Fn(M0j5*_9u47_B_85 z-l*`t5ngYH_oeX0ghvKD4Xd{GJ{R7&@MeUU?eIe3O$hIf5%P9)`+O+8N#X4qJP~HM z`@AQ-Dd9CluRBjuc+<lBO!T^Q;Q;5Lj2ww07s$*d-{NThKIs|~1W2<TDJDfyb3#IY zMMT!NWV>LA(S_H0Vjc5`KMM<Oo%@!xW8F2+>Me8Y<Gp>e>eOl`f_E{{VXIO6v3ck< zgK&P{WS#3gw_m(cvS_lH<c?LgIMMyns&0gwjU<z7>~8Kz+L8X*G(?-*B3%-=CU9LC zt1I#;MW40kv%VtP%PMU|U+ZT4jp^3Aar;*MeJ}pLAAL)fe9N(ZIo2;*k$ySWFI$m* z*^2bbR-|8!^>;qrmxNevg^gAyOM9@%SqO=%ymJucTV%5+$vS@B)f{}BZk_O$@z+S9 z$oYZiAJufFrrk>2-vZ&70deX~b$$cMVNRx(e#t&6sQ>3pCb&0#tJo$uDHb4Uxx`E3 zl)=%C<Bc6!j=CplYL?*Ne55gjSqcr#!<>P;4N21qNjeQ-Xq~pT(w7A@mm59OU@gQC z>t@mZsJS2~W`a)tg4315?FpZUZ>iH~kX!%cQ@ThZo18~8;QY}18V#NiAJV~d!7~!< zUn4VLq{x2<X{2c=h^0jApCZ;HVus=*4KdEp{Xj5mif;2E9}dvt0vcHC(?8O|(?8IG zKSJT4obWL_GK>U1?7A(7cM&y+cn=3g?5V5bFs>I=ou(@^$91i77PMyD(&f^sH3!OD zpukmjclP!+OXd5O^8NKaYY}9WJCD3-y;g5ED~DbfYBw~Q=GAJg6VG=Lot4l#(Up$W z5$6Cu#4!IusLB0IzEs53hfb>&#RWQ!LcXRs6QC61ECXK-D)qxd$$k<*ph(L2wc~{{ zA29%&9!7!l>6+6BcvM7|C$izO7gV6|8WDxcFB;yjIKC_DzhPPcYf+((!z#}|4xZ?1 z6jWMjm7FoFvWj1>UUF)}$fznb@L($?H2N7~|Ky4VUhv{JW8$(Y-RTPUszS>8DJ%Y& z-v9$qG%h;pRH}dD29L}43P7nl6+6u{Lh;J8+2CN^c));5D7gMzL@!rTs8#n-yK+f2 zC^wBHIVp0|<YdTS#6^NRIe?)T*?duW;cCL$+x!9-3--kkryn80?sq%J3WE7L+&N+a zG0+IleOrp#g$1)+E8aE5E0&jUF1L}D0M^~&{8=+gZ=3a|x%##@$|R}Yy(wVmD}YUR z!eiYuPaymglWXQj&ZF9y87Z$qH|{4$vhc2Fu0+>@1UdmJx+);;$!$VP<d+Q=G2}|| zeck`Afm?@#U=^ok=f*50!b@vg7Rqo7g|h`mwL}={!NL{A!ul+%*+Ly{y$5iIL5Rc< z)<dUOxe~J0`;fZLpa`FlOG4YsT}OPS55o9=<u^cHpx#0v%h52w2hga&$B;3kh7yR2 zoXQ(jNZ`SEYy8U2!8187m@3;2-gXfV-8DwFrX8Ov4<<%ej2{*rn=JmE-#9!X)8qaq zWmOjxB~SLSq_yiUq8gE*tq+(YUbf$C>By)Zn~8Z}x*;3rX956e(1QP2xDi=10Jy_i z%K)96ZJB7!16&7q1K<Y0n*i?ubkezX3r+EcMPMZW<N*sCVPVOyX(rkDd+cnjn*JGl oJV2iVsxO~Tr8&o?lS3-ax$TADODGd+Hj^F9-psy}O=NHU2Q-}eMgRZ+ literal 0 HcmV?d00001 diff --git a/xmas_tree/twin_random.py b/xmas_tree/twin_random.py new file mode 100644 index 0000000..1b4d2b6 --- /dev/null +++ b/xmas_tree/twin_random.py @@ -0,0 +1,19 @@ +import tree2 +import random + +bottom_right_reds = [tree2.RR1, tree2.RR2, tree2.RR3, tree2.RR4, tree2.RR5, tree2.RR6] +bottom_left_reds = [tree2.LR1, tree2.LR2, tree2.LR3, tree2.LR4, tree2.LR5, tree2.LR6] + +# note that we must tell setup() that we have a bicolour LED +tree2.setup() # you must always call setup() first! + +# for _ in range(5): +while True: + leds_on = random.sample(tree2.POSSIBLE_LEDS, random.randint(0, 8)) + tree2.leds_on_and_wait(leds_on, 0.8) + +tree2.all_leds_off() # extinguish all LED + +# All done! +tree2.cleanup() # call cleanup() at the end + -- 2.43.0