class LedStrip: forward = True numpixels = 80 head = 0 tail = -10 def random_color(self): return random.choice(color_library) def __init__(self, datapin, clockpin, brightness): self.datapin = datapin self.clockpin = clockpin self.strip = Adafruit_DotStar(self.numpixels, self.datapin, self.clockpin, order='bgr') self.strip.begin() self.set_brightness(brightness) self.color = self.random_color() def set_pixel(self, pos, color): r, g, b = toRGB(color) self.strip.setPixelColor(pos, gamma[r], gamma[g], gamma[b]) def set_brightness(self, brightness): self.brightness = clamp(brightness, 0, 255) self.strip.setBrightness(self.brightness) def render(self): self.strip.show()
class LedStrip: forward = True numpixels = 80 head = 0 tail = -10 def random_color(self): return random.choice(colors) def __init__(self, datapin, clockpin): self.datapin = datapin self.clockpin = clockpin self.strip = Adafruit_DotStar(self.numpixels, self.datapin, self.clockpin, order='bgr') self.strip.begin() self.strip.setBrightness(255) self.color = self.random_color() def display_pixel(self, pos, color): self.strip.setPixelColor(pos, color) def render(self): self.strip.show()
def strand_test(): """ Basically the same as the Adafruit stand test """ test_strip = Adafruit_DotStar(ALL_LIGHTS, 12000000, order='bgr') test_strip.begin() test_strip.show() head = 0 # Index of first 'on' pixel tail = -10 # Index of last 'off' pixel color = 0xFF0000 # 'On' color (starts red) counter = ALL_LIGHTS * 3 + 10 while counter > 0: # Loop forever test_strip.setPixelColor(head, color) # Turn on 'head' pixel test_strip.setPixelColor(tail, 0) # Turn off 'tail' test_strip.show() # Refresh strip time.sleep(1.0 / 100) # Pause 20 milliseconds (~50 fps) head += 1 # Advance head position if head >= ALL_LIGHTS: # 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 >= ALL_LIGHTS: tail = 0 # Off end? Reset counter -= 1
def lightshow(): numpixels = 72 # Number of LEDs in strip # Here's how to control the strip from any two GPIO pins: datapin = 23 clockpin = 24 strip = Adafruit_DotStar(numpixels, datapin, clockpin) strip.begin() # Initialize pins for output strip.setBrightness(128) # Limit brightness to ~1/4 duty cycle #First, turn all black offspot = 1 offcolor = 0x000000 while offspot >= 1: strip.setPixelColor(offspot, offcolor) offspot += 1 if offspot == 72: break #set initial spots and colors of Jupiter and moons jupspot = 36 #jupiter position jupcolor = 0xFF8801 #jupiter color iospot = iopos #Io position iocolor = 0x9932cc #Io color eurspot = eurpos #Europa position eurcolor = 0x9932cc #Europa color ganspot = ganpos #Ganymede position gancolor = 0x9932cc #Ganymede color calspot = calpos #Calisto position calcolor = 0x9932cc #Calisto color lastcolor = 0x000000 lastiospot = (iospot - 1) gang = [iospot, eurspot, ganspot, calspot] #list of the four moon positions while True: # Loop forever strip.setBrightness(128) # Limit brightness strip.setPixelColor(jupspot, jupcolor) # Turn on jupiter to orange strip.setPixelColor(gang, 0) #Turn off last plots gang[:] = [x + 1 for x in a] # +=1 for each member of gang strip.setPixelColor(gang, iocolor) # Turn all moons to blue strip.show() # Refresh strip time.sleep(1.0 / 5) if t == now: strip.setBrightness(128) #max brightness time.sleep(3) if (iospot >= numpixels): iospot = 0 if (lastiospot >= numpixels): lastiospot = 0
def strandtest(): #!/usr/bin/python # Simple strand test for Adafruit Dot Star RGB LED strip. # This is a basic diagnostic tool, NOT a graphics demo...helps confirm # correct wiring and tests each pixel's ability to display red, green # and blue and to forward data down the line. By limiting the number # and color of LEDs, it's reasonably safe to power a couple meters off # USB. DON'T try that with other code! import time from dotstar import Adafruit_DotStar numpixels = 72 # Number of LEDs in strip # Here's how to control the strip from any two GPIO pins: datapin = 23 clockpin = 24 strip = Adafruit_DotStar(numpixels, datapin, clockpin) # Alternate ways of declaring strip: # Adafruit_DotStar(npix, dat, clk, 1000000) # Bitbang @ ~1 MHz # Adafruit_DotStar(npix) # Use SPI (pins 10=MOSI, 11=SCLK) # Adafruit_DotStar(npix, 32000000) # SPI @ ~32 MHz # Adafruit_DotStar() # SPI, No pixel buffer # 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 # 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. head = 0 # Index of first 'on' pixel tail = -10 # Index of last 'off' pixel color = 0xFF0000 # 'On' color (starts red) stranditer = 4 strandnum = 0 while strandnum <= stranditer: # Loop forever 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 strandnum += 1
class PhysicalStrip: def __init__(self, numpixels): self._strip = Adafruit_DotStar(numpixels) self._strip.begin() def setPixelColor(self, i, color): self._strip.setPixelColor(i, color) def show(self): self._strip.show()
def main(): # set up audio input... recorder = alsaaudio.PCM(alsaaudio.PCM_CAPTURE) recorder.setchannels(CHANNELS) recorder.setrate(RATE) recorder.setformat(INFORMAT) recorder.setperiodsize(FRAMESIZE) # Set up off button GPIO.setmode(GPIO.BCM) GPIO.setup(23,GPIO.IN,pull_up_down = GPIO.PUD_UP) # Initialize colors of each LED... strip = Adafruit_DotStar(numpixels) strip.begin() for i in range(15): time.sleep(float(1.0/float(i+1))) strip.setBrightness(int(stripBright*(i+1)/15)) strip.setPixelColor(i,colors[i][0],colors[i][1],colors[i][2]) strip.setPixelColor(29-i,colors[29-i][0],colors[29-i][1],colors[29-i][2]) strip.show() time.sleep(1) # MAIN LOOP: i=0 bigtime = 0.0 valsold = [] print "IN MAIN LOOP" try: while True: # Check for off button press on = GPIO.input(23) if on == False: shutdown(strip) # Read music and get magnitudes for FRAMESIZE length Y = getMagnitudes(recorder) if Y != None: # Update LED strip based on magnitudes vals = controlLights(strip,Y,valsold) # Update valsold list which is used by my smoothAvg function # to make a running average of brightnesses rather than actual brightnesses valsold.insert(0,vals) if len(valsold) > 20: valsold.pop() if i % 1000 == 0: print "TIME:",time.time()-bigtime print "ITERATION: ",i bigtime = time.time() i+=1 except KeyboardInterrupt: pass
class LedStrip: forward = True numpixels = 80 head = 0 tail = -10 def random_color(self): return random.choice(colors) def __init__(self, datapin, clockpin): self.datapin = datapin self.clockpin = clockpin self.strip = Adafruit_DotStar(self.numpixels, self.datapin, self.clockpin, order='bgr') self.strip.begin() self.strip.setBrightness(255) self.color = self.random_color() def step(self): if self.forward: if self.head < self.numpixels: self.strip.setPixelColor(self.head, self.color) # Turn on 'head' pixel self.strip.setPixelColor(self.tail, 0) # Turn off 'tail' self.head += 1 self.tail += 1 else: self.color = self.random_color() self.head = 70 self.tail = 80 self.forward = False else: # backwards if self.head >= 0: self.strip.setPixelColor(self.head, self.color) # Turn on 'head' pixel self.strip.setPixelColor(self.tail, 0) # Turn off 'tail' self.head = self.head - 1 self.tail = self.tail - 1 else: self.head = 10 self.tail = 0 self.color = self.random_color() self.forward = True def render(self): self.strip.show()
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 rgbStrip(R, G, B): numpixels = 30; # Number of LEDs in strip # strip = Adafruit_DotStar(numpixels, rgb_strip_datapin, rgb_strip_clockpin) strip = Adafruit_DotStar(numpixels) # SPI @ ~32 MHz strip.begin() # Initialize pins for output strip.setBrightness(64) # Limit brightness to ~1/4 duty cycle # 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. led = 0 # Index of first 'on' pixel while (led != 30): # Loop for each light strip.setPixelColor(led, R, G, B) # Set pin color strip.show() # Refresh strip led += 1 # Advance head position\
def rgbStrip(R, G, B): numpixels = 30 # Number of LEDs in strip # strip = Adafruit_DotStar(numpixels, rgb_strip_datapin, rgb_strip_clockpin) strip = Adafruit_DotStar(numpixels) # SPI @ ~32 MHz strip.begin() # Initialize pins for output strip.setBrightness(64) # Limit brightness to ~1/4 duty cycle # 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. led = 0 # Index of first 'on' pixel while (led != 30): # Loop for each light strip.setPixelColor(led, R, G, B) # Set pin color strip.show() # Refresh strip led += 1 # Advance head position\
class Blinkt: def __init__(self, host): self.host = host self.strip = Adafruit_DotStar(numpixels, datapin, clockpin) self.strip.begin() self.strip.setBrightness(32) green = self.to_rgb(0,255,0) self.show_all(green) def to_rgb(self,r,g,b): return (g << 16) + (r << 8) + b def show(self, colour, pixel): self.strip.setPixelColor(pixel, colour) self.strip.show() def show_all(self, colour): for x in range(0,8): self.strip.setPixelColor(x, colour) self.strip.show()
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")
def rgbStripTest(): numpixels = 30 # Number of LEDs in strip # strip = Adafruit_DotStar(numpixels, datapin, clockpin) strip = Adafruit_DotStar(numpixels, 12000000) # SPI @ ~32 MHz strip.begin() # Initialize pins for output strip.setBrightness(64) # Limit brightness to ~1/4 duty cycle # 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. head = 0 # Index of first 'on' pixel tail = -10 # Index of last 'off' pixel color = 0xFF0000 # 'On' color (starts red) repeat = 0 while True: # Loop forever 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 repeat += 1 if (repeat == 10): rgbStripOff(strip) break
def rgbStripTest(): numpixels = 30; # Number of LEDs in strip # strip = Adafruit_DotStar(numpixels, datapin, clockpin) strip = Adafruit_DotStar(numpixels, 12000000) # SPI @ ~32 MHz strip.begin() # Initialize pins for output strip.setBrightness(64) # Limit brightness to ~1/4 duty cycle # 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. head = 0 # Index of first 'on' pixel tail = -10 # Index of last 'off' pixel color = 0xFF0000 # 'On' color (starts red) repeat = 0 while True: # Loop forever 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 repeat += 1 if(repeat == 10): rgbStripOff(strip) break;
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
while presentation_time > int(time.time() * 1000) - start_time: oled._buffer = buffer_cache[frame_index % 10] oled.display() time.sleep(0.0001) # Set Drive #Command 01 = Sequence run vpos start vpos_steps = int(meta[2]*drive_max_steps) arduinoSerial.write(chr(0x40 + ((vpos_steps >> 12) & 0x3F)) + chr((vpos_steps >> 6) & 0x3F) + chr(vpos_steps & 0x3F)) # Set LED Strips # print(str(frame_index) + ", " + sequence_led_f_www[frame_index]) if sequence_led_f_www[frame_index] is not None: led_f_w.show(sequence_led_f_www[frame_index]) if sequence_led_f_rgb[frame_index] is not None: led_f_rgb.show(sequence_led_f_rgb[frame_index]) if sequence_led_r_www[frame_index] is not None: led_r_w.show(sequence_led_r_www[frame_index]) if sequence_led_r_rgb[frame_index] is not None: led_r_rgb.show(sequence_led_r_rgb[frame_index]) if (log_to_console): print("Frame " + str(frame_index) + " vpos_steps " + str(vpos_steps)) # Sequence End for strip in [led_r_rgb, led_r_w, led_f_rgb, led_f_w]: strip.show(offBytes)
gamma = bytearray(256) for i in range(256): gamma[i] = int(pow(float(i) / 255.0, 2.7) * 255.0 + 0.5) # Allocate list of bytearrays, one for each column of image. # Each pixel REQUIRES 4 bytes (0xFF, B, G, R). print "Allocating..." column = [0 for x in range(width)] for x in range(width): column[x] = bytearray(height * 4) # Convert entire RGB image into column-wise BGR bytearray list. # The image-paint.py example proceeds in R/G/B order because it's counting # on the library to do any necessary conversion. Because we're preparing # data directly for the strip, it's necessary to work in its native order. print "Converting..." for x in range(width): # For each column of image... for y in range(height): # For each pixel in column... value = pixels[x, y] # Read pixel in image y4 = y * 4 # Position in raw buffer column[x][y4] = 0xFF # Pixel start marker column[x][y4 + rOffset] = gamma[value[0]] # Gamma-corrected R column[x][y4 + gOffset] = gamma[value[1]] # Gamma-corrected G column[x][y4 + bOffset] = gamma[value[2]] # Gamma-corrected B print "Displaying..." while True: # Loop forever for x in range(width): # For each column of image... strip.show(column[x]) # Write raw data to strip
strip.begin() # Initialize pins for output # Load image in RGB format and get dimensions: print "Loading..." img = Image.open(filename).convert("RGB") pixels = img.load() width = img.size[0] height = img.size[1] print "%dx%d pixels" % img.size if (height > strip.numPixels()): height = strip.numPixels() # Calculate gamma correction table, makes mid-range colors look 'right': gamma = bytearray(256) for i in range(256): gamma[i] = int(pow(float(i) / 255.0, 2.7) * 255.0 + 0.5) print "Displaying..." while True: # Loop forever for x in range(width): # For each column of image... for y in range(height): # For each pixel in column... value = pixels[x, y] # Read pixel in image strip.setPixelColor( y, # Set pixel in strip gamma[value[0]], # Gamma-corrected red gamma[value[1]], # Gamma-corrected green gamma[value[2]]) # Gamma-corrected blue strip.show() # Refresh LED strip
strip = Adafruit_DotStar(num_pixels, 12000000, order='bgr') # Initialize strip strip.begin() max_brightness = 20 # Save my eyes strip.setBrightness(max_brightness) effect.update_brightness(max_brightness) effect.set_strip(strip, num_pixels) # Set up effects module # Set up button pins GPIO.setmode(GPIO.BCM) for pin in pins.keys(): GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) while True: strip.show() # Update strip # Get button states, and execute appropriate effects for pin, e_id in pins.items(): active = not GPIO.input(pin) is_supplemental = e_id in supplementals # Checks if it is a supplemental effect if is_supplemental: if active and e_id not in effect_id: effect_id.append(e_id) else: effect_id.remove(e_id) elif val: effect_id[0] = e_id print(effect_id)
# Here's how to control the strip from any two GPIO pins: datapin = 23 clockpin = 24 strip = Adafruit_DotStar(numpixels, datapin, clockpin) strip.begin() # Initialize pins for output strip.setBrightness(8) # Limit brightness to ~1/4 duty cycle #turn all leds to black (off) offspot = 1 offcolor = 0x000000 nump = 73 while offspot < nump: strip.setPixelColor(offspot, offcolor) offspot += 1 strip.show() #PYEPHEM PART--GET MOON SPOTS moons = ((ephem.Io(), 'i'), (ephem.Europa(), 'e'), (ephem.Ganymede(), 'g'), (ephem.Callisto(), 'c')) linelen = 72 maxradii = 36 def put(line, character, radii): if abs(radii) > maxradii: return offset = radii / maxradii * (linelen - 1) / 2
# rotate color through rainbow if (color & 0xFF0000) and not (color & 0x0000FF): color = color - 0x010000 # decrement red color = color + 0x000100 # increment green elif(color & 0x00FF00): color = color - 0x000100 # decrement green color = color + 0x000001 # increment blue elif(color & 0x0000FF): color = color - 0x000001 # decrement blue color = color + 0x010000 # increment red # Turn off old dot strip.setPixelColor(dot, 0) # Calculate wave based on time now = time.time() angle = angle_mult * (now - start) amplitude = math.cos(now/mod_period) wave = amplitude * math.cos(angle) #dot = int(math.floor(((wave + 1.0)*(numpixels-1) + 1.0)/2.0)) #dot = int(((wave + 1.0)*(numpixels-1)/2.0 + 1.0)//2.0 + numpixels/2) dot = int(((wave + 1.0)*(numpixels-1) + 1.0)//2.0) # Turn on new dot strip.setPixelColor(dot, color) strip.show() # Refresh strip #time.sleep(1.0 / 50) # Pause 20 milliseconds (~50 fps)
if i == 0: if random.random() < 0.03: s.setPixelColor(p, 0xFFFFFF) return True s.setPixelColor(p, 0) return True else: i = i - 20 if (i < 0): s.setPixelColor(p, 0) return True s.setPixelColor(p, rgb(i)) return True s.setPixelColor(0, 0xFFFFFF) s.show() time.sleep(2) s.setPixelColor(0, 0x000000) s.show() while True: pixel = 0 while pixel < num: twinkle(pixel) pixel = pixel + 1 s.show() time.sleep(1.0 / 20)
class Bartender(MenuDelegate): def __init__(self): self.running = False # set the oled screen height self.screen_width = SCREEN_WIDTH self.screen_height = SCREEN_HEIGHT self.btn1Pin = LEFT_BTN_PIN self.btn2Pin = RIGHT_BTN_PIN # configure interrups for buttons GPIO.setup(self.btn1Pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(self.btn2Pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # configure screen spi_bus = 0 spi_device = 0 #Load the display driver. Attention: 128_64 is the display size. Needed to be changed if different in your setup self.led = disp = Adafruit_SSD1306.SSD1306_128_64( rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000) ) # Change rows & cols values depending on your display dimensions. # Initialize library. self.led.begin() # Clear display. self.led.clear() self.led.display() # Create image buffer. # Make sure to create image with mode '1' for 1-bit color. self.image = Image.new('1', (self.screen_width, self.screen_height)) # Load default font. #self.font = ImageFont.load_default() self.font = ImageFont.truetype(FONTFILE, FONTSIZE) # Create drawing object. self.draw = ImageDraw.Draw(self.image) # load the pump configuration from file self.pump_configuration = Bartender.readPumpConfiguration() for pump in self.pump_configuration.keys(): GPIO.setup(self.pump_configuration[pump]["pin"], GPIO.OUT, initial=GPIO.HIGH) # setup pixels: self.numpixels = NUMBER_NEOPIXELS # Number of LEDs in strip # Here's how to control the strip from any two GPIO pins: datapin = NEOPIXEL_DATA_PIN clockpin = NEOPIXEL_CLOCK_PIN self.strip = Adafruit_DotStar(self.numpixels, datapin, clockpin) #Auskommentiert solange noch kein LED Strip angebracht. #self.strip.begin() # Initialize pins for output self.strip.setBrightness( NEOPIXEL_BRIGHTNESS) # Limit brightness to ~1/4 duty cycle # turn everything off for i in range(0, self.numpixels): self.strip.setPixelColor(i, 0) self.strip.show() print "Done initializing" @staticmethod def readPumpConfiguration(): return json.load(open('pump_config.json')) @staticmethod def writePumpConfiguration(configuration): with open("pump_config.json", "w") as jsonFile: json.dump(configuration, jsonFile) def startInterrupts(self): GPIO.add_event_detect(self.btn1Pin, GPIO.FALLING, callback=self.left_btn, bouncetime=LEFT_PIN_BOUNCE) GPIO.add_event_detect(self.btn2Pin, GPIO.FALLING, callback=self.right_btn, bouncetime=RIGHT_PIN_BOUNCE) def buildMenu(self, drink_list, drink_options): # create a new main menu m = Menu("Main Menu") # add drink options drink_opts = [] for d in drink_list: drink_opts.append( MenuItem('drink', d["name"], {"ingredients": d["ingredients"]})) configuration_menu = Menu("Configure") # add pump configuration options pump_opts = [] for p in sorted(self.pump_configuration.keys()): config = Menu(self.pump_configuration[p]["name"]) # add fluid options for each pump for opt in drink_options: # star the selected option selected = "*" if opt["value"] == self.pump_configuration[p][ "value"] else "" config.addOption( MenuItem('pump_selection', opt["name"], { "key": p, "value": opt["value"], "name": opt["name"] })) # add a back button so the user can return without modifying config.addOption(Back("Back")) config.setParent(configuration_menu) pump_opts.append(config) # add pump menus to the configuration menu configuration_menu.addOptions(pump_opts) # add a back button to the configuration menu configuration_menu.addOption(Back("Back")) # adds an option that cleans all pumps to the configuration menu configuration_menu.addOption(MenuItem('clean', 'Clean')) # adds an option that shuts down the rpi configuration_menu.addOption(MenuItem('shutdown', 'Shutdown')) configuration_menu.setParent(m) m.addOptions(drink_opts) m.addOption(configuration_menu) # create a menu context self.menuContext = MenuContext(m, self) def filterDrinks(self, menu): """ Removes any drinks that can't be handled by the pump configuration """ for i in menu.options: if (i.type == "drink"): i.visible = False ingredients = i.attributes["ingredients"] presentIng = 0 for ing in ingredients.keys(): for p in self.pump_configuration.keys(): if (ing == self.pump_configuration[p]["value"]): presentIng += 1 if (presentIng == len(ingredients.keys())): i.visible = True elif (i.type == "menu"): self.filterDrinks(i) def selectConfigurations(self, menu): """ Adds a selection star to the pump configuration option """ for i in menu.options: if (i.type == "pump_selection"): key = i.attributes["key"] if (self.pump_configuration[key]["value"] == i.attributes["value"]): i.name = "%s %s" % (i.attributes["name"], "*") else: i.name = i.attributes["name"] elif (i.type == "menu"): self.selectConfigurations(i) def prepareForRender(self, menu): self.filterDrinks(menu) self.selectConfigurations(menu) return True def menuItemClicked(self, menuItem): if (menuItem.type == "drink"): self.makeDrink(menuItem.name, menuItem.attributes["ingredients"]) return True elif (menuItem.type == "pump_selection"): self.pump_configuration[menuItem.attributes["key"]][ "value"] = menuItem.attributes["value"] Bartender.writePumpConfiguration(self.pump_configuration) return True elif (menuItem.type == "clean"): self.clean() return True elif (menuItem.type == "shutdown"): self.shutdown() return True return False def clean(self): waitTime = 20 pumpThreads = [] # cancel any button presses while the drink is being made # self.stopInterrupts() self.running = True for pump in self.pump_configuration.keys(): pump_t = threading.Thread( target=self.pour, args=(self.pump_configuration[pump]["pin"], waitTime)) pumpThreads.append(pump_t) # start the pump threads for thread in pumpThreads: thread.start() # start the progress bar self.progressBar(waitTime) # wait for threads to finish for thread in pumpThreads: thread.join() # show the main menu self.menuContext.showMenu() # sleep for a couple seconds to make sure the interrupts don't get triggered time.sleep(2) def shutdown(self): shutdowntext = "Shutdown takes 10 seconds. Bye!" self.led.clear() self.draw.rectangle((0, 0, self.screen_width, self.screen_height), outline=0, fill=0) words_list = WRAPPER.wrap(text=shutdowntext) TextNew = '' for ii in words_list[:-1]: TextNew = TextNew + ii + "\n" TextNew += words_list[-1] self.draw.text((0, 10), str(TextNew), font=self.font, fill=255) self.led.image(self.image) self.led.display() time.sleep(5) #Clean shutdown device subprocess.Popen(['shutdown', '-h', 'now']) def displayMenuItem(self, menuItem): print menuItem.name self.led.clear() self.draw.rectangle((0, 0, self.screen_width, self.screen_height), outline=0, fill=0) words_list = WRAPPER.wrap(text=menuItem.name) MenuItemNew = '' for ii in words_list[:-1]: MenuItemNew = MenuItemNew + ii + "\n" MenuItemNew += words_list[-1] self.draw.text((0, 10), str(MenuItemNew), font=self.font, fill=255) self.led.image(self.image) self.led.display() def cycleLights(self): t = threading.currentThread() head = 0 # Index of first 'on' pixel tail = -10 # Index of last 'off' pixel color = 0xFF0000 # 'On' color (starts red) while getattr(t, "do_run", True): self.strip.setPixelColor(head, color) # Turn on 'head' pixel self.strip.setPixelColor(tail, 0) # Turn off 'tail' self.strip.show() # Refresh strip time.sleep(1.0 / 50) # Pause 20 milliseconds (~50 fps) head += 1 # Advance head position if (head >= self.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 >= self.numpixels): tail = 0 # Off end? Reset def lightsEndingSequence(self): # make lights green for i in range(0, self.numpixels): self.strip.setPixelColor(i, 0xFF0000) self.strip.show() time.sleep(5) # turn lights off for i in range(0, self.numpixels): self.strip.setPixelColor(i, 0) self.strip.show() def pour(self, pin, waitTime): GPIO.output(pin, GPIO.LOW) time.sleep(waitTime) GPIO.output(pin, GPIO.HIGH) def progressBar(self, waitTime): interval = waitTime / 100.0 for x in range(1, 101): self.led.clear() self.draw.rectangle((0, 0, self.screen_width, self.screen_height), outline=0, fill=0) self.updateProgressBar(x, y=35) self.led.image(self.image) self.led.display() time.sleep(interval) def makeDrink(self, drink, ingredients): # cancel any button presses while the drink is being made # self.stopInterrupts() self.running = True # launch a thread to control lighting lightsThread = threading.Thread(target=self.cycleLights) lightsThread.start() # Parse the drink ingredients and spawn threads for pumps maxTime = 0 pumpThreads = [] for ing in ingredients.keys(): for pump in self.pump_configuration.keys(): if ing == self.pump_configuration[pump]["value"]: waitTime = ingredients[ing] * FLOW_RATE if (waitTime > maxTime): maxTime = waitTime pump_t = threading.Thread( target=self.pour, args=(self.pump_configuration[pump]["pin"], waitTime)) pumpThreads.append(pump_t) # start the pump threads for thread in pumpThreads: thread.start() # start the progress bar self.progressBar(maxTime) # wait for threads to finish for thread in pumpThreads: thread.join() # show the main menu self.menuContext.showMenu() # stop the light thread lightsThread.do_run = False lightsThread.join() # show the ending sequence lights self.lightsEndingSequence() # sleep for a couple seconds to make sure the interrupts don't get triggered time.sleep(2) # reenable interrupts # self.startInterrupts() self.running = False def left_btn(self, ctx): print("LEFT_BTN pressed") if not self.running: self.running = True self.menuContext.advance() print("Finished processing button press") self.running = False def right_btn(self, ctx): print("RIGHT_BTN pressed") if not self.running: self.running = True self.menuContext.select() print("Finished processing button press") self.running = 2 print("Starting button timeout") def updateProgressBar(self, percent, x=15, y=15): height = 10 width = self.screen_width - 2 * x for w in range(0, width): self.draw.point((w + x, y), fill=255) self.draw.point((w + x, y + height), fill=255) for h in range(0, height): self.draw.point((x, h + y), fill=255) self.draw.point((self.screen_width - x, h + y), fill=255) for p in range(0, percent): p_loc = int(p / 100.0 * width) self.draw.point((x + p_loc, h + y), fill=255) def run(self): self.startInterrupts() # main loop try: try: while True: letter = raw_input(">") if letter == "l": self.left_btn(False) if letter == "r": self.right_btn(False) except EOFError: while True: time.sleep(0.1) if self.running not in (True, False): self.running -= 0.1 if self.running == 0: self.running = False print("Finished button timeout") except KeyboardInterrupt: GPIO.cleanup() # clean up GPIO on CTRL+C exit GPIO.cleanup() # clean up GPIO on normal exit traceback.print_exc()
# Load image in RGB format and get dimensions: print "Loading..." img = Image.open(filename).convert("RGB") pixels = img.load() width = img.size[0] height = img.size[1] print "%dx%d pixels" % img.size if height > strip.numPixels(): height = strip.numPixels() # Calculate gamma correction table, makes mid-range colors look 'right': gamma = bytearray(256) for i in range(256): gamma[i] = int(pow(float(i) / 255.0, 2.7) * 255.0 + 0.5) print "Displaying..." while True: # Loop forever for x in range(width): # For each column of image... for y in range(height): # For each pixel in column... value = pixels[x, y] # Read pixel in image strip.setPixelColor( y, # Set pixel in strip gamma[value[0]], # Gamma-corrected red gamma[value[1]], # Gamma-corrected green gamma[value[2]], ) # Gamma-corrected blue strip.show() # Refresh LED strip
for i in range(256): gamma[i] = int(pow(float(i) / 255.0, 2.7) * 255.0 + 0.5) def rgb_to_data(red, green, blue): data = [0xFF, 0x00, 0x00, 0x00] data[r_offs] = gamma[red] data[g_offs] = gamma[green] data[b_offs] = gamma[blue] print "Displaying..." solid_time = 1 fade_time = 0.05 print "Off" strip.show(rgb_to_data(0,0,0)) time.sleep(solid_time) print "Red" strip.show(rgb_to_data(255,0,0)) time.sleep(solid_time) print "Green" strip.show(rgb_to_data(0,255,0)) time.sleep(solid_time) print "Blue" strip.show(rgb_to_data(0,255,0)) time.sleep(solid_time) print "Off"
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()
# Paint! if dev is None: # Time-based startTime = time.time() while True: t1 = time.time() elapsed = t1 - startTime if elapsed > duration: break # dither() function is passed a # destination buffer and a float # from 0.0 to 1.0 indicating which # column of the source image to # render. Interpolation happens. lightpaint.dither(ledBuf, elapsed / duration) strip.show(ledBuf) # else: # Encoder-based # # mousepos = 0 # scale = 0.01 / (speed_pixel + 1) # while True: # input = epoll.poll(-1) # Non-blocking # for i in input: # For each pending... # try: # for event in dev.read(): # if(event.type == ecodes.EV_REL and # event.code == ecodes.REL_X): # mousepos += event.value # except: # # If this occurs, usually power settings
class Elevator(threading.Thread): def __init__(self, kill_event, loop_time=1.0 / 60.0): self.status = "INIT" self.q = Queue() self.kill_event = kill_event self.timeout = loop_time self.baudrate = BAUDRATE self.dev = DEVICE self.strip = Adafruit_DotStar(NUMPIXELS, DATAPIN, CLOCKPIN) self.strip.begin() self.strip.setBrightness(255) self.serial = serial.Serial(self.dev) self.serial.baudrate = 115200 # Initial state self.send_elevator_command(ELEVATOR_DOWN) self.status = "DOWN" self.set_lights(OFF) super(Elevator, self).__init__() def onThread(self, function, *args, **kwargs): self.q.put((function, args, kwargs)) def run(self): self.down() while True: if self.kill_event.is_set(): self.close() return try: function, args, kwargs = self.q.get(timeout=self.timeout) function(*args, **kwargs) except Empty: pass def send_elevator_command(self, command): self.serial.flushInput() # avoids that the input buffer overfloats self.serial.write(command) self.serial.flush() def up(self): self.status = "GOING_UP" self.send_elevator_command(ELEVATOR_UP) time.sleep(TIME_UP_S) self.status = "UP" self.set_lights(GREEN) def down(self): self.status = "GOING_DOWN" self.send_elevator_command(ELEVATOR_DOWN) self.set_lights(OFF) time.sleep(TIME_DOWN_S) self.status = "DOWN" time.sleep(TIME_TO_LEAVE_ELEVATOR_S) self.status = "FREE" def close(self): self.serial.close() def set_lights(self, color): for i in range(NUMPIXELS): self.strip.setPixelColor(i, color) if color == OFF: self.strip.setBrightness(0) else: self.strip.setBrightness(255) self.strip.show()
#!/usr/bin/python #Turn off all leds import time from dotstar import Adafruit_DotStar #INITIALIZE AND CLEAR DOTSTAR numpixels = 72 # Number of LEDs in strip # Here's how to control the strip from any two GPIO pins: datapin = 23 clockpin = 24 strip = Adafruit_DotStar(numpixels, datapin, clockpin) strip.begin() # Initialize pins for output strip.setBrightness(32) # Limit brightness to ~1/4 duty cycle #turn all leds to black (off) offspot = 1 offcolor = 0x000000 nump = 73 while offspot < nump: strip.setPixelColor(offspot, offcolor) offspot += 1 strip.show()
gamma = bytearray(256) for i in range(256): gamma[i] = int(pow(float(i) / 255.0, 2.7) * 255.0 + 0.5) # Allocate list of bytearrays, one for each column of image. # Each pixel REQUIRES 4 bytes (0xFF, B, G, R). print "Allocating..." column = [0 for x in range(width)] for x in range(width): column[x] = bytearray(height * 4) # Convert entire RGB image into column-wise BGR bytearray list. # The image-paint.py example proceeds in R/G/B order because it's counting # on the library to do any necessary conversion. Because we're preparing # data directly for the strip, it's necessary to work in its native order. print "Converting..." for x in range(width): # For each column of image... for y in range(height): # For each pixel in column... value = pixels[x, y] # Read pixel in image y4 = y * 4 # Position in raw buffer column[x][y4] = 0xFF # Pixel start marker column[x][y4 + 1] = gamma[value[2]] # Gamma-corrected blue column[x][y4 + 2] = gamma[value[1]] # Gamma-corrected green column[x][y4 + 3] = gamma[value[0]] # Gamma-corrected red print "Displaying..." while True: # Loop forever for x in range(width): # For each column of image... strip.show(column[x]) # Write raw data to strip
import time import random from dotstar import Adafruit_DotStar numpixels = 80 # Number of LEDs in strip # Here's how to control the strip from any two GPIO pins: datapins = [16, 13] clockpin = 27 a = Adafruit_DotStar(numpixels, datapins[0], clockpin, order='bgr') a.begin() a.setBrightness(100) b = Adafruit_DotStar(numpixels, datapins[1], clockpin, order='bgr') b.begin() b.setBrightness(100) a.setPixelColor(68, 0x0000FF) a.show() time.sleep(2) b.setPixelColor(68, 0x0000FF) b.show()
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)
class Bartender(MenuDelegate): def __init__(self): self.running = False # set the oled screen height self.screen_width = SCREEN_WIDTH self.screen_height = SCREEN_HEIGHT self.btn1Pin = LEFT_BTN_PIN self.btn2Pin = RIGHT_BTN_PIN # configure interrups for buttons GPIO.setup(self.btn1Pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(self.btn2Pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # configure screen spi_bus = 0 spi_device = 0 # Very important... This lets py-gaugette 'know' what pins to use in order to reset the display self.led = disp = Adafruit_SSD1306.SSD1306_128_64( rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000) ) # Change rows & cols values depending on your display dimensions. # Initialize library. self.led.begin() # Clear display. self.led.clear() self.led.display() # Create image buffer. # Make sure to create image with mode '1' for 1-bit color. self.image = Image.new('1', (self.screen_width, self.screen_height)) # Load default font. self.font = ImageFont.truetype("FreeMono.ttf", 15) # Create drawing object. self.draw = ImageDraw.Draw(self.image) # load the pump configuration from file self.pump_configuration = Bartender.readPumpConfiguration() for pump in self.pump_configuration.keys(): GPIO.setup(self.pump_configuration[pump]["pin"], GPIO.OUT, initial=GPIO.HIGH) # setup pixels: self.numpixels = NUMBER_NEOPIXELS # Number of LEDs in strip # Here's how to control the strip from any two GPIO pins: datapin = NEOPIXEL_DATA_PIN clockpin = NEOPIXEL_CLOCK_PIN self.strip = Adafruit_DotStar(self.numpixels, datapin, clockpin) self.strip.begin() # Initialize pins for output self.strip.setBrightness( NEOPIXEL_BRIGHTNESS) # Limit brightness to ~1/4 duty cycle # Set the Default or "StandBy Light" to Blue in this case for i in range(0, self.numpixels): self.strip.setPixelColor(i, COLOR_BLUE) self.strip.show() print "Done initializing" @staticmethod def readPumpConfiguration(): return json.load(open('pump_config.json')) @staticmethod def writePumpConfiguration(configuration): with open("pump_config.json", "w") as jsonFile: json.dump(configuration, jsonFile) def startInterrupts(self): self.running = True GPIO.add_event_detect(self.btn1Pin, GPIO.FALLING, callback=self.left_btn, bouncetime=LEFT_PIN_BOUNCE) time.sleep(1) GPIO.add_event_detect(self.btn2Pin, GPIO.FALLING, callback=self.right_btn, bouncetime=RIGHT_PIN_BOUNCE) time.sleep(1) self.running = False def buildMenu(self, drink_list, drink_options): # create a new main menu m = Menu("Main Menu") # add drink options drink_opts = [] for d in drink_list: drink_opts.append( MenuItem('drink', d["name"], {"ingredients": d["ingredients"]})) configuration_menu = Menu("Configure") # add pump configuration options pump_opts = [] for p in sorted(self.pump_configuration.keys()): config = Menu(self.pump_configuration[p]["name"]) # add fluid options for each pump for opt in drink_options: # star the selected option selected = "*" if opt["value"] == self.pump_configuration[p][ "value"] else "" config.addOption( MenuItem('pump_selection', opt["name"], { "key": p, "value": opt["value"], "name": opt["name"] })) # add a back button so the user can return without modifying config.addOption(Back("Back")) config.setParent(configuration_menu) pump_opts.append(config) # add pump menus to the configuration menu configuration_menu.addOptions(pump_opts) # add a back button to the configuration menu configuration_menu.addOption(Back("Back")) # adds an option that cleans all pumps to the configuration menu configuration_menu.addOption(MenuItem('clean', 'Clean')) configuration_menu.setParent(m) m.addOptions(drink_opts) m.addOption(configuration_menu) # create a menu context self.menuContext = MenuContext(m, self) def filterDrinks(self, menu): """ Removes any drinks that can't be handled by the pump configuration """ for i in menu.options: if (i.type == "drink"): i.visible = False ingredients = i.attributes["ingredients"] presentIng = 0 for ing in ingredients.keys(): for p in self.pump_configuration.keys(): if (ing == self.pump_configuration[p]["value"]): presentIng += 1 if (presentIng == len(ingredients.keys())): i.visible = True elif (i.type == "menu"): self.filterDrinks(i) def selectConfigurations(self, menu): """ Adds a selection star to the pump configuration option """ for i in menu.options: if (i.type == "pump_selection"): key = i.attributes["key"] if (self.pump_configuration[key]["value"] == i.attributes["value"]): i.name = "%s %s" % (i.attributes["name"], "*") else: i.name = i.attributes["name"] elif (i.type == "menu"): self.selectConfigurations(i) def prepareForRender(self, menu): self.filterDrinks(menu) self.selectConfigurations(menu) return True def menuItemClicked(self, menuItem): if (menuItem.type == "drink"): self.makeDrink(menuItem.name, menuItem.attributes["ingredients"]) return True elif (menuItem.type == "pump_selection"): self.pump_configuration[menuItem.attributes["key"]][ "value"] = menuItem.attributes["value"] Bartender.writePumpConfiguration(self.pump_configuration) return True elif (menuItem.type == "clean"): self.clean() return True return False def clean(self): waitTime = 20 pumpThreads = [] # cancel any button presses while the drink is being made # self.stopInterrupts() self.running = True for pump in self.pump_configuration.keys(): pump_t = threading.Thread( target=self.pour, args=(self.pump_configuration[pump]["pin"], waitTime)) pumpThreads.append(pump_t) # start the pump threads for thread in pumpThreads: thread.start() # start the progress bar self.progressBar(waitTime) # wait for threads to finish for thread in pumpThreads: thread.join() # show the main menu self.menuContext.showMenu() # sleep for a couple seconds to make sure the interrupts don't get triggered time.sleep(2) def displayMenuItem(self, menuItem): print menuItem.name self.led.clear() self.draw.rectangle((0, 0, self.screen_width, self.screen_height), outline=0, fill=0) self.draw.text((0, 20), str(menuItem.name), font=self.font, fill=255) self.led.image(self.image) self.led.display() def cycleLights(self): t = threading.currentThread() head = 0 # Index of first 'on' pixel tail = -10 # Index of last 'off' pixel color = COLOR_RED # 'On' color (starts red) while getattr(t, "do_run", True): self.strip.setPixelColor(head, color) # Turn on 'head' pixel self.strip.setPixelColor(tail, 0) # Turn off 'tail' self.strip.show() # Refresh strip time.sleep(1.0 / 50) # Pause 20 milliseconds (~50 fps) head += 1 # Advance head position if (head >= self.numpixels): # Off end of strip? head = 0 # Reset to start if (color == COLOR_RED): color = COLOR_YELLOW # if red,set to yellow elif (color == COLOR_YELLOW): color = COLOR_BLUE # if yellow,set to blue elif (color == COLOR_BLUE): color = COLOR_RED # if blue,set back to red tail += 1 # Advance tail position if (tail >= self.numpixels): tail = 0 # Off end? Reset def lightsEndingSequence(self): # make lights yellow for i in range(0, self.numpixels): self.strip.setPixelColor(i, COLOR_YELLOW) self.strip.show() os.system("mpg123 " + DONESOUND) # time.sleep(5) # set them back to blue "StandBy Light" for i in range(0, self.numpixels): self.strip.setPixelColor(i, COLOR_BLUE) self.strip.show() def pour(self, pin, waitTime): GPIO.output(pin, GPIO.LOW) time.sleep(waitTime) GPIO.output(pin, GPIO.HIGH) # other way of dealing with Display delay, Thanks Yogesh def progressBar(self, waitTime): #-with the outcommented version, it updates faster, but there is a limit with the delay, you have to figure out-# #mWaitTime = waitTime - 7 #interval = mWaitTime/ 100.0 #if interval < 0.07: # interval = 0 #for x in range(1, 101): interval = waitTime / 10.0 for x in range(1, 11): self.led.clear() self.draw.rectangle((0, 0, self.screen_width, self.screen_height), outline=0, fill=0) # self.updateProgressBar(x, y=35) self.updateProgressBar(x * 10, y=35) self.led.image(self.image) self.led.display() time.sleep(interval) def makeDrink(self, drink, ingredients): # cancel any button presses while the drink is being made # self.stopInterrupts() os.system("mpg123 " + DRINKME) self.running = True # launch a thread to control lighting lightsThread = threading.Thread(target=self.cycleLights) lightsThread.start() # Parse the drink ingredients and spawn threads for pumps maxTime = 0 pumpThreads = [] for ing in ingredients.keys(): for pump in self.pump_configuration.keys(): if ing == self.pump_configuration[pump]["value"]: vWaitTime = self.pump_configuration[pump]["flowrate"] waitTime = ingredients[ing] * vWaitTime if (waitTime > maxTime): maxTime = waitTime pump_t = threading.Thread( target=self.pour, args=(self.pump_configuration[pump]["pin"], waitTime)) pumpThreads.append(pump_t) # start the pump threads for thread in pumpThreads: thread.start() #Show in Console how long the Pumps running print("The pumps run for", maxTime, "seconds") # start the progress bar self.progressBar(maxTime) # wait for threads to finish for thread in pumpThreads: thread.join() # show the main menu self.menuContext.showMenu() # stop the light thread lightsThread.do_run = False lightsThread.join() # show the ending sequence lights self.lightsEndingSequence() # sleep for a couple seconds to make sure the interrupts don't get triggered # time.sleep(2); # reenable interrupts # self.startInterrupts() self.running = False def left_btn(self, ctx): print("LEFT_BTN pressed") if not self.running: self.running = True self.menuContext.advance() print("Finished processing button press") self.running = False def right_btn(self, ctx): print("RIGHT_BTN pressed") if not self.running: self.running = True self.menuContext.select() print("Finished processing button press") self.running = 2 print("Starting button timeout") def updateProgressBar(self, percent, x=15, y=15): height = 25 width = self.screen_width - 2 * x for w in range(0, width): self.draw.point((w + x, y), fill=255) self.draw.point((w + x, y + height), fill=255) for h in range(0, height): self.draw.point((x, h + y), fill=255) self.draw.point((self.screen_width - x, h + y), fill=255) for p in range(0, percent): p_loc = int(p / 100.0 * width) self.draw.point((x + p_loc, h + y), fill=255) def run(self): self.startInterrupts() # main loop try: try: while True: letter = raw_input(">") if letter == "l": self.left_btn(False) if letter == "r": self.right_btn(False) except EOFError: while True: time.sleep(0.1) if self.running not in (True, False): self.running -= 0.1 if self.running == 0: self.running = False print("Finished button timeout") except KeyboardInterrupt: GPIO.cleanup() # clean up GPIO on CTRL+C exit GPIO.cleanup() # clean up GPIO on normal exit traceback.print_exc()
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 for y in range(frame_height - 1, -1, -1):
print("Displaying...") count = [0, 0.2, 0] def sync_magnet(counter): a = counter def magnet_cbk(m): a[0] = 0 a[1] = m.estimated_rpm() a[2] = time.time() return magnet_cbk magnet = MagnetButton(27) magnet.when_magnet = sync_magnet(count) while True: # Loop forever last_update = time.time() while (count[0] < width): c = int(width * (time.time() - count[2]) / count[1]) if c >= width: c = 0 strip.show(column[c]) # count[0] = count[0] + 1 last_update = time.time() # for x in range(width): # For each column of image... # strip.show(column[width-x-1]) # Write raw data to strip
if dev is None: # Time-based startTime = time.time() while True: t1 = time.time() elapsed = t1 - startTime if elapsed > duration: break # dither() function is passed a # destination buffer and a float # from 0.0 to 1.0 indicating which # column of the source image to # render. Interpolation happens. lightpaint.dither(ledBuf, elapsed / duration) strip.show(ledBuf) else: # Encoder-based mousepos = 0 scale = 0.01 / (speed_pixel + 1) while True: input = epoll.poll(-1) # Non-blocking for i in input: # For each pending... try: for event in dev.read(): if(event.type == ecodes.EV_REL and event.code == ecodes.REL_X): mousepos += event.value except: # If this occurs, usually power settings
16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68, 69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89, 90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 109, 110, 112, 114, 115, 117, 119, 120, 122, 124, 126, 127, 129, 131, 133, 135, 137, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 167, 169, 171, 173, 175, 177, 180, 182, 184, 186, 189, 191, 193, 196, 198, 200, 203, 205, 208, 210, 213, 215, 218, 220, 223, 225, 228, 231, 233, 236, 239, 241, 244, 247, 249, 252, 255 ] arr = np.zeros(numpixels * 4, dtype=np.float32) # arr = np.zeros(numpixels*4, dtype=np.byte) arr[0:-1:4] = 0xff strip.show(arr.tostring()) t = np.arange(0, numpixels, dtype=np.float64) A = 0.05 w = 0.5 for phase in np.arange(0, 1, 0.0005): r, g, b = colorsys.hsv_to_rgb(phase, 1, 1) arr[1:-1:4] = gamma[int( 255 * b)] * (A * np.sin(-2 * w * t + 2 * np.pi * phase) + A) / 2 arr[2:-1:4] = gamma[int( 255 * g)] * (A * np.sin(w * t + 2 * np.pi * phase) + A) / 2 arr[3:3 + numpixels * 4:4] = gamma[int( 255 * r)] * (A * np.sin(w * t + 9 * phase) + A) / 2
print hue print sat print val print "" h = scale(hue, 0, 255, 0, 1) s = scale(sat, 0, 255, 0, 1) v = scale(val, 0, 255, 0, 1) r,g,b = colorsys.hsv_to_rgb(h,s,v) print r print g print b print "" r = int(scale(r, 0, 1, 0, 255)) g = int(scale(g, 0, 1, 0, 255)) b = int(scale(b, 0, 1, 0, 255)) print r print g print b color = strip.Color(g,r,b) for i in range(numpixels): strip.setPixelColor(i, color) strip.show()
# Each pixel REQUIRES 4 bytes (0xFF, B, G, R). print( "Allocating...") column = [0 for x in range(width)] for x in range(width): column[x] = bytearray(height * 4) # Convert entire RGB image into column-wise BGR bytearray list. # The image-paint.py example proceeds in R/G/B order because it's counting # on the library to do any necessary conversion. Because we're preparing # data directly for the strip, it's necessary to work in its native order. print( "Converting...") for x in range(width): # For each column of image... for y in range(height): # For each pixel in column... value = pixels[x, y] # Read pixel in image y4 = y * 4 # Position in raw buffer column[x][y4] = 0xFF # Pixel start marker column[x][y4 + rOffset] = gamma[value[0]] # Gamma-corrected R column[x][y4 + gOffset] = gamma[value[1]] # Gamma-corrected G column[x][y4 + bOffset] = gamma[value[2]] # Gamma-corrected B print( "Displaying...") while True: # Loop forever for x in range(width): # For each column of image... lt = time.time() strip.show(column[width-x-1]) # Write raw data to strip print "after ", width, " shows, ", time.time() - lt, "passed (", 4000/(time.time() - lt), " hz)"
class povThread(threading.Thread): def __init__(self, FreqAverage=5, Path="pov/", start=""): threading.Thread.__init__(self) self.datapin = 2 # GPIO-Numbering! self.clockpin = 3 # GPIO-Numbering! self.strip = Adafruit_DotStar(0, self.datapin, self.clockpin) # Notice the number of LEDs is set to 0. This is on purpose...we're asking # the DotStar module to NOT allocate any memory for this strip...we'll handle # our own allocation and conversion and will feed it 'raw' data. self.strip.begin() # Initialize pins for output self.empty_array=bytearray(60*4) # prepare empty-flash for x in range(60): self.empty_array[x*4]=0xFF self.empty_array[x*4+1]=0x00 self.empty_array[x*4+2]=0x00 self.empty_array[x*4+3]=0x00 self.povPath=Path self.povFile = start self.size=[0,0] self.FAverage=FreqAverage self.actPeriod=0 self.freq = get_freq.freqThread(NAverage=self.FAverage) # initialize frequency-thread self.running=False # is Thread displaying a pov-File? self.NEWrunning=False # want to stop and start new? self.active=True # is Thread active? (& playing OR waiting to play) -> only False if quitting main. self.pause=False self.pos=0 self.loading=False # loading? --> main waits for finishing loading-process if start!="": self.running=True else: self.off() self.start() ####status data / show status function def off(self): self.running=False self.pause=False self.strip.show(self.empty_array) self.size=[0,0] self.pos=0 def doPause(self): if self.running==True: if self.pause: self.pause=False else: self.pause=True def stop(self): # only to quit!! else: use self.off() self.off() self.freq.running=False self.active=False # def restart(self): # self.off() # self.running=True def showPOV(self, File=""): self.off() if File!="": self.povFile=File self.NEWrunning=True self.loading=True def run(self): while self.active: if self.NEWrunning==True: self.running=True self.NEWrunning=False if self.running == True: if self.povFile == "": print "Error: No pov-file specified!" self.off() self.loading=False else: f=open(self.povPath+self.povFile,'r') self.size=map(int,(f.readline().rstrip("\n")).split(',')) width=self.size[0] print "\nLoading "+self.povPath+self.povFile + " into buffer; size: "+str(self.size[0])+"x"+str(self.size[1]) lines = f.read().splitlines() array=[0 for i in range(width)] for i in range(width): array[i]=bytearray(60*4) j=0 for LED in lines[i].split(','): array[i][j]=int(LED) j=j+1 if i%900==0: print "\r"+str(100*i/width)+"% loaded." print "\r100% loaded." print "\nwaiting for valid frequency-values..." while (self.freq.period>2.0) or (self.freq.period<0.05): pass print "Displaying... period="+ str(self.freq.period) + "\t frequency=" + str(self.freq.frequency) self.pos=0 # start at beginning; first rotation # for calculating needed time for one period timeB=time.time() timeDiff=0 timeDiff_new=0 self.loading=False period=.16 while self.running: # Loop period=self.freq.period pixel_time=(period-timeDiff)/60. if self.pause==False: # pause? for x in range(60): # For each column of image... self.strip.show(array[x+self.pos*60]) # Write raw data to strip time.sleep(pixel_time) self.pos=(self.pos+1)%(width/60) # next slice/rotation; modulo(%)=>endless loop else: time.sleep(period) self.actPeriod=time.time()-timeB timeDiff_new=self.actPeriod-period timeDiff=(timeDiff+timeDiff_new)%period timeB=time.time() self.off() time.sleep(0.1)
class Bartender(MenuDelegate): def __init__(self): self.running = False # set the oled screen height self.screen_width = SCREEN_WIDTH self.screen_height = SCREEN_HEIGHT self.make_drink = MAKE_DRINK self.btn1Pin = LEFT_BTN_PIN self.btn2Pin = RIGHT_BTN_PIN self.clk = CLK_PIN self.dt = DT_PIN # configure interrupts for buttons #GPIO.setup(self.btn1Pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) GPIO.setup(self.btn2Pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # configure interrupts for encoder GPIO.setup(self.clk, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) GPIO.setup(self.dt, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) #Pi config RST = 21 DC = 20 SPI_PORT = 0 SPI_DEVICE = 0 # configure screen self.disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST) self.disp.begin() self.disp.clear() self.disp.display() #draw self.image = Image.new('1', (SCREEN_WIDTH, SCREEN_HEIGHT)) self.draw = ImageDraw.Draw(self.image) self.draw.rectangle((0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), outline=0, fill=0) self.font = ImageFont.load_default() # Very important... This lets py-gaugette 'know' what pins to use in order to reset the display # Change rows & cols values depending on your display dimensions. # load the pump configuration from file self.pump_configuration = Bartender.readJson( '/home/pi/Documents/PiDrink/static/json/pump_config.json') for pump in self.pump_configuration.keys(): GPIO.setup(self.pump_configuration[pump]["pin"], GPIO.OUT, initial=GPIO.HIGH) # load the current drink list self.drink_list = Bartender.readJson( '/home/pi/Documents/PiDrink/static/json/drink_list.json') self.drink_list = self.drink_list["drink_list"] # load the current drink options self.drink_options = Bartender.readJson( '/home/pi/Documents/PiDrink/static/json/drink_options.json') self.drink_options = self.drink_options["drink_options"] # setup pixels: self.numpixels = NUMBER_NEOPIXELS # Number of LEDs in strip # Here's how to control the strip from any two GPIO pins: datapin = NEOPIXEL_DATA_PIN clockpin = NEOPIXEL_CLOCK_PIN self.strip = Adafruit_DotStar(self.numpixels, datapin, clockpin) self.strip.begin() # Initialize pins for output self.strip.setBrightness( NEOPIXEL_BRIGHTNESS) # Limit brightness to ~1/4 duty cycle # turn everything off for i in range(0, self.numpixels): self.strip.setPixelColor(i, 0) self.strip.show() print('Done initializing') # def check_email(self): # status, email_ids = self.imap_server.search(None, '(UNSEEN)') # if email_ids == ['']: # mail_list = [] # else: # mail_list = self.get_subjects(email_ids) #FYI when calling the get_subjects function, the email is marked as 'read' # self.imap_server.close() # return mail_list # def get_subjects(self, email_ids): # subjects_list = [] # for e_id in email_ids[0].split(): # resp, data = self.imap_server.fetch(e_id, '(RFC822)') # perf = HeaderParser().parsestr(data[0][1]) # subjects_list.append(perf['Subject']) # return subjects_list def voice_command(self, mail_list): for mail in mail_list: found = False while (found == False): currmen = self.menuContext.currentMenu.getSelection() if (currmen.name == mail): self.makeDrink(currmen.name, currmen.attributes["ingredients"]) self.make_drink = False found = True else: self.menuContext.currentMenu.nextSelection() found = False @staticmethod def readJson(file): return json.load(open(file)) @staticmethod def writePumpConfiguration(configuration): with open("/home/pi/Documents/PiDrink/static/json/pump_config.json", "w") as jsonFile: json.dump(configuration, jsonFile) def startInterrupts(self): #GPIO.add_event_detect(self.btn1Pin, GPIO.FALLING, callback=self.left_btn, bouncetime=LEFT_PIN_BOUNCE) GPIO.add_event_detect(self.btn2Pin, GPIO.FALLING, callback=self.right_btn, bouncetime=RIGHT_PIN_BOUNCE) GPIO.add_event_detect(self.clk, GPIO.BOTH, callback=self.rotary_on_change, bouncetime=1000) def stopInterrupts(self): #GPIO.remove_event_detect(self.btn1Pin) GPIO.remove_event_detect(self.btn2Pin) GPIO.remove_event_detect(self.clk) def buildMenu(self): # create a new main menu m = Menu("Main Menu") # add drink options drink_opts = [] for d in self.drink_list: drink_opts.append( MenuItem('drink', d["name"], {"ingredients": d["ingredients"]})) configuration_menu = Menu("Configure") # add pump configuration options pump_opts = [] for p in sorted(self.pump_configuration.keys()): config = Menu(self.pump_configuration[p]["name"]) # add fluid options for each pump for opt in self.drink_options: # star the selected option selected = "*" if opt["value"] == self.pump_configuration[p][ "value"] else "" config.addOption( MenuItem('pump_selection', opt["name"], { "key": p, "value": opt["value"], "name": opt["name"] })) # add a back button so the user can return without modifying config.addOption(Back("Back")) config.setParent(configuration_menu) pump_opts.append(config) # add pump menus to the configuration menu configuration_menu.addOptions(pump_opts) # add a back button to the configuration menu configuration_menu.addOption(Back("Back")) # adds an option that cleans all pumps to the configuration menu configuration_menu.addOption(MenuItem('clean', 'Clean')) configuration_menu.setParent(m) m.addOptions(drink_opts) m.addOption(configuration_menu) # create a menu context self.menuContext = MenuContext(m, self) def filterDrinks(self, menu): """ Removes any drinks that can't be handled by the pump configuration """ for i in menu.options: if (i.type == "drink"): i.visible = False ingredients = i.attributes["ingredients"] presentIng = 0 for ing in ingredients.keys(): for p in self.pump_configuration.keys(): if (ing == self.pump_configuration[p]["value"]): presentIng += 1 if (presentIng == len(ingredients.keys())): i.visible = True elif (i.type == "menu"): self.filterDrinks(i) def selectConfigurations(self, menu): """ Adds a selection star to the pump configuration option """ for i in menu.options: if (i.type == "pump_selection"): key = i.attributes["key"] if (self.pump_configuration[key]["value"] == i.attributes["value"]): i.name = "%s %s" % (i.attributes["name"], "*") else: i.name = i.attributes["name"] elif (i.type == "menu"): self.selectConfigurations(i) def prepareForRender(self, menu): self.filterDrinks(menu) self.selectConfigurations(menu) return True def menuItemClicked(self, menuItem): if (menuItem.type == "drink"): if self.make_drink: self.makeDrink(menuItem.name, menuItem.attributes["ingredients"]) self.make_drink = False return True elif (menuItem.type == "pump_selection"): self.pump_configuration[menuItem.attributes["key"]][ "value"] = menuItem.attributes["value"] Bartender.writePumpConfiguration(self.pump_configuration) return True elif (menuItem.type == "clean"): if self.make_drink: self.clean() self.make_drink = False return True return False def changeConfiguration(self, pumps): # Change configuration of every pump for i in range(1, 7): self.pump_configuration["pump_" + str(i)]["value"] = pumps[i - 1] Bartender.writePumpConfiguration(self.pump_configuration) def clean(self): waitTime = 30 pumpProcesses = [] # cancel any button presses while the drink is being made # self.stopInterrupts() self.running = True for pump in self.pump_configuration.keys(): pump_p = threading.Thread(target=self.pour, args=( self.pump_configuration[pump]["pin"], waitTime, )) pumpProcesses.append(pump_p) disp_process = threading.Thread(target=self.progressBar, args=(waitTime, )) pumpProcesses.append(disp_process) # start the pump threads for process in pumpProcesses: process.start() # wait for threads to finish for process in pumpProcesses: process.join() # sleep for a couple seconds to make sure the interrupts don't get triggered time.sleep(2) # reenable interrupts # self.startInterrupts() self.running = False self.make_drink = True self.menuContext.showMenu() def displayMenuItem(self, menuItem): #Clear display self.draw.rectangle((0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), outline=0, fill=0) self.draw.text((20, 10), menuItem.name, font=self.font, fill=255) self.disp.image(self.image) self.disp.display() def cycleLights(self): t = threading.currentThread() head = 0 # Index of first 'on' pixel tail = -10 # Index of last 'off' pixel color = 0xFF0000 # 'On' color (starts red) while getattr(t, "do_run", True): self.strip.setPixelColor(head, color) # Turn on 'head' pixel self.strip.setPixelColor(tail, 0) # Turn off 'tail' self.strip.show() # Refresh strip time.sleep(1.0 / 50) # Pause 20 milliseconds (~50 fps) head += 1 # Advance head position if (head >= self.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 >= self.numpixels): tail = 0 # Off end? Reset def lightsEndingSequence(self): # make lights green for i in range(0, self.numpixels): self.strip.setPixelColor(i, 0xFF0000) self.strip.show() time.sleep(5) # turn lights off for i in range(0, self.numpixels): self.strip.setPixelColor(i, 0) self.strip.show() def pour(self, pin, waitTime): GPIO.output(pin, GPIO.LOW) time.sleep(waitTime) GPIO.output(pin, GPIO.HIGH) def progressBar(self, waitTime): interval = waitTime / 116.3 for x in range(1, 101): # Clear display self.draw.rectangle((0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), outline=0, fill=0) #self.draw.text((55,20), str(x) + '%', font = self.font, fill=255) self.updateProgressBar(x, y=10) self.disp.image(self.image) self.disp.display() time.sleep(interval) # # self.disp.clear() # # self.disp.display() # self.image = Image.open('happycat_oled_32.ppm').convert('1') # self.disp.image(self.image) # self.disp.display() def makeDrink(self, drink, ingredients): if self.running: return # cancel any button presses while the drink is being made # self.stopInterrupts() print('Making a ' + drink) self.running = True # launch a thread to control lighting lightsThread = threading.Thread(target=self.cycleLights) lightsThread.start() # Make a list for each potential time maxTime = 0 pumpProcesses = [] for ing in ingredients.keys(): for pump in self.pump_configuration.keys(): if ing == self.pump_configuration[pump]["value"]: waitTime = ingredients[ing] * FLOW_RATE if (waitTime > maxTime): maxTime = waitTime pump_p = threading.Thread( target=self.pour, args=(self.pump_configuration[pump]["pin"], waitTime)) pumpProcesses.append(pump_p) disp_process = threading.Thread(target=self.progressBar, args=(maxTime, )) pumpProcesses.append(disp_process) # start the pump threads for process in pumpProcesses: process.start() # wait for threads to finish for process in pumpProcesses: process.join() # stop the light thread lightsThread.do_run = False lightsThread.join() # show the ending sequence lights self.lightsEndingSequence() # reenable interrupts # sleep for a couple seconds to make sure the interrupts don't get triggered time.sleep(2) # self.startInterrupts() self.running = False print('Finished making ' + drink) self.make_drink = True # show the main menu self.menuContext.showMenu() def left_btn(self, ctx): if not self.running: self.menuContext.advance() def right_btn(self, ctx): if not self.running: self.menuContext.select() def rotary_on_change(self, ctx): if not self.running: if GPIO.input(self.dt): self.menuContext.retreat() else: self.menuContext.advance() def get_ingredients_time(self, drink): # Get the ingredients for the specified drink found = False while (found == False): currmen = self.menuContext.currentMenu.getSelection() if (currmen.name == drink): ingredients = currmen.attributes["ingredients"] self.make_drink = False found = True else: self.menuContext.currentMenu.nextSelection() # Get the drink making time maxTime = 0 for ing in ingredients.keys(): for pump in self.pump_configuration.keys(): if ing == self.pump_configuration[pump]["value"]: waitTime = ingredients[ing] * FLOW_RATE if (waitTime > maxTime): maxTime = waitTime # Return making time and ingredients for drink return ingredients, maxTime def updateProgressBar(self, percent, x=15, y=10): height = 10 width = self.screen_width - 2 * x for w in range(0, width): self.draw.point((w + x, y), fill=255) self.draw.point((w + x, y + height), fill=255) for h in range(0, height): self.draw.point((x, h + y), fill=255) self.draw.point((self.screen_width - x, h + y), fill=255) for p in range(0, percent): p_loc = int(p / 100.0 * width) self.draw.point((x + p_loc, h + y), fill=255) self.draw.text((55, 20), str(percent) + '%', font=self.font, fill=255) #self.disp.image(self.image) #self.disp.display() def endprogram(self): global stopprogram stopprogram = True # Goodbye message self.draw.rectangle((0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), outline=0, fill=0) self.draw.text((25, 10), "Goodbye...", font=self.font, fill=255) self.disp.image(self.image) self.disp.display() time.sleep(3) self.draw.rectangle((0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), outline=0, fill=0) self.draw.text((15, 10), "Have a great day!", font=self.font, fill=255) self.disp.image(self.image) self.disp.display() time.sleep(3) self.disp.clear() self.disp.display() def run(self): self.startInterrupts() # main loop try: while True: if stopprogram: return # self.imap_server = imaplib.IMAP4_SSL("imap.gmail.com",993) # self.imap_server.login(USERNAME, PASSWORD) # self.imap_server.select('INBOX') # mail_list = self.check_email() # if mail_list and not self.running: # self.voice_command(mail_list) time.sleep(0.1) except KeyboardInterrupt: GPIO.cleanup() # clean up GPIO on CTRL+C exit sys.exit(0) GPIO.cleanup() # clean up GPIO on normal exit traceback.print_exc()