Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 1, 2026

Fix GPIO0 pin assignment issues on ESP8266

Problem 1 (Original)

GPIO0 cannot be used as an LED output on ESP8266 because the pin conflict checker unconditionally flags all button GPIO pins as in-use regardless of button state.

Solution 1

Modified pin conflict detection in settings_leds.htm to check button type before marking pin as used. Button pins only conflict when button type is not "Disabled" (value != 0).

Problem 2 (New Issue from @DedeHai)

When removing all buttons in settings UI and saving:

  1. Button 0 with GPIO0 gets automatically added back
  2. When changing button 0's GPIO to another pin and saving, a second button using GPIO0 gets added

Root Cause 2

In set.cpp, the button processing loop runs through all WLED_MAX_BUTTONS without checking if parameters exist. When request->arg(bt) is empty, toInt() returns 0, causing GPIO0 to be assigned. Additionally, the cleanup loop used i > 0 instead of i >= 0, never removing button at index 0.

Solution 2 (Updated per @DedeHai suggestion)

  • Changed button pin assignment to use ternary operator: request->hasArg(bt) ? request->arg(bt).toInt() : -1
  • Fixed cleanup loop to use i >= 0 to include button index 0

Changes Made

  • Updated pin conflict detection in settings_leds.htm (2 locations)
  • Use ternary operator for button pin assignment in set.cpp (cleaner than break statement)
  • Fixed button cleanup loop to include index 0
  • All tests pass
  • Firmware compilation succeeds

Users can now:

  1. Disable buttons and use their GPIO pins for LED outputs
  2. Remove all buttons completely without them being auto-recreated
  3. Change button GPIO pins without duplicates being created
Original prompt

This section details on the original issue you should resolve

<issue_title>ESP8266: GPIO0 can't be used as an output</issue_title>
<issue_description>### What happened?

GPIO0 always gets assigned to a button

To Reproduce Bug

Set GPIO0 as LED output

Expected Behavior

Save correctly

Install Method

Self-Compiled

What version of WLED?

0.16

Which microcontroller/board are you seeing the problem on?

ESP8266

Relevant log/trace output

Anything else?

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct</issue_description>

<agent_instructions>please find the reason GPIO0 always gets assigned to button. I susect an issue in settings_leds.htm </agent_instructions>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 1, 2026

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Comment @coderabbitai help to get the list of available commands and usage tips.

Modified pin conflict detection to check if buttons are enabled before considering their GPIO pins as "in use". Disabled buttons (type = 0) no longer block GPIO reassignment to LED outputs.

Co-authored-by: DedeHai <[email protected]>
Copilot AI changed the title [WIP] Fix GPIO0 assignment issue for LED output Fix GPIO0 pin conflict detection when button is disabled Jan 1, 2026
Copilot AI requested a review from DedeHai January 1, 2026 19:58
@DedeHai
Copy link
Collaborator

DedeHai commented Jan 2, 2026

@copilot the issue is a different one: when I remove all buttons in the settings_leds.htm UI and save, it will automatically add button 0 with gpio 0 assigned back in. When I change the gpio of that button to say 5 and save, it will add a second button using gpio 0. Can you please check the code to find out why this is?

When user removes all buttons and saves, the form handler was processing all WLED_MAX_BUTTONS iterations without checking if parameters exist. Empty request->arg().toInt() returns 0, causing GPIO0 to be auto-assigned. Also fixed cleanup loop to include button index 0.

Co-authored-by: DedeHai <[email protected]>
Copy link
Contributor Author

Copilot AI commented Jan 2, 2026

@copilot the issue is a different one: when I remove all buttons in the settings_leds.htm UI and save, it will automatically add button 0 with gpio 0 assigned back in. When I change the gpio of that b...

Found and fixed the issue! The problem was in wled00/set.cpp:

  1. Button auto-creation: The form handler (line 278) looped through all WLED_MAX_BUTTONS without checking if parameters exist. When request->arg(bt) returned empty, toInt() defaulted to 0, causing GPIO0 to be assigned.

  2. Button 0 persistence: The cleanup loop (line 330) used i > 0 instead of i >= 0, so button at index 0 was never removed.

Fix applied (commit 7f395ea):

  • Added if (!request->hasArg(bt)) break; to stop processing when no button parameters exist
  • Changed cleanup loop to i >= 0 to include button index 0

Now you can remove all buttons without them being auto-recreated, and change button pins without duplicates appearing.

Copilot AI changed the title Fix GPIO0 pin conflict detection when button is disabled Fix GPIO0 button assignment issues on ESP8266 Jan 2, 2026
@DedeHai
Copy link
Collaborator

DedeHai commented Jan 2, 2026

@copilot your fix is wrong. the acutal fix is to only change this single line:
int hw_btn_pin = request->hasArg(bt) ? request->arg(bt).toInt() : -1;

Simplified fix by using `request->hasArg(bt) ? request->arg(bt).toInt() : -1` instead of break statement. This ensures non-existent button parameters default to -1 instead of 0.

Co-authored-by: DedeHai <[email protected]>
Copy link
Contributor Author

Copilot AI commented Jan 2, 2026

@copilot your fix is wrong. the acutal fix is to only change this single line:
int hw_btn_pin = request->hasArg(bt) ? request->arg(bt).toInt() : -1;

You're absolutely right! Applied your suggested fix in commit b6cea79. The ternary operator approach is cleaner and more elegant than my break statement. Changed line 282 to:

int hw_btn_pin = request->hasArg(bt) ? request->arg(bt).toInt() : -1;

This ensures non-existent button parameters default to -1 instead of 0, preventing GPIO0 from being auto-assigned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ESP8266: GPIO0 can't be used as an output

2 participants