VWire Arduino Library
Version 3.1.0 â connects ESP32, ESP8266, and compatible boards to the VWire cloud via secure MQTT.
Supported boardsâ
| Board | TCP | TLS (recommended) | Cloud OTA |
|---|---|---|---|
| ESP32 | â | â | â |
| ESP8266 | â | â | â |
| RP2040 (Pico W) | â | â ď¸ Limited | â |
| Arduino (WiFiNINA / Ethernet) | â | â | â |
| SAMD | â | â | â |
Installationâ
Manual installation from GitHubâ
The VWire Arduino library is not currently available through Arduino Library Manager.
- Download the latest VWire Arduino ZIP archive from the official VWire GitHub repository.
- In Arduino IDE, open Sketch â Include Library â Add .ZIP Library.
- Select the downloaded ZIP archive.
- Install the dependencies separately: PubSubClient and ArduinoJson.
PlatformIOâ
If you use PlatformIO, place the VWire library in your project's local lib/VWire directory and declare the remaining dependencies in platformio.ini:
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps =
knolleary/PubSubClient
bblanchon/ArduinoJson
Manualâ
If you are not using PlatformIO, use the same GitHub ZIP install flow above.
Minimal sketchâ
#include <Vwire.h>
const char* WIFI_SSID = "YOUR_WIFI_SSID";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";
// Both values from device settings in the dashboard
const char* AUTH_TOKEN = "YOUR_AUTH_TOKEN";
const char* DEVICE_ID = "YOUR_DEVICE_ID"; // e.g. VU-ABC123
VWIRE_CONNECTED() {
Serial.println("Connected!");
Vwire.syncVirtual(V0); // request last stored value
}
void setup() {
Serial.begin(115200);
Vwire.config(AUTH_TOKEN);
Vwire.setDeviceId(DEVICE_ID);
Vwire.begin(WIFI_SSID, WIFI_PASSWORD);
}
void loop() {
Vwire.run();
static unsigned long last = 0;
if (Vwire.connected() && millis() - last >= 2000) {
last = millis();
Vwire.virtualSend(V0, analogRead(A0));
}
}
API referenceâ
Configurationâ
Vwire.config(authToken)â
Configure using only the auth token. Connects to mqtt.vwire.io:8883 over TLS by default.
Vwire.config("YOUR_AUTH_TOKEN");
Vwire.config(authToken, server, port)â
Configure with a custom server and port.
Vwire.config("YOUR_AUTH_TOKEN", "mqtt.vwire.io", 8883);
Vwire.setDeviceId(deviceId)â
Set the device ID (shown in the dashboard device settings, e.g. VU-ABC123). Call after config() and before begin().
Vwire.setDeviceId("VU-ABC123");
Vwire.setTransport(transport)â
Override the transport protocol. Default is TLS.
Vwire.setTransport(VWIRE_TRANSPORT_TCP_SSL); // TLS port 8883 (default, recommended)
Vwire.setTransport(VWIRE_TRANSPORT_TCP); // Plain TCP port 1883
Use plain TCP only on boards that don't support TLS (RP2040, SAMD, some Arduino models).
Connectionâ
Vwire.begin(ssid, password)â
Connect to WiFi and the Vwire cloud. Blocks until connected or times out.
bool ok = Vwire.begin(WIFI_SSID, WIFI_PASSWORD);
if (!ok) {
Serial.printf("Error: %d\n", Vwire.getLastError());
}
Vwire.run()â
Process MQTT messages and maintain the connection. Must be called on every loop() iteration.
void loop() {
Vwire.run();
// your code here
}
Vwire.connected()â
Returns true if currently connected to the MQTT broker.
Vwire.disconnect()â
Cleanly disconnect from the MQTT broker.
Sending data (device â cloud)â
Vwire.virtualSend(pin, value)â
Send a value to a virtual pin. Supported types: int, float, bool, String, const char*.
Vwire.virtualSend(V0, 23.5); // float
Vwire.virtualSend(V1, 42); // int
Vwire.virtualSend(V2, true); // bool (sends "1" or "0")
Vwire.virtualSend(V3, "hello"); // string
Vwire.virtualSend(100, sensorVal); // pin 100 (beyond V31 macro range)
Vwire.virtualSendArray(pin, values, count)â
Send multiple values to one pin as a comma-separated payload.
float readings[3] = { 1.1, 2.2, 3.3 };
Vwire.virtualSendArray(V5, readings, 3);
int data[2] = { 100, 200 };
Vwire.virtualSendArray(V6, data, 2);
Vwire.virtualSendf(pin, format, ...)â
Send a formatted string to a pin (printf-style).
Vwire.virtualSendf(V7, "%.1f°C / %.1f%%", temp, humidity);
Receiving data (cloud â device)â
VWIRE_RECEIVE(pin) { ... }â
Handler macro â declare outside setup() and loop(). Automatically registered; no manual call needed. The variable param (type VirtualPin&) holds the received value.
VWIRE_RECEIVE(V0) {
int value = param.asInt();
digitalWrite(LED_BUILTIN, value);
}
VWIRE_RECEIVE(V1) {
float setpoint = param.asFloat();
Serial.printf("New setpoint: %.1f\n", setpoint);
}
Vwire.onVirtualReceive(pin, handler) (manual)â
Register a handler at runtime instead of using the macro.
void onLedChange(VirtualPin& p) {
digitalWrite(LED_BUILTIN, p.asBool());
}
void setup() {
Vwire.onVirtualReceive(V0, onLedChange);
// ...
}
VirtualPin value methodsâ
The param object inside VWIRE_RECEIVE provides:
| Method | Return type | Description |
|---|---|---|
param.asInt() | int | Value as integer |
param.asFloat() | float | Value as float |
param.asDouble() | double | Value as double |
param.asBool() | bool | true for "1", "true", "on" |
param.asString() | String | Raw string value |
param.asCString() | const char* | Raw C-string |
param.getArraySize() | int | Number of comma-separated elements |
param.getArrayInt(i) | int | i-th element as int |
param.getArrayFloat(i) | float | i-th element as float |
Connection handlersâ
VWIRE_CONNECTED() {
Serial.println("Connected to VWire!");
Vwire.sync(V0, V1); // restore last values
}
VWIRE_DISCONNECTED() {
Serial.println("Disconnected!");
}
Sync (restore stored values)â
After a reboot the device can request the last value stored in the cloud for any pin:
Vwire.syncVirtual(V0); // sync one pin
Vwire.sync(V0, V1, V2); // sync multiple pins
Vwire.syncAll(); // sync all pins
Typically called inside VWIRE_CONNECTED().
Notificationsâ
Vwire.notify(message)â
Send a standard notification to the user's history and mobile app.
Vwire.notify("Motion detected!");
Vwire.alarm(message)â
Send a persistent alarm notification with mobile sound and vibration handling.
Vwire.alarm("Temperature critical!");
Available sound options for Vwire.alarm(message, sound, priority, volume): "default", "warning", "urgent".
Vwire.alarm("Pump failure", "urgent");
Vwire.alarm("Low battery", "warning", 2); // priority: 1=normal, 2=high, 3=critical
Vwire.alarm("Leak detected", "urgent", 3, 90); // volume: 0-100, default 50
alarm() requires Pro plan or above. Calls from Free accounts are silently ignored.
Vwire.email(subject, body)â
Send an email notification.
Vwire.email("Sensor alert", "Temperature exceeded 40°C");
email() requires Pro plan or above.
OTA updates (ESP32/ESP8266 only)â
Local OTA (Arduino OTA)â
void setup() {
Vwire.config(AUTH_TOKEN);
Vwire.setDeviceId(DEVICE_ID);
Vwire.enableOTA("my-device"); // optional hostname and password
Vwire.begin(WIFI_SSID, WIFI_PASSWORD);
}
Cloud OTA (triggered from dashboard)â
Vwire.enableCloudOTA(); // call before begin()
With Cloud OTA enabled, you can push firmware updates directly from the VWire dashboard without physical access.
Reliable deliveryâ
Enable application-level acknowledgment for critical data:
Vwire.setReliableDelivery(true);
Vwire.setAckTimeout(5000); // ms to wait for ACK (default 5000)
Vwire.setMaxRetries(3); // retry count before dropping (default 3)
Debuggingâ
Vwire.setDebug(true); // print debug output to Serial
Vwire.printDebugInfo(); // print version, board, connection status, memory
Serial.println(Vwire.getVersion()); // "3.1.0"
Serial.println(Vwire.getBoardName()); // "ESP32", "ESP8266", etc.
Serial.println(Vwire.getFreeHeap()); // free RAM in bytes
Virtual pin numbersâ
Convenience macros V0âV31 are defined. For pins above V31, use the number directly:
Vwire.virtualSend(V0, val); // pin 0
Vwire.virtualSend(50, val); // pin 50
Vwire.virtualSend(255, val); // pin 255 (maximum)
Connection settingsâ
| Method | Default | Description |
|---|---|---|
Vwire.setAutoReconnect(bool) | true | Auto-reconnect on drop |
Vwire.setReconnectInterval(ms) | 5000 | Delay between reconnect attempts |
Vwire.setHeartbeatInterval(ms) | 15000 | Heartbeat interval |
GPIO pin managementâ
Version 3.1.0 adds a built-in GPIO manager that lets you control physical digital and analog pins directly from the dashboard â without writing individual VWIRE_RECEIVE handlers.
See the full reference in GPIO Pin Manager.
Summaryâ
// Enable GPIO management (call before begin())
Vwire.enableGPIO();
// Optionally pre-register pins locally (cloud config overrides on connect)
Vwire.addGPIOPin("D2", VWIRE_GPIO_OUTPUT); // relay / LED
Vwire.addGPIOPin("D4", VWIRE_GPIO_INPUT_PULLUP, 200); // button, read every 200 ms
Vwire.addGPIOPin("A0", VWIRE_GPIO_ANALOG_INPUT, 500); // potentiometer, read every 500 ms
After calling Vwire.enableGPIO(), the device subscribes to pin configuration updates from the cloud. Pin modes, read intervals, and widget bindings are all managed from the dashboard.
| Method | Description |
|---|---|
Vwire.enableGPIO() | Enable automatic GPIO management |
Vwire.addGPIOPin(name, mode) | Pre-register a pin locally |
Vwire.addGPIOPin(name, mode, interval) | Pre-register an input pin with read interval |
Vwire.gpioWrite(name, value) | Write a value to an output pin |
Vwire.gpioRead(name) | Read last polled value of an input pin |
Vwire.gpioSend(name, value) | Publish a pin value to the cloud |
Vwire.isGPIOEnabled() | Returns true if GPIO management is active |
Vwire.getGPIO() | Access the VwireGPIOManager object directly |
Event handler macrosâ
| Macro | Description |
|---|---|
VWIRE_RECEIVE(pin) {} | Fires when the cloud sends a value to the device on pin. param (VirtualPin&) holds the value. |
VWIRE_CONNECTED() {} | Fires after a successful connection to the broker. Use to sync pin state with syncVirtual(). |
VWIRE_DISCONNECTED() {} | Fires when the connection is lost. |
VWIRE_RECEIVE(V0) {
// param.asInt(), param.asFloat(), param.asStr(), etc.
digitalWrite(RELAY_PIN, param.asInt());
}
VWIRE_CONNECTED() {
Vwire.syncVirtual(V0); // request last stored value from cloud
}
VWIRE_DISCONNECTED() {
Serial.println("Lost connection â attempting to reconnect");
}