VCON is a framework for remote (OTA) firmware updates and remote serial monitor, for a wide range of microcontrollers. VCON framework consists of two parts:
Any ESP32 / ESP32C3 device can be used. Flashing VCON pre-built firmware turns that device into a remote programmer and serial monitor. It can be registered on the management cloud, and be controlled remotely via GUI or the REST API. Once ESP32 is wired to the external device, that external device can be re-programmed over the secure REST API. An external device is called a "Host".
In addition to the OTA wiring, VCON module can be wired to the Host's UART. In this case, VCON module could be configured to act as a network bridge - either in transparent, or non-transparent mode:
The following list shows target devices that can be reflashed by the current version of VCON firmware. Please contact us if you'd like to support your architecture of choice:
NOTE: UART bridging works on all architectures.
Note: The difference between the "full" and "update" firmwares is that the "full" firmware contains the bootloader, the partition table, and the VCON app. The "update" firmware contains only VCON app. To update a production VCON module, use the "update" firmware.
COMPORT
. On Windows, it is COMn
, like COM3
, COM4
, ... -
open Windows' device manager to double-check.
On Linux, it is usually /dev/ttyUSBn
or /dev/ttyACMn
. On Mac,
it is usually /dev/cu.usbXXXX
esputil
tool:esputil
, then chmod 0755 esputil
esputil
, then chmod 0755 esputil
esputil.exe
vcon.hex
vcon.hex
cd DIRECTORY_WITH_DOWNLOADED_FILES
./esputil -p COMPORT flash vcon.hex
Note: for ESP32C3 boards, you might need to specify an extra argument
for flash parameters, -fp 0x22f
. The most common parameters are -fp 0x220
.
For more options, see https://github.com/cpq/esputil#flash-parameters.Run the following command to see module's debug logs:
esputil -p COMPORT monitor
You should see debug logs appearing. Press "enter" once to trigger command-line mode. You should see this:
Entering CLI mode, log output suspended. CLI commands:
set PATH VALUE Set config PATH to VALUE
call NAME ARGS Call RPC function NAME
cat FILE Show file contents
reset Reset to factory defaults
reboot Reboot device
<enter> Exit CLI mode, resume logs
Enter the following commands, line by line, terminating by single "enter":
set $.wifi.sta.ssid "YOUR_WIFI_NAME"
set $.wifi.sta.pass "YOUR_WIFI_PASSWORD"
set $.dash.pass "DEVICE_CLOUD_PASSWORD"
reboot
Note the double quotes! To get a DEVICE_CLOUD_PASSWORD
, login to
https://dash.vcon.io. Click on "add device" to add a new device. Click on
"action" button. Click on "Copy device password to clipboard:
After WiFi and cloud credentials are set and device is rebooted, your device should become online:
Congratulations! Now ESP32 module can be controlled remotely. Time to attach an external microcontroller to it.
In this setup, it is ESP32C3 that powers both boards over USB. After the setup is done, it could the vica versa: the RPI board can power both. Once wiring is done, go to https://dash.vcon.io and select "action" → "Manage device" to configure the Host:
This loads device management console with several different sections. Now we're interested in "Host MCU" section. Change values to make it look like this and hit "save":
After a second or two, a device should momentarily go offline and then online again: that means it has updated configuration and rebooted. Now we are ready to update firmware over the air!
Shield Setup
Once wiring is complete, power the Arduino Nano board by plugging in USB cable. The VCON shield should start blinking blue LED, which indicates the network is unconfigured. Jump to the Network Setup section to configure network on your VCON shield, and return here when done. The blue LED should be lit solid, and a respective device on a dashboard should become online.
Host MCU setup
Now we have to tell VCON shield, which microcontroller is attached, which pins are used, etcetera. Switch to the https://dash.vcon.io, select "action" → "Manage device":
This loads device management console with several different sections. Now we're interested in "Host MCU" section. Change values to make it look like this and hit "save":
After a second or two, a device should momentarily go offline and then online again: that means it has updated configuration and rebooted. Now we are ready to update firmware over the air!
OTA firmware update
Fire Arduino IDE, and create a new sketch. This sketch is a modification of the classic Blink sketch with some changes:
This sketch, therefore, implements some trivial remote control over UART. Choose one of the following:
int led = LED_BUILTIN, sleeptime = 1200, on = 0;
void setup() {
Serial.begin(115200);
pinMode(led, OUTPUT);
}
void loop() {
on = !on; // Invert LED status
digitalWrite(led, on); // Set LED
delay(sleeptime); // Sleep for `sleeptime` milliseconds
Serial.println(on); // Print LED status to serial
// Read serial input. If we read a number from "0" to "9",
// then change blink interval
if (Serial.available() > 0) {
int ch = Serial.read();
if (ch >= '0' && ch <= '9') sleeptime = (ch - '0' + 1) * 300;
}
}
Next, let us compile (but not upload!) this sketch into a downloadable file. In Arduino IDE, perform the following steps:
A folder with a compiled .hex
file should popup. It should be named
SKETCH_NAME.ino.standard.hex
, which is a text file in
Intel hex format
that contains binary code of
your compiled firmware.
Switch to the VCON dashboard, device management console. In the "Host MCU"
section, click on the "firmware update" button, choose firmware .hex
file.
A button is going to show an OTA progress indicator,
and finish in a second or two:
Congratulations! Arduino Nano firmware has been updated remotely over the secure management interface.
Remote control
When the previous step is done and Arduino Nano firmware is remotely updated, two things should be noticed:
What happens? In the Host MCU configuration, we told VCON to forward UART to a Websocket server. VCON grabs UART output from a specified pin, and sends it to the dashboard, since no Websocket URL is specified. That's why we can see what Host MCU prints to the serial port.
Now, type "7" to the serial input and press "send":
The dashboard grabs your input and calls a serial.write
function on the
VCON shield, which sends the input to the specified rx
UART pin.
Also, serial monitor prints your input on a console in an alternate color,
making it easy to see input and output.
Host MCU receives character "7", adjusts blinking interval to 800 milliseconds,
and Arduino starts blinking slower.
Congratulations! Now your Arduino is remotely controllable.
The cool things is that Arduino is not even "aware" it is connected to the Internet. It "thinks" it communicates via UART - which is very easy to develop, debug and test. This way, a Host MCU can be nicely isolated to perform only required business tasks and not care about networking and management.
See Recipes section for some further insights on how can you enhance remote control and data reporting.
Shield Setup
Once wiring is complete, power the board by plugging in USB cable. The VCON shield should start blinking blue LED, which indicates the network is unconfigured. Jump to the Network Setup section to configure network on your VCON shield, and return here when done. The blue LED should be lit solid, and a respective device on a dashboard should become online.
Host MCU setup
Now we have to tell VCON shield, which microcontroller is attached, which pins are used, etcetera. Switch to the https://dash.vcon.io, select "action" → "Manage device":
This loads device management console with several different sections. Now we're interested in "Host MCU" section. Change values to make it look like this and hit "save":
After a second or two, a device should momentarily go offline and then online again: that means it has updated configuration and rebooted. Now we are ready to update firmware over the air!
OTA firmware update
Let's build a firmware that performs the following:
Choose one of the following:
int led = LED_BUILTIN, sleeptime = 1200, on = 0;
void setup() {
Serial1.begin(115200); // Note: we're using Serial1, not Serial
pinMode(led, OUTPUT);
}
void loop() {
on = !on;
if (Serial1.available() > 0) { int ch = Serial1.read(); if (ch >= '0' && ch <= '9') sleeptime = (ch - '0' + 1) * 300; }
Serial1.println(on);
digitalWrite(led, on);
delay(sleeptime);
}
Next, let us compile (but not upload!) this sketch into a downloadable file. In Arduino IDE, perform the following steps:
A folder with a compiled .uf2
file should popup.
Switch to the VCON dashboard, device management console. In the "Host MCU"
section, click on the "firmware update" button, choose firmware .uf2
file.
A button is going to show an OTA progress indicator until OTA is done.
Congratulations! You've updated firmware over the air.
Remote control
When the previous step is done and firmware is remotely updated, two things should be noticed:
What happens? In the Host MCU configuration, we told VCON to forward UART to a Websocket server. VCON grabs UART output from a specified pin, and sends it to the dashboard, since no Websocket URL is specified. That's why we can see what Host MCU prints to the serial port.
Now, type "7" to the serial input and press "send":
The dashboard grabs your input and calls a serial.write
function on the
VCON shield, which sends the input to the specified rx
UART pin.
Also, serial monitor prints your input on a console in an alternate color,
making it easy to see input and output.
Host MCU receives character "7", adjusts blinking interval to 2400 milliseconds,
and the board starts blinking slower.
Congratulations! Now your microcontroller is remotely controllable.
NOTE: the SWDIO and SWCLK pads are on the bottom of the board and need to be soldered.
Shield Setup
Once wiring is complete, power the board by plugging in USB cable. The VCON shield should start blinking blue LED, which indicates the network is unconfigured. Jump to the Network Setup section to configure network on your VCON shield, and return here when done. The blue LED should be lit solid, and a respective device on a dashboard should become online.
Host MCU setup
Now we have to tell VCON shield, which microcontroller is attached, which pins are used, etcetera. Switch to the https://dash.vcon.io, select "action" → "Manage device":
This loads device management console with several different sections. Now we're interested in "Host MCU" section. Change values to make it look like this and hit "save":
After a second or two, a device should momentarily go offline and then online again: that means it has updated configuration and rebooted. Now we are ready to update firmware over the air!
OTA firmware update
Let's build a firmware that performs the following:
Choose one of the following:
int led = LED_BUILTIN, sleeptime = 1200, on = 0;
void setup() {
Serial1.begin(115200); // Note: we're using Serial1, not Serial
pinMode(led, OUTPUT);
}
void loop() {
on = !on;
if (Serial1.available() > 0) { int ch = Serial1.read(); if (ch >= '0' && ch <= '9') sleeptime = (ch - '0' + 1) * 300; }
Serial1.println(on);
digitalWrite(led, on);
delay(sleeptime);
}
Next, let us compile (but not upload!) this sketch into a downloadable file. In Arduino IDE, perform the following steps:
A folder with a compiled .bin
file should popup.
Switch to the VCON dashboard, device management console. In the "Host MCU"
section, click on the "firmware update" button, choose firmware .bin
file.
A button is going to show an OTA progress indicator until OTA is done.
Congratulations! You've updated firmware over the air.
Remote control
When the previous step is done and firmware is remotely updated, two things should be noticed:
What happens? In the Host MCU configuration, we told VCON to forward UART to a Websocket server. VCON grabs UART output from a specified pin, and sends it to the dashboard, since no Websocket URL is specified. That's why we can see what Host MCU prints to the serial port.
Now, type "7" to the serial input and press "send":
The dashboard grabs your input and calls a serial.write
function on the
VCON shield, which sends the input to the specified rx
UART pin.
Also, serial monitor prints your input on a console in an alternate color,
making it easy to see input and output.
Host MCU receives character "7", adjusts blinking interval to 2400 milliseconds,
and the board starts blinking slower.
Congratulations! Now your microcontroller is remotely controllable.
Shield Setup
Once wiring is complete, power the Arduino Nano board by plugging in USB cable. The VCON shield should start blinking blue LED, which indicates the network is unconfigured. Jump to the Network Setup section to configure network on your VCON shield, and return here when done. The blue LED should be lit solid, and a respective device on a dashboard should become online.
Shield Setup
Arduino Pro Mini, Arduino Nano, Arduino Uno use the same microcontroller - Atmega328p. The next steps are identical to those described for the Arduino Nano. Therefore, jump to the Arduino Nano tutorial and continue from the Host MCU setup section.
Shield Setup
Once wiring is complete, power the Arduino Nano board by plugging in USB cable. The VCON shield should start blinking blue LED, which indicates the network is unconfigured. Jump to the Network Setup section to configure network on your VCON shield, and return here when done. The blue LED should be lit solid, and a respective device on a dashboard should become online.
Shield Setup
Arduino Pro Mini, Arduino Nano, Arduino Uno use the same microcontroller - Atmega328p. The next steps are identical to those described for the Arduino Nano. Therefore, jump to the Arduino Nano tutorial and continue from the Host MCU setup section.
Shield Setup
Once wiring is complete, power the Arduino Nano board by plugging in USB cable. The VCON shield should start blinking blue LED, which indicates the network is unconfigured. Jump to the Network Setup section to configure network on your VCON shield, and return here when done. The blue LED should be lit solid, and a respective device on a dashboard should become online.
Host MCU setup
Now we have to tell VCON shield, which microcontroller is attached, which pins are used, etcetera. Switch to the https://dash.vcon.io, select "action" → "Manage device":
This loads device management console with several different sections. Now we're interested in "Host MCU" section. Change values to make it look like this and hit "save":
After a second or two, a device should momentarily go offline and then online again: that means it has updated configuration and rebooted. Now we are ready to update firmware over the air!
OTA firmware update
First, build an STM32 equivalent of the demo Arduino sketch:
Choose one of the 3 options:
make
to build bluepill.bin
.#include "mbed.h"
#include "platform/mbed_thread.h"
Serial pc(PA_9, PA_10, 115200); // TX, RX
DigitalOut myled(PC_13); // on-board LED
int main() {
int on = 0, wait_ms = 300; // Initial blink interval is 300ms
for (;;) {
on = !on; // Invert LED status
myled = on; // Set LED
pc.printf(on ? "1" : "0"); // Print LED status to serial
thread_sleep_for(wait_ms); // Sleep
// Read serial input. If we read a number from "0" to "9", change blink interval
if (pc.readable()) {
int ch = pc.getc();
if (ch >= '0' && ch <= '9') wait_ms = (ch - '0' + 1) * 300;
}
}
}
Click on "Compile", that will compile and download a .bin
firmware file.
Now, we have a built .bin
firmware file.
Switch to the VCON dashboard, device management console. In the "Host MCU"
section, click on the "firmware update" button, navigate to, and choose
a .bin
firmware file. A firmware update button would spin for some time,
showing OTA progress. When OTA finishes, the board should start blinking.
Congratulations! A firmware has been updated remotely over the secure management interface.
Remote control
When the previous step is done, notice one more thing that changed: in the "Serial Console" section of the device dashboard, a serial output of "0" and "1" starts to appear.
What happens? In the Host MCU configuration, we told VCON to forward UART to a Websocket server. VCON grabs UART output from a specified pin, and sends it to the dashboard, since no Websocket URL is specified. That's why we can see what Host MCU prints to the serial port.
Now, type "7" to the serial input and press "send":
The dashboard grabs your input and calls a serial.write
function on the
VCON shield, which sends the input to the specified rx
UART pin.
Also, serial monitor prints your input on a console in an alternate color,
making it easy to see input and output.
Host MCU receives character "7", adjusts blinking interval to 800 milliseconds,
and your board starts blinking slower.
Congratulations! Now your microcontroller is remotely controllable.
The cool things is that your microcontroller is not even "aware" it is connected to the Internet. It "thinks" it communicates via UART - which is very easy to develop, debug and test. This way, a microcontoller can be nicely isolated to perform only required business tasks and not care about networking and management.
Shield Setup
Once wiring is complete, power the board by plugging in USB cable. The VCON shield should start blinking blue LED, which indicates the network is unconfigured. Jump to the Network Setup section to configure network on your VCON shield, and return here when done. The blue LED should be lit solid, and a respective device on a dashboard should become online.
Host MCU setup
Now we have to tell VCON shield, which microcontroller is attached, which pins are used, etcetera. Switch to the https://dash.vcon.io, select "action" → "Manage device":
This loads device management console with several different sections. Now we're interested in "Host MCU" section. Change values to make it look like this and hit "save":
After a second or two, a device should momentarily go offline and then online again: that means it has updated configuration and rebooted. Now we are ready to update firmware over the air!
OTA firmware update
Let's build a firmware that performs the following:
Choose one of the following:
int led = LED_BUILTIN, sleeptime = 1200, on = 0;
void setup() {
Serial1.begin(115200); // Note: we're using Serial1, not Serial
pinMode(led, OUTPUT);
}
void loop() {
on = !on;
if (Serial1.available() > 0) { int ch = Serial1.read(); if (ch >= '0' && ch <= '9') sleeptime = (ch - '0' + 1) * 300; }
Serial1.println(on);
digitalWrite(led, on);
delay(sleeptime);
}
Next, let us compile (but not upload!) this sketch into a downloadable file. In Arduino IDE, perform the following steps:
A folder with a compiled .bin
file should popup. It should be named
SKETCH_NAME.ino.itsybitsy_m4.bin
.
Switch to the VCON dashboard, device management console. In the "Host MCU"
section, click on the "firmware update" button, choose firmware .bin
file.
A button is going to show an OTA progress indicator,
and finish in a second or two:
Congratulations! You've updated firmware over the air.
Remote control
When the previous step is done and firmware is remotely updated, two things should be noticed:
What happens? In the Host MCU configuration, we told VCON to forward UART to a Websocket server. VCON grabs UART output from a specified pin, and sends it to the dashboard, since no Websocket URL is specified. That's why we can see what Host MCU prints to the serial port.
Now, type "7" to the serial input and press "send":
The dashboard grabs your input and calls a serial.write
function on the
VCON shield, which sends the input to the specified rx
UART pin.
Also, serial monitor prints your input on a console in an alternate color,
making it easy to see input and output.
Host MCU receives character "7", adjusts blinking interval to 800 milliseconds,
and the board starts blinking slower.
Congratulations! Now your microcontroller is remotely controllable.
The cool things is that your microcontroller is not even "aware" it is connected to the Internet. It "thinks" it communicates via UART - which is very easy to develop, debug and test. This way, a microcontroller can be nicely isolated to perform only required business tasks and not care about networking and management.
See Recipes section for some further insights on how can you enhance remote control and data reporting.
The setup and the start guide for the Adafruit ItsyBitsyM0 is identical to the Adafruit ItsyBitsyM4, with the following differences:
8192
instead of 16384
Condidering the above differences, please follow ItsyBitsyM4 tutorial.
NOTE: SWDIO and SWCLK pads are on the bottom, and need to be soldered.
Shield Setup
Once wiring is complete, power the board by plugging in USB cable. The VCON shield should start blinking blue LED, which indicates the network is unconfigured. Jump to the Network Setup section to configure network on your VCON shield, and return here when done. The blue LED should be lit solid, and a respective device on a dashboard should become online.
Host MCU setup
Now we have to tell VCON shield, which microcontroller is attached, which pins are used, etcetera. Switch to the https://dash.vcon.io, select "action" → "Manage device":
This loads device management console with several different sections. Now we're interested in "Host MCU" section. Change values to make it look like this and hit "save":
After a second or two, a device should momentarily go offline and then online again: that means it has updated configuration and rebooted. Now we are ready to update firmware over the air!
OTA firmware update
Let's build a firmware that performs the following:
Choose one of the following:
int sleeptime = 1200, on = 0;
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel led = Adafruit_NeoPixel(1, 25, NEO_GRB + NEO_KHZ800);
void setup() {
Serial1.begin(115200); // Note: we're using Serial1, not Serial
led.begin();
}
void loop() {
on = !on;
if (Serial1.available() > 0) { int ch = Serial1.read(); if (ch >= '0' && ch <= '9') sleeptime = (ch - '0' + 1) * 300; }
Serial1.println(on);
led.setPixelColor(0, on ? 0xff00ff : 0);
led.show();
delay(sleeptime);
}
Next, let us compile (but not upload!) this sketch into a downloadable file. In Arduino IDE, perform the following steps:
A folder with a compiled .uf2
file should popup.
Switch to the VCON dashboard, device management console. In the "Host MCU"
section, click on the "firmware update" button, choose firmware .uf2
file.
A button is going to show an OTA progress indicator until OTA is done.
Congratulations! You've updated firmware over the air.
Remote control
When the previous step is done and firmware is remotely updated, two things should be noticed:
What happens? In the Host MCU configuration, we told VCON to forward UART to a Websocket server. VCON grabs UART output from a specified pin, and sends it to the dashboard, since no Websocket URL is specified. That's why we can see what Host MCU prints to the serial port.
Now, type "7" to the serial input and press "send":
The dashboard grabs your input and calls a serial.write
function on the
VCON shield, which sends the input to the specified rx
UART pin.
Also, serial monitor prints your input on a console in an alternate color,
making it easy to see input and output.
Host MCU receives character "7", adjusts blinking interval to 2400 milliseconds,
and the board starts blinking slower.
Congratulations! Now your microcontroller is remotely controllable.
The commumication chip can be configured to read the serial output of the Host MCU and forward all data to the MQTT server of your choice. That is called a "UART-MQTT bridge mode". In order to enable that,
Step 1. Login to https://dash.vcon.io, make sure your device is online, choose "action" → "Manage device"
Step 2. In the file editor section, choose config.json
file,
and edit the configuration JSON object by adding the following section:
...
"mqtt": {
"rx": "vcon/rx",
"tx": "vcon/tx",
"url": "mqtt://broker.hivemq.com:1883"
},
...
Step 3. Click on "save" button, then click on "reboot device" button
That's it! Now all data that is printed to the serial, gets forwarded to the
topic vcon/tx
of the MQTT server broker.hivemq.com:1883. Feel free to choose
a different topic or server address.
Note there is an rx
topic, too. You've guessed it: everything that is sent
to that MQTT topic, a communication chip catches and sends to the Host MCU
serial line, so MQTT/Serial communication is bi-directional.
NOTE: on Arduino framework, Serial
on VCON-328 and Serial1
on VCON-D51.
Below is a detailed step-by-step guide on how to enable VCON module to connect to AWS IoT and forward UART data to/from the specified MQTT topics.
YOUR_AWS_IOT_ENDPOINT_URL
,
click on "Settings" link on the AWS IoT console left bar
and copy the "Endpoint" URL on the right pane):"mqtt": {
"url": "mqtts://YOUR_AWS_IOT_ENDPOINT_URL:8883",
"rx": "vcon/rx",
"tx": "vcon/tx",
"cert": "/spiffs/cert.pem",
"key": "/spiffs/key.pem",
"hexdump": 0
},
What if you want to send data to something that is not MQTT - for example, to a custom server, or to a database like Influx? That is also possible. When a communication chip reads Host MCU serial, it generates a notification on the management cloud. It is possible to intercept that notification, and have a custom code to forward data to any destination.
Read the Notifications section for exact details.
An easy remote control via MQTT could be implemented by the "Send data to MQTT" recipe. Configure your RX and TX topics, MQTT server, then send data to the TX topic.
Use a simple Arduino sketch to read Serial to turn an LED on or off:
// IMPORTANT! On VCON-D51, use Serial1 instead of Serial
void setup() {
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
if (Serial.available() > 0) {
int character = Serial.read();
if (character == '0') digitalWrite(LED_BUILTIN, LOW); // '0' switches LED off
if (character == '1') digitalWrite(LED_BUILTIN, HIGH); // '1' switches LED on
}
}
Of course, the serial message format in this simple example is trivial. It is done for demonstration purposes. You could implement any format you wish, test it on a local serial monitor, then it is going to work the same way when you send commands over MQTT.
Keep it simple, though.
When a communication chip is in Serial/MQTT bridge mode, a Host MCU is not aware it is connected to the Internet. It "thinks" that it is controlled via Serial, but in fact, serial data comes from the internets. A communication chip is, so to say, transparent, invisible to the Host MCU.
It is possible to put communication chip into an RPC mode. In this mode, a communication chip expects data to be in a JSON-RPC format: each chunk of data must be a JSON-RPC frame, separated by a newline character. This way, a communication chip is not transparent to the Host MCU: Host MCU knows it is there, it could send JSON-RPC requests to it and receive responses.
In RPC mode, a Host MCU can register any number of custom handler functions,
like GetStatus
, SwitchOnMotor
, or whatever is required. A communication
chip can bridge these to the management cloud, and any function could be
called via a familiar REST API.
Read RPC section below for a detailed explanation and an example sketch.
This recipe demonstrates how to build a complete custom monitoring dashboard using VCON platform. The implementation is very compact, well commented, and is designed to be a reference implementation of the production system. It consists of the following parts:
The overall architecture of such setup is as follows:
Step 1. Follow Quick Start Guide to register a VCON device on a dash.vcon.io management dashboard
Step 2. Clone or download the https://github.com/cesanta/vcon-app-example repository to your workstation
Step 3. Flash the firmware/firmware.ino
sketch to your VCON device
using remote OTA.
This sketch implements a simple LED control and simulates periodic sensor data upload:
void setup() {
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
// Handle serial input: switch LED on/off
if (Serial.available() > 0) {
int ch = Serial.read();
if (ch == '0') digitalWrite(LED_BUILTIN, LOW); // '0' switches LED off
if (ch == '1') digitalWrite(LED_BUILTIN, HIGH); // '1' switches LED on
}
// Print current status to serial every 5 seconds
// A status message is a JSON string like this: {"led": 0, "sensor": 27}
static unsigned long prev;
unsigned long curr = millis();
if (curr - prev > 5000) {
char buf[100];
snprintf(buf, sizeof(buf), "{\"led\": %d, \"sensor\": %d}",
(int) digitalRead(LED_BUILTIN), (int) random(20, 30));
Serial.println(buf);
prev = curr;
}
}
Step 4. Install Node.js, or skip this step if you have it installed
Step 5. Install ws
node package for Websocket support:
$ npm i -g ws
Step 6. Edit backend/config.json
file, change vcon_api_key
value
and save the file. You can get you API key by logging to https://dash.vcon.io
dashboard on the Account page.
Step 4. Run your backend
$ node backend/main.js
That's it! Now point your browser to https://localhost:8000 and login as test/test. Here are the links for the core pieces of functionality:
Here are some possible choices for where you can host your custom node.js backend, once the customisation is complete:
Service | Price from | Payment type |
---|---|---|
https://www.heroku.com/ | 0 | usage based, with freebie quota |
https://aws.amazon.com/ | 0 | usage based, with freebie quota |
https://cloud.google.com/ | 0 | usage based, with freebie quota |
https://azure.microsoft.com/ | 0 | usage based, with freebie quota |
https://www.digitalocean.com/ | $5 / month | fixed price, run on a virtual instance |
A simplest way to use VCON is to set $.host.mode
parameter to a MQTT or
Websocket bridge (2
or 3
respectively). In this case, everything that
Host MCU sends UART, VCON catches and sends over to a remote server.
VCON does not interpret UART data in any way, so the bridge is transparent.
However, if $.host.mode
is set to 1
(RPC bridge), then VCON interprets
UART data that Host MCU sends as JSON-RPC commands. VCON module exports
many RPC methods (see RPC reference below), therefore Host MCU can call them
and utilise additional functionality VCON offers - like, reading/writing
files on VCON module, send HTTP requests to remote servers, etc.
Note that not all available RPC methods are exported via UART by default.
Available methods are controlled by the $.rpc.safe
configuration setting,
see configuration reference below. Set $.rpc.safe
to *
to allow all
methods. Note: for production, tighten that up, because methods allowed by
$.rpc.safe
are available over UART and BLE.
So, in this recipe, Host MCU periodically calls rpc.list
RPC function
that lists methods available for Host MCU to call. The Arduino sketch is
for VCON-D51, or any other hardware setup where Serial
is wired to the
serial console, and Serial1
to the VCON.
Step 1. Follow Quick Start Guide to register a VCON device on a dash.vcon.io management dashboard
Step 2. When you device is online on dash.vcon.io, choose
action → Manage device. In the FileSystem section, choose config.json
file. Add "rpc": {"safe": "*"},
right after the
first opening {
at the beginning of the file. Change $.host.mode
from 2 to 1.
Click Save. Click "reboot device" in the "General Information" section.
Step 3. Open Arduino IDE, Tools → Manage Libraries, search for msjon
and install mjson
library.
Step 4. Create a new sketch. If you use VCON-D51, choose Adafruit ItsyBitsy M4 as a board. Copy-paste the following code: using remote OTA.
// Example firmware that calls VCON RPC function
// Set $.host.mode to 1 in the VCON configuration
#include <mjson.h>
int fn(const char *buf, int len, void *userdata) {
return Serial1.write(buf, len);
}
int response_callback(const char *buf, int len, void *userdata) {
Serial.write("Got response: ");
Serial.write(buf, len);
Serial.println();
return len;
}
void setup() {
Serial1.begin(115200);
Serial.begin(115200);
jsonrpc_init(response_callback, NULL);
}
void loop() {
char buf[800];
if (Serial1.available() > 0) {
int len = Serial1.readBytes(buf, sizeof(buf));
jsonrpc_process(buf, len, fn, NULL, NULL);
}
// Call RPC function every 3 seconds
static unsigned long old;
unsigned long now = millis();
if (old > now || old + 3000 < now) {
old = now;
mjson_printf(fn, NULL, "{%Q:%d,%Q:%Q,%Q:{}}\n", "id", 1, "method", "rpc.list", "params");
}
}
Step 5. Update Host MCU remotely. Open Serial console. You should see
messages printed periodically by the response_callback()
function, that
shows a list of available RPC functions.
Congratulations! Now you know how to call any VCON RPC method from a Host MCU. See RPC reference below for a detailed description of each method.
VCON cloud provides management API access to your devices, and an easy to use Web UI with device dashboard:
Cloud API access can be authenticated via a Basic HTTP authorisation, or
by setting a Authorization: Bearer APIKEY
header. For a Basic auth,
use your user/password. For a Bearer auth, take your APIKEY from the
"Account" tab in the cloud UI.
NOTE: you can use APIKEY in a Basic auth. Set user to an empty string, and password to your APIKEY. Curl examples for all three methods are listed below:
Method | Description |
---|---|
Basic |
|
APIKEY |
|
Basic + APIKEY |
|
dash.vcon.io provides a test account with the following credentials:
Password | APIKEY | |
---|---|---|
test | test | test |
It is open to everyone for demonstration purposes. Anyone can login to dash.vcon.io using test/test as an email/password. And below is an example of an API usage:
Get all devices registered under a test account:
curl -su :test https://dash.vcon.io/api/v3/devices
List all available functions of device 42:
curl -su :test https://dash.vcon.io/api/v3/devices/42/rpc/rpc.list
Call device 42, function sys.reboot
:
curl -su :test https://dash.vcon.io/api/v3/devices/42/rpc/sys.reboot
NOTE: URI in a table below must be prefixed with https://dash.vcon.io/api/v3
.
Method | URI | Description |
---|---|---|
GET | /user | Get user |
POST | /user | Set user. Parameters: JSON object with new user data: {"fullname":"...", "company":"...", "email":"...", "address":"...", "phone":"...", "settings":{...}} |
GET | /devices | Get device list |
POST | /devices | Create new device. Parameters: none |
GET | /devices/:id | Get device with ID :id |
POST | /devices/:id | Update device with ID :id . Parameters: JSON object with device data: {"labels":{"board":"nano33"}, "state":{...}} |
DELETE | /devices/:id | Delete device with ID :id |
GET | /devices/:id/fs/:name | Get file :name on device :id |
POST | /devices/:id/fs/:name | Write file :name on device :id . File data is the HTTP POST body, sent varbatim - e.g. using curl --data-binary |
POST | /devices/:id/rpc/:name | Call RPC function :name on device :id . Parameters: none, or a JSON object specific to that RPC function. If no parameters are given, a GET request can be used too |
POST | /devices/:id/ota | Update firmware over the air. By default, a Host MCU gets updated. If you want to OTA a VCON module, append ?target=vcon to the URL. HTTP body must be a raw .hex or .bin file data with a new firmware. Example: curl -su :test ttps://dash.vcon.io/api/v3/devices/42/ota?hex=1 --data-binary @PATH_TO_FIRMWARE.hex |
GET | /devices/:id/bye | Disconnect device. If, for various reasons, a device gets stuck, force reconnection |
GET | /devices/:id/tx?t=n | Capture serial output from device :id for n seconds. If t is not specified, it defaults to 5 |
Hint: to list files on a device, use fs.list
RPC:
curl -su :API_KEY https://dash.vcon.io/api/v3/devices/ID/rpc/fs.list
A Host MCU can receive commands remotely using a technique called RPC bridge. RPC stands for Remote Procedure Call.
VCON module and a cloud communicate with each other using a standard JSON-RPC 2.0 protocol over the secure Websocket. Also, by default, a Host MCU and VCON module talk to each other using JSON-RPC. JSON-RPC is a very simple protocol: client and server exchange JSON strings with the following format:
The rules are simple:
method
attribute, and optional params
id
attribute, then a server must send
a response frame. Otherwise, frames without id
are considered notification
frames. Server does not respond on notification frames{"id":1, "error": {"code": 500, "message": doh""}}
For example, VCON sends a status notifications to the Host MCU. This frame does
not have an id
attribute, thus Host does not send a response:
{"method": "status", "params": "cloud_down"} // VCON -> Host
When Host receives a JSON-RPC frame, it parses the frame and calls a
corresponding handler function. A handler function processes the request and
produces a reply, which is sent back to the VCON. In the following
communication example, VCON calls a custom function sum
that adds two
numbers:
{"id": 12, "method": "Sum", "params": [2,3]} // VCON -> Host
{"id": 12, "result": 5} // VCON <- Host
And here is the example when VCON calls a non-existent function:
{"id": 13, "method": "This_Function_Does_Not_Exist", "params": true} // VCON -> Host
{"id": 13, "error": {"code": -32601, "message": "method not found"}} // Host -> VCON
VCON cloud exposes JSON-RPC interface as a RESTful endpoints, implementing a so-called RPC bridge. Commands are sent to the cloud via HTTP/REST, and the cloud sends commands to devices via JSON-RPC wrapped into a TLS-secured WebSocket connection:
The REST URL should be https://dash.vcon.io/api/v3/devices/:id/rpc/:name
,
where :id
is a device ID, and :name
is an RPC function name that must
be implemented by a device. Note that dash.vcon.io does not know which
functions are implemented by a device - whatever :name
is specified in the
URL, it triggers RPC function :name
on a device. Devices,
however, implement rpc.list
function that enumerates all functions that
device exports. This gives an ability to easily see what functions are
implemented by a device. For example, this curl command lists all functions
implemented by device with ID 42
under a test account:
curl -su :test https://dash.vcon.io/api/v3/devices/42/rpc/rpc.list
An RPC function may be without parameters, like rpc.list
, fs.list
,
sys.info
or sys.reboot
. Other RPC functions take parameters. Parameters
are set in a JSON string, passed as HTTP POST body. For example,
RPC function fs.read
reads a file on a VCON filesystem, and it expects
a file
and offset
parameters. A function returns base64-encoded
file data from given offset, and also tells how many bytes are left to read:
curl -su :test https://dash.vcon.io/api/v3/devices/42/rpc/fs.read -d "{\"file\":\"ca.pem\",\"offset\":123}"
Response:
{"file":"ca.pem","offset":123,"left":28127,"data":"MjAyMS...."}
If VCON module has a host microcontroller attached in an RPC (non-transparent) bridge mode, then an additional link is added between VCON and Host MCU. They also talk using JSON-RPC.
NOTE: to stress it again, the following applies only when a bridge setting set to RPC mode. See Configuration Reference section for details.
There is a wildcard RPC function on VCON, host.*
that passes all RPC calls
that start with host.
to the Host microcontroller. So, for example,
RPC function rpc.list
lists all functions on VCON module, whereas RPC
function host.rpc.list
lists all functions exported by a Host MCU. For
example, the following session lists all function on a Host
microcontroller on device 42
, and then reads a temperature an Host MCU.
Note the host.
prefix in those API calls:
curl -su :test https://dash.vcon.io/api/v3/devices/42/rpc/host.rpc.list
["rpc.list","sensor.read"]
curl -su :test https://dash.vcon.io/api/v3/devices/42/rpc/host.sensor.read
{"value":42}
Below is a detailed diagram describing the whole sequence of calls for the
host.sensor.read
request:
Host MCU can use mjson client library
to implement JSON-RPC. Note that mjson.h
is a completely stand-alone
piece of software, independent of VCON. It helps to turn a microcontroller
into a JSON-RPC client and server using any available transport, for example
an UART connection. Let's demonstrate it.
Take any Arduino board. Install mjson library if it is not already installed.
Note: in order to install an
mjson
library, start Arduino IDE, choose "Sketch" → "Include Library" → "Manage libraries". In the dialog search field, enter "mjson". You should see a "mjson" library. Click on "Install" button to install that library.
Create a new sketch. Copy/paste the following code:
#include "mjson.h"
// RPC handler for "Sum". Expected RPC frame is like this:
// {id: 1, "method": "Sum", "params": [40, 2]}
static void sum(struct jsonrpc_request *r) {
double a = 0, b = 0;
mjson_get_number(r->params, r->params_len, "$[0]", &a);
mjson_get_number(r->params, r->params_len, "$[1]", &b);
jsonrpc_return_success(r, "%d", (int) (a + b));
}
void setup() {
Serial.begin(115200); // Setup serial port
jsonrpc_init(NULL, NULL); // Initialise library
jsonrpc_export("Sum", sum, NULL); // Export "Sum" function
}
static int wfn(const char *frame, int frame_len, void *privdata) {
return Serial.write(frame, frame_len);
}
void loop() {
if (Serial.available() > 0) jsonrpc_process_byte(Serial.read(), wfn, NULL);
}
The sketch above registers a custom RPC function Sum
. In the loop()
,
we read serial input. An expected input is a series of JSON-RPC strings,
delimited by the new line characters.
The jsonrpc_process_byte()
function buffers serial input into an internal
buffer, and when a new line character is read, jsonrpc_process_byte()
calls
jsonrpc_process()
function which parses the received frame and calls a
registered handler function, if any.
Therefore, in order to "talk" to the Arduino using JSON-RPC protocol, we need to open a Serial Monitor, type in a valid JSON-RPC frame in it and press "Enter" to emit a new line character.
Let's call our custom function Sum
we've just created.
Start Arduino Serial Monitor, choose port speed 115200, and type
{"id": 1,"method": "Sum", "params": [2,3]}
. Hit enter.
You should see an answer frame:
Note that mjson.h
library provides one built-in RPC function rpc.list
,
which returns a list of all registered RPC functions. If you are unsure which
functions are provided by the mjson-enabled microcontroller, call rpc.list
:
{"id": 1,"method": "rpc.list"} // Request
{"id": 1,"result": ["rpc.list","Sum"]} // Response
Now you should get an idea. Any microcontroller that implements mjson.h
becomes controlled using a standard JSON-RPC over UART - which you can easily
test manually using Serial Monitor, or in your lab by setting up an integration
test. VCON module just makes that serial line accessible via cloud.
VCON cloud provides a special secure WebSocket endpoint
wss://dash.vcon.io/api/v3/notify
. This is a read-only notifications endpoint.
Each notification is a JSON object with three keys:
name
- a notification name, e.g. online
, offline
, and so ondid
- an ID of a device that generated the eventdata
- an optional notification-specific data.Below is the list of the events:
{"name":"online","did":ID}
- generated by the cloud when a device becomes
online{"name":"offline","did":ID}
- generated by the cloud when a device becomes
offline{"name":"updated","did":ID,"data":{...}}
- generated by the cloud when a
device changes its state
attribute{"name":"ble.adv","did":ID,"data":{...}}
- generaged by the VCON module
in the BLE bridge mode, when ble.mode=2
. The data
contains BLE beacon
data.{"name":"CUSTOM","did":ID,"data":CUSTOM}
- a custom event that could be
generated by a Host microcontroller in the RPC bridge mode. A Host
micro must call the cloud.CUSTOM
RPC function with any params
you want.
For example, this is how a Host microcontroller can send some sensor data:jsonrpc_printf(fn, NULL, "{%Q:%Q,%Q:{%Q:%g}}",
"method", "cloud.temperature",
"params", "value", 123.456)
This call generates {"name":"temperature","did":ID,"data":{"value":123.456}}
NOTE: the cloud UI uses notification endpoint to catch device changes, like online/offline, and dispays that respectively. You can create your custom dashboard using cloud API and notifications.
You can catch all notifications sent by the cloud.
Below is a simple NodeJS application that catches all incoming notifications
and prints them on a console. Create file catcher.js
, copy/paste the
folowing content:
const Websocket = require('ws'); // npm install -g ws
const addr = 'wss://dash.vcon.io/api/v3/notify?access_token=APIKEY';
const reconnect = function() {
const ws = new Websocket(addr, {origin: addr});
ws.on('error', msg => console.log('Got error:', msg.toString()));
ws.on('message', msg => console.log('Got message:', msg.toString()));
ws.on('close', () => setTimeout(reconnect, 1000));
};
reconnect();
Change APIKEY
to your API key which could be copied from the "Account" tab in
the cloud UI. Run this file and see how arriving notifications are printed:
$ node catcher.js
Got message: {"name":"online","did":1}
NOTE: by bringing up a custom notification catcher, you can integrate with any other 3rd party service - for example, store data into a Google/AWS/Azure, dump data in your custom dashboard, send SMS, run analytics, et cetera.
In the BLE bridge mode, VCON module receives BLE beacon advertisements from nearby BLE beacons, and forwards them to the cloud as device notifications. You can catch those notifications by using a notification catcher, and do whatever you want with the data - store in a database, do real-time processing, etc.
Also VCON provides a BLE.Advertise
RPC function, which you can call
from anywhere via the cloud and trigger VCON module to send a BLE advertisement
with configurable payload.
To configure BLE bridge, see ble
section in the
Configuration Reference.
VCON module can update Host MCU remotely. You can securely pass a new firmware over the VCON cloud, then VCON reprograms an attached microcontroller. It works because VCON knows respective flashing protocols for different architectures. Network communication is over TLS, encrypted and authenticated.
See Configuration Reference for exact details on how to setup OTA for your microcontroller.
VCON can also update itself, using the same cloud API. Just add an extra
?target=vcon
query string to the ota endpoint, and send a VCON firmware,
not your MCU firmware:
curl -su :API_KEY 'https://dash.vcon.io/api/v3/devices/ID/ota?target=vcon' --data-binary @fw.bin
A VCON module, in order to operate, requires two crucial settings in its configuration file:
wifi.sta.ssid
and wifi.sta.pass
.
For ethernet and cellular, these are not requireddash.pass
Thus this section explains different methods of setting these configuration parameters.
Method 1. Flashing VCON configuration file using a flasher CLI tool
Method 2. Using WiFi access point
A VCON module with unconfigured wifi.sta.ssid
automatically starts
a WiFi network vcon-????
. Join that network, and talk to a VCON module
on IP address 192.168.4.1
. VCON runs an HTTP server which accepts
configuration command:
curl http://192.168.4.1/rpc/config.set -d "{\"config\":{\"wifi\":{\"sta\":{\"ssid\":\"X\",\"pass\":\"Y\"}}},\"save\":true}"
Method 3. Using Bluetooth Low Energy (BLE), described at Network Setup section
The following table summarises built-in RPC functions that are exposed by a VCON module. These functions can be called remotely via REST, or locally via UART (for example, Host MCU can call any of the VCONs RPC function).
This is an example of the remote function call using curl
utility.
APIKEY
is your API key you can get from the Account tab on dash.vcon.io,
ID
is a device ID, and NAME
is an RPC name:
$ curl -su :APIKEY https://dash.vcon.io/api/v3/devices/ID/rpc/NAME
This is an example calling sys.info
function on device 1
:
$ curl -su :APIKEY https://dash.vcon.io/api/v3/devices/1/rpc/sys.info
{"id":1,"result":{"version":"4m-1.3.3-v3.3","built":"2020-05-09 20:03:20","uptime":9,"ram_free":104360,"reboot_reason":"other watchdog"}}
Some API calls require parameters, a JSON string in HTTP POST body:
$ curl -su :APIKEY https://dash.vcon.io/api/v3/devices/1/rpc/fs.read -d "{\"file\":\"config.json\"}"
{"id":2,"result":{"file":"config.json","offset":0,"left":0,"data":"ewogICJ3aWZp..."}}
Method | Parameters | Description |
---|---|---|
rpc.list | - | Show all RPC functions available |
sys.info | - | Show general information about a device, like build timestamp, firmware version, uptime in seconds |
sys.log | - | Show the current console log buffer. Every console log message is stored in a fixed-size, 1K buffer. New messages are appended to the end, older messages are removed to keep the space fixed. This RPC returns the log buffer and cleans it. Call this function repeatedly to get devices's console log |
sys.reboot | - | Reboot device |
config.get | - | Show devices configuration |
config.set |
|
Update device configuration. config attribute specify configuration changes. save is an optional parameter (default false ) that tells to make changes permanent by storing them in a config.json file on a device. Note: config.json file keeps only configuration overrides. If you set configuration option to its default value, it disappears from the "config.json" file |
gpio.write |
|
Set a given VCON pin to a given value |
gpio.read |
|
Read a given VCON pin |
fs.list | - | List files on VCON filesystem |
fs.read |
|
Get file data from given offset. Returned file data is base64-encoded |
fs.write |
|
Write data to a file. Data must be base64-encoded. Data is appended to the end of the file. A written file gets truncated before write, unless an optional append parameter is set to true (it is false by default) |
swd.exec |
|
Send a list of SWD commands to the Host MCU. Available SWD commands:rst - send SWD reset sequencerd0 ,rd1 ,rd2 ,rd3 - read debug registerwd0 ,wd1 ,wd2 - write debug registerra0 ,ra1 ,ra2 ,ra3 - read access registerwa0 ,wa1 ,wa2 ,wa3 - write access registerrm,ADDR - read memory at ADDR (hex)rm,ADDR,MASK,VAL - read memory at ADDR until MASK equals to VALwm,ADDR,VAL - write memoryNote: ADDR, VAL, MASK values must be lowercase hexadecimal numbers without the 0x prefix, e.g.: 2ef . Example - a standard MCU init sequence is rst rd0 wd0,1f wd2,0 wd1,50000f00 wa0,23000012 |
swd.read |
|
Read Host MCU memory over SWD |
swd.write |
|
Write to the Host MCU memory over SWD. Data is a hex-encoded buffer to write. |
mcu.reset | - | Reset Host MCU |
spi.txn |
|
Execute SPI transaction on Host MCU. $host.spi must be configured. COMMANDS is a space-separated list of SPI commands which has format ADDRESS HEX_WRITE.READ_SIZE. For example, reading AVR fuses is the following command: ac530000.04 50000000.04 58080000.04 50080000.04 |
wifi.scan | - | Scan WiFi and return a list of available WiFi networks |
http.request |
|
Send HTTP request to a given URL. Note: $.host.mode must be set to 1 (RPC bridge). The url parameter is mandatory, whereas method , headers and body are optional. Response is an object {"code": 200, "headers": {...}, "body": "base64-encoded-response-body"} . Note that the response gets fully buffered in VCON RAM. You can see the amount of free RAM on VCON by calling sys.info RPC call. Do not send requests which trigger responses larger than several Kb |
ws.send |
|
Send data to the Websocket server. Note: $.host.mode must be set to 3, and $.ws section configured |
host.* | any | Forward RPC frame to the Host MCU, stripping host. prefix from method name |
cloud.* | any | Forward RPC frame to the cloud, stripping cloud. prefix from method name. Use this RPC to send custom notifications to the cloud. The following method names are treated specially by the cloud:{"method":"cloud.state.set","data":...} - This notification changes device's state attribute on the cloud. The behavior is similar to AWS/Azure device shadow - setting an attribute touches only that attribute and leaves the rest intact. To delete an attribute, set it to null |
VCON module configuration is a JSON string. It is stored on the root filesystem
in "config.json" file. It could be viewed by calling config.get
RPC function:
curl -su :APIKEY https://dash.vcon.io/api/v3/devices/ID/rpc/config.get
{"wifi":{"sta":{"ssid":"MyWiFiNetwork","pass":"mypassword"}},"dash":{...},...}
In order to change one or more configuration option, call config.set
RPC function and pass
a JSON object with 2 parameters: required config
with your changes, and optional
boolean save
to save your changes to "config.json".
For example, this command changes an architecture of Host microcontroller to
200 (STM32 with 1k flash pages), and saves:
curl -su :APIKEY https://dash.vcon.io/api/v3/devices/ID/rpc/config.set -d "{\"config\":{\"host\":{\"arch\":200}},\"save\":true}"
The following table describes all configuration options. Every option name is specified by its JSON path.
Name | Type | Description |
---|---|---|
$.wifi.mode | int | WiFi mode. Default: 1 (enabled). Possible values: 0 - disabled, 1 - enabled |
$.wifi.sta.ssid | string | WiFi network name. Default: "" (unset) |
$.wifi.sta.pass | string | WiFi network password. Default: "" (unset) |
$.wifi.ap.ssid | string | WiFi Access Point name for an unconfigured device . Default: "vcon-????". Note: ? characters in the AP name will be replaced with the MAC address hex values |
$.dash.url | string | Cloud address. Default: "wss://dash.vcon.io/api/v3/rpc". Override it if you have a dedicated/private cloud instance |
$.dash.pass | string | Device cloud auth token. Default: "" (unset) |
$.debug.level | string | Console log level. Default: "2". Possible values: "0" - disable console log "1" - log errors only "2" - log errors and info messages "3" - log erros, info and debug messages "4" - log everything Per-file overrides are supported, e.g. "2,tcp:3" |
$.debug.tlslevel | int | Console log level for TLS. Default: 1. Possible values: 0-5 |
$.debug.udpaddr | string | UDP log address "IP:PORT". Default: "". If set, then console log messages are also sent to the specified HOST:PORT |
$.mqtt.url | string | MQTT server URL. Required only when $.host.mode is 2 . Default: NULL (not set). The format of the URL is PROTO://USER:PASS@HOST:PORT , where PROTO is mqtt or mqtts , USER and PASS are MQTT credentials (could be omitted). NOTE: VCON sets MQTT client ID equal to the $.device.id |
$.mqtt.rx | string | MQTT topic for VCON to subsribe to. All data read from this topic, VCON will forward to the Host MCU UART RX |
$.mqtt.tx | string | MQTT topic for VCON to publish to. All data VCON reads from the Host MCU UAET, VCON publishes to that topic |
$.mqtt.cert | string | Client TLS certificate file name. Required only for 2-way TLS. Must be prefixed with /spiffs , e.g. /spiffs/my_cert.pem |
$.mqtt.key | string | Client TLS certificate key file name. Required only for 2-way TLS. Must be prefixed with /spiffs , e.g. /spiffs/my_key.pem |
$.ws.url | string | Websocket server URL. Required only when $.host.mode is 3 . Default: NULL (not set) |
$.ws.hdrs | string | Websocket extra HTTP headers for WS handshake. Required only when $.host.mode is 3 . Default: NULL (not set). Example: Authorization: Bearer foobar\r\n |
$.ws.cert | string | Client TLS certificate file name. Required only for 2-way TLS. Must be prefixed with /spiffs , e.g. /spiffs/my_cert.pem |
$.ws.key | string | Client TLS certificate key file name. Required only for 2-way TLS. Must be prefixed with /spiffs , e.g. /spiffs/my_key.pem |
$.device.id | string | An arbitrary device identification. Used only in the BLE adv forwarding, and passed as a gw BLE adv frame parameter |
$.device.dns | string | Custom DNS server URL. Example: udp://1.1.1.1:53 - which is a CloudFlare DNS server. Default: "" (unset), in which case Google's udp://8.8.8.8:53 is used |
$.rpc.safe | string | List of comma-separated RPC functions available to Host MCU, and over the HTTP server. Default: config.set,sys.*,rpc.*,gpio.*,cloud.* |
$.host.arch | int | A Host MCU arhitecture. Default: 0 (unset). Required for reprogramming. Possible values: 100 - Microchip SAMD200 - STM32 with 1k flash pages201 - STM32 with 2k flash pages202 - STM32 with 16,16,16,16,64,128,128,128k pages203 - STM32 with 32,32,32,32,128,256,256,256k pages300 - AVR (e.g. classic Arduinos) |
$.host.rst | int | VCON pin to which Host MCU's RESET pin is connected. Default: -1 (unset). Required for reprogramming / rebooting an attached MCU if that cannot be done via SWD, for example for attached AVR |
$.host.mode | int | Host MCU communication mode. Default: 0 (disabled). Possible values:0 - disabled1 - RPC bridge. Serial link is exchanging JSON-RPC frames, delimited by newline characters2 - transparent UART/MQTT bridge. Serial data is uninterpeted, sent to/from mqtt.rx and mqtt.tx topics. Make sure to configure the mqtt section 3 - transparent UART/Websocket bridge. Serial data is uninterpeted, sent to/from $.ws.url Websocket server. Make sure to configure the $.ws section |
$.host.addr | int | Flash memory address for .bin firmwares. For .hex firmwares, this value is ignored. Default: 0 |
$.host.swd.io | int | VCON pin to which Host MCU's SWDIO pin is connected. Default: -1 (unset). Required for reprogramming ARM MCUs |
$.host.swd.clk | int | VCON pin to which Host MCU's SWDCLK pin is connected. Default: -1 (unset). Required for reprogramming ARM MCUs |
$.host.swd.dur | int | SWD clock duration in VCON's nop instructions. Default: 50 |
$.host.uart.tx | int | VCON pin to which Host MCU's UART TX pin is connected. Default: -1 |
$.host.uart.rx | int | VCON pin to which Host MCU's UART RX pin is connected. Default: -1 |
$.host.uart.cts | int | VCON pin to which Host MCU's UART CTS pin is connected. Default: -1 (unset) |
$.host.uart.rts | int | VCON pin to which Host MCU's UART RTS pin is connected. Default: -1 (unset) |
$.host.uart.baud | int | A Host MCU's UART baud rate. Default: 115200 |
$.host.spi.mosi | int | VCON pin to which Host MCU's SPI MOSI pin is connected. Default: -1 |
$.host.spi.miso | int | VCON pin to which Host MCU's SPI MISO pin is connected. Default: -1 |
$.host.spi.clk | int | VCON pin to which Host MCU's SPI CLK pin is connected. Default: -1 |
$.host.spi.freq | int | Host MCU's SPI clock frequency. Default: 50000 |
$.ble.mode | int | BLE gateway mode. Default: 0 (disabled). Possible values:0 - BLE disabled1 - BLE enabled, configurator is starged2 - BLE enabled. Beacon data is forwarded to the cloud as a ble.adv notification. NOTE: this mode disables BLE device configurator 3 Beacon data is forwarded to the $.mqtt.tx topic of the configured MQTT server. NOTE: this mode disables BLE device configurator |
$.ble.filter | string | A comma separated list of glob patterns. BLE advertisements whose MAC addresses or names do not match all patterns, are ignored. Default: empty, which means all BLE advertisements match. Example: MyName*,aabbcc* - match devices whose names start with MyName or MAC address start with aabbcc |
$.ble.lowat | int | A RAM threshold. If free RAM is lower than this value, then ignore an incoming BLE advertisement, do not forward it to the cloud to preserve RAM. Default: 0 |
$.eth.mode | int | Ethernet mode. Default: 0 (disabled). Possible value:0 - Ethernet disabled1 - Ethernet enabled |
$.eth.addr | int | Ethernet PHY address. Default: -1 |
$.eth.clk | int | Ethernet clock source. Default: 0 . Possible values: CONFIG_ETH_RMII_CLK_* constants |
$.eth.mdc | int | Ethernet MDC pin. Default: -1 |
$.eth.mdio | int | Ethernet MDIO pin. Default: -1 |
$.eth.pwr | int | Ethernet PHY power pin. Default: -1 |
$.pins.status | int | Status LED pin. Default: 2 (enabled). To disable, set to -1 . If enabled, it is assumed that is an LED, and does the following:fast 75 ms blink - when network is not connected, slow 750 ms blink - when network is connected, but cloud is not, steady light - when cloud is connected |
$.pins.factory | int | Factory reset pin. Default: 4 (enabled). To disable, set to -1 . If enabled, it is assumed that this pin is connected to a (pulled up) button. Pressing this button for more than 3 seconds (pulling low) triggers factory reset, which copies factory.json to `config.json |
If any quick start guide step fails, or the VCON module behaves in an unexpected way, please follow these steps: