esphome-yeelight-led-screen-light-bar icon indicating copy to clipboard operation
esphome-yeelight-led-screen-light-bar copied to clipboard

[Guide] Hardware hack to work around flickering RGB LEDs

Open NZSmartie opened this issue 1 year ago • 13 comments

TL;DR

Cut the wire labelled RGB and wire it up to the RX pad on the Wifi Module, then use pin: GPIO3 in the yaml file

Guide

I'm not sure if to make a pull request or to add it here as a helpful guide. ESPHome now uses Arduino 3, Fast LED is no longer supported on the ESP8266

(source https://esphome.io/components/light/fastled)

[!warning] FastLED does not work as expected with Arduino 3 or newer for ESP8266. For now, you can either downgrade the arduino version or use NeoPixelBus Light.

esp8266:
  framework:
    version: 2.7.4

See these related issues:

  • https://github.com/FastLED/FastLED/issues/1322
  • https://github.com/FastLED/FastLED/issues/1264
  1. The first step is to Switch over to using Neopixelbus in the config yaml

    diff --git a/test.yaml b/test.yaml
    index 9269e18..20171a3 100644
    --- a/test.yaml
    +++ b/test.yaml
    @@ -65,12 +65,12 @@ light:
         warm_white: output_ww
         cold_white_color_temperature: 6500 K
         warm_white_color_temperature: 2700 K
    -  - platform: fastled_clockless
    -    rgb_order: GRB
    +  - platform: neopixelbus
    +    type: GRB
    +    variant: WS2812X
         num_leds: 40
         pin: GPIO13
         name: "Yeelight Screenbar back LED Ring"
    -    chipset: WS2812B
         id: LED_ring
         power_supply: power
         effects:
    
  2. As for NeoPixelBus, There are three suggested GPIOs for driving the LEDs smoothly (source https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods)

    [!important] The ESP8266 requires hardware support to be able to reliably send the data stream. While a bit bang method is provided, it is not recommended. Due to this and the restrictions on which pins are used by each hardware peripheral, only I/O pins GPIO1, GPIO2, and GPIO3 can be used. The Pin argument is ignored and can be omitted.

    The DMA methods will use GPIO3. The UART1 methods will use GPIO2. The UART0 methods will use GPIO1.

    For the light bar, GPIO2 is used by the wireless remote receiver, and GPIO1 is unknown GPIO3 which is the RX pin on the ESP8266 is unused as ESPHome provides Over The Air updates. So Cut the RGB wire and spliced it to the RX pad. image

  3. Then update the yaml to use GPIO3

    diff --git a/test.yaml b/test.yaml
    index 20171a3..7db94f8 100644
    --- a/test.yaml
    +++ b/test.yaml
    @@ -69,7 +69,7 @@ light:
         type: GRB
         variant: WS2812X
         num_leds: 40
    -    pin: GPIO13
    +    pin: GPIO3
         name: "Yeelight Screenbar back LED Ring"
         id: LED_ring
         power_supply: power
    

NZSmartie avatar Jan 10 '24 23:01 NZSmartie

hi, cool I'm trying to test this weekend. I will update the page with your information.

dckiller51 avatar Jan 11 '24 10:01 dckiller51

Above hack absolutely works, tested with 2 LEDs and totally controllable.

light:
  - platform: neopixelbus
    variant: WS2812X
    type: GRB
    pin: GPIO3
    num_leds: 5
    name: "Yeelight Screenbar back LED Ring"
    id: LED_ring

but only one thing, when brightness is less than 10% the LEDs goes off.

mutthunaveen avatar Jan 16 '24 12:01 mutthunaveen

I am trying to repeat this project, but when I try to compile a yaml file, errors appear. Who can share a working yaml file? The first error is due to rx_pin: GPIO2, it is repeated in the UART and i2C block. The second error is related to the lack of FastLED support.

TeslaWorks239 avatar Jan 20 '24 23:01 TeslaWorks239

Also problem while compiling. List: Compiling .pioenvs/yeelight/src/esphome/components/api/api_pb2_service.cpp.o In file included from src/esphome/components/api/api_connection.h:6:0, from src/esphome/components/api/api_connection.cpp:1: src/esphome/components/api/api_server.h:118:96: error: invalid use of '::' Trigger<std::string, std::string> *client_connected_trigger_ = new Trigger<std::string, std::string>(); ^ src/esphome/components/api/api_server.h:118:96: error: expected ';' at end of member declaration src/esphome/components/api/api_server.h:118:102: error: expected unqualified-id before '>' token Trigger<std::string, std::string> *client_connected_trigger_ = new Trigger<std::string, std::string>(); ^ src/esphome/components/api/api_server.h:119:99: error: invalid use of '::' Trigger<std::string, std::string> *client_disconnected_trigger_ = new Trigger<std::string, std::string>(); ^ src/esphome/components/api/api_server.h:119:99: error: expected ';' at end of member declaration src/esphome/components/api/api_server.h:119:105: error: expected unqualified-id before '>' token Trigger<std::string, std::string> *client_disconnected_trigger_ = new Trigger<std::string, std::string>(); ^ src/esphome/components/api/api_server.h:118:83: error: template argument 1 is invalid Trigger<std::string, std::string> *client_connected_trigger_ = new Trigger<std::string, std::string>(); ^ src/esphome/components/api/api_server.h:119:86: error: template argument 1 is invalid Trigger<std::string, std::string> *client_disconnected_trigger_ = new Trigger<std::string, std::string>(); ^ cc1plus: warning: unrecognized command line option "-Wno-nonnull-compare" [enabled by default] *** [.pioenvs/yeelight/src/esphome/components/api/api_connection.cpp.o] Error 1

TeslaWorks239 avatar Jan 21 '24 00:01 TeslaWorks239

I have not changed anything in the code that is posted here on github, the only thing I have commented out the lines so that an error does not occur. I did this just to check the performance. But there is a compilation error that I wrote above. #i2c: #sda: GPIO2 #scl: GPIO14 #scan: false

TeslaWorks239 avatar Jan 21 '24 00:01 TeslaWorks239

@TeslaWorks239 For the compiler error change "version": esp8266: board: esp_wroom_02 framework: version: recommended

dckiller51 avatar Jan 21 '24 02:01 dckiller51

@NZSmartie hello, your modification works however do you have a solution for the problem of conflict between i2c and uart because we lose the remote control?

dckiller51 avatar Jan 21 '24 08:01 dckiller51

Remove I2C, the remote control uses UART according to the example

https://github.com/K-4U/custom_components/blob/39eb7ed1b88f326a19aba3400e572fc62d82378b/components/yeelight_remote/README.md?plain=1#L11-L14

NZSmartie avatar Jan 21 '24 08:01 NZSmartie

@NZSmartie thanks. For the version did you put recommended or a particular version?

dckiller51 avatar Jan 21 '24 09:01 dckiller51

This is the yaml I'm using for the light bar:

esphome:
  name: lightbar

esp8266:
  board: esp01_1m

# Enable Home Assistant API
api:
  encryption:
    key: "[redacted]"

ota:
  password: "[redacted]"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Lightbar Fallback Hotspot"
    password: "[redacted]"
    
  domain: .localdomain

captive_portal:

external_components:
  - source:
      type: git
      url: https://github.com/thedsv/yeelight_remote
    components: [ yeelight_remote ]

wled:

# Specify the two pins of the h-bridge as PWM pins
output:
  - platform: esp8266_pwm
    pin: GPIO12
    id: output_cw
    power_supply: power
  - platform: esp8266_pwm
    pin: GPIO5
    id: output_ww
    power_supply: power
    
power_supply:
  - id: power
    pin: GPIO4
    enable_time: 0s
    keep_on_time: 0s

light:
  - platform: cwww
    id: light1
    constant_brightness: true
    gamma_correct: 0
    name: "Yeelight Screenbar face"
    cold_white: output_cw
    warm_white: output_ww
    cold_white_color_temperature: 6500 K
    warm_white_color_temperature: 2700 K
  - platform: neopixelbus
    id: ring
    type: GRB
    variant: WS2812X
    pin: GPIO3
    num_leds: 40
    name: "Yeelight Screenbar back LED Ring"
    power_supply: power
    effects:
      - wled:
          port: 21324
      - addressable_rainbow:
    # Limit the brightness to prevent power supply from browning out.
    color_correct: [90%, 90%, 90%]


uart:
  - id: remote_bus
    baud_rate: 4800
    rx_pin: GPIO2

yeelight_remote:
  on_press:
    - light.toggle: light1
  on_left:
    then:
      - light.dim_relative:
          id: light1
          relative_brightness: -5%
  on_right:
    then:
      - light.dim_relative:
          id: light1
          relative_brightness: 5%
  on_long_press:
    - light.toggle: ring
  on_press_left: 
    - then:
        light.control:
          id: light1
          color_temperature: !lambda |-
            float temp = id(light1).remote_values.get_color_temperature() * 0.95;
            if (temp < 153.8) {
              return 153.8;
            }
            return temp;
  on_press_right: 
    - then:
        light.control:
          id: light1
          color_temperature: !lambda |-
            float temp = id(light1).remote_values.get_color_temperature() * 1.05;
            if (temp > 370.4) {
              return 370.4;
            }
            return temp;

NZSmartie avatar Jan 21 '24 09:01 NZSmartie

I understand correctly that for your version of the code I need cut the RGB wire and spliced it to the RX pad?

TeslaWorks239 avatar Jan 21 '24 09:01 TeslaWorks239

I understand correctly that for your version of the code I need cut the RGB wire and spliced it to the RX pad?

Yes, GPIO3 is the name of the RX pin used that is also used for flash programming.

# ...
light:
  # ...
  - platform: neopixelbus
    # ...
    pin: GPIO3

image [source]

NZSmartie avatar Jan 21 '24 09:01 NZSmartie

Thank you very much)

TeslaWorks239 avatar Jan 21 '24 10:01 TeslaWorks239