H-Bridge 2-wire fairy light controller

So, this project was born out of wanting to replace the controller from two sets of these fairy lights.

Partially because I wanted them both to turn on at the same time, and partly because having the stock controller on a z-wave plug seemed to reset the effects back to the ‘demo’ one, which cycled through some seizure-inducing flashing.

Evidently anyone else that has done so hasn’t written it up, or my Google-fu sucked, because I really struggled to find anything I could use as base, other than the example stuff on the ESPHome docs, and a snippet of Red-Green transition lambda code.

I’ll post a bit more about the hardware used and add a wiring diagram later, but the proof of concept on a test set of string lights works a treat - and I’ve managed to bodge together a couple of effects that work for the way ESPHome sees these lights.

Hardware:

Issues:

  • Need to see if there’s a better way to ‘activate’ each string in the strobe effect, rather than color_temperature. Tried cold_white/warm_white but it threw a “Color temperature value 0.00 is out of range (153.0 - 500.0)”. 3500K seems to be close to the mid-point to activate both strings so have been using that as an “all on” value.
  • In the lambda effect, it seems to flicker a little on each cycle.
  • Add some more effects - in particular a ‘twinkle’ where the two sets of lights twinkle at random brightnesses.

ESPHome YAML:

esphome:
  name: "led-strings"
  platform: ESP8266
  board: d1_mini

wifi:
  ssid: !secret wifi_iot_ssid
  password: !secret wifi_iot_password
  ap:
    ssid: $friendly_name Fallback Hotspot
    password: !secret esphome_fallback_ap_password

captive_portal:

logger:

api:
  encryption:
    key: !secret esphome_api_key

ota:
  password: !secret esphome_api_password

output:
  - platform: esp8266_pwm
    id: pina
    pin: GPIO12
  - platform: esp8266_pwm
    id: pinb
    pin: GPIO14

light:
  - platform: hbridge
    id: ledstrings
    name: "led-strings"
    pin_a: pina
    pin_b: pinb
    
    effects:
      - strobe:
          name: "Flash A-B 500ms"
          colors:
            - state: true
              color_temperature: 2000 K
              duration: 500ms
            - state: true
              color_temperature: 6534 K
              duration: 500ms
      - strobe:
          name: "Flash A-AB-B 500ms"
          colors:
            - state: true
              color_temperature: 2000 K
              duration: 500ms
            - state: true
              color_temperature: 3500 K
              duration: 500ms
            - state: true
              color_temperature: 6534 K
              duration: 500ms
            - state: true
              color_temperature: 3500 K
              duration: 500ms
      - lambda:
          name: "Fade A-AB-B 10s"
          update_interval: 10s
          lambda: |-
            static int state = 0;
            auto call = id(ledstrings).make_call();
            call.set_transition_length(10000);
            if (state == 0) {
              call.set_warm_white(1.0);
              call.set_cold_white(0.0);
            } else if (state ==1) {
              call.set_warm_white(0.0);
              call.set_cold_white(1.0);
            }
            call.perform();
            state += 1;
            if (state == 2)
              state = 0;
2 Likes

Hi @KablammoNick - this is excellent timing - I’ve just got my hbridge driver working myself, and so the effects are great to add in!
Just one question though - do your lights glitch? It’s really noticeable on my system…

Yeah, doesn’t seem to be as noticeable on the effects I’ve got there, but when manually changing colour temp or brightness they glitch/flash a little.
Messing around trying to DIY a “twinkle” effect it does the same, so about all I’ve got is what’s up there at the moment.
Happy to test any you’ve got though.

I agree, Googling for this info is quite hard so I appreciate you doing a write up of it.
@KablammoNick are you able to add the wiring diagram and/or real photos of the hardware all set up?

Below are some of my finding on this topic:
Hanson Electronics sells a DMX2-24 piece of hardware that seems to allow you to control these 2 wire LED fairy lights. It uses DMX instead of ESPHome. DMX can be controlled through HA though.
More interestingly though is in the manual he explains more about the Multifunction modes.

  1. Combination cycles through the 7 actual modes
  2. In Waves toggles 1 half followed by other at about 5hz
  3. Sequential toggles 1 half followed by other half at about 1hz
  4. “Slo Glo” ramps 1 half up then down followed by the other. about 5s up, 5s down
  5. Chasing /Flash toggles 1 half followed by the other half about 3 times at 5hz followed by 1 half flashing 3 times
    at 5 hz then the other 3 times.
  6. Slow Fade ramps all up followed by all down. about 5s each way
  7. Twinkle / Flash flashes 1 half twice then other half twice
  8. Steady On lights on 100%

You can get a smart controller that replaces the stock controller. It’s tuya based and says that it works on most lights 31-33V 8.4W or less. So for your long lights it likely wouldn’t work.

With wiring it up you could get a fairy light female pigtail meaning you wouldn’t have to chop off the end of your existing lights.

Would it work with other ESP’s such as a ESP32 dev board or ESP32-C3?
Did you just pick a power supply with the same amps and volts as your stock controller?

1 Like

Years ago I looked into trying to flash a similar set of lights from Aussie KMart which were running an ESP (back in the Tuya-Convert days) but since I couldn’t figure out a suitable ESPhome config for them the project went stale. I’ll have to have another crack at it with what you have here. My main concern was with trying to get decent effects similar to the standard ones out of the box. The main difference I se with the ones I have is that they have multiple colours effects.

They are like the ones in this Christmas tree set.

Here is the original thread about them.

The ambient heat outside got to the adhesive that was holding the wago connectors onto the outside of the case, so it’s a bit of a mess but:



Not sure how best to draw a wiring diagram but hopefully the pictures help.
Orange and Yellow wires are on D5 + D6, and the White issnuck in on GND. Terrible colour choice but this was ‘temporary’ for testing - but has been going fine so far so haven’t bothered getting back up to tidy up.

I did find those - funnily enough from my original thread on AusChristmasLighting. They were the backup ‘throw money at it’ solution, but felt like overkill for a single string.
Interesting to see the modes in the manual - if I get some spare time I might see if I can recreate them in ESPHome.

Interesting, didn’t see them at all in my searching - Tuya based so possibly even flashable with ESPHome depending on how long the production run was - might get lucky and they’re older chips.
Agreed it might not be enough - I can’t measure the actual power usage of these but the original bricks are 12w.

I’ve got a feeling those weren’t quite right sizing but ended up just chopping the lights and using a couple of the threeway wago’s.

I assume it would be fine with other ESP’s, but I don’t know enough to say with certainty.

The PSU is variable voltage, adjusted it to 31v. I can’t remember why I ended up with 8A, given from a quick re-calculation that’s ~240w so well and truly overkill. Quite possibly because there was buggerall cost difference and figured if I wanted to use it for more strings then it was good to go.

Yeah wow, I think adding RGB would be a huge step up in complexity if starting from scratch - not only for the ESP but the effects.

Thanks for the great extra info. Seems like enough details for me to have a crack at it. I also found Jaycar has a write-up on a method of using these sort of 2-wire lights with an Arduino UNO. Jaycar-Electronics/Christmas-Light-Controller: Lost your power supply or light controller? (github.com)

I did ended up buying the Tuya smart controller. It’s actually pretty good. I’ve opened a PR to get it supported in Tuya Local: Add support for 8 Functions String Light Control Adaptor by BenJamesAndo · Pull Request #1630 · make-all/tuya-local (github.com). More info about the device can be found there. I might end up flashing it to ESPHome, although replicating all the functionality it exposes with Tuya already would be quite challenging, but likely possible. I reckon though the 8 modes could definitely be improved with ESPHome, such as Slow-Glo. It would be nice if it didn’t fade all the way off and on again, but instead faded down to 5% and then up.

1 Like

Is using an H-bridge to control LED’s a new thing? It makes sense now that i think about it, its just 4 Fets in there. IDK how ive never heard of people doing this before.

What are the pros and cons for using this vs. a 4 channel mosfet module?

TBH no idea. I came across it whilst googling how to replace the controller & power supply with something that used ESPHome and just ran with that.

Looks like it was added to ESPHome in Version 1.16.0 back in Feb 2021 - by someone that was looking to control Christmas lights too.
I suspect the lights he refers to used to use ESP chips that were flashable, whereas now most of the Mirabella ones available here use ?BK or the other not easily flashable ones.

… and no idea about these vs mosfets sorry!

Hrmm. I will try and have a play this afternoon - will probably have to wait until its dark to test properly.
Thinking just use fade A-AB-B but the crossover would be at say 0.1 instead of 0.0.

Couldn’t help myself…

2 seconds to transition, no hold between the cycle, “down” to a value of 0.2 as 0.1 seemed too dull but it’s the middle of the day here so will test again tonight.

      - lambda:
          name: "Slow-Glo | Fade A-AB-B 2s 0.2"
          update_interval: 2s
          lambda: |-
            static int state = 0;
            auto call = id(ledstrings).make_call();
            call.set_transition_length(2000);
            if (state == 0) {
              call.set_warm_white(1.0);
              call.set_cold_white(0.2);
            } else if (state ==1) {
              call.set_warm_white(0.2);
              call.set_cold_white(1.0);
            }
            call.perform();
            state ++;
            if (state == 2)
              state = 0;

I remember seeing this now.

Ive jusr never considered using an H-bridge since ive always used these.
https://www.amazon.com/3-7-27VDC-4-Channel-Driver-Amplifier-Circuit/dp/B07QGXY7F3/ref=asc_df_B07QGXY7F3/?tag=hyprod-20&linkCode=df0&hvadid=459440176747&hvpos=&hvnetw=g&hvrand=3589419955251698302&hvpone=&hvptwo=&hvqmt=&hvdev=m&hvdvcmdl=&hvlocint=&hvlocphy=9016042&hvtargid=pla-949854341482&psc=1&mcid=bb66a86754773c29b93c2f1c45f78d3b&gclid=CjwKCAiA2pyuBhBKEiwApLaIO3FvSJCBN2KJyNu56ETVOqKq5_RmF_7nB_XtWfcTMvPtoOPvaMV8uBoC68AQAvD_BwE

I gueas my curiosity is about chiosing one over the other? I dont think its just me but, h-bridges are usually associated with driving motors. I get that its the same process to drive a motor and drive led’s. Its just interesting to me i guess.

These can now be flashed with ESPhome as well though.

I’ve got a feeling when I last looked, it required opening them up which was difficult to do non-destructively. That or it could be done with tuya-cloudcutter first but needed a setup beyond what I had readily available.

Might have to look into that again too though - these are pretty neat as spare room lights.

You know you can get smart bulbs with esphome pre-flashed right? Or is it just the shape of this that you like?

Yeah it’s the shape for these, in a location without a shade - got a handful of Hue, Wiz and ESPhome flashed bulbs elsewhere in the house

Finally remembered to film at night… although the iPhone camera tries to correct the darkness.

1 Like

I managed to get the Tuya 2-wire controller flashed with ESPHome. It uses a Beken chip. None of the Cloud-Cutter profiles worked but I was able to get it working without soldering using Tuya-Cloudcutter Lightleak. I wish I knew about Lightleak before I used a rotary tool to open it up haha. It’s now officially supported in Cloud-Cutter see Lexi String Light Controller · Issue #629 · tuya-cloudcutter/tuya-cloudcutter (github.com)
Thanks so much to your ESPHome code I was able to quickly get it working. The scenes you made look really nice!
Here’s my modified YAML.

esphome:
  name: lexi-controller
  on_boot:
      priority: 600
      then:
        - light.turn_on:
            id: ledstrings
            brightness: 100%
            color_temperature: 4268K

bk72xx:
  board: generic-bk7231t-qfn32-tuya

logger:

web_server:

captive_portal:

mdns:

api:
  password: ""

ota:
  password: ""

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

output:
  - platform: libretiny_pwm
    id: pina
    pin: P24
  - platform: libretiny_pwm
    id: pinb
    pin: P26

binary_sensor:
  - platform: gpio
    id: binary_switch_1
    pin:
      number: P8
      inverted: true
      mode: INPUT_PULLUP
    on_press:
      then:
        - light.toggle: ledstrings

light:
  - platform: status_led
    id: stat_led
    name: "Switch state"
    pin:
      number: P7
  - platform: hbridge
    id: ledstrings
    name: "led-strings"
    pin_a: pina
    pin_b: pinb
    restore_mode: RESTORE_DEFAULT_OFF
    on_turn_on:
    - light.turn_on: stat_led
    on_turn_off:
    - light.turn_off: stat_led
    effects:
      - strobe:
          name: "Flash A-B 500ms"
          colors:
            - state: true
              color_temperature: 2000 K
              duration: 500ms
            - state: true
              color_temperature: 6534 K
              duration: 500ms
      - strobe:
          name: "Flash A-AB-B 500ms"
          colors:
            - state: true
              color_temperature: 2000 K
              duration: 500ms
            - state: true
              color_temperature: 3500 K
              duration: 500ms
            - state: true
              color_temperature: 6534 K
              duration: 500ms
            - state: true
              color_temperature: 3500 K
              duration: 500ms
      - lambda:
          name: "Fade A-AB-B 10s"
          update_interval: 10s
          lambda: |-
            static int state = 0;
            auto call = id(ledstrings).make_call();
            call.set_transition_length(10000);
            if (state == 0) {
              call.set_warm_white(1.0);
              call.set_cold_white(0.0);
            } else if (state ==1) {
              call.set_warm_white(0.0);
              call.set_cold_white(1.0);
            }
            call.perform();
            state += 1;
            if (state == 2)
              state = 0;
      - lambda:
          name: "Slow-Glo | Fade A-AB-B 2s 0.2"
          update_interval: 2s
          lambda: |-
            static int state = 0;
            auto call = id(ledstrings).make_call();
            call.set_transition_length(2000);
            if (state == 0) {
              call.set_warm_white(1.0);
              call.set_cold_white(0.2);
            } else if (state ==1) {
              call.set_warm_white(0.2);
              call.set_cold_white(1.0);
            }
            call.perform();
            state ++;
            if (state == 2)
              state = 0;
1 Like