GPIO Pin Manager
The GPIO Pin Manager lets you control hardware digital and analog pins on your device directly from the VWire dashboard — without writing custom VWIRE_RECEIVE handlers for each pin. Configure pin modes in the dashboard, and the library handles setup, reading, and writing automatically at runtime.
Supported boards: ESP32, ESP8266/NodeMCU, RP2040-W, Arduino (WiFiNINA / Ethernet).
Pin naming
VWire uses board-label pin names that match the silkscreen on your development board:
| Prefix | Range | Description |
|---|---|---|
D0–D99 | Digital pins | Resolved to board-specific GPIO numbers automatically |
A0–A15 | Analog pins | Resolved via the Arduino A0 macro mapping |
V0–V255 | Virtual pins | Handled by the existing virtual pin system — not by the GPIO manager |
Board-specific GPIO mapping
The library resolves D-prefixed pin names to hardware GPIO numbers automatically.
| Pin name | ESP8266/NodeMCU | ESP32 |
|---|---|---|
D0 | GPIO 16 | GPIO 0 |
D1 | GPIO 5 | GPIO 1 |
D2 | GPIO 4 | GPIO 2 |
D3 | GPIO 0 | GPIO 3 |
D4 | GPIO 2 (built-in LED) | GPIO 4 |
D5 | GPIO 14 | GPIO 5 |
D6 | GPIO 12 | GPIO 6 |
D7 | GPIO 13 | GPIO 7 |
D8 | GPIO 15 | GPIO 8 |
Dx (other) | — | GPIO x |
A0 | ADC0 | ADC channel 0 |
On ESP32, Dx maps directly to GPIO x. On ESP8266/NodeMCU, the mapping follows the standard NodeMCU labeling.
Pin modes
| Mode constant | Dashboard name | Description |
|---|---|---|
VWIRE_GPIO_OUTPUT | OUTPUT | Digital or PWM output — see Smart Write below |
VWIRE_GPIO_INPUT | INPUT | Digital input (floating) |
VWIRE_GPIO_INPUT_PULLUP | INPUT_PULLUP | Digital input with internal pull-up resistor |
VWIRE_GPIO_PWM | PWM | Alias for OUTPUT — kept for compatibility |
VWIRE_GPIO_ANALOG_INPUT | ANALOG_INPUT | Analog (ADC) input |
Smart Write
OUTPUT pins automatically adapt to the value sent — no separate PWM mode needed:
| Value | Behavior |
|---|---|
0 | digitalWrite(LOW) — pin fully OFF |
1 | digitalWrite(HIGH) — pin fully ON |
2–255 | analogWrite / PWM — proportional duty cycle |
This means a Switch widget (sends 0 or 1) toggles the pin, and a Slider widget (sends 0–255) controls brightness or speed — both work with a single OUTPUT pin, no extra configuration needed. All platform differences (ESP32 LEDC, ESP8266 PWMRANGE scaling, Arduino analogWrite) are handled by the library automatically.
Quick start
Step 1 — Enable the GPIO manager
Call Vwire.enableGPIO() before begin() in your sketch:
#include <Vwire.h>
const char* WIFI_SSID = "YOUR_WIFI_SSID";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";
const char* AUTH_TOKEN = "YOUR_AUTH_TOKEN";
const char* DEVICE_ID = "YOUR_DEVICE_ID";
void setup() {
Serial.begin(115200);
Vwire.config(AUTH_TOKEN);
Vwire.setDeviceId(DEVICE_ID);
// Enable automatic GPIO pin management
Vwire.enableGPIO();
Vwire.begin(WIFI_SSID, WIFI_PASSWORD);
}
void loop() {
Vwire.run(); // GPIO polling runs inside run() automatically
}
Step 2 — Configure pins in the dashboard
- Open your device in the VWire dashboard
- Go to Device → Pins → + Add Pin
- Enter a pin name (
D2,A0, etc.) and select its mode - Set the Read Interval for input pins (how often the value is read and sent to the cloud)
- Save — the cloud configuration is sent to your device automatically on the next connection
Step 3 — Add widgets
Add any Control or Display widget to your project and bind it to the physical pin (e.g., D2):
- Switch →
D2(OUTPUT) — toggles relay on/off - Slider →
D5(OUTPUT) — controls LED brightness via PWM - Value Display →
D4(INPUT_PULLUP) — shows button state - Gauge →
A0(ANALOG_INPUT) — shows potentiometer reading
That's it. No additional firmware code is required.
API reference
Vwire.enableGPIO()
Enable the GPIO pin manager. Must be called before Vwire.begin().
When enabled, the device:
- Subscribes to the
pinconfigMQTT topic on connection - Automatically applies hardware pin modes from cloud settings
- Periodically reads input pins and publishes changed values to the cloud
- Handles incoming commands for output pins from dashboard widgets
Vwire.enableGPIO();
Vwire.addGPIOPin(pinName, mode)
Vwire.addGPIOPin(pinName, mode, readInterval)
Pre-register a GPIO pin locally without waiting for cloud configuration. The hardware GPIO number is resolved automatically from the pin name. The cloud configuration overrides local registrations on connect.
// Output pin
Vwire.addGPIOPin("D2", VWIRE_GPIO_OUTPUT);
// Input pin — read every 500 ms
Vwire.addGPIOPin("D4", VWIRE_GPIO_INPUT_PULLUP, 500);
// Analog input — read every 1000 ms (default)
Vwire.addGPIOPin("A0", VWIRE_GPIO_ANALOG_INPUT);
| Parameter | Type | Description |
|---|---|---|
pinName | const char* | Pin name (e.g., "D5", "A0") |
mode | VwireGPIOMode | Pin mode constant |
readInterval | uint16_t | (Optional) Read interval in ms for input pins. Default: 1000 ms. Range: 100–60000 ms |
Returns true if the pin was added successfully.
Vwire.gpioWrite(pinName, value)
Write a value to a managed output pin immediately.
Vwire.gpioWrite("D13", HIGH); // digital HIGH
Vwire.gpioWrite("D13", LOW); // digital LOW
Vwire.gpioWrite("D5", 128); // ~50% PWM duty cycle
The pin must be configured as OUTPUT — either via the dashboard or addGPIOPin().
gpioWrite applies the value to the hardware directly; it does not publish to the cloud. Use gpioSend() if you also want to update the cloud value.
Vwire.gpioRead(pinName)
Read the last polled value of a managed input pin.
int buttonState = Vwire.gpioRead("D4"); // 0 or 1 for digital
int rawAdc = Vwire.gpioRead("A0"); // 0–1023 (ESP8266) or 0–4095 (ESP32)
Returns the last value read by the GPIO manager's polling loop, or -1 if the pin is not managed.
Vwire.gpioSend(pinName, value)
Publish a GPIO pin value to the cloud immediately.
Vwire.gpioSend("D2", 1); // publishes current state to dashboard
Use this to manually trigger a cloud update outside of the automatic polling interval, for example after a state change that needs to be reflected in the dashboard immediately.
Vwire.isGPIOEnabled()
Returns true if enableGPIO() has been called.
Vwire.getGPIO()
Returns a reference to the internal VwireGPIOManager for advanced use.
VWIRE_CONNECTED() {
Serial.print("GPIO pins managed: ");
Serial.println(Vwire.getGPIO().getPinCount());
}
Read intervals
For input pins, the GPIO manager polls the hardware at the configured interval and publishes only when the value changes. The default interval is 1000 ms.
| Interval | Suitable for |
|---|---|
100–200 ms | Fast-response buttons, encoders |
500 ms | General-purpose switches |
1000 ms | Sensors that change slowly (default) |
5000–60000 ms | Temperature, humidity, rarely-changing sensors |
Analog reads return the raw ADC value:
- ESP8266: 10-bit, 0–1023
- ESP32: 12-bit, 0–4095
Mixing GPIO and virtual pins
GPIO pins and virtual pins work independently — you can use both in the same sketch:
#include <Vwire.h>
VwireTimer statusTimer;
void setup() {
Serial.begin(115200);
Vwire.config(AUTH_TOKEN);
Vwire.setDeviceId(DEVICE_ID);
// Enable GPIO for hardware pin control
Vwire.enableGPIO();
Vwire.begin(WIFI_SSID, WIFI_PASSWORD);
// Send a virtual pin status every 10 seconds
statusTimer.setInterval(10000L, []() {
int pot = Vwire.gpioRead("A0");
Vwire.virtualSendf(V0, "Pot: %d", pot);
});
}
// Handle a virtual pin command from a dashboard widget
VWIRE_RECEIVE(V1) {
Serial.println("Virtual command: " + String(param.asStr()));
}
VWIRE_CONNECTED() {
Serial.println("Connected! Managed pins: " + String(Vwire.getGPIO().getPinCount()));
}
void loop() {
Vwire.run();
statusTimer.run();
}
Examples
The library includes two complete GPIO examples:
| Example | Description |
|---|---|
17_Digital_Pins | Digital OUTPUT and INPUT_PULLUP — relay, LED dimmer, button state |
18_Analog_Pins | ANALOG_INPUT and PWM output — potentiometer, sensor reading, LED brightness |
Load them from File → Examples → Vwire → 17_Digital_Pins in the Arduino IDE.
Platform limits
| Board | Max managed pins |
|---|---|
| ESP32 | 24 |
| ESP8266 | 12 |
| Others | 16 |
These limits can be overridden at compile time by defining VWIRE_MAX_GPIO_PINS before including the library.