class LedStrip: def __init__(self): # LED strip configuration: self._LED_COUNT = 4 # Number of LED pixels. self._LED_PIN = 18 # GPIO pin connected to the pixels (must support PWM!). self._LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz) self._LED_DMA = 5 # DMA channel to use for generating signal (try 5) self._LED_BRIGHTNESS = 255 # Set to 0 for darkest and 255 for brightest self._LED_INVERT = False # True to invert the signal (when using NPN transistor level shift) self._LED_CHANNEL = 0 self._strip = Adafruit_NeoPixel(self._LED_COUNT, self._LED_PIN, self._LED_FREQ_HZ, self._LED_DMA, self._LED_INVERT, self._LED_BRIGHTNESS) self._strip.begin() self.switchOffStrip() def setPixelColourRgb(self, position, red, green, blue): self._strip.setPixelColor(position, Color(red, green, blue)) self._strip.show() def setStripBrightness(self, brightness): self._strip.setBrightness(brightness) def switchOffPixel(self, position): self._strip.setPixelColor(position, Color(0, 0, 0)) self._strip.show() def switchOffStrip(self): for n in range(0, self._LED_COUNT): self._strip.setPixelColor(n, Color(0, 0, 0)) self._strip.show()
class StripManager: @staticmethod def default(): led_count = 159 # Number of LED pixels. led_pin = 18 # GPIO pin connected to the pixels (18 uses PWM!). led_freq_hz = 800000 # LED signal frequency in hertz (usually 800khz) led_dma = 10 # DMA channel to use for generating signal (try 10) led_brightness = 255 # Set to 0 for darkest and 255 for brightest led_invert = False # True to invert the signal (when using NPN transistor level shift) led_channel = 0 # set to '1' for GPIOs 13, 19, 41, 45 or 53 return StripManager(led_count, led_pin, led_freq_hz, led_dma, led_invert, led_brightness, led_channel) def __init__(self, led_count, led_pin, led_freq_hz, led_dma, led_invert, led_brightness, led_channel): self.strip = Adafruit_NeoPixel(led_count, led_pin, led_freq_hz, led_dma, led_invert, led_brightness, led_channel) self.strip.begin() def solid_color(self, r, g, b): self.strip.setBrightness(255) for i in range(0, self.strip.numPixels()): self.strip.setPixelColor(i, Color(r, g, b)) self.strip.show() def alert(self, r, g, b, wait_ms=50, iterations=10): for j in range(iterations): for q in range(3): for i in range(0, self.strip.numPixels(), 3): self.strip.setPixelColor(i + q, Color(r, g, b)) self.strip.show() time.sleep(wait_ms / 1000.0) for i in range(0, self.strip.numPixels(), 3): self.strip.setPixelColor(i + q, 0) def clear(self): self.solid_color(0, 0, 0) def orange(self): self.solid_color(255, 64, 0)
DOT_COLORS = [ 0xFF0000, # red 0xFF7F00, # orange 0xFFFF00, # yellow 0x00FF00, # green 0x00FFFF, # lightblue 0x0000FF, # blue 0xFF00FF, # purple 0xFF007F ] # pink # Create NeoPixel object with appropriate configuration. strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL) # Intialize the library (must be called once before other functions). strip.setBrightness(50) strip.begin() strip.show() offset = 0 count = 0 flag = 1 Ab = AlphaBot() pwm = PCA9685(0x40) pwm.setPWMFreq(50) BUZ = 4 GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(BUZ, GPIO.OUT)
class PiWS281X(DriverBase): """ Driver for controlling WS281X LEDs via the rpi_ws281x C-extension. Only supported on the Raspberry Pi 2, 3, and Zero This driver needs to be run as sudo and requires the rpi_ws281x C extension. Install rpi_ws281x with the following shell commands: git clone https://github.com/jgarff/rpi_ws281x.git cd rpi_ws281x sudo apt-get install python-dev swig scons sudo scons cd python # If using default system python3 sudo python3 setup.py build install # If using virtualenv, enter env then run python setup.py build install Provides the same parameters of :py:class:`.driver_base.DriverBase` as well as those below: :param int gpio: GPIO pin to output to. Typically 18 or 13 :param int ledFreqHz: WS2812B base data frequency in Hz. Only change to 400000 if using very old WS218B LEDs :param int ledDma: DMA channel to use for generating signal (between 1 and 14) :param bool ledInvert: True to invert the signal (when using NPN transistor level shift) """ def __init__( self, num, gamma=gamma.NEOPIXEL, c_order="RGB", gpio=18, ledFreqHz=800000, ledDma=5, ledInvert=False, color_channels=3, brightness=255, **kwds): if not NeoColor: raise ValueError(WS_ERROR) super().__init__(num, c_order=c_order, gamma=gamma, **kwds) self.gamma = gamma if gpio not in PIN_CHANNEL.keys(): raise ValueError('{} is not a valid gpio option!') try: strip_type = STRIP_TYPES[color_channels] except: raise ValueError('In PiWS281X, color_channels can only be 3 or 4') self._strip = Adafruit_NeoPixel( num, gpio, ledFreqHz, ledDma, ledInvert, brightness, PIN_CHANNEL[gpio], strip_type) # Intialize the library (must be called once before other functions). try: self._strip.begin() except RuntimeError as e: if os.geteuid(): if os.path.basename(sys.argv[0]) in ('bp', 'bibliopixel'): command = ['bp'] + sys.argv[1:] else: command = ['python'] + sys.argv error = SUDO_ERROR.format(command=' '.join(command)) e.args = (error,) + e.args raise def set_brightness(self, brightness): self._strip.setBrightness(brightness) return True def _compute_packet(self): self._render() data = self._buf self._packet = [tuple(data[(p * 3):(p * 3) + 3]) for p in range(len(data) // 3)] def _send_packet(self): for i, p in enumerate(self._packet): self._strip.setPixelColor(i, NeoColor(*p)) self._strip.show()
# Main program logic follows: if __name__ == '__main__': # Create NeoPixel object with appropriate configuration. strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS) # Intialize the library (must be called once before other functions). strip.begin() for i in range(0, strip.numPixels(), 1): strip.setPixelColor(i, Color(0, 0, 0)) while True: now = datetime.datetime.now() # Low light during 19-8 o'clock if (8 < now.hour < 19): strip.setBrightness(200) else: strip.setBrightness(25) hour = now.hour % 12 minute = now.minute / 5 second = now.second / 5 secondmodulo = now.second % 5 timeslot_in_microseconds = secondmodulo * 1000000 + now.microsecond for i in range(0, strip.numPixels(), 1): secondplusone = second + 1 if (second < 11) else 0 secondminusone = second - 1 if (second > 0) else 11 colorarray = [0, 0, 0] if i == second:
class Animator: def __init__(self): self._kill_previous_process() self._animations_dir = os.path.join(os.getcwd(), 'animations') self._frame_handlers = { ord('P'): self._on_pframe, ord('I'): self._on_iframe, ord('D'): self._on_dframe, ord('F'): self._on_fframe } settings = self._load_settings() brightness = settings['brightness'] * 255 // 50 self._strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, brightness, LED_CHANNEL) self._strip.begin() self._strip.setBrightness(50) self._animation = None def _load_settings(self): with open('settings.yaml') as fh: settings = yaml.load(fh, Loader=yaml.FullLoader) return settings def _get_previous_process(self): cur_pid = psutil.Process().pid for proc in psutil.process_iter(['pid', 'name', 'cmdline']): if proc.pid == cur_pid or proc.name( ) != 'python' or 'animate.py' not in proc.cmdline(): continue return proc return None def _kill_previous_process(self): proc = self._get_previous_process() if proc: proc.terminate() psutil.wait_procs([proc]) def _on_pframe(self, frame): for item in frame.data: clr = self._animation.palette[item.palette_index] color = Color(clr.g, clr.r, clr.b) index = TOPOLOGY[EPX_TOPOLOGY[item.pixel_index]] if index > 0: self._strip.setPixelColor(index, color) return def _on_iframe(self, frame): for pixel_index, palette_index in enumerate(frame.data): clr = self._animation.palette[palette_index] color = Color(clr.g, clr.r, clr.b) index = TOPOLOGY[EPX_TOPOLOGY[pixel_index]] if index > 0: self._strip.setPixelColor(index, color) return def _on_dframe(self, frame): sleep(frame.delay / 1000) def _on_fframe(self, frame): # TODO: implement proper fading sleep(frame.delay) def _show_frame(self, frame): handler = self._frame_handlers[frame.type] handler(frame) self._strip.show() def _run(self): if self._animation == None: return self.clear() loop_count = max(self._animation.loop_count, 1) try: for i in range(loop_count): for frame in self._animation.data: self._show_frame(frame) sleep(0.1) except KeyboardInterrupt: pass self.clear() def _load_animations(self): files = [f for f in os.listdir(self._animations_dir)] animations = [] for file in files: filepath = os.path.join(self._animations_dir, file) animation = Animation.load(filepath) animations.append(animation) return animations def _find_animation_by_id(self, id): animations = self._load_animations() animation = next((x for x in animations if x.id == id), None) return animation def _find_animation_by_name(self, name): animations = self._load_animations() animation = next((x for x in animations if x.name == name), None) return animation def clear(self): color = Color(0, 0, 0) for i in range(LED_COUNT): self._strip.setPixelColor(i, color) self._strip.show() def play(self, filename): self._animation = Animation.load(filename) self._run() def play_by_id(self, id): self._animation = self._find_animation_by_id(id) self._run() def play_by_name(self, name): self._animation = self._find_animation_by_name(name) self._run() def restart(self): proc = self._get_previous_process() if not proc: return args = ['sudo', proc.name()] args.extend(proc.cmdline()) proc.terminate() psutil.wait_procs([proc]) subprocess.run(args) def play_all(self, randomly, forever): animations = self._load_animations() if randomly: random.shuffle(animations) while True: for animation in animations: print(f'{animation.name}') self._animation = animation self._run() if not forever: break if randomly: random.shuffle(animations)
class LedController(Actuator): """Implementation for the Neopixel Programmable RGB LEDS. Extends :class:`Actuator`. It use's rpi_ws281x library. Args: led_count (int): Number of leds. led_pin (int): GPIO pin connected to the pixels. led_freq_hz (int): LED signal frequency in hertz (usually 800khz) led_brightness (int): Set to 0 for darkest and 255 for brightest led_dma (int): DMA channel to use for generating signal. Defaults to :data:`10`. led_invert (boolean): True to invert the signal (when using NPN transistor level shift). Defaults to :data:`False`. led_channel (int): Set to '1' for GPIOs 13, 19, 41, 45 or 53. Defaults to :data:`0`. led_strip: Strip type and colour ordering. Defaults to :data:`ws.WS2811_STRIP_RGB`. """ def __init__(self, led_count, led_pin, led_freq_hz, led_brightness, led_dma=10, led_invert=False, led_channel=0, led_strip=ws.WS2811_STRIP_RGB, name=""): """Constructor""" self._led_count = led_count self._led_pin = led_pin self._led_freq_hz = led_freq_hz self._led_dma = led_dma self._led_brightness = led_brightness self._led_invert = led_invert self._led_channel = led_channel self._led_strip = led_strip # Set the id of the actuator super(LedController, self).__init__(name) self.start() @property def led_count(self): """Number of leds.""" return self._led_count @led_count.setter def led_count(self, x): self._led_count = x @property def led_pin(self): """GPIO pin connected to the pixels.""" return self._led_pin @led_pin.setter def led_pin(self, x): self._led_pin = x @property def led_freq_hz(self): """LED signal frequency in hertz.""" return self._led_freq_hz @led_freq_hz.setter def led_freq_hz(self, x): self._led_freq_hz = x @property def led_brightness(self): """Set to 0 for darkest and 255 for brightest.""" return self._led_brightness @led_brightness.setter def led_brightness(self, x): self._led_brightness = x @property def led_dma(self): """DMA channel to use for generating signal.""" return self._led_dma @led_dma.setter def led_dma(self, x): self._led_dma = x @property def led_invert(self): """True to invert the signal.""" return self._led_invert @led_invert.setter def led_invert(self, x): self._led_invert = x @property def led_channel(self): """Set to '1' for GPIOs 13, 19, 41, 45 or 53.""" return self._led_channel @led_channel.setter def led_channel(self, x): self._led_channel = x @property def led_strip(self): """Strip type and color ordering.""" return self._led_strip @led_strip.setter def led_strip(self, x): self._led_strip = x def start(self): """Initialize hardware and os resources.""" # Create NeoPixel object with appropriate configuration. self.strip = Adafruit_NeoPixel(self.led_count, self.led_pin, int(self.led_freq_hz), self.led_dma, self.led_invert, self.led_brightness, self.led_channel, self.led_strip) # Intialize the library (must be called once before other functions). self.strip.begin() self.strip.show() def stop(self): """Free hardware and os resources.""" # Turn-off led strip self.close() def write(self, data, wait_ms=50, wipe=False): """Write to the leds. Args: data: A list of lists of which each list corresponds to each led and the values are [red, green, blue, brightness]. wait_ms (int): Optional argument that has to be set when wipe is :data:`True`. Defaults to :data:`50`. wipe: Flag for writting to all leds at once. """ if wipe: self._color_wipe(data[0][:3], wait_ms=wait_ms, brightness=data[0][3]) else: for (i, led) in enumerate(data): self.strip.setPixelColor(i, Color(led[1], led[0], led[2])) self.strip.setBrightness(led[3]) self.strip.show() time.sleep(0.1) def close(self): """Free hardware and os resources.""" for i in range(self.strip.numPixels()): self.strip.setPixelColor(i, Color(0, 0, 0)) self.strip.show() self.strip._cleanup() del self.strip def _color_wipe(self, rgb_color=[0, 0, 255], wait_ms=50, brightness=60): """Wipe color across display a pixel at a time.""" for i in range(self.strip.numPixels()): self.strip.setPixelColor( i, Color(rgb_color[1], rgb_color[0], rgb_color[2])) self.strip.setBrightness(brightness) self.strip.show() time.sleep(wait_ms / 1000.0)
class HardwareHandler(): """Class to handle LEDs and camera.""" def __init__(self, imageQueue): self.imageQueue = imageQueue self.capture = False self.capture_thread = None self.cap = cv2.VideoCapture(constants.CAMERA_NUM - 1 + cv2.CAP_ANY) self.UV_LED = False self.COLOR_LED = False if not testMode: GPIO.setmode(GPIO.BOARD) GPIO.setup(constants.GPIO_UV_LED, GPIO.OUT) self.UV_LED_PWM = GPIO.PWM(constants.GPIO_UV_LED, 800) # channel=12 frequency=50Hz self.UV_LED_PWM.start(0) self.strip = Adafruit_NeoPixel(constants.COLOR_LED_NUM, constants.GPIO_COLOR_LED, dma=10) self.strip.begin() for n in range(constants.COLOR_LED_NUM): self.strip.setPixelColorRGB( n, constants.settings["Color"]["LED_Red"], constants.settings["Color"]["LED_Green"], constants.settings["Color"]["LED_Blue"]) ###################### LED ###################### def switchUV_LED(self, val=None): """ switch UV LED or set to val""" if val is not None: self.UV_LED = val else: self.UV_LED = not self.UV_LED if not testMode: if self.UV_LED: self.UV_LED_PWM.ChangeDutyCycle( constants.settings["UV"]["LED_Brigh"]) else: self.UV_LED_PWM.ChangeDutyCycle(0) if self.UV_LED: logger.info("UV LED: On") else: logger.info("UV LED: Off") def switchCOLOR_LED(self, val=None): """ switch color LED or set to val :param bool val:""" if val is not None: self.COLOR_LED = val else: self.COLOR_LED = not self.COLOR_LED if not testMode: if self.COLOR_LED: self.strip.setBrightness( constants.settings["Color"]["LED_Brigh"]) else: self.strip.setBrightness(0) self.strip.show() if self.COLOR_LED: logger.info("Color LED: On") else: logger.info("Color LED: Off") def updateLEDColors(self): """ Update Color LED settings to constants.settings """ if not testMode: for n in range(constants.COLOR_LED_NUM): self.strip.setPixelColorRGB( n, constants.settings["Color"]["LED_Red"], constants.settings["Color"]["LED_Green"], constants.settings["Color"]["LED_Blue"]) if self.COLOR_LED: self.strip.setBrightness( constants.settings["Color"]["LED_Brigh"]) self.strip.show() else: color = (constants.settings["Color"]["LED_Red"], constants.settings["Color"]["LED_Green"], constants.settings["Color"]["LED_Blue"], constants.settings["Color"]["LED_Brigh"]) logger.info(f"New LED Color: {color}. LED on: {self.COLOR_LED}") def updateLEDUV(self): """ Update UV LED settings to constants.settings """ if not testMode: if self.UV_LED: self.UV_LED_PWM.ChangeDutyCycle( constants.settings["UV"]["LED_Brigh"]) else: logger.info( f"New UV LED Brightness: {constants.settings['UV']['LED_Brigh']}. LED on: {self.UV_LED}" ) ###################### Camera ###################### def startCapturing(self, mode="Color"): """ Start image capture & display """ self.capture = True def grab_images(queue): self.setCaptureSettings(mode, "low") while self.capture: if self.cap.grab(): _, image = self.cap.retrieve(0) if image is not None and queue.qsize() < 2: image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image = cv2.resize(image, constants.DISPLAY_RESOLUTION[::-1], interpolation=cv2.INTER_CUBIC) queue.put(image) else: time.sleep(constants.DISP_MSEC / 1000.0) else: logger.fatal("Can't grab camera image") logger.fatal("Using test image instead") image = cv2.imread(constants.TEST_IMAGE_NAME) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image = cv2.resize(image, constants.DISPLAY_RESOLUTION[::-1], interpolation=cv2.INTER_CUBIC) queue.put(image) break self.capture_thread = threading.Thread( target=grab_images, args=(self.imageQueue, )) # Thread to grab images self.capture_thread.start() def shootImage_fullResolution(self, mode="Color"): """Shoot single image with maximal camera resolution :return np.ndarray: image """ self.setCaptureSettings(mode, "full") if self.cap.grab(): _, fullImage = self.cap.retrieve(0) else: logger.fatal("Can't grab camera image") logger.fatal("Using test image instead") fullImage = cv2.imread(constants.TEST_IMAGE_NAME) fullImage = cv2.cvtColor(fullImage, cv2.COLOR_RGB2BGR) return fullImage def stopCapturing(self): """Stop if capturing.""" if self.capture: self.capture = False self.capture_thread.join() self.imageQueue.queue.clear() def updateCaptureSettings(self, mode="Color"): """Stop capturing and start again with new settings""" self.stopCapturing() self.startCapturing(mode=mode) def __del__(self): if not testMode: GPIO.cleanup() def setCaptureSettings(self, LEDMmode, resolution): """Call cv2.VideoCapture and set settings.""" #set fps dynamic to exposure fps = 20 if constants.settings[LEDMmode]["exposureTime"] != 0: fps = int( max( 1, min(20, 10000 / constants.settings[LEDMmode]["exposureTime"]))) self.cap.set(cv2.CAP_PROP_FPS, fps) if resolution == "full": self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, constants.CAMERA_RESOLUTION[1]) self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, constants.CAMERA_RESOLUTION[0]) if resolution == "low": self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, constants.DISPLAY_RESOLUTION[1]) self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, constants.DISPLAY_RESOLUTION[0]) if not testMode: #set white balance subprocess.check_call( f"v4l2-ctl -d /dev/video0 -c white_balance_auto_preset=0 -c red_balance={constants.RED_GAIN} -c blue_balance={constants.BLUE_GAIN} -c exposure_dynamic_framerate=1 -c iso_sensitivity_auto=0 ", shell=True) #set exposure if constants.settings[LEDMmode][ "exposureTime"] == 0: # exposureTime==0 -> auto subprocess.check_call( "v4l2-ctl -d /dev/video0 -c white_balance_auto_preset=0 -c auto_exposure=0", shell=True) else: subprocess.check_call( f"v4l2-ctl -d /dev/video0 -c auto_exposure=1 -c exposure_time_absolute={constants.settings[LEDMmode]['exposureTime']}", shell=True)