Initial commit of Xmas tree
authorNeil Smith <neil.git@njae.me.uk>
Sun, 13 Dec 2015 16:01:30 +0000 (16:01 +0000)
committerNeil Smith <neil.git@njae.me.uk>
Sun, 13 Dec 2015 16:01:30 +0000 (16:01 +0000)
14 files changed:
.gitignore [new file with mode: 0644]
xmas_tree/README.txt [new file with mode: 0644]
xmas_tree/example_1.py [new file with mode: 0644]
xmas_tree/example_2.py [new file with mode: 0644]
xmas_tree/example_3.py [new file with mode: 0644]
xmas_tree/example_4.py [new file with mode: 0644]
xmas_tree/example_5.py [new file with mode: 0644]
xmas_tree/example_bicolour.py [new file with mode: 0644]
xmas_tree/example_twin.py [new file with mode: 0644]
xmas_tree/tree.py [new file with mode: 0644]
xmas_tree/tree.pyc [new file with mode: 0644]
xmas_tree/tree2.py [new file with mode: 0644]
xmas_tree/tree2.pyc [new file with mode: 0644]
xmas_tree/twin_random.py [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..3d99462
--- /dev/null
@@ -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 (file)
index 0000000..27ea5fa
--- /dev/null
@@ -0,0 +1,19 @@
+To get started with your GPIO Xmas Tree for the\r
+Raspberry Pi, type the following at the command prompt:\r
+\r
+sudo python example_1.py\r
+\r
+You can then try the other examples:\r
+\r
+example_1.py : each LED on in turn\r
+example_2.py : several LEDs on at once\r
+example_3.py : one LED off each time, all the others on\r
+example_4.py : all LEDs flashing on and off simultaneously\r
+example_5.py : random LEDs\r
+example_bicolour : an example with the Kickstarter bicolour LED\r
+\r
+For bicolour example, make sure you edit tree.py and set\r
+bicolour_fitted to True.\r
+\r
+Please share your own code! Go to www.pocketmoneytronics.co.uk\r
+or follow us on Twitter @pocketmoneytron\r
diff --git a/xmas_tree/example_1.py b/xmas_tree/example_1.py
new file mode 100644 (file)
index 0000000..7ea6708
--- /dev/null
@@ -0,0 +1,32 @@
+import tree\r
+\r
+# Some constants to identify each LED\r
+L0 = 1\r
+L1 = 2\r
+L2 = 4\r
+L3 = 8\r
+L4 = 16\r
+L5 = 32\r
+L6 = 64\r
+ALL = 1+2+4+8+16+32+64\r
+NO_LEDS = 0\r
+\r
+tree.setup() # you must always call setup() first!\r
+\r
+# Pattern: flash each LED in turn\r
+\r
+for i in range(5): # repeat 5 times\r
+  tree.leds_on_and_wait(L0, 0.3) # LED 0 on for 0.3 seconds\r
+  tree.leds_on_and_wait(L1, 0.3) # LED 1 on for 0.3 seconds\r
+  tree.leds_on_and_wait(L2, 0.3) # etc.\r
+  tree.leds_on_and_wait(L3, 0.3)\r
+  tree.leds_on_and_wait(L4, 0.3)\r
+  tree.leds_on_and_wait(L5, 0.3)\r
+  tree.leds_on_and_wait(L6, 0.3)\r
+\r
+  \r
+tree.all_leds_off() # extinguish all LEDs\r
+\r
+# All done!\r
+tree.cleanup() # call cleanup() at the end\r
+\r
diff --git a/xmas_tree/example_2.py b/xmas_tree/example_2.py
new file mode 100644 (file)
index 0000000..c8297f6
--- /dev/null
@@ -0,0 +1,35 @@
+import tree\r
+\r
+# Some constants to identify each LED\r
+L0 = 1\r
+L1 = 2\r
+L2 = 4\r
+L3 = 8\r
+L4 = 16\r
+L5 = 32\r
+L6 = 64\r
+ALL = 1+2+4+8+16+32+64\r
+NO_LEDS = 0\r
+\r
+tree.setup() # you must always call setup() first!\r
+\r
+# Pattern: two or three LEDs are on at the same time.\r
+# Note that each pair is on for 0.4 seconds\r
+\r
+for i in range(7): # repeat the pattern 7 times\r
+  tree.leds_on_and_wait(L1+L4, 0.4)      # LED 1 and LED 4\r
+  tree.leds_on_and_wait(L5+L3+L0, 0.4) # LEDs 5, 3 and 0\r
+  tree.leds_on_and_wait(L2+L6, 0.4)      # LEDs 2 and 6\r
+  tree.leds_on_and_wait(L5+L3+L0, 0.4) # LEDs 5, 3 and 0\r
+\r
+  \r
+tree.all_leds_off() # extinguish all LEDs\r
+\r
+# All done!\r
+tree.cleanup() # call cleanup() at the end\r
+\r
+\r
+\r
+\r
+\r
+\r
diff --git a/xmas_tree/example_3.py b/xmas_tree/example_3.py
new file mode 100644 (file)
index 0000000..a02222e
--- /dev/null
@@ -0,0 +1,32 @@
+import tree\r
+\r
+# Some constants to identify each LED\r
+L0 = 1\r
+L1 = 2\r
+L2 = 4\r
+L3 = 8\r
+L4 = 16\r
+L5 = 32\r
+L6 = 64\r
+ALL = 1+2+4+8+16+32+64\r
+NO_LEDS = 0\r
+\r
+tree.setup() # you must always call setup() first!\r
+\r
+# Pattern: all LEDs illuminated except for one each time\r
+\r
+for i in range(3): # repeat 3 times\r
+  tree.leds_on_and_wait(ALL-L0, 0.5) # all on except for LED 0\r
+  tree.leds_on_and_wait(ALL-L1, 0.5) # all on except for LED 1\r
+  tree.leds_on_and_wait(ALL-L2, 0.5) # etc.\r
+  tree.leds_on_and_wait(ALL-L3, 0.5)\r
+  tree.leds_on_and_wait(ALL-L4, 0.5)\r
+  tree.leds_on_and_wait(ALL-L5, 0.5)\r
+  tree.leds_on_and_wait(ALL-L6, 0.5)\r
+\r
+  \r
+tree.all_leds_off() # extinguish all LEDs\r
+\r
+# All done!\r
+tree.cleanup() # call cleanup() at the end\r
+\r
diff --git a/xmas_tree/example_4.py b/xmas_tree/example_4.py
new file mode 100644 (file)
index 0000000..40d5571
--- /dev/null
@@ -0,0 +1,35 @@
+import tree\r
+import time\r
+\r
+# Some constants to identify each LED\r
+L0 = 1\r
+L1 = 2\r
+L2 = 4\r
+L3 = 8\r
+L4 = 16\r
+L5 = 32\r
+L6 = 64\r
+ALL = 1+2+4+8+16+32+64\r
+NO_LEDS = 0\r
+\r
+tree.setup() # you must always call setup() first!\r
+\r
+# Two slightly different ways of flashing *all* LEDs on and off.\r
+\r
+# Way 1\r
+for i in range(3): # repeat 3 times\r
+  tree.leds_on_and_wait(ALL, 0.5)     # all on for 0.5s\r
+  tree.leds_on_and_wait(NO_LEDS, 0.5) # all off for 0.5s\r
+  \r
+# Way 2\r
+for i in range(3): # repeat 3 times\r
+  tree.leds_on_and_wait(ALL, 0.5) # all on for 0.5s\r
+  tree.all_leds_off()             # extinguish all LEDs\r
+  time.sleep(0.5)                 # wait for 0.5s\r
+\r
+  \r
+tree.all_leds_off() # extinguish all LEDs\r
+\r
+# All done!\r
+tree.cleanup() # call cleanup() at the end\r
+\r
diff --git a/xmas_tree/example_5.py b/xmas_tree/example_5.py
new file mode 100644 (file)
index 0000000..843ce74
--- /dev/null
@@ -0,0 +1,42 @@
+import tree\r
+import random\r
+\r
+# Some constants to identify each LED\r
+L0 = 1\r
+L1 = 2\r
+L2 = 4\r
+L3 = 8\r
+L4 = 16\r
+L5 = 32\r
+L6 = 64\r
+ALL = 1+2+4+8+16+32+64\r
+NO_LEDS = 0\r
+\r
+tree.setup() # you must always call setup() first!\r
+\r
+# Two ways of randomly illuminating LEDs (they do the\r
+# same thing but Way 1 is easier to understand whilst\r
+# Way 2 is a shorter piece of code).\r
+\r
+# Way 1\r
+for i in range(100): # repeat 100 times\r
+  random_led = random.randint(0, 6)\r
+  if (random_led == 0):   tree.leds_on_and_wait(L0, 0.2) # D0 on for 0.2s\r
+  elif (random_led == 1): tree.leds_on_and_wait(L1, 0.2) # D1 on for 0.2s\r
+  elif (random_led == 2): tree.leds_on_and_wait(L2, 0.2) # D2 on for 0.2s\r
+  elif (random_led == 3): tree.leds_on_and_wait(L3, 0.2) # D3 on for 0.2s\r
+  elif (random_led == 4): tree.leds_on_and_wait(L4, 0.2) # D4 on for 0.2s\r
+  elif (random_led == 5): tree.leds_on_and_wait(L5, 0.2) # D5 on for 0.2s\r
+  elif (random_led == 6): tree.leds_on_and_wait(L6, 0.2) # D6 on for 0.2s\r
+\r
+# Way 2\r
+for i in range(100): # repeat 100 times\r
+  random_led = random.randint(0, 6)\r
+  tree.leds_on_and_wait(1<<random_led, 0.5) # randomly selected LED on for 0.2s\r
+  \r
+  \r
+tree.all_leds_off() # extinguish all LEDs\r
+\r
+# All done!\r
+tree.cleanup() # call cleanup() at the end\r
+\r
diff --git a/xmas_tree/example_bicolour.py b/xmas_tree/example_bicolour.py
new file mode 100644 (file)
index 0000000..4426ffc
--- /dev/null
@@ -0,0 +1,36 @@
+import tree\r
+\r
+# some constants to identify each LED\r
+L1 = 2\r
+L2 = 4\r
+L3 = 8\r
+L4 = 16\r
+L5 = 32\r
+L6 = 64\r
+AMBER = 1 # LED 0 = amber\r
+RED = 128 # LED 0 = red\r
+GREEN = 256 # LED 0 = green\r
+NO_LEDS = 0\r
+BOTTOM6 = 2+4+8+16+32+64 # the 6 standard red LEDs\r
+\r
+# note that we must tell setup() that we have a bicolour LED\r
+tree.setup() # you must always call setup() first!\r
+\r
+# All the red LEDs will be permanently illuminated and we rotate\r
+# between the various colours for the bicolour LED at the top.\r
+for i in range(7): # repeat 7 times\r
+  tree.leds_on_and_wait(BOTTOM6, 0.8) # top LED off\r
+  tree.leds_on_and_wait(BOTTOM6 + GREEN, 0.8) # top LED green\r
+  tree.leds_on_and_wait(BOTTOM6 + RED,   0.8) # top LED red\r
+  tree.leds_on_and_wait(BOTTOM6 + AMBER, 0.8) # top LED amber\r
+  \r
+  tree.leds_on_and_wait(NO_LEDS, 0.8) # all LEDs off\r
+  tree.leds_on_and_wait(GREEN, 0.8) # top LED green\r
+  tree.leds_on_and_wait(RED,   0.8) # top LED red\r
+  tree.leds_on_and_wait(AMBER, 0.8) # top LED amber\r
+  \r
+tree.all_leds_off() # extinguish all LEDs\r
+\r
+# All done!\r
+tree.cleanup() # call cleanup() at the end\r
+\r
diff --git a/xmas_tree/example_twin.py b/xmas_tree/example_twin.py
new file mode 100644 (file)
index 0000000..2e0afd6
--- /dev/null
@@ -0,0 +1,28 @@
+import tree2\r
+\r
+bottom_right_reds = [tree2.RR1, tree2.RR2, tree2.RR3, tree2.RR4, tree2.RR5, tree2.RR6]\r
+bottom_left_reds = [tree2.LR1, tree2.LR2, tree2.LR3, tree2.LR4, tree2.LR5, tree2.LR6]\r
+\r
+# note that we must tell setup() that we have a bicolour LED\r
+tree2.setup() # you must always call setup() first!\r
+\r
+# All the red LEDs will be permanently illuminated and we rotate\r
+# between the various colours for the bicolour LED at the top.\r
+for i in range(1): # repeat 7 times\r
+  tree2.leds_on_and_wait(bottom_right_reds, 0.8) # top LED off\r
+  tree2.leds_on_and_wait(bottom_right_reds + [tree2.LBG], 0.8) # top LED green\r
+  tree2.leds_on_and_wait(bottom_right_reds + [tree2.LBR], 0.8) # top LED green\r
+  tree2.leds_on_and_wait(bottom_right_reds + [tree2.LBA], 0.8) # top LED green\r
+\r
+  tree2.leds_on_and_wait([], 0.8) # all LEDs off\r
+\r
+  tree2.leds_on_and_wait(bottom_left_reds, 0.8) # top LED off\r
+  tree2.leds_on_and_wait(bottom_left_reds + [tree2.RBG], 0.8) # top LED green\r
+  tree2.leds_on_and_wait(bottom_left_reds + [tree2.RBR], 0.8) # top LED green\r
+  tree2.leds_on_and_wait(bottom_left_reds + [tree2.RBA], 0.8) # top LED green\r
+  \r
+tree2.all_leds_off() # extinguish all LEDs\r
+\r
+# All done!\r
+tree2.cleanup() # call cleanup() at the end\r
+\r
diff --git a/xmas_tree/tree.py b/xmas_tree/tree.py
new file mode 100644 (file)
index 0000000..2f0c6c7
--- /dev/null
@@ -0,0 +1,204 @@
+# Example code for [charlieplexed] GPIO Xmas Tree for \r
+# Raspberry Pi by Andrew Gale.\r
+\r
+import RPi.GPIO as GPIO\r
+import time\r
+\r
+# The tree connects to the 6 GPIO pins furthest away from the\r
+# corner of Raspberry Pi i.e. *physical* pin numbers 21-26 on\r
+# the model A or B and 35-40 on the B+.\r
+\r
+# Some Kickstarter supporters opted to receive a 'bi-colour'\r
+# LED as their stretch goal reward. This fits in the top\r
+# LED position (i.e. LED_0) but actually contains a second\r
+# LED that we shall call LED_7\r
+\r
+# Bicolour LED fitted or not?\r
+# bicolour_fitted = False # the default is False\r
+bicolour_fitted = True # the default is False\r
+\r
+# The time for which each LED is illuminated.\r
+# This is the place to tweak the brightness of the bicolour\r
+# LEDs by altering their illumination time.\r
+illumination_time_bicolour_green = 0.004 # the ON time for the bicolour green LED\r
+illumination_time_bicolour_red = 0.004 # the ON time for the bicolour red LED\r
+illumination_time_default = 0.001 # the ON time for all the other LEDs\r
+\r
+# The following constants will be configured by tree.setup()\r
+# but we will set them to -1 for now.\r
+A, B, C, D = -1, -1, -1, -1  # The four Charlieplexing nodes\r
+total_illumination_time = -1 # Time for one whole cycle\r
+\r
+# The following code to detect which version of Raspberry Pi\r
+# you are using is courtesy of Matt Hawkins at\r
+# http://www.raspberrypi-spy.co.uk\r
+\r
+def getrevision():\r
+  # Extract board revision from cpuinfo file\r
+  myrevision = "0000"\r
+  try:\r
+    f = open('/proc/cpuinfo','r')\r
+    for line in f:\r
+      if line[0:8]=='Revision':\r
+        length=len(line)\r
+        myrevision = line[11:length-1]\r
+    f.close()\r
+  except:\r
+    myrevision = "0000"\r
\r
+  return myrevision\r
+\r
+\r
+\r
+def single_led_on(n):\r
+  if (A==-1):\r
+    print "***********************************************"\r
+    print "**                                           **"\r
+    print "** ERROR: you MUST call tree.setup() first!! **"\r
+    print "**                                           **"\r
+    print "***********************************************"\r
+    raise Exception('You MUST call tree.setup() first!!')\r
+    \r
+  # First, set all the nodes to be input (effectively\r
+  # 'disconnecting' them from the Raspberry Pi)  \r
+  GPIO.setup(A, GPIO.IN)\r
+  GPIO.setup(B, GPIO.IN)\r
+  GPIO.setup(C, GPIO.IN)\r
+  GPIO.setup(D, GPIO.IN)\r
+  GPIO.setup(A2, GPIO.IN)\r
+  GPIO.setup(B2, GPIO.IN)\r
+  GPIO.setup(C2, GPIO.IN)\r
+  GPIO.setup(D2, GPIO.IN)\r
+  \r
+  # Now determine which nodes are connected to the anode\r
+  # and cathode for this LED\r
+  if   (n==1): anode, cathode = C, A\r
+  elif (n==2): anode, cathode = C, D\r
+  elif (n==4): anode, cathode = D, C\r
+  elif (n==8): anode, cathode = D, B\r
+  elif (n==16): anode, cathode = B, D\r
+  elif (n==32): anode, cathode = A, B\r
+  elif (n==64): anode, cathode = B, A\r
+  elif (n==128): anode, cathode = A, C\r
+  elif (n==(256+1)): anode, cathode = C2, A2\r
+  elif (n==(256+2)): anode, cathode = C2, D2\r
+  elif (n==(256+4)): anode, cathode = D2, C2\r
+  elif (n==(256+8)): anode, cathode = D2, B2\r
+  elif (n==(256+16)): anode, cathode = B2, D2\r
+  elif (n==(256+32)): anode, cathode = A2, B2\r
+  elif (n==(256+64)): anode, cathode = B2, A2\r
+  elif (n==(256+128)): anode, cathode = A2, C2\r
+  else: return # invalid LED number\r
+\r
+  # Configure the anode and cathode nodes to be outputs\r
+  GPIO.setup(anode, GPIO.OUT)\r
+  GPIO.setup(cathode, GPIO.OUT)\r
+  \r
+  # Make the anode high (+3.3v) and the cathode low (0v)\r
+  GPIO.output(anode, GPIO.HIGH)\r
+  GPIO.output(cathode, GPIO.LOW)\r
\r
+  \r
+def leds_on_and_wait(leds, wait_time):\r
+  # This routine is passed an 8-bit value (in the "leds"\r
+  # parameter) with one bit representing each LED. This routine\r
+  # checks each bit in turn and, if it's set to '1' then it\r
+  # turns the LED on for 0.001 seconds (or whatever is defined\r
+  # in the constants at the top). The whole routine\r
+  # loops around as many times as it can in the time specified\r
+  # in the "wait_time" parameter, thereby creating the illusion\r
+  # that all LEDs are on simultaneously (due to persistence\r
+  # of vision) when, in reality, only one is on at a time.\r
+  \r
+  # When used with a bicolour LED at the top of the tree, this\r
+  # routine is passed a 9-bit value.\r
+  # Bit 7 is for the red LED in the bicolour LED.\r
+  # Bit 8 is for the green LED in the bicolour LED.\r
+  # Bit 0: to maintain compatibility with code for a non-bicolour version of\r
+  # the tree, if bit 0 is set then we want the bicolour LED to light BOTH LEDs\r
+  # to mimic the yellow of the non-bicolour version of the tree.\r
+  \r
+  if (bicolour_fitted):\r
+    bicolour_leds = 0\r
+    if (leds & 1):\r
+      # bit 0 is set, so display bicolour as amber/yellow\r
+      #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits\r
+      bicolour_leds |= (128+1) # enable the red and green bicolour LEDs\r
+    if (leds & 128):\r
+      # bit 7 is set so display bicolour as red\r
+      #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits\r
+      bicolour_leds |= 128 # enable the red bicolour LEDs\r
+    if (leds & 256):\r
+      # bit 8 is set so display bicolour as green\r
+      #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits\r
+      bicolour_leds |= 1 # enable the green bicolour LEDs\r
+    if (leds & 2**9):\r
+      # bit 9 is set, so display second bicolour as amber/yellow\r
+      #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits\r
+      bicolour_leds |= (2**15+2**8) # enable the red and green bicolour LEDs\r
+    if (leds & 2**16):\r
+      # bit 16 is set so display bicolour as red\r
+      #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits\r
+      bicolour_leds |= 2**15 # enable the red bicolour LEDs\r
+    if (leds & 2*17):\r
+      # bit 8 is set so display bicolour as green\r
+      #leds = (leds & 0b001111110) # preserve the 6 standard red LED bits\r
+      bicolour_leds |= 2**8 # enable the green bicolour LEDs\r
+    leds = (leds & 0b00111111001111110) # preserve the 6 standard red LED bits\r
+    leds = leds | bicolour_leds\r
+  print '{:017b}'.format(leds)\r
+      \r
+  for j in range(int(wait_time/total_illumination_time)):\r
+    for i in range(16):\r
+      single_led_on(leds & (1<<i))\r
+      \r
+      if (bicolour_fitted and (i==0 or i == 8)):\r
+        time.sleep(illumination_time_bicolour_green)\r
+      elif (bicolour_fitted and (i==7 or i == 16)):\r
+        time.sleep(illumination_time_bicolour_red)\r
+      else:\r
+        time.sleep(illumination_time_default)\r
+      \r
+        \r
+def all_leds_off():\r
+  single_led_on(0)\r
+  \r
+def setup():\r
+  global A\r
+  global B\r
+  global C\r
+  global D\r
+  global A2\r
+  global B2\r
+  global C2\r
+  global D2\r
+  global total_illumination_time\r
+  \r
+  GPIO.setmode(GPIO.BCM)\r
+  \r
+  # choose the correct GPIO pins depending on model\r
+  revision = getrevision()\r
+  print "** revision: ", revision\r
+  if ((revision == "0010") or (revision == "0012")):\r
+    print "Model B+ or A+"\r
+    A, B, C, D = 21, 19, 26, 20\r
+  else:\r
+    print "Other model, probably Model A or Model B"\r
+    print "Pi 2"\r
+    # A, B, C, D = 7, 9, 11, 8\r
+    A, B, C, D = 15, 3, 4, 14 # near corner\r
+    A2, B2, C2, D2 = 21, 19, 26, 20 # near USB\r
+\r
+  \r
+  if (bicolour_fitted):\r
+    total_illumination_time = 6 * illumination_time_default\r
+    total_illumination_time += illumination_time_bicolour_green\r
+    total_illumination_time += illumination_time_bicolour_red\r
+  else:\r
+    total_illumination_time = 8 * illumination_time_default\r
+    \r
+  #print "total_illumination_time: ", total_illumination_time\r
+  \r
+def cleanup():\r
+  GPIO.cleanup()\r
+  \r
diff --git a/xmas_tree/tree.pyc b/xmas_tree/tree.pyc
new file mode 100644 (file)
index 0000000..ea2ca6a
Binary files /dev/null and b/xmas_tree/tree.pyc differ
diff --git a/xmas_tree/tree2.py b/xmas_tree/tree2.py
new file mode 100644 (file)
index 0000000..15f6f5d
--- /dev/null
@@ -0,0 +1,212 @@
+# Example code for [charlieplexed] GPIO Xmas Tree for \r
+# Raspberry Pi by Andrew Gale.\r
+\r
+import RPi.GPIO as GPIO\r
+import time\r
+\r
+# The tree connects to the 6 GPIO pins furthest away from the\r
+# corner of Raspberry Pi i.e. *physical* pin numbers 21-26 on\r
+# the model A or B and 35-40 on the B+.\r
+\r
+# Some Kickstarter supporters opted to receive a 'bi-colour'\r
+# LED as their stretch goal reward. This fits in the top\r
+# LED position (i.e. LED_0) but actually contains a second\r
+# LED that we shall call LED_7\r
+\r
+# Bicolour LED fitted or not?\r
+# bicolour_fitted = False # the default is False\r
+bicolour_fitted = True # the default is False\r
+\r
+# The time for which each LED is illuminated.\r
+# This is the place to tweak the brightness of the bicolour\r
+# LEDs by altering their illumination time.\r
+illumination_time_bicolour_green = 0.004 # the ON time for the bicolour green LED\r
+illumination_time_bicolour_red = 0.004 # the ON time for the bicolour red LED\r
+illumination_time_default = 0.001 # the ON time for all the other LEDs\r
+\r
+# The following constants will be configured by tree.setup()\r
+# but we will set them to -1 for now.\r
+A, B, C, D = -1, -1, -1, -1  # The four Charlieplexing nodes\r
+total_illumination_time = -1 # Time for one whole cycle\r
+\r
+RR1 = 1 # Red LEDs on right tree\r
+RR2 = 2\r
+RR3 = 3\r
+RR4 = 4\r
+RR5 = 5\r
+RR6 = 6\r
+RBA = 7 # Right bicolour amber\r
+RBG = 8 # Right bicolour green\r
+RBR = 9 # Right bicolour red\r
+\r
+LR1 = 11 # Red LEDs on right tree\r
+LR2 = 12\r
+LR3 = 13\r
+LR4 = 14\r
+LR5 = 15\r
+LR6 = 16\r
+LBA = 17 # Right bicolour amber\r
+LBG = 18 # Right bicolour green\r
+LBR = 19 # Right bicolour red\r
+\r
+POSSIBLE_LEDS = [RR1, RR2, RR3, RR4, RR5, RR6, RBG, RBR, \r
+                 LR1, LR2, LR3, LR4, LR5, LR6, LBG, LBR]\r
+\r
+\r
+# The following code to detect which version of Raspberry Pi\r
+# you are using is courtesy of Matt Hawkins at\r
+# http://www.raspberrypi-spy.co.uk\r
+\r
+def getrevision():\r
+  # Extract board revision from cpuinfo file\r
+  myrevision = "0000"\r
+  try:\r
+    f = open('/proc/cpuinfo','r')\r
+    for line in f:\r
+      if line[0:8]=='Revision':\r
+        length=len(line)\r
+        myrevision = line[11:length-1]\r
+    f.close()\r
+  except:\r
+    myrevision = "0000"\r
\r
+  return myrevision\r
+\r
+\r
+\r
+def single_led_on(n):\r
+  if (A==-1):\r
+    print "***********************************************"\r
+    print "**                                           **"\r
+    print "** ERROR: you MUST call tree.setup() first!! **"\r
+    print "**                                           **"\r
+    print "***********************************************"\r
+    raise Exception('You MUST call tree.setup() first!!')\r
+    \r
+  # First, set all the nodes to be input (effectively\r
+  # 'disconnecting' them from the Raspberry Pi)  \r
+  GPIO.setup(A, GPIO.IN)\r
+  GPIO.setup(B, GPIO.IN)\r
+  GPIO.setup(C, GPIO.IN)\r
+  GPIO.setup(D, GPIO.IN)\r
+  GPIO.setup(A2, GPIO.IN)\r
+  GPIO.setup(B2, GPIO.IN)\r
+  GPIO.setup(C2, GPIO.IN)\r
+  GPIO.setup(D2, GPIO.IN)\r
+  \r
+  # Now determine which nodes are connected to the anode\r
+  # and cathode for this LED\r
+  if   (n==RBG): anode, cathode = C, A\r
+  elif (n==RR1): anode, cathode = C, D\r
+  elif (n==RR2): anode, cathode = D, C\r
+  elif (n==RR3): anode, cathode = D, B\r
+  elif (n==RR4): anode, cathode = B, D\r
+  elif (n==RR5): anode, cathode = A, B\r
+  elif (n==RR6): anode, cathode = B, A\r
+  elif (n==RBR): anode, cathode = A, C\r
+  elif (n==LBG): anode, cathode = C2, A2\r
+  elif (n==LR1): anode, cathode = C2, D2\r
+  elif (n==LR2): anode, cathode = D2, C2\r
+  elif (n==LR3): anode, cathode = D2, B2\r
+  elif (n==LR4): anode, cathode = B2, D2\r
+  elif (n==LR5): anode, cathode = A2, B2\r
+  elif (n==LR6): anode, cathode = B2, A2\r
+  elif (n==LBR): anode, cathode = A2, C2\r
+  else: return # invalid LED number\r
+\r
+  # Configure the anode and cathode nodes to be outputs\r
+  GPIO.setup(anode, GPIO.OUT)\r
+  GPIO.setup(cathode, GPIO.OUT)\r
+  \r
+  # Make the anode high (+3.3v) and the cathode low (0v)\r
+  GPIO.output(anode, GPIO.HIGH)\r
+  GPIO.output(cathode, GPIO.LOW)\r
\r
+  \r
+def leds_on_and_wait(leds, wait_time):\r
+  # This routine is passed a list of LEDs to illumnate. \r
+  # The whole routine\r
+  # loops around as many times as it can in the time specified\r
+  # in the "wait_time" parameter, thereby creating the illusion\r
+  # that all LEDs are on simultaneously (due to persistence\r
+  # of vision) when, in reality, only one is on at a time.\r
+  \r
+  # When used with a bicolour LED at the top of the tree, this\r
+  # routine is passed a 9-bit value.\r
+  # Bit 7 is for the red LED in the bicolour LED.\r
+  # Bit 8 is for the green LED in the bicolour LED.\r
+  # Bit 0: to maintain compatibility with code for a non-bicolour version of\r
+  # the tree, if bit 0 is set then we want the bicolour LED to light BOTH LEDs\r
+  # to mimic the yellow of the non-bicolour version of the tree.\r
+  \r
+  led_set = set(leds)\r
+  if RBA in led_set:\r
+    led_set.discard(RBA)\r
+    led_set.add(RBG)\r
+    led_set.add(RBR)\r
+  if LBA in led_set:\r
+    led_set.discard(LBA)\r
+    led_set.add(LBG)\r
+    led_set.add(LBR)\r
+\r
+  if led_set & set(POSSIBLE_LEDS):\r
+    elapsed = 0\r
+    while elapsed < wait_time:\r
+      for i in led_set:\r
+        single_led_on(i)\r
+      \r
+        if (bicolour_fitted and (i == RBG or i == LBG)):\r
+          this_wait = illumination_time_bicolour_green\r
+        elif (bicolour_fitted and (i == RBR or i == LBR)):\r
+          this_wait = illumination_time_bicolour_red\r
+        else:\r
+          this_wait = illumination_time_default\r
+        elapsed += this_wait\r
+        time.sleep(this_wait)\r
+  else:\r
+      all_leds_off()\r
+      time.sleep(wait_time)\r
+      \r
+        \r
+def all_leds_off():\r
+  single_led_on(0)\r
+  \r
+def setup():\r
+  global A\r
+  global B\r
+  global C\r
+  global D\r
+  global A2\r
+  global B2\r
+  global C2\r
+  global D2\r
+  global total_illumination_time\r
+  \r
+  GPIO.setmode(GPIO.BCM)\r
+  \r
+  # choose the correct GPIO pins depending on model\r
+  revision = getrevision()\r
+  print "** revision: ", revision\r
+  if ((revision == "0010") or (revision == "0012")):\r
+    print "Model B+ or A+"\r
+    A, B, C, D = 21, 19, 26, 20\r
+  else:\r
+    print "Other model, probably Model A or Model B"\r
+    print "Pi 2"\r
+    # A, B, C, D = 7, 9, 11, 8\r
+    A, B, C, D = 15, 3, 4, 14 # near corner\r
+    A2, B2, C2, D2 = 21, 19, 26, 20 # near USB\r
+\r
+  \r
+  if (bicolour_fitted):\r
+    total_illumination_time = 6 * illumination_time_default\r
+    total_illumination_time += illumination_time_bicolour_green\r
+    total_illumination_time += illumination_time_bicolour_red\r
+  else:\r
+    total_illumination_time = 8 * illumination_time_default\r
+    \r
+  #print "total_illumination_time: ", total_illumination_time\r
+  \r
+def cleanup():\r
+  GPIO.cleanup()\r
+  \r
diff --git a/xmas_tree/tree2.pyc b/xmas_tree/tree2.pyc
new file mode 100644 (file)
index 0000000..a5468e2
Binary files /dev/null and b/xmas_tree/tree2.pyc differ
diff --git a/xmas_tree/twin_random.py b/xmas_tree/twin_random.py
new file mode 100644 (file)
index 0000000..1b4d2b6
--- /dev/null
@@ -0,0 +1,19 @@
+import tree2\r
+import random\r
+\r
+bottom_right_reds = [tree2.RR1, tree2.RR2, tree2.RR3, tree2.RR4, tree2.RR5, tree2.RR6]\r
+bottom_left_reds = [tree2.LR1, tree2.LR2, tree2.LR3, tree2.LR4, tree2.LR5, tree2.LR6]\r
+\r
+# note that we must tell setup() that we have a bicolour LED\r
+tree2.setup() # you must always call setup() first!\r
+\r
+# for _ in range(5):\r
+while True:\r
+  leds_on = random.sample(tree2.POSSIBLE_LEDS, random.randint(0, 8))\r
+  tree2.leds_on_and_wait(leds_on, 0.8)\r
+\r
+tree2.all_leds_off() # extinguish all LED\r
+\r
+# All done!\r
+tree2.cleanup() # call cleanup() at the end\r
+\r