From 3fcdaaefe08ad2b2d6104a65b42b874aba3651c6 Mon Sep 17 00:00:00 2001 From: Nico B <17694+youknow0@users.noreply.github.com> Date: Sun, 1 Nov 2020 19:45:21 +0100 Subject: [PATCH] add FastLED YAML option for data rate (#1338) * fix: FastLED SPI_DATA_RATE being truncated to 8 bits FastLED expects SPI_DATA_RATE as an uint32_t, but we had it as uint8_t. Fix that to avoid the data rate being truncated. * fastled: allow specifying data rate Previously, we've just taken the default data rate from FastLED. However, that does not always work properly. In my case, I had a slow level shifter that couldn't keep up with the 1 MHz data rate default for WS2801. Long cabling might also be a reason why one might want to reduce the data rate. This will add a new optional "data_rate" config option where one may specify the desired data rate as a frequency: light: - platform: fastled_spi chipset: WS2801 data_pin: GPIO23 clock_pin: GPIO22 data_rate: 500kHz num_leds: 178 --- .../components/fastled_base/fastled_light.h | 2 +- esphome/components/fastled_spi/light.py | 20 ++++++++++++++----- esphome/const.py | 1 + tests/test1.yaml | 1 + 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/esphome/components/fastled_base/fastled_light.h b/esphome/components/fastled_base/fastled_light.h index 0729941e31..59d143dbef 100644 --- a/esphome/components/fastled_base/fastled_light.h +++ b/esphome/components/fastled_base/fastled_light.h @@ -38,7 +38,7 @@ class FastLEDLightOutput : public light::AddressableLight { return *this->controller_; } - template + template CLEDController &add_leds(int num_leds) { switch (CHIPSET) { case LPD8806: { diff --git a/esphome/components/fastled_spi/light.py b/esphome/components/fastled_spi/light.py index 959c8a1b19..ef14c05738 100644 --- a/esphome/components/fastled_spi/light.py +++ b/esphome/components/fastled_spi/light.py @@ -2,7 +2,8 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome import pins from esphome.components import fastled_base -from esphome.const import CONF_CHIPSET, CONF_CLOCK_PIN, CONF_DATA_PIN, CONF_NUM_LEDS, CONF_RGB_ORDER +from esphome.const import CONF_CHIPSET, CONF_CLOCK_PIN, CONF_DATA_PIN, CONF_DATA_RATE, \ + CONF_NUM_LEDS, CONF_RGB_ORDER AUTO_LOAD = ['fastled_base'] @@ -21,15 +22,24 @@ CONFIG_SCHEMA = fastled_base.BASE_SCHEMA.extend({ cv.Required(CONF_CHIPSET): cv.one_of(*CHIPSETS, upper=True), cv.Required(CONF_DATA_PIN): pins.output_pin, cv.Required(CONF_CLOCK_PIN): pins.output_pin, + cv.Optional(CONF_DATA_RATE): cv.frequency, }) def to_code(config): var = yield fastled_base.new_fastled_light(config) - rgb_order = None - if CONF_RGB_ORDER in config: - rgb_order = cg.RawExpression(config[CONF_RGB_ORDER]) + rgb_order = cg.RawExpression(config[CONF_RGB_ORDER] if CONF_RGB_ORDER in config else "RGB") + data_rate = None + + if CONF_DATA_RATE in config: + data_rate_khz = int(config[CONF_DATA_RATE] / 1000) + if data_rate_khz < 1000: + data_rate = cg.RawExpression(f"DATA_RATE_KHZ({data_rate_khz})") + else: + data_rate_mhz = int(data_rate_khz / 1000) + data_rate = cg.RawExpression(f"DATA_RATE_MHZ({data_rate_mhz})") template_args = cg.TemplateArguments(cg.RawExpression(config[CONF_CHIPSET]), - config[CONF_DATA_PIN], config[CONF_CLOCK_PIN], rgb_order) + config[CONF_DATA_PIN], config[CONF_CLOCK_PIN], rgb_order, + data_rate) cg.add(var.add_leds(template_args, config[CONF_NUM_LEDS])) diff --git a/esphome/const.py b/esphome/const.py index 4d45d68839..e42da2e178 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -136,6 +136,7 @@ CONF_DALLAS_ID = 'dallas_id' CONF_DATA = 'data' CONF_DATA_PIN = 'data_pin' CONF_DATA_PINS = 'data_pins' +CONF_DATA_RATE = 'data_rate' CONF_DATA_TEMPLATE = 'data_template' CONF_DAYS_OF_MONTH = 'days_of_month' CONF_DAYS_OF_WEEK = 'days_of_week' diff --git a/tests/test1.yaml b/tests/test1.yaml index 10e35594fe..6208f8ec70 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -1230,6 +1230,7 @@ light: chipset: WS2801 data_pin: GPIO23 clock_pin: GPIO22 + data_rate: 2MHz num_leds: 60 rgb_order: BRG name: "FastLED SPI Light"