From 4c09d8bf029b5fac770fba9026c930805fd6ba32 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Tue, 6 Aug 2019 19:30:48 -0400 Subject: [PATCH] dotstar: Initial support for "dotstar" LEDs Signed-off-by: Kevin O'Connor --- config/example-extras.cfg | 23 +++++++++++++-- docs/Config_Changes.md | 2 ++ docs/G-Codes.md | 20 ++++++------- klippy/extras/dotstar.py | 61 +++++++++++++++++++++++++++++++++++++++ klippy/extras/neopixel.py | 10 +++---- 5 files changed, 98 insertions(+), 18 deletions(-) create mode 100644 klippy/extras/dotstar.py diff --git a/config/example-extras.cfg b/config/example-extras.cfg index fc28000e..50d1ecfb 100644 --- a/config/example-extras.cfg +++ b/config/example-extras.cfg @@ -1654,9 +1654,9 @@ # Neopixel (aka WS2812) LED support (one may define any number of -# sections with a "neopixel" prefix). One may set the LED color via a -# "SET_NEOPIXEL NEOPIXEL=my_neopixel RED=0.1 GREEN=0.1 BLUE=0.1" type -# extended g-code commands. +# sections with a "neopixel" prefix). One may set the LED color via +# "SET_LED LED=my_neopixel RED=0.1 GREEN=0.1 BLUE=0.1" type extended +# g-code commands. #[neopixel my_neopixel] #pin: # The pin connected to the neopixel. This parameter must be @@ -1671,6 +1671,23 @@ # Sets the initial LED color of the Neopixel. Each value should be # between 0.0 and 1.0. The default for each color is 0. +# Dotstar (aka APA102) LED support (one may define any number of +# sections with a "dotstar" prefix). One may set the LED color via +# "SET_LED LED=my_dotstar RED=0.1 GREEN=0.1 BLUE=0.1" type extended +# g-code commands. +#[dotstar my_dotstar] +#data_pin: +# The pin connected to the data line of the dotstar. This parameter +# must be provided. +#clock_pin: +# The pin connected to the clock line of the dotstar. This parameter +# must be provided. +#chain_count: +#initial_RED: 0.0 +#initial_GREEN: 0.0 +#initial_BLUE: 0.0 +# See the "neopixel" section for information on these parameters. + # Firmware filament retraction. This enables G10 (retract) and G11 # (unretract) GCODE commands issued by many slicers. The parameters diff --git a/docs/Config_Changes.md b/docs/Config_Changes.md index 979b0967..28f20635 100644 --- a/docs/Config_Changes.md +++ b/docs/Config_Changes.md @@ -6,6 +6,8 @@ All dates in this document are approximate. # Changes +20190806: The SET_NEOPIXEL command has been renamed to SET_LED. + 20190726: The mcp4728 digital-to-analog code has changed. The default i2c_address is now 0x60 and the voltage reference is now relative to the mcp4728's internal 2.048 volt reference. diff --git a/docs/G-Codes.md b/docs/G-Codes.md index fef5680b..cf5f2784 100644 --- a/docs/G-Codes.md +++ b/docs/G-Codes.md @@ -191,17 +191,17 @@ The following command is available when an "output_pin" config section is enabled: - `SET_PIN PIN=config_name VALUE=` -## Neopixel Commands +## Neopixel and Dotstar Commands -The following command is available when a "neopixel" config section -is enabled: -- `SET_NEOPIXEL NEOPIXEL= INDEX= RED= - GREEN= BLUE=`: This sets the Neopixel LED output. Each - color must be between 0.0 and 1.0. If multiple Neopixel - chips are daisy-chained then one may specify INDEX to alter the - color of just the given Neopixel chip (1 for the first Neopixel, 2 - for the second, etc.). If INDEX is not provided then all Neopixels - in the daisy-chain will be set to the provided color. +The following command is available when "neopixel" or "dotstar" config +sections are enabled: +- `SET_LED LED= INDEX= RED= GREEN= + BLUE=`: This sets the LED output. Each color must be + between 0.0 and 1.0. If multiple LED chips are daisy-chained then + one may specify INDEX to alter the color of just the given chip (1 + for the first chip, 2 for the second, etc.). If INDEX is not + provided then all LEDs in the daisy-chain will be set to the + provided color. ## Servo Commands diff --git a/klippy/extras/dotstar.py b/klippy/extras/dotstar.py new file mode 100644 index 00000000..51730fb4 --- /dev/null +++ b/klippy/extras/dotstar.py @@ -0,0 +1,61 @@ +# Support for "dotstar" leds +# +# Copyright (C) 2019 Kevin O'Connor +# +# This file may be distributed under the terms of the GNU GPLv3 license. +import bus + +class PrinterDotstar: + def __init__(self, config): + self.printer = config.get_printer() + name = config.get_name().split()[1] + # Configure a software spi bus + ppins = self.printer.lookup_object('pins') + data_pin_params = ppins.lookup_pin(config.get('data_pin')) + clock_pin_params = ppins.lookup_pin(config.get('clock_pin')) + mcu = data_pin_params['chip'] + if mcu is not clock_pin_params['chip']: + raise config.error("Dotstar pins must be on same mcu") + sw_spi_pins = (data_pin_params['pin'], data_pin_params['pin'], + clock_pin_params['pin']) + self.spi = bus.MCU_SPI(mcu, None, None, 0, 500000, sw_spi_pins) + # Initial color + self.chain_count = config.getint('chain_count', 1, minval=1, maxval=12) + red = config.getfloat('initial_RED', 0., minval=0., maxval=1.) + green = config.getfloat('initial_GREEN', 0., minval=0., maxval=1.) + blue = config.getfloat('initial_BLUE', 0., minval=0., maxval=1.) + red = int(red * 255. + .5) + blue = int(blue * 255. + .5) + green = int(green * 255. + .5) + color_data = [0xff, blue, green, red] * self.chain_count + self.color_data = [0, 0, 0, 0] + color_data + [0xff, 0xff, 0xff, 0xff] + self.printer.register_event_handler("klippy:connect", self.send_data) + # Register commands + self.gcode = self.printer.lookup_object('gcode') + self.gcode.register_mux_command("SET_LED", "LED", name, + self.cmd_SET_LED, + desc=self.cmd_SET_LED_help) + def send_data(self, minclock=0): + self.spi.spi_send(self.color_data, minclock=minclock, reqclock=minclock) + cmd_SET_LED_help = "Set the color of an LED" + def cmd_SET_LED(self, params): + # Parse parameters + red = self.gcode.get_float('RED', params, 0., minval=0., maxval=1.) + green = self.gcode.get_float('GREEN', params, 0., minval=0., maxval=1.) + blue = self.gcode.get_float('BLUE', params, 0., minval=0., maxval=1.) + red = int(red * 255. + .5) + blue = int(blue * 255. + .5) + green = int(green * 255. + .5) + color_data = [0xff, blue, green, red] + if 'INDEX' in params: + index = self.gcode.get_int('INDEX', params, + minval=1, maxval=self.chain_count) + self.color_data[index*4:(index+1)*4] = color_data + else: + self.color_data[4:-4] = color_data * self.chain_count + # Send command + print_time = self.printer.lookup_object('toolhead').get_last_move_time() + self.send_data(self.spi.get_mcu().print_time_to_clock(print_time)) + +def load_config_prefix(config): + return PrinterDotstar(config) diff --git a/klippy/extras/neopixel.py b/klippy/extras/neopixel.py index 4920adf6..8379f65b 100644 --- a/klippy/extras/neopixel.py +++ b/klippy/extras/neopixel.py @@ -29,9 +29,9 @@ class PrinterNeoPixel: self.printer.register_event_handler("klippy:connect", self.send_data) # Register commands self.gcode = self.printer.lookup_object('gcode') - self.gcode.register_mux_command("SET_NEOPIXEL", "NEOPIXEL", name, - self.cmd_SET_NEOPIXEL, - desc=self.cmd_SET_NEOPIXEL_help) + self.gcode.register_mux_command("SET_LED", "LED", name, + self.cmd_SET_LED, + desc=self.cmd_SET_LED_help) def build_config(self): if self.mcu.get_constant_float('CLOCK_FREQ') <= 20000000: raise self.printer.config_error( @@ -42,8 +42,8 @@ class PrinterNeoPixel: def send_data(self, minclock=0): self.neopixel_send_cmd.send([self.oid, self.color_data], minclock=minclock) - cmd_SET_NEOPIXEL_help = "Set the color of a neopixel led" - def cmd_SET_NEOPIXEL(self, params): + cmd_SET_LED_help = "Set the color of an LED" + def cmd_SET_LED(self, params): # Parse parameters red = self.gcode.get_float('RED', params, 0., minval=0., maxval=1.) green = self.gcode.get_float('GREEN', params, 0., minval=0., maxval=1.)