You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add Pin Info: overview of used and available Pins (#5361)
* Add pin manager feature with serializePins() API and UI
* update comment about ESP8266 A0 deficiency
* moved pin capabilities to pinmanager
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: DedeHai <6280424+DedeHai@users.noreply.github.com>
constexprint ENUM_PINS = WLED_NUM_PINS; // GPIO0-16 (A0 (17) is analog input only and always assigned to any analog input, even if set "unused") TODO: can currently not be handled
// Skip pins that are neither usable nor allocated (truly unusable pins)
1065
+
if (!canInput && !canOutput && !isAllocated) continue;
1066
+
1067
+
JsonObject pinObj = pins.createNestedObject();
1068
+
pinObj["p"] = gpio; // pin number
1069
+
1070
+
// Pin capabilities
1071
+
// Touch capability is provided by appendGPIOinfo() via d.touch
1072
+
uint8_t caps = 0;
1073
+
1074
+
#ifdef ARDUINO_ARCH_ESP32
1075
+
if (PinManager::isAnalogPin(gpio)) caps |= PIN_CAP_ADC;
1076
+
1077
+
// PWM on all ESP32 variants: all output pins can use ledc PWM so this is redundant
1078
+
//if (canOutput) caps |= PIN_CAP_PWM;
1079
+
1080
+
// Input-only pins (ESP32 classic: GPIO34-39)
1081
+
if (canInput && !canOutput) caps |= PIN_CAP_INPUT_ONLY;
1082
+
1083
+
// Bootloader/strapping pins
1084
+
#if defined(CONFIG_IDF_TARGET_ESP32S3)
1085
+
if (gpio == 0) caps |= PIN_CAP_BOOT; // pull low to enter bootloader mode
1086
+
if (gpio == 45 || gpio == 46) caps |= PIN_CAP_BOOTSTRAP; // IO46 must be low to enter bootloader mode, IO45 controls flash voltage, keep low for 3.3V flash
1087
+
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
1088
+
if (gpio == 0) caps |= PIN_CAP_BOOT; // pull low to enter bootloader mode
1089
+
if (gpio == 45 || gpio == 46) caps |= PIN_CAP_BOOTSTRAP; // IO46 must be low to enter bootloader mode, IO45 controls flash voltage, keep low for 3.3V flash
1090
+
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
1091
+
if (gpio == 9) caps |= PIN_CAP_BOOT; // pull low to enter bootloader mode
1092
+
if (gpio == 2 || gpio == 8) caps |= PIN_CAP_BOOTSTRAP; // both GPIO2 and GPIO8 must be high to enter bootloader mode
if (gpio == 0) caps |= PIN_CAP_BOOT; // pull low to enter bootloader mode
1095
+
if (gpio == 2 || gpio == 12) caps |= PIN_CAP_BOOTSTRAP; // note: if GPIO12 must be low at boot, (high=1.8V flash mode), GPIO 2 must be low or floating to enter bootloader mode
1096
+
#endif
1097
+
#else
1098
+
// ESP8266: GPIO 0-16 + GPIO17=A0
1099
+
// if (gpio < 16) caps |= PIN_CAP_PWM; // software PWM available on all GPIO except GPIO16
1100
+
// ESP8266 strapping pins
1101
+
if (gpio == 0) caps |= PIN_CAP_BOOT;
1102
+
if (gpio == 2 || gpio == 15) caps |= PIN_CAP_BOOTSTRAP; // GPIO2 must be high, GPIO15 low to boot normally
1103
+
if (gpio == 17) caps = PIN_CAP_INPUT_ONLY | PIN_CAP_ADC; // TODO: display as A0 pin
1104
+
#endif
1105
+
1106
+
pinObj["c"] = caps; // capabilities
1107
+
1108
+
// Add allocated status and owner
1109
+
pinObj["a"] = isAllocated; // allocated status
1110
+
1111
+
// check if this pin is used as a button (need to get button type for owner name)
1112
+
int buttonIndex = PinManager::getButtonIndex(gpio); // returns -1 if not a button pin, otherwise returns index in buttons array
1113
+
1114
+
// Add owner ID and name
1115
+
PinOwner owner = PinManager::getPinOwner(gpio);
1116
+
if (isAllocated) {
1117
+
pinObj["o"] = static_cast<uint8_t>(owner); // owner ID (can be used for UI lookup)
1118
+
pinObj["n"] = PinManager::getPinOwnerName(gpio); // owner name (string)
1119
+
1120
+
// Relay pin
1121
+
if (owner == PinOwner::Relay) {
1122
+
pinObj["m"] = 1; // mode: output
1123
+
pinObj["s"] = digitalRead(rlyPin); // read state from hardware (digitalRead returns output state for output pins)
1124
+
}
1125
+
// Button pins, get type and state using isButtonPressed()
1126
+
elseif (buttonIndex >= 0) {
1127
+
pinObj["m"] = 0; // mode: input
1128
+
pinObj["t"] = buttons[buttonIndex].type; // button type
1129
+
pinObj["s"] = isButtonPressed(buttonIndex) ? 1 : 0; // state
1130
+
1131
+
// for touch buttons, get raw reading value (useful for debugging threshold)
int adc_channel = digitalPinToAnalogChannel(gpio);
364
+
if (adc_channel >= 0 && adc_channel <= 7) returntrue;
365
+
#elif CONFIG_IDF_TARGET_ESP32S2
366
+
// ESP32-S2: ADC1 channels 0-9 (GPIO 1-10)
367
+
int adc_channel = digitalPinToAnalogChannel(gpio);
368
+
if (adc_channel >= 0 && adc_channel <= 9) returntrue;
369
+
#elif CONFIG_IDF_TARGET_ESP32S3
370
+
// ESP32-S3: ADC1 channels 0-9 (GPIO 1-10)
371
+
int adc_channel = digitalPinToAnalogChannel(gpio);
372
+
if (adc_channel >= 0 && adc_channel <= 9) returntrue;
373
+
#elif CONFIG_IDF_TARGET_ESP32C3
374
+
// ESP32-C3: ADC1 channels 0-4 (GPIO 0-4)
375
+
int adc_channel = digitalPinToAnalogChannel(gpio);
376
+
if (adc_channel >= 0 && adc_channel <= 4) returntrue;
377
+
#endif
378
+
#endif
379
+
returnfalse; // not an analog pin if it doesn't have ADC capability, ESP8266 has only one ADC pin (A0) which is handled separately in button.cpp, so return false for all pins here
0 commit comments