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
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

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