GPIO API
The GPIO API provides access to the ESP32’s general-purpose input and output pins. This is the API you use to read buttons, drive LEDs, control enable pins, and react to digital edge transitions.
The API supports both simple polling and interrupt-driven operation. For interactive applications and responsive hardware handling, the callback-based approach is usually the better choice.
For simple maker projects, GPIO is often the first API to try. Use it for low-current logic signals, buttons, relays with proper driver circuits, and LED experiments with a current-limiting resistor. Do not connect motors, LED strips, or other high-current loads directly to an ESP32 GPIO pin.
Creating a GPIO Object
Function signature:
gpio = esp32.gpio(pin, mode [, cfg])
Parameters
pin: GPIO pin number.mode: One of the following strings:"IN": Input only."OUT": Output only."OUTOD": Output only with open-drain behavior."INOUTOD": Input/output with open-drain behavior."INOUT": Input/output.
cfg: Optional configuration table.
Configuration options:
pullup: Enable the internal pull-up resistor. Default isfalse.pulldown: Enable the internal pull-down resistor. Default isfalse.callback: Lua callback function used for interrupt-driven input handling.type: Interrupt trigger type whencallbackis set.
Supported interrupt types:
"LOW": Trigger while the input level is low."HIGH": Trigger while the input level is high."POSEDGE": Trigger on rising edge."NEGEDGE": Trigger on falling edge."ANYEDGE": Trigger on both rising and falling edges.
If a callback is provided and type is omitted, the default interrupt type
is "POSEDGE".
Use edge triggers for buttons and pulse inputs when you want to react to a transition. Use level triggers only when the application really needs to know that a pin remains high or low, since a level condition can produce repeated interrupt activity while the level remains active.
GPIO Object Methods
gpio:value([val])
If val is provided, this method writes the pin level:
truefor highfalsefor low
If val is omitted, the method returns the current GPIO level.
On boards where an LED is wired as active-low, false turns the LED on and
true turns it off. Check the schematic or board documentation if the output
appears inverted.
gpio:close()
Releases the GPIO object and frees the underlying hardware resources.
Examples
The following examples are designed to run well as Lua Server Pages (LSP), but the same GPIO patterns also work in regular Lua application code.
Example 1: Set GPIO 18 High
This example opens GPIO 18 as an output, drives it high, waits two seconds, and then automatically releases the GPIO object when it goes out of scope.
local pin <close> = esp32.gpio(18, "OUT")
pin:value(true)
ba.sleep(2000)
The <close> syntax is useful when you want the resource to be released
automatically at the end of the current scope.
Example 2: Toggle an LED Through Garbage Collection
This example demonstrates an Xedge32 pattern that is especially convenient during hot reloading. When the page is refreshed, the previous GPIO object becomes unreachable and can be garbage-collected, which releases the pin.
collectgarbage()
ba.sleep(2000)
local pin = esp32.gpio(18, "OUT")
pin:value(true)
If an LED is connected to GPIO 18, it turns off briefly while the previous object is collected, then turns on again when the new object is created.
Practical Guidance
Use polling when you only need occasional state checks.
Use callbacks for buttons, pulse inputs, and other event-driven signals.
Confirm the board pinout before using a GPIO number. Some ESP32 pins are reserved for flash, PSRAM, USB, boot mode selection, camera, or SD card hardware.
Prefer explicit cleanup with
gpio:close()in long-running applications.In short-lived LSP pages, Lua’s automatic cleanup can simplify iteration.