dotstar: Initial support for "dotstar" LEDs

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2019-08-06 19:30:48 -04:00
parent c2a08962b7
commit 4c09d8bf02
5 changed files with 98 additions and 18 deletions

View File

@ -1654,9 +1654,9 @@
# Neopixel (aka WS2812) LED support (one may define any number of # Neopixel (aka WS2812) LED support (one may define any number of
# sections with a "neopixel" prefix). One may set the LED color via a # sections with a "neopixel" prefix). One may set the LED color via
# "SET_NEOPIXEL NEOPIXEL=my_neopixel RED=0.1 GREEN=0.1 BLUE=0.1" type # "SET_LED LED=my_neopixel RED=0.1 GREEN=0.1 BLUE=0.1" type extended
# extended g-code commands. # g-code commands.
#[neopixel my_neopixel] #[neopixel my_neopixel]
#pin: #pin:
# The pin connected to the neopixel. This parameter must be # 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 # 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. # 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 # Firmware filament retraction. This enables G10 (retract) and G11
# (unretract) GCODE commands issued by many slicers. The parameters # (unretract) GCODE commands issued by many slicers. The parameters

View File

@ -6,6 +6,8 @@ All dates in this document are approximate.
# Changes # Changes
20190806: The SET_NEOPIXEL command has been renamed to SET_LED.
20190726: The mcp4728 digital-to-analog code has changed. The default 20190726: The mcp4728 digital-to-analog code has changed. The default
i2c_address is now 0x60 and the voltage reference is now relative to i2c_address is now 0x60 and the voltage reference is now relative to
the mcp4728's internal 2.048 volt reference. the mcp4728's internal 2.048 volt reference.

View File

@ -191,17 +191,17 @@ The following command is available when an "output_pin" config section
is enabled: is enabled:
- `SET_PIN PIN=config_name VALUE=<value>` - `SET_PIN PIN=config_name VALUE=<value>`
## Neopixel Commands ## Neopixel and Dotstar Commands
The following command is available when a "neopixel" config section The following command is available when "neopixel" or "dotstar" config
is enabled: sections are enabled:
- `SET_NEOPIXEL NEOPIXEL=<config_name> INDEX=<index> RED=<value> - `SET_LED LED=<config_name> INDEX=<index> RED=<value> GREEN=<value>
GREEN=<value> BLUE=<value>`: This sets the Neopixel LED output. Each BLUE=<value>`: This sets the LED output. Each color <value> must be
color <value> must be between 0.0 and 1.0. If multiple Neopixel between 0.0 and 1.0. If multiple LED chips are daisy-chained then
chips are daisy-chained then one may specify INDEX to alter the one may specify INDEX to alter the color of just the given chip (1
color of just the given Neopixel chip (1 for the first Neopixel, 2 for the first chip, 2 for the second, etc.). If INDEX is not
for the second, etc.). If INDEX is not provided then all Neopixels provided then all LEDs in the daisy-chain will be set to the
in the daisy-chain will be set to the provided color. provided color.
## Servo Commands ## Servo Commands

61
klippy/extras/dotstar.py Normal file
View File

@ -0,0 +1,61 @@
# Support for "dotstar" leds
#
# Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net>
#
# 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)

View File

@ -29,9 +29,9 @@ class PrinterNeoPixel:
self.printer.register_event_handler("klippy:connect", self.send_data) self.printer.register_event_handler("klippy:connect", self.send_data)
# Register commands # Register commands
self.gcode = self.printer.lookup_object('gcode') self.gcode = self.printer.lookup_object('gcode')
self.gcode.register_mux_command("SET_NEOPIXEL", "NEOPIXEL", name, self.gcode.register_mux_command("SET_LED", "LED", name,
self.cmd_SET_NEOPIXEL, self.cmd_SET_LED,
desc=self.cmd_SET_NEOPIXEL_help) desc=self.cmd_SET_LED_help)
def build_config(self): def build_config(self):
if self.mcu.get_constant_float('CLOCK_FREQ') <= 20000000: if self.mcu.get_constant_float('CLOCK_FREQ') <= 20000000:
raise self.printer.config_error( raise self.printer.config_error(
@ -42,8 +42,8 @@ class PrinterNeoPixel:
def send_data(self, minclock=0): def send_data(self, minclock=0):
self.neopixel_send_cmd.send([self.oid, self.color_data], self.neopixel_send_cmd.send([self.oid, self.color_data],
minclock=minclock) minclock=minclock)
cmd_SET_NEOPIXEL_help = "Set the color of a neopixel led" cmd_SET_LED_help = "Set the color of an LED"
def cmd_SET_NEOPIXEL(self, params): def cmd_SET_LED(self, params):
# Parse parameters # Parse parameters
red = self.gcode.get_float('RED', params, 0., minval=0., maxval=1.) red = self.gcode.get_float('RED', params, 0., minval=0., maxval=1.)
green = self.gcode.get_float('GREEN', params, 0., minval=0., maxval=1.) green = self.gcode.get_float('GREEN', params, 0., minval=0., maxval=1.)