def main(): # Alternate ways of declaring strip: # Only use hardware SPI # print "Data pin GPIO/BCM {0}".format(datapin) # print "Clock pin GPIO/BCM {0}".format(clockpin) print("Opening LED strip with {0} pixels".format(numpixels)) # NOTE: This is not the same as omitting data/clock pin args!!! # strip = Adafruit_DotStar(numpixels, datapin, clockpin, order='gbr') # Use SPI (pins 10=MOSI, 11=SCLK) # strip = Adafruit_DotStar(numpixels, datapin, clockpin, order='grb') # Use SPI (pins 10=MOSI, 11=SCLK) # strip = Adafruit_DotStar(numpixels) # Use SPI (pins 10=MOSI, 11=SCLK) # strip = Adafruit_DotStar(numpixels, order='gbr') # Use SPI (pins 10=MOSI, 11=SCLK) # NOTE: The default color order is BRG (not RGB) strip = Adafruit_DotStar( numpixels, order='rgb'.encode('utf-8')) # Use SPI (pins 10=MOSI, 11=SCLK) strip.begin() # Initialize pins for output strip.setBrightness(brightness) # Limit brightness #strip.setBrightness(127) # Unlimited brightness print("Hit Ctrl-C to end test") try: while True: # scroll_pixels(strip, Color(255, 83, 13), numpixels * 20) # This one pretty much produces the expected results (gamma applied) #scroll_pixels(strip, Color(255, 83, 13, gamma=True), numpixels * 20) #scroll_pixels(strip, rgb_color(255, 0, 0), numpixels * 20) #scroll_pixels(strip, rgb_color(0, 255, 0), numpixels * 20) #scroll_pixels(strip, rgb_color(0, 0, 255), numpixels * 20) #solid_fill(strip, Color(255, 0, 0, gamma=True), iterations=2) #solid_fill(strip, Color(0, 255, 0, gamma=True), iterations=2) #solid_fill(strip, Color(0, 0, 255, gamma=True), iterations=2) wheel_fill(strip, iterations=1) print("Pass complete") except (KeyboardInterrupt, Exception) as ex: print(ex) print("") print("Turning off all lights...") # Not well documented, but this is how you turn # off everything strip.clear() strip.show() strip.close() print("Strip closed")
def main(): # Alternate ways of declaring strip: print("Data pin GPIO/BCM {0}".format(datapin)) print("Clock pin GPIO/BCM {0}".format(clockpin)) print("Opening LED strip with {0} pixels".format(numpixels)) # The default here is SPI at 800 KHz # strip = Adafruit_DotStar(numpixels) # Use SPI (pins 10=MOSI, 11=SCLK by default) # This strip uses the specified pins at 800 KHz #strip = Adafruit_DotStar(numpixels, datapin, clockpin, order='gbr') # Use SPI (pins 10=MOSI, 11=SCLK) strip = Adafruit_DotStar( numpixels, order='gbr'.encode('utf-8')) # Use SPI (pins 10=MOSI, 11=SCLK) # strip = Adafruit_DotStar(numpixels, 32000000) # SPI @ ~32 MHz # strip = Adafruit_DotStar() # SPI, No pixel buffer # strip = Adafruit_DotStar(32000000) # 32 MHz SPI, no pixel buf # See image-pov.py for explanation of no-pixel-buffer use. # Append "order='gbr'" to declaration for proper colors w/older DotStar strips) strip.begin() # Initialize pins for output # strip.setBrightness(64) # Limit brightness to ~1/4 duty cycle strip.setBrightness(brightness) # Limit brightness # Runs 10 LEDs at a time along strip, cycling through red, green and blue. # This requires about 200 mA for all the 'on' pixels + 1 mA per 'off' pixel. print("Hit Ctrl-C to end test") try: while True: random_pixels(strip) run_all_effects(strip) scroll_pixels(strip, numpixels * 20) except (KeyboardInterrupt, Exception) as ex: print(ex) print("") print("Turning off all lights...") # Not well documented, but this is how you turn # off everything strip.clear() strip.show() strip.close() print("Strip closed")
class StripClient(object): def __init__(self, numpixels): self.numpixels = numpixels self.strip = Adafruit_DotStar(numpixels) self.strip.begin() self.strip.setBrightness(64) def clear(self): self.strip.clear() print("clear") def setBrightness(self, value): self.strip.setBrightness(value) self.strip.show() print("setBrightness:", value) def setPixelColor(self, pixel, color): color_value = ((color[0] & 0xFF) << 8) | ( (color[1] & 0xFF) << 16) | (color[2] & 0xFF) self.strip.setPixelColor(pixel, color_value) self.strip.show() print("setPixelColor:", pixel, color) def show(self): self.strip.show() print("show") def getPixelColor(self): self.strip.getPixelColor() print("getPixelColor") def numPixels(self): return self.strip.numPixels() return self.numpixels def getBrightness(self): return self.strip.getBrightness() return 64
ANIMATION_PATH = "/opt/hat_server/animations/" STATUS_FILE = "{}current.status".format(ANIMATION_PATH) hat = Adafruit_DotStar(NUM_PIXELS, DATA_PIN, CLOCK_PIN, order='bgr') hat.begin() hat.setBrightness(16) while True: status = None with open(STATUS_FILE, 'r') as statusfile: status = json.loads(statusfile.read()) if (status['type'] == "off"): hat.clear() hat.show() time.sleep(2) continue annimation = None animation_file = "{}{}.json".format(ANIMATION_PATH, status['name']) with open(animation_file, 'r') as infile: annimation = json.loads(infile.read()) fps = 15 for frame in annimation['frames']: # munge frame array into list of pixels frame_width = len(frame) frame_height = len(frame[0]) pixel_index = 0
def run_strip(mode="off", brightness=255): numpixels = 240 # Number of LEDs in strip print("run_strip inbound mode:", mode) # Here's how to control the strip from any two GPIO pins: datapin = 10 clockpin = 11 strip = Adafruit_DotStar(numpixels, datapin, clockpin) # brightness is an integer from 1 to 255 # mode, in time, should enable other things besides just being full on # strip.begin() # Initialize pins for output # strip.setBrightness(brightness) # Limit brightness to ~1/4 duty cycle # used for mode: comet # head = 0 # Index of first 'on' pixel # tail = -10 # Index of last 'off' pixel color = 0xFFFFFF # 'On' color (starts red) # some control variables for light power on/off easing _pow = 3 _frames = 50 _maxb = 255 # _max_brightness, might change when brightness configuration is enabled if mode == "off": print("run_strip: turn off strip") try: count = 0 const = _maxb**(1 / (_pow * 1.0)) is_turning_off = True strip.begin() while is_turning_off: count += 1 if count == _frames: is_turning_off = False strip.setBrightness(_maxb) # now that ramping is done set # to max configured brightness else: brightness = int(_maxb - (count / (_frames * 1.0) * const)**_pow) strip.setBrightness(brightness) for idx in range(numpixels): strip.setPixelColor(idx, color) strip.show() # Refresh strip time.sleep(1.0 / 50) except KeyboardInterrupt: print("cleaning up") GPIO.cleanup() strip.clear() strip.show() print("done") # try to set color to black/off before turning off to prevent final flash for idx in range(numpixels): strip.setPixelColor(idx, 0x000000) strip.setBrightness(0) # clean up interrupts? # GPIO.cleanup() # strip.clear() strip.show() # print("done") elif mode == "on": print("run_strip: starting strip") try: count = 0 const = _maxb**(1 / (_pow * 1.0)) is_turning_on = True strip.begin() while True: # Loop forever if is_turning_on: count += 1.0 if count == _frames: is_turning_on = False strip.setBrightness( _maxb) # now that ramping is done set # to max configured brightness else: brightness = int( (count / (_frames * 1.0) * const)**_pow) strip.setBrightness(brightness) for idx in range(numpixels): strip.setPixelColor(idx, color) # strip.setPixelColor(head, color) # Turn on 'head' pixel # strip.setPixelColor(tail, 0) # Turn off 'tail' strip.show() # Refresh strip time.sleep(1.0 / 50) # Pause 20 milliseconds (~50 fps) # head += 1 # Advance head position # if(head >= numpixels): # Off end of strip? # head = 0 # Reset to start # color >>= 8 # Red->green->blue->black # if(color == 0): color = 0xFF0000 # If black, reset to red # tail += 1 # Advance tail position # if(tail >= numpixels): tail = 0 # Off end? Reset except KeyboardInterrupt: print("cleaning up") GPIO.cleanup() strip.clear() strip.show() print("done") except SystemError as err: print("SystemError:", err)
for i in range(numpixels): strip.setPixelColor(i, 0, 0, 0) strip.setPixelColor(numpixels - 1, 100, 100, 100) strip.setPixelColor(numpixels - 1, 100, 100, 100) strip.show() print("about to wait") time.sleep(wait) #begin the happenings strip.begin() # Initialize pins for output strip.setBrightness(50) # Limit brightness to ~1/4 duty cycle strip.clear() #print("rainbow") rainbow() #setAllPixels(getColour("orange")) print("testing battery life") while True: strip.clear() time.sleep(1) setAllPixels(getColour("red")) flashLights(0.5) strip.clear() strip.show() time.sleep(10)
class PovFan: def __init__(self): datapin = 10 clockpin = 11 self.column = None self.width = 0 self.sequence = [] self.cur_column = 0 self.images_folder = "" self.next_buffer_index = 0 self.last_push = 0 self.image_start_time = 0 if is_running_on_pi: self.strip = Adafruit_DotStar(0, datapin, clockpin, 18500000) else: self.strip = None def add_image(self, image_path, reverse): if is_running_on_pi == False: # print "add_image" return img = Image.open(image_path).convert("RGB") pixels = img.load() width = img.size[0] height = img.size[1] if (height < STRIP_LENGTH): assert ("trying to load image too small") column = [0 for x in range(width)] for x in range(width): column[x] = bytearray(STRIP_LENGTH * 4) bytess = img.tobytes() for x in range(width): offset = x * 3 multiplier = width * 3 self.strip.prepareBuffer(column[x], bytess, offset, multiplier, reverse) self.sequence.append(column) self.width = width img.close() def disabled_animation(): pass def clear_fan(): pass def loading_animation(): pass #TODO: set sequence length def load_sequence(self, sequence_path, fan_id, seq_size=-1): if is_running_on_pi == False: # print "load_sequence: ", sequence_path, fan_id return start = time.time() path = os.path.join(self.images_folder, 'incoming_images', sequence_path, "fan_" + str(fan_id)) files = sorted(glob.glob(os.path.join(path, "*.png"))) for i in range(len(files)): print "loading image ", i self.add_image(files[i], i % 2) print "loading took ", time.time() - start def transition_image(self, next_image): for i in range(len(self.column)): self.strip.pushBuffer(self.column[i], next_image[i], self.next_buffer_index) self.next_buffer_index = self.next_buffer_index + 1 if self.next_buffer_index / 2 > len(next_image[i]): self.next_buffer_index = 0 print "restart buffer loop" def next_image(self, magnet_synced=False): # check if image have been looping for enough time if time.time() - self.image_start_time > 15: self.next_buffer_index = 0 self.image_start_time = time.time() self.cur_column = (self.cur_column + 1) % len(self.sequence) print "next image is ", self.cur_column self.transition_image(self.sequence[self.cur_column]) def no_magnet_callback(self, timing): timing["lapse_time"] = timing["no_magnet_lapse_time"] timing["last_update"] = time.time() timing["lapses"] = timing["lapses"] + 1 timing["need_swap"] = 0 if timing["lapses"] % 10 == 0: print "MAGNET SENSOR INACTIVE! FALLBACK ESTIMATING SPEED" print "lapse ", timing["lapses"], " refresh count: ", timing[ "refresh_count"] print "lapse time", timing["lapse_time"] timing["refresh_count"] = 0 def play(self, length): if len(self.sequence) == 0: print "No sequence loaded! Cancel play" return if is_running_on_pi == False: return self.strip.begin() end_time = length + time.time() PIXELS_IN_CIRCLE = 2 * self.width self.column = [] for i in range(len(self.sequence[self.cur_column])): r = bytearray(STRIP_LENGTH * 4) r[:] = self.sequence[0][i] self.column.append(r) self.cur_column = 0 self.image_start_time = time.time() timing = { "lapse_time": 0.18, # time to complete lapse "last_update": time.time(), # last frame time "lapses": 0, # number of whole rotations (or every magnet on) "refresh_count": 0, # number of columns showed "need_swap": 0, # track for estimating mid-lapse image swap "max_lapse_time": 0.33, # max time allowed before force swap "use_magnet": True, "no_magnet_lapse_time": 0.2 } print "playing sequence for ", length, "seconds" if is_running_on_pi: def sync_magnet(counter): a = timing def magnet_cbk(m): if not timing["use_magnet"]: return timing["lapse_time"] = m.estimated_rpm() timing["last_update"] = time.time() timing["lapses"] = timing["lapses"] + 1 timing["need_swap"] = 0 if timing["lapses"] % 10 == 0: # print "lapse ", timing["lapses"], " refresh count: ", timing["refresh_count"] # print "lapse time", timing["lapse_time"] timing["refresh_count"] = 0 return magnet_cbk magnet = MagnetButton(16) magnet.when_magnet = sync_magnet(timing) magnet.set_timeout(timing["max_lapse_time"]) while end_time > timing["last_update"]: timing["use_magnet"] = not (magnet.is_not_responding()) if not timing["use_magnet"]: if time.time( ) > timing["last_update"] + timing["no_magnet_lapse_time"]: self.no_magnet_callback(timing) if timing["need_swap"] == 0: self.next_image() timing["need_swap"] = 1 c = int(PIXELS_IN_CIRCLE * (time.time() - timing["last_update"]) / timing["lapse_time"]) # TODO: make this cleaner... if c >= (self.width): if timing["need_swap"] == 1: self.next_image() timing["need_swap"] = 2 ## if overflowing since lapse is longer now c = c % self.width self.strip.show(self.column[c]) timing["refresh_count"] = timing["refresh_count"] + 1 time.sleep(0.0001) magnet.close() else: while end_time > timing["last_update"]: timing["last_update"] = time.time() self.strip.clear() self.strip.close() def stop(self): self.strip.clear() self.strip.close()
if btn() != pin_go: # Button released? strip.show(clearBuf) elif b == 2: # Decrease paint duration if speed_pixel > 0: speed_pixel -= 1 duration = (min_time + time_range * speed_pixel / (num_leds - 1)) strip.setPixelColor(speed_pixel, 0x000080) strip.show() startTime = time.time() while (btn() == 2 and ((time.time() - startTime) < rep_time)): continue strip.clear() strip.show() elif b == 3: # Increase paint duration (up to 10 sec maximum) if speed_pixel < num_leds - 1: speed_pixel += 1 duration = (min_time + time_range * speed_pixel / (num_leds - 1)) strip.setPixelColor(speed_pixel, 0x000080) strip.show() startTime = time.time() while (btn() == 3 and ((time.time() - startTime) < rep_time)): continue strip.clear() strip.show() elif b == 4 and filename != None:
class PovFan: def __init__(self): datapin = 10 clockpin = 11 self.column = None self.width = 0 self.sequence = [] self.cur_column = 0 self.images_folder = "" if is_running_on_pi: self.strip = Adafruit_DotStar(0, datapin, clockpin, 18500000) else: self.strip = None def add_image(self, image1_path, image2_path): if not is_running_on_pi: # print "add_image" return img1 = Image.open(image1_path).convert("RGB") pixels1 = img1.load() width = img1.size[0] height = img1.size[1] img2 = Image.open(image2_path).convert("RGB") pixels2 = img2.load() if (height < STRIP_LENGTH): assert("trying to load image too small") column = [0 for x in range(width*2)] for x in range(width*2): column[x] = bytearray(STRIP_LENGTH * 4) bytess = img1.tobytes() for x in range(width): offset = x * 3 multiplier = width * 3 self.strip.prepareBuffer(column[x], bytess, offset, multiplier, False) bytess = img2.tobytes() for x in range(width): offset = x * 3 multiplier = width * 3 self.strip.prepareBuffer(column[x+width], bytess, offset, multiplier, True) column.reverse() self.sequence.append(column) self.width = width*2 img1.close() img2.close() def disabled_animation(): pass def clear_fan(): pass def loading_animation(): pass #TODO: set sequence length def load_sequence(self, sequence_path, fan_id, seq_size = -1): if is_running_on_pi == False: # print "load_sequence: ", sequence_path, fan_id return start = time.time() path = os.path.join(self.images_folder, 'incoming_images', sequence_path, "fan_"+str(fan_id)) files = sorted( glob.glob( os.path.join(path, "*.png") )) for i in range(len(files)): print "load images ", i, i+1 if i%2 == 0 and i+1 < len(files): self.add_image(files[i], files[i+1]) print "loading took ", time.time() - start def next_image(self, magnet_synced=False): self.cur_column = (self.cur_column + 1) % len(self.sequence) # Make sure that is on even numbered image when hitting magnet if magnet_synced and self.cur_column % 2 == 1: self.cur_column = (self.cur_column + 1) % len(self.sequence) self.column = self.sequence[self.cur_column] # print "showing frame #",self.cur_column def no_magnet_callback(self, timing): timing["lapse_time"] = timing["no_magnet_lapse_time"] timing["last_update"] = time.time() timing["lapses"] = timing["lapses"] + 1 timing["need_swap"] = 0 if timing["lapses"] % 10 == 0: print "MAGNET SENSOR INACTIVE! FALLBACK ESTIMATING SPEED" print "lapse ", timing["lapses"], " refresh count: ", timing["refresh_count"] print "lapse time", timing["lapse_time"] timing["refresh_count"] = 0 def play(self, length): if len(self.sequence) == 0: print "No sequence loaded! Cancel play" return if is_running_on_pi == False: return self.strip.begin() end_time = length + time.time() PIXELS_IN_CIRCLE = self.width angle_offset_pixels = (int) (PHYSICAL_ANGLE_OFFSET * 360.0 / PIXELS_IN_CIRCLE) print "offsting image by " + str(angle_offset_pixels) self.column = self.sequence[self.cur_column] timing = { "lapse_time": 0.18, # time to complete lapse "last_update": time.time(), # last frame time "lapses": 0, # number of whole rotations (or every magnet on) "refresh_count": 0, # number of columns showed "need_swap": 0, # track for estimating mid-lapse image swap "max_lapse_time": 0.33, # max time allowed before force swap "use_magnet": True, "no_magnet_lapse_time": 0.2 } print "playing sequence for ", length, "seconds" if is_running_on_pi: def sync_magnet(counter): a = timing def magnet_cbk(m): if not timing["use_magnet"]: return timing["lapse_time"] = m.estimated_rpm() timing["last_update"] = time.time() timing["lapses"] = timing["lapses"] + 1 timing["need_swap"] = 0 if timing["lapses"] % 10 == 0: print "lapse ", timing["lapses"], " refresh count: ", timing["refresh_count"] print "lapse time", timing["lapse_time"] timing["refresh_count"] = 0 return magnet_cbk magnet = MagnetButton(16) magnet.when_magnet = sync_magnet(timing) magnet.set_timeout(timing["max_lapse_time"]) while end_time > timing["last_update"]: timing["use_magnet"] = not (magnet.is_not_responding()) if not timing["use_magnet"]: if time.time() > timing["last_update"] + timing["no_magnet_lapse_time"]: self.no_magnet_callback(timing) if timing["need_swap"] == 0: self.next_image() timing["need_swap"] = 1 ## Angle_offset_pixels is a temp solutions .... need to fix in actual image c = angle_offset_pixels + int(PIXELS_IN_CIRCLE * (time.time() - timing["last_update"]) / timing["lapse_time"]) # TODO: make this cleaner... if c >= (self.width): # if timing["need_swap"] == 1: # self.next_image() # timing["need_swap"] = 2 ## if overflowing since lapse is longer now c = c % self.width self.strip.show(self.column[c]) timing["refresh_count"] = timing["refresh_count"] + 1 time.sleep(0.0001) magnet.close() else: while end_time > timing["last_update"]: timing["last_update"] = time.time() self.strip.show(bytearray(STRIP_LENGTH * 4)) self.strip.close() def stop(self): self.strip.clear() self.strip.close()