Skip to main content

VWire Arduino Library

Version 3.1.0 — connects ESP32, ESP8266, and compatible boards to the VWire cloud via secure MQTT.


Supported boards​

BoardTCPTLS (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.

  1. Download the latest VWire Arduino ZIP archive from the official VWire GitHub repository.
  2. In Arduino IDE, open Sketch → Include Library → Add .ZIP Library.
  3. Select the downloaded ZIP archive.
  4. 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:

MethodReturn typeDescription
param.asInt()intValue as integer
param.asFloat()floatValue as float
param.asDouble()doubleValue as double
param.asBool()booltrue for "1", "true", "on"
param.asString()StringRaw string value
param.asCString()const char*Raw C-string
param.getArraySize()intNumber of comma-separated elements
param.getArrayInt(i)inti-th element as int
param.getArrayFloat(i)floati-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
note

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");
note

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​

MethodDefaultDescription
Vwire.setAutoReconnect(bool)trueAuto-reconnect on drop
Vwire.setReconnectInterval(ms)5000Delay between reconnect attempts
Vwire.setHeartbeatInterval(ms)15000Heartbeat 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.

MethodDescription
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​

MacroDescription
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");
}