3dprinterbox/mqttcontrol/printerbox_hardware.py

231 lines
6.4 KiB
Python

import random
from gpiozero import PWMLED
from rpi_ws281x import Color, PixelStrip, ws
import time
import threading
# ------------------------------------------------------------------------------
# Control script for 3D printer fan & LED control
#
#
# Raspi Zero W Pin assignment, in order from top to bottom on PCB
#
# On PCB | Cable color | Raspberry PIN
# --------------------------------------------
# 5V | not connected | ------
# LED | grey | GPIO 19 [PWM]
# GND | black | ------
# DHT22 | white | GPIO 26
# FAN1 | purple | GPIO 13
# FAN2 | blue | GPIO 6
#
# LED strip configuration:
LED_COUNT = 120 # Number of LED pixels.
LED_PIN = 19 # GPIO pin connected to the pixels (must support 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 (for NPN transistor)
LED_CHANNEL = 1
LED_STRIP = ws.SK6812_STRIP
LED_SUBSETS = {
'top_back': list(range(24)),
'top_mid': list(range(24, 48)),
'left': list(range(48, 72)),
'top_front': list(range(72, 96)),
'right': list(reversed(range(96, 120))),
}
LED_SUBSETS['top'] = LED_SUBSETS['top_back'] + \
LED_SUBSETS['top_mid'] + LED_SUBSETS['top_front']
LED_SUBSETS['sides'] = LED_SUBSETS['left'] + LED_SUBSETS['right']
LED_SUBSETS['all'] = LED_SUBSETS['top'] + LED_SUBSETS['sides']
LED_SUBSET_NAMES = {
'top_back': "Oben hinten",
'top_mid': "Oben mitte",
'left': "Seite links",
'top_front': "Oben vorne",
'right': "Seite rechts",
'top': "Oben",
'sides': "Seiten",
'all': "Alle"
}
leds = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA,
LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL, LED_STRIP)
leds.begin()
# Fan configuration
PWM_FREQ = 600
venting_fan = PWMLED(13, frequency=PWM_FREQ)
filter_fan = PWMLED(6, frequency=PWM_FREQ)
#
led_thread_running = True
led_thread = None
def normalize_subset(subset):
if type(subset) is str:
return LED_SUBSETS[subset]
else:
return subset
def next_color_func(r, g, b):
if type(r) is tuple or type(g) is tuple or type(b) is tuple:
def next_color():
return Color(*(random.randint(e[0], e[1]) if isinstance(e, tuple) else e for e in (r, g, b)))
else:
def next_color():
return Color(r, g, b)
return next_color
def _thread_set_leds_color(r, g, b, subset='all'):
global led_thread_running
led_thread_running = True
next_color = next_color_func(r, g, b)
for i in normalize_subset(subset):
leds.setPixelColor(i, next_color())
leds.show()
led_thread_running = False
def _thread_set_leds_brightness(new_brightness):
global led_thread_running
led_thread_running = True
leds.setBrightness(new_brightness)
leds.show()
led_thread_running = False
def _thread_set_leds_on(subset='all'):
global led_thread_running
led_thread_running = True
changed = False
for i in normalize_subset(subset):
if leds.getPixelColor(i) == 0:
leds.setPixelColor(i, Color(180, 180, 180))
changed = True
if changed:
leds.show()
led_thread_running = False
def _thread_set_leds_off(subset='all'):
_thread_set_leds_color(0, 0, 0, subset=subset)
def _thread_effect_color_wipe(r, g, b, wait_ms=25, subset='all'):
"""Wipe color across display a pixel at a time."""
global led_thread_running
next_color = next_color_func(r, g, b)
_thread_set_leds_off(subset)
led_thread_running = True
while led_thread_running:
for i in normalize_subset(subset):
leds.setPixelColor(i, next_color())
leds.show()
if not led_thread_running:
break
time.sleep(wait_ms / 1000.0)
for i in reversed(normalize_subset(subset)):
leds.setPixelColor(i, Color(0, 0, 0))
leds.show()
if not led_thread_running:
break
time.sleep(wait_ms / 1000.0)
def _thread_effect_blink_on_off(r, g, b, wait_ms=1000, subset='all'):
global led_thread_running
next_color = next_color_func(r, g, b)
_thread_set_leds_off(subset)
led_thread_running = True
while led_thread_running:
for i in normalize_subset(subset):
leds.setPixelColor(i, next_color())
leds.show()
time.sleep(wait_ms / 1000.0)
if not led_thread_running:
break
for i in normalize_subset(subset):
leds.setPixelColor(i, Color(0, 0, 0))
leds.show()
time.sleep(wait_ms / 1000.0)
def _thread_effect_move_blink(r, g, b, wait_ms=500, subset='all'):
global led_thread_running
next_color = next_color_func(r, g, b)
_thread_set_leds_off(subset)
led_thread_running = True
ctr = 0
while led_thread_running:
for nr, led_id in enumerate(normalize_subset(subset)):
color = next_color() if nr % 2 == ctr % 2 else Color(0, 0, 0)
leds.setPixelColor(led_id, color)
leds.show()
ctr += 1
time.sleep(wait_ms / 1000.0)
def _start_in_led_thread(func, *args, **kwargs):
global led_thread_running
global led_thread
led_thread_running = False
if led_thread is not None:
led_thread.join()
led_thread = threading.Thread(target=func, args=args, kwargs=kwargs)
led_thread.start()
# ---------------------- Settings Lights ---------------------------------
def set_leds_color(r, g, b, subset='all'):
_start_in_led_thread(_thread_set_leds_color, r, g, b, subset)
def set_leds_on(subset='all'):
if not led_thread_running:
_start_in_led_thread(_thread_set_leds_on, subset)
def set_leds_off(subset='all'):
_start_in_led_thread(_thread_set_leds_off, subset)
def set_leds_brightness(new_brightness):
_start_in_led_thread(_thread_set_leds_brightness, new_brightness)
def effect_color_wipe(r, g, b, wait_ms=25, subset='all'):
_start_in_led_thread(_thread_effect_color_wipe, r, g, b, wait_ms, subset)
def effect_move_blink(r, g, b, wait_ms=500, subset='all'):
_start_in_led_thread(_thread_effect_move_blink, r, g, b, wait_ms, subset)
def effect_blink_on_off(r, g, b, wait_ms=1000, subset='all'):
_start_in_led_thread(_thread_effect_blink_on_off, r, g, b, wait_ms, subset)