Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganization and encapsulation of the main program #10

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
500 changes: 500 additions & 0 deletions Python/coords.txt

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# xmastree2020
My 500 LED xmas tree

treeshow.py - runs the program

xmastrees.py - contains XmasTree (for running the hardware version) and VirtualXmasTree (for on-screen emulation)


user patterns taking a tree as an argument:

* xmaslights - original function (two colors spinning around a moving point)
* spirolight - draws three color waves (RGB) going around the tree at different speeds
* wavesoflight - draws waves of light starting at random points

Xmastree objects are initiated with a path to the file containing led coordinates and they let you set the led color using the set_led_RGB(led_id, RGBcolor) method and update the whole tree using the display() method.
26 changes: 26 additions & 0 deletions spirolight.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import math


# function by pikuch
def spirolight(tree):
"""Draws three color waves (RGB) going around the tree at different speeds"""
# starting angle for each color channel (in radians)
angles = [0.0] * 3
# how quickly the color waves go around the tree
delta_angles = [1/5, 1/7, 1/9]
# maximum intensity of any one colour channel
max_intensity = 100

while True:
for led in range(len(tree.coords)):
rotation = math.atan2(tree.coords[led].y, tree.coords[led].x)
colour = [max_intensity * (math.sin(angles[0] + rotation) + 1) / 2,
max_intensity * (math.sin(angles[1] + rotation) + 1) / 2,
max_intensity * (math.sin(angles[2] + rotation) + 1) / 2]
tree.set_led_RGB(led, colour)

tree.display()

# update angles
for i in range(len(angles)):
angles[i] = math.fmod(angles[i] + delta_angles[i], 2 * math.pi)
21 changes: 21 additions & 0 deletions treeshow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from xmastrees import VirtualXmasTree, XmasTree

# user patterns
from xmaslights import xmaslights
from spirolight import spirolight
from wavesoflight import wavesoflight

def run_lights():
coord_filename = "Python/coords.txt"

# choose the tree to use
# tree = XmasTree(coord_filename)
tree = VirtualXmasTree(coord_filename)

spirolight(tree)
# wavesoflight(tree)
# xmaslights(tree)


if __name__ == "__main__":
run_lights()
64 changes: 64 additions & 0 deletions wavesoflight.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import math
from random import randint


class Wave:
def __init__(self, tree):
self.radius = 0
self.max_radius = 1000
self.max_intensity = 100
self.speed = 6
self.source = randint(0, len(tree.coords))
self.color = [randint(0, self.max_intensity), randint(0, self.max_intensity), randint(0, self.max_intensity)]

def update(self, leds, tree):
self.radius += self.speed
# wave drawing
for led in range(len(leds)):
distance_from_source = math.dist(tree.coords[led], tree.coords[self.source])
if self.radius - self.speed < distance_from_source <= self.radius:
for i in range(3):
if leds[led][i] < self.color[i]:
leds[led][i] = self.color[i]


# function by pikuch
def wavesoflight(tree):
"""Draws waves of light starting at random points"""
# list of waves
waves = [Wave(tree)]
# color persistance (1 = lasts forever)
persistance = 0.99
# time between waves
wave_frequency = 60
timer = wave_frequency
# led colors
leds = [[0, 0, 0]] * len(tree.coords)

while True:
timer -= 1
if timer <= 0:
timer = wave_frequency
# create another wave
waves.append(Wave(tree))

for wave in waves:
wave.update(leds, tree)

# remove old waves
to_remove = []
for wave in waves:
if wave.radius > wave.max_radius:
to_remove.append(wave)
for wave in to_remove:
waves.remove(wave)

# color dimming
for led in range(len(tree.coords)):
leds[led] = [leds[led][0] * persistance, leds[led][1] * persistance, leds[led][2] * persistance]

# writing the new color data
for led in range(len(tree.coords)):
tree.set_led_RGB(led, [int(leds[led][0]), int(leds[led][1]), int(leds[led][2])])

tree.display()
144 changes: 0 additions & 144 deletions xmaslights-spin.py

This file was deleted.

94 changes: 94 additions & 0 deletions xmaslights.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import time
import math

# You are welcome to add any of these:
# import random
# import numpy
# import scipy
# import sys

# If you want to have user changable values, they need to be entered from the command line
# so import sys sys and use sys.argv[0] etc
# some_value = int(sys.argv[0])


def xmaslights(tree):

# VARIOUS SETTINGS

# how much the rotation points moves each time
dinc = 1

# a buffer so it does not hit to extreme top or bottom of the tree
buffer = 200

# pause between cycles (normally zero as it is already quite slow)
slow = 0

# starting angle (in radians)
angle = 0

# how much the angle changes per cycle
inc = 0.1

# if you are turning a lot of lights on at once, keep their brightness down please
colourA = [50, 0, 50] # purple
colourB = [50, 50, 0] # yellow

# INITIALISE SOME VALUES

swap01 = 0
swap02 = 0

# direct it move in
direction = -1

# the starting point on the vertical axis
c = 100

# run forever
while True:

time.sleep(slow)

for led in range(len(tree.coords)):
if math.tan(angle) * tree.coords[led].y <= tree.coords[led].z + c:
tree.set_led_RGB(led, colourA)
else:
tree.set_led_RGB(led, colourB)

# use the display() option as rarely as possible as it takes ages
# do not use display() each time you change a LED but rather wait until you have changed them all
tree.display()

# now we get ready for the next cycle

angle += inc
if angle > 2*math.pi:
angle -= 2*math.pi
swap01 = 0
swap02 = 0

# this is all to keep track of which colour is 'on top'

if angle >= 0.5*math.pi:
if swap01 == 0:
colour_hold = [i for i in colourA]
colourA = [i for i in colourB]
colourB = [i for i in colour_hold]
swap01 = 1

if angle >= 1.5*math.pi:
if swap02 == 0:
colour_hold = [i for i in colourA]
colourA = [i for i in colourB]
colourB = [i for i in colour_hold]
swap02 = 1

# and we move the rotation point
c += direction * dinc

if c <= tree.min_z + buffer:
direction = 1
if c >= tree.max_z - buffer:
direction = -1
Loading