▲ 0 r/esp32

Strange ESP32 behaviour with addressable LED

Edit: Somehow I've resolved this, just by changing the pin assignment and connections, even though I'd already done that.

Context: I'm running ESPhome on an ESP32-C6 supermini. It's connected to three output devices; a 360 degree servo on GPIO20, a 180 servo on GPIO19, and a single WS2811 LED on GPIO 18.

I had it all set up and working fine, until in a daft moment, I used some metal tweezers to move the LED and I think I shorted something. From that point on I couldn't get the LED to work, but both servos behaved fine. But this is where it gets weird

I assumed I blew the LED, no big I have spares. So I hooked up a new LED but nothing worked. I thought maybe I grabbed a duff second LED so I took it over to my testing bench, copied the code from my prod ESP and hooked up the LED. Everything worked fine.

Next thing I thought it could be was that I'd somehow blown the pin the LED was connected to. So I changed the pinout to GPIO15 (and then GPIO16) and connected everything up. Still nothing.

Finally I thought maybe I'd blow the the power or ground line. I'd done a continuity check on both and it was fine. But nonetheless, I hooked up the prod boards 5V and GND lines to the testing boards corresponding lines, powered the test board, and confirmed that the prod board was receiving power. So far so good. I then connected the 2nd LED to the 5V and GND lines on the prod board, but the data pin on the testing board. On accessing the test-board, I was able to confirm the LED works.

So far I've confirmed:

  • 5v continuity on the prod esp
  • GND continuity on the prod esp
  • Continuity between the data pin and the LED
  • LED works
  • Code works
  • Prod board works for servos and logging with no errors

What doesn't work:

  • LED on original GPIO18
  • LED on GPIO15 or 16

My question is—is there some kind of hardware element on an ESP board that could be damaged by shorting an attached LED that would disable it from controlling LEDs, but not affect anything else?

Here's my sanitised ESPHome Code

esphome:
  name: n26-comms-array
  friendly_name: N26 - Comms Array
  min_version: 2026.4.0
  name_add_mac_suffix: false

esp32:
  variant: esp32c6
  framework:
    type: esp-idf

# Enable logging
logger:

# Enable Home Assistant API
api:

# Allow Over-The-Air updates
ota:
  - platform: esphome

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

espnow:
  peers: 
    - ###########
  on_receive:
    - lambda: |-
        char hex[256];
        ESP_LOGD("espnow", "Data %s:", format_hex_pretty_to(hex, data, size));
    - if:
        condition:
          lambda: "return size >= 1 && data[3] == 0x11;"
        then:
        - lambda: |-
            ESP_LOGD("espnow", "Toggled");
        - button.press: rotate_dish_left
    - if:
        condition:
          lambda: "return size >= 1 && data[3] == 0x22;"
        then:
        - lambda: |-
            ESP_LOGD("espnow", "Faulty Lights 1");
        - button.press: rotate_dish_right
    - if:
        condition:
          lambda: "return size >= 1 && data[3] == 0x33;"
        then:
        - lambda: |-
            ESP_LOGD("espnow", "Faulty Lights 2");
        - button.press: pan_dish_up
    - if:
        condition:
          lambda: "return size >= 1 && data[3] == 0x44;"
        then:
        - lambda: |-
            ESP_LOGD("espnow", "Faulty Lights 1");
        - button.press: pan_dish_down
    - if:
        condition:
          lambda: "return size >= 1 && data[3] == 0x55;"
        then:
        - lambda: |-
            ESP_LOGD("espnow", "Faulty Lights 2");
        - button.press: connection_sweep

servo:
  - id: rotation
    output: pwm_output_1
    min_level: 3%
    idle_level: 7.5%
    max_level: 12.5%
    transition_length: 1s
    
  - id: pan
    output: pwm_output_2
    min_level: 3%
    idle_level: 7.5%
    max_level: 12.5%
    transition_length: 2s

output:
  - platform: ledc
    id: pwm_output_1
    pin: GPIO20
    frequency: 50Hz
    
  - platform: ledc
    id: pwm_output_2
    pin: GPIO19
    frequency: 50Hz

number:
  - platform: template
    id: pan_position
    name: "Pan Position"
    min_value: -1
    max_value: 1
    initial_value: 0
    step: 0.01
    restore_value: false
    optimistic: true
    on_value:
      then:
        - servo.write: 
            id: pan
            level: !lambda "return x;"
  - platform: template
    id: pan_increment
    name: "Pan Increment"
    min_value: 0.00
    max_value: 1
    initial_value: 0.05
    step: 0.05
    restore_value: false
    optimistic: true

switch:
  - platform: template
    id: sweep_mode
    optimistic: true
    on_turn_on:
      then:
        - light.control:
            id: uplink
            state: on
            effect: "Scanning"
            red: 50%
            blue: 0%
            green: 0%
        - servo.write: 
            id: rotation
            level: -0.16
        - while: 
            condition:
              lambda: 'return id(sweep_mode).state;'
            then:
            - servo.write:
                id: pan
                level: 1
            - delay: 2000ms
            - servo.write:
                id: pan
                level: -1
            - delay: 2000ms

    on_turn_off:
      then:
      - servo.detach: 
          id: pan
      - servo.write:
          id: rotation
          level: 0
      - servo.detach: 
          id: rotation
      - light.turn_off: 
          id: uplink

script:
  - id: rotate_left
    then:
      - servo.write:
          id: rotation
          level: -16.0%
      - delay: 500ms
      - servo.write:
          id: rotation
          level: 0%        
  - id: rotate_right
    then:
      - servo.write:
          id: rotation
          level: 16.0%
      - delay: 500ms
      - servo.write:
          id: rotation
          level: 0%
  - id: pan_up
    then:
      - if: 
          condition:
            lambda: 'return (id(pan_position).state - id(pan_increment).state) > -1.0;'
          then: 
            - number.set: 
                id: pan_position
                value: !lambda "return id(pan_position).state - id(pan_increment).state;"
          else: 
            - number.set: 
                id: pan_position
                value: -1.0

  - id: pan_down
    then:
      - if: 
          condition:
            lambda: 'return (id(pan_position).state + id(pan_increment).state) < 1.0;'
          then: 
            - number.set: 
                id: pan_position
                value: !lambda "return id(pan_position).state + id(pan_increment).state;"
          else: 
            - number.set: 
                id: pan_position
                value: 1.0
light:
  - platform: esp32_rmt_led_strip
    channel_colors: GRB
    pin: GPIO18
    num_leds: 1
    chipset: WS2811
    rmt_symbols: 96
    id: uplink
    name: "Uplink"
    effects: 
      - pulse:
          name: "Scanning"
          transition_length: 1s
          update_interval: 1s
          min_brightness: 0%
          max_brightness: 50%
      - flicker:
          name: "Data Transmision"
          alpha: 50%
          intensity: 100%

button:
  - platform: template
    id: rotate_dish_left
    name: "Rotate Left"
    on_press:
      then:
        - script.execute: rotate_left
  - platform: template
    id: rotate_dish_right
    name: "Rotate Right"
    on_press:
      then:
        - script.execute: rotate_right
  - platform: template
    id: pan_dish_up
    name: "Pan Up"
    on_press:
      then:
        - script.execute: pan_up
  - platform: template
    id: pan_dish_down
    name: "Pan Down"
    on_press:
      then:
        - script.execute: pan_down
  - platform: template
    id: home_dish
    name: "Home Dish Position"
    on_press:
      then:
      - servo.write:
          id: pan
          level: 0.0%
      - number.set: 
          id: pan_position
          value: 0.00
  - platform: template
    id: scanning
    name: "Scanning"
    on_press:
      then:
        - light.control:
            id: uplink
            state: on
            effect: "Scanning"
            red: 50%
            blue: 0%
            green: 0%

            
  - platform: template
    id: transmitting
    name: "Transmitting"
    on_press:
      then:
        - light.control:
            id: uplink
            state: on
            effect: "Data Transmision"
            red: 0%
            blue: 0%
            green: 50%

  - platform: template
    id: connection_sweep
    name: "Connection Sweep"
    on_press:
      then:
        - switch.toggle: 
            id: sweep_mode
reddit.com
u/Davedamon — 6 days ago

Digitally kitbashed a custom crane for my N26 board

I wanted a crane I could suspend a cargo container from in the middle of the board I'm working on, to serve as a precarious "bridge" between two platforms. None of the models I could find worked, so I did some digital kitbashing. All the base components are taken from models by Two goblins in a trench coat over on MakerWorld who does some amazing Necromunda terrain.

u/Davedamon — 2 months ago

Suggestions for Dracolithe proxies ?

I really like the rules for the Exodites kill team, but the models don't super appeal. I'm very keen to do a jetbike proxy team, which is the easy part. The hard part is figuring out what to use to proxy the dracolithes. In theory it needs to satisfy the following criteria:

  • 32mm base
  • aeldari model
  • makes sense as a 'beast' type operative
  • fits in with a team of three jetbikes

I'd love any suggestions

reddit.com
u/Davedamon — 3 months ago

Finally finished my red terror mini, including a digital life counter in the base

I swear the base took longer than the mini itself, especially figuring out how to fit all the electronics inside. But I'm really happy with how it all turned out

u/Davedamon — 4 months ago

Nemesis NPO Card PDFs in blank and form fillable versions

Knocked these up in photoshop. They should print at 1:1 scale, but with all things, do a test print first

drive.google.com
u/Davedamon — 5 months ago

I mentioned this in another thread and someone requested I make it into its own post. Here's how you can configure custom search actions in Chrome for various aspects of D&D Beyond:

  1. Open Chrome settings, go to Search engine and then Manage search engines and site search
  2. Scroll down to Site Search and click Add
  3. Give the site search a useful name, such as "DDB Feats"
  4. Give it a useful shortcut, such as "feat"
  5. Finally, in the third field add this URL: https://www.dndbeyond.com/feats?filter-name=%s&filter-partnered-content=t
  6. Click save

Now if you go to the URL bar and type in "feat" followed by a space, it'll switch to a search operator. You can now search for any feat and it'll take you directly to the feats listing with the searched feat in the search field.

I've set up the following searches which I find really useful:

Sitewide: shortcut ddb and url https://www.dndbeyond.com/search?q=%s

Backgrounds: shortcut background and url https://www.dndbeyond.com/backgrounds?filter-name=%s&filter-partnered-content=t

Equipment: equipment and https://www.dndbeyond.com/equipment?filter-search=%s&filter-cost-min=&filter-cost-max=&filter-weight-min=&filter-weight-max=&filter-partnered-content=t

Magic items: item and https://www.dndbeyond.com/magic-items?filter-type=0&filter-search=%s&filter-requires-attunement=&filter-effect-type=&filter-effect-subtype=&filter-has-charges=&filter-partnered-content=t

Monsters: monster and https://www.dndbeyond.com/monsters?filter-search=%s&filter-partnered-content=t

Spells: spell and https://www.dndbeyond.com/spells?filter-search=%s&filter-partnered-content=t

If you want to customise any of these, go to a listing page and search for "TEST". Adjust any filters such as source or partnered content, then copy the URL. Change TEST to %s and you're good to go.

reddit.com
u/Davedamon — 5 months ago