Bridge Manual (EN)
This document is the complete command reference for
MyDotDevStudioBridge.ino.
The bridge reads one UTF-8 line at a time from Serial at 115200 baud.
Every command must end with a newline. Commands and subcommands are
case-insensitive; values such as text, Wi-Fi SSIDs and cloud tokens keep their
original case.
The Serial Monitor should use Newline as the line ending.
Structured capabilities
CAPS returns protocol version 2. In addition to the summary lines, it emits
one machine-readable line for every command:
CAPS COMMAND DISPLAY_TEXT args=text type=string
CAPS COMMAND RELAY args=state type=enum values=ON|OFF|TOGGLE|STATUS result=variable
CAPS COMMAND SENSOR_READ args=field,variable type=bme690 values=TEMPERATURE|PRESSURE|HUMIDITY|GAS
The command identifier uses underscores so a web editor can use it as a stable
key. args lists positional arguments, type identifies the API family, and
optional values/range fields describe accepted values. The summary
CAPS RUNTIME line remains available for clients that only need category names.
Protocol basics
The bridge prints one of these response families:
OK ... Command accepted
ERR ... Command rejected or failed
INFO ... Informational message
STATUS ... Runtime, connection and resource status
At startup it prints MyDot Dev Studio Bridge ready. It also reports whether a
microSD card was initialized. USB power is enough for serial communication,
but the MyDot carrier must be powered through its external DC jack when using
the relay, NeoPixels or fan.
Top-level commands
These commands manage the in-memory sequence or the bridge itself.
| Command | Description |
|---|---|
HELP |
Prints a short human-readable command list. |
CAPS |
Prints the machine-readable command families, limits and file format. |
STATUS |
Prints the board model, USB/runtime state plus Wi‑Fi, My Microeden, microSD capacity and ESP32 heap information when supported. |
ADD <runtime-command> |
Appends one command to the current sequence. |
LIST |
Lists the sequence with zero-based command indexes. |
CLEAR |
Immediately acknowledges deletion of the in-memory sequence, then stops execution and switches relay, fan and NeoPixels to a safe off state. It does not delete the SD file. |
SAVE |
Encrypts the current sequence and writes /MyDot.run to SD. |
LOAD |
Reads, decrypts, verifies and loads /MyDot.run. |
RUN |
Starts the current sequence at command zero. Execution is non-blocking. |
STOP |
Stops execution, disables the runtime watchdog, switches off relay, fan and NeoPixels, and clears the OLED display. |
REBOOT |
Safely stops the runtime and reboots the MyDot board using the native reset primitive of the selected Arduino core. |
EXEC <runtime-command> |
Executes one immediate command. Control-flow commands require RUN and are rejected by EXEC. |
The portable watchdog commands are available as runtime instructions and can
also be sent through EXEC:
WATCHDOG BEGIN <timeout-ms>
WATCHDOG FEED
WATCHDOG STOP
BEGIN enables the cooperative watchdog, FEED refreshes its deadline and
STOP disables it. The Bridge checks the deadline from MyDot::run() and
reboots the board when the timeout expires. Add a WATCHDOG FEED node to the
continuous flow; no automatic feed is performed by the library, so a stalled
flow can still be detected. CAPS FEATURE watchdog=cooperative identifies
this backend.
STATUS keeps the original key/value fields and adds board (the readable
board name detected from the Arduino core), wifi, wifiRssi,
cloud, sdCardBytes, sdTotalBytes, sdUsedBytes, sdFreeBytes,
ramFreeBytes and ramTotalBytes. sdCardBytes is the physical card
capacity (cardSize()); sdTotalBytes is the usable filesystem capacity.
Resource sizes are reported when the selected board exposes the corresponding
API; otherwise their value is unknown.
The Dev Studio also has a priority USB control lane for stopping the board:
the ETX byte (0x03) interrupts RUN even while a long microSD read or write
is in progress. This requires the updated bridge firmware; older firmware can
still receive the text STOP command, but it cannot pre-empt an operation
already in progress.
Example:
HELP
CLEAR
ADD BRIGHTNESS 255
ADD PIXELS 255 0 0
LIST
SAVE
RUN
SAVE stores the complete textual sequence in its current order, including
delays, labels, variable assignments and cloud commands. It does not store the
current live value of a variable unless that value is represented by a SET
command in the sequence.
After a reset the file is detected, loaded and started automatically when the
SD card is available and the integrity check succeeds. This makes the saved
runtime resume operation after a power interruption. LOAD remains available
to retry or reload the file manually, and RUN can restart the sequence after
STOP.
Runtime limits
| Resource | Limit |
|---|---|
| Sequence commands | Limited by payload size |
| Command length | 96 characters |
| Encrypted script payload | 4096 bytes |
Nested REPEAT blocks |
8 |
| Runtime variables | 16 |
| Variable name length | 16 characters |
| Variable value length | 64 characters |
Variables and value substitution
Variables are held in RAM by the interpreter. Names are normalized to
uppercase and may contain letters, numbers and _.
SET <name> <value>
GET <name>
VARS
UNSET <name>
CLEAR_VARS
Reference a variable in any later command with $NAME or ${NAME}:
SET LIMIT 2200
ANALOG_READ A0 SOIL
SERIAL soil=$SOIL limit=$LIMIT
BRIGHTNESS $SOIL
SET stores the complete remaining text after the variable name. Variable
references are expanded when a runtime command is executed, not when it is
added. This permits a value read from a sensor to be reused later in the same
sequence.
VARS prints:
BEGIN_VARS
VAR SOIL=1840
END_VARS
The live values are volatile. To recreate an initial value after LOAD/RUN,
include a SET command in the saved sequence.
Digital and analog I/O
Pin arguments accept numeric Arduino pin numbers and board labels such as
A0, A1, D2 and D3. On the Nano ESP32 the D* and A* aliases follow
the Arduino Nano pinout.
DIGITAL_READ <pin> <variable>
DIGITAL_WRITE <pin> <value>
ANALOG_READ <pin> <variable>
ANALOG_WRITE <pin> <0..255>
DIGITAL_READ configures the pin as INPUT and stores 0 or 1. Digital
write values may be HIGH, LOW, ON, OFF, TRUE, FALSE or a number.
ANALOG_READ stores the raw ADC value. ANALOG_WRITE accepts the PWM range
0–255 where supported by the selected board pin.
Example:
EXEC DIGITAL_READ D4 BUTTON_STATE
EXEC GET BUTTON_STATE
EXEC DIGITAL_WRITE D13 HIGH
EXEC ANALOG_READ A0 SOIL
EXEC SERIAL soil=$SOIL
Generic I²C bus blocks
The bridge exposes the Arduino Wire bus as byte-oriented runtime commands.
These primitives are deliberately independent of a particular sensor, so a
web editor can build a dedicated sensor block by emitting one READ_REG or
TRANSFER command. The bus uses the board's default SDA/SCL pins; no GPIO
numbers are hard-coded in the protocol.
I2C BEGIN [frequency]
I2C SCAN
I2C PING <address>
I2C WRITE <address> <byte0> [byte1 ... byte31]
I2C READ <address> <length> [prefix]
I2C TRANSFER <address> <writeCount> <readCount> <writeByte...> [prefix]
I2C READ_REG <address> <register> <length> [prefix]
I2C WRITE_REG <address> <register> <value>
Addresses and byte values accept decimal notation or hexadecimal notation such
as 0x76. Valid 7-bit device addresses are 0x03–0x77; a transaction can
contain up to 32 bytes. I2C BEGIN is optional because MyDot::begin() starts
the default bus, but it can be used to select a clock from 10 kHz to 1 MHz.
The normal sensor speed is 100 kHz; use 400000 for devices that support fast
mode.
SCAN prints every acknowledged address. PING tests one address. WRITE
sends a raw byte sequence. READ requests bytes without a register phase.
TRANSFER performs a combined write-then-read transaction with a repeated
start, which is the common pattern for register-based sensors. Its counts make
the command unambiguous for a visual block:
I2C TRANSFER <address> <number-of-bytes-to-write> <number-to-read> <write-bytes...> [prefix]
READ_REG is a convenience block for the most common case: it writes one
register byte and reads the requested number of response bytes. WRITE_REG
writes one register byte followed by one value byte.
When prefix is supplied, every received byte is saved as a runtime variable
named <prefix>0, <prefix>1, and so on. This lets later blocks use the
result, for example $WHO0, in a display, cloud value, condition or SD log.
The bridge also prints the bytes in hexadecimal using an I2C DATA line.
Examples:
EXEC I2C BEGIN 400000
EXEC I2C SCAN
EXEC I2C READ_REG 0x76 0xD0 1 WHO
EXEC SERIAL sensor-id=$WHO0
A dedicated sensor block can therefore contain the address, register, byte order and conversion formula while using this generic bus command as its only hardware transport. Keep SDA and SCL pulled up according to the sensor board and never connect an I²C device above the board's logic voltage.
Control flow
Control-flow commands are executed inside a sequence started with RUN.
EXEC rejects them because it has no sequence cursor or loop stack.
Labels and jumps
LABEL <name>
GOTO <name>
IF_BUTTON A|B PRESSED|CLICKED GOTO <name>
IF_VAR <name> <operator> <value> GOTO <name>
Labels are case-insensitive. A jump that leaves a repeat block automatically unwinds the active loop frames.
IF_BUTTON and IF_VAR are instantaneous tests: when the condition is false,
the runtime continues with the next line. Use WAIT_BUTTON when execution
must actually wait for a press. In the Dev Studio graph, a conditional branch
without a continuation is closed automatically so it cannot accidentally fall
through into a label block.
IF_VAR supports numeric comparisons ==, =, !=, >, >=, < and
<=. Text variables support ==, = and !=.
Example:
ADD ANALOG_READ A0 SOIL
ADD IF_VAR SOIL > 2200 GOTO DRY
ADD BRIGHTNESS 32
ADD GOTO END
ADD LABEL DRY
ADD BRIGHTNESS 255
ADD LABEL END
Waiting for a button
WAIT_BUTTON A|B PRESSED|CLICKED [timeoutMs]
The command pauses the sequence without blocking serviceSerial() or
MyDot::run(). With no timeout it waits indefinitely. If the timeout expires,
the sequence continues and prints INFO WAIT_BUTTON timeout.
The bridge prints INFO WAIT_BUTTON waiting when the wait is armed and
INFO WAIT_BUTTON triggered when the click is detected. Button edges are
latched by the bridge loop, so a short click is not lost while slower work is
being processed.
Repeat blocks
REPEAT <positive-count>
...commands...
ENDREPEAT
BREAK exits the innermost repeat block. CONTINUE jumps to its
ENDREPEAT, decrements the loop counter and starts the next iteration.
Example:
ADD REPEAT 3
ADD PIXELS_RANDOM
ADD DELAY 500
ADD ENDREPEAT
Relay and NeoPixels
RELAY ON
RELAY OFF
RELAY TOGGLE
RELAY STATUS <variable>
BRIGHTNESS <0..255>
PIXELS <red> <green> <blue>
PIXELS_SHOW
PIXELS_RANDOM
PIXEL <index> <red> <green> <blue>
CLEAR_PIXELS
RELAY STATUS reads the current output without changing it and stores the
text ON or OFF in the selected runtime variable.
Example:
ADD RELAY STATUS RELAY_STATE
ADD SERIAL relay=$RELAY_STATE
PIXELS and PIXEL immediately call showPixels(). PIXELS_SHOW is
provided for sequences that explicitly control when the current pixel buffer
is sent to the LEDs. Pixel indexes range from 0 to NUMPIXELS - 1.
Fan and DRV8830
FAN <-100..100>
FAN STOP
FAN STATUS
FAN CLEAR_FAULT
Positive and negative values select the direction. STATUS prints the last
requested speed and the DRV8830 fault register in hexadecimal. CLEAR_FAULT
sends the driver clear command; it does not repair an active hardware fault.
OLED display
The display commands are safe when no OLED is detected. DISPLAY <text> is a
compact form; the structured forms expose the individual display methods.
DISPLAY <text>
DISPLAY PRESENT
DISPLAY LOGO
DISPLAY SENSOR
DISPLAY CLEAR
DISPLAY SHOW
DISPLAY RAW_SHOW
DISPLAY CURSOR <x> <y>
DISPLAY SIZE <1..4>
DISPLAY COLOR <0..65535>
DISPLAY TEXT <text>
DISPLAY TEXT_AT <x> <y> <size> <text>
DISPLAY PRINT <text>
DISPLAY PRINTLN <text>
DISPLAY NEWLINE
Write operations return OK DISPLAY TEXT (or the matching operation). If the
OLED was not detected, the bridge also prints WARN DISPLAY unavailable; the
sequence continues, but power, I2C wiring and address 0x3C should be checked.
RAW_SHOW calls the underlying Adafruit_SSD1306 object returned by
getDisplay().
BME690 sensor
SENSORS
SENSOR_READ TEMPERATURE|PRESSURE|HUMIDITY|GAS <variable>
SENSORS_LOG <path>
Reads the onboard BME690 and prints temperature, pressure, humidity and gas resistance to the serial port. The hardware sensor is a BME690, accessed using the compatible Adafruit BME680 driver API.
SENSORS_LOG performs the same reading and appends one CSV row to the supplied
SD path. It creates the file and writes the header on the first call. The CSV
columns are epoch, time, temperature_c, pressure_hpa,
humidity_percent and gas_kohm.
For custom output, use SENSOR_READ to put one field in a runtime variable and
then reference it in any later command. This also works with DISPLAY,
SERIAL, SET, cloud writes and SD writes:
EXEC SENSOR_READ TEMPERATURE TEMP
EXEC SENSOR_READ HUMIDITY HUM
EXEC DISPLAY T=$TEMP C H=$HUM %
EXEC SD APPEND_LINE /custom.csv $TEMP,$HUM
Example of a one-minute logger:
CLEAR
ADD LABEL LOG
ADD SENSORS_LOG /bme690.csv
ADD DELAY 60000
ADD GOTO LOG
SAVE
RUN
Read the resulting file with:
EXEC SD READ /bme690.csv
Buttons
BUTTON STATUS
BUTTON A PRESSED
BUTTON A CLICKED
BUTTON B PRESSED
BUTTON B CLICKED
PRESSED reports the current level. CLICKED reports a debounced edge and is
consumed by the library when used by a condition; BUTTON STATUS displays it
without consuming it. For sequence control use IF_BUTTON or WAIT_BUTTON.
The editor may also send the structured form BUTTON READ A PRESSED (or
CLICKED/B); it is equivalent to the short form.
Wi-Fi and time
WIFI BEGIN <ssid> <password>
WIFI STATUS
WIFI RSSI
TIME EPOCH
TIME FORMAT [gmtOffset]
After WIFI BEGIN, the bridge calls MyDot::run() continuously so automatic
Wi-Fi and MQTT recovery remains active. SSIDs and passwords containing spaces
are not supported by this simple whitespace-delimited protocol.
Microeden cloud
CLOUD BEGIN <deviceId> <token>
CLOUD SEND
CLOUD STATUS
CLOUD BUFFER <128..65535>
CLOUD SYNC <intervalMs>
CLOUD WRITE_TEXT <key> <value>
CLOUD WRITE_INT <key> <integer>
CLOUD WRITE_FLOAT <key> <number>
CLOUD WRITE_DOUBLE <key> <number>
CLOUD WRITE_BOOL <key> TRUE|FALSE
CLOUD ON_COMMAND <expected> [key]
CLOUD READ <key>
CLOUD READ_ONCE <key>
Within the continuous flow the Bridge may append GOTO <label> to
CLOUD ON_COMMAND <expected> to poll multiple commands without blocking the
other listeners. Without GOTO, the legacy cooperative wait is preserved.
READ returns the cached cloud state. READ_ONCE consumes a newly received
widget value and returns CLOUD VALUE_ONCE empty when no new value is pending.
ON_COMMAND uses the default content key, consumes a matching command from
the inbound cloud document and, during RUN, cooperatively waits until the
command arrives. The optional key argument remains accepted for backwards
compatibility, but the Bridge runtime supports content.
CLOUD SYNC installs the bridge telemetry callback, which publishes the bridge
name and current sequence length at the requested interval.
Cloud widgets
All widget wrappers exposed by MyDot.h are available through one command:
WIDGET READ <type> <key>
WIDGET WRITE <type> <key> <value...>
Supported types and values:
| Type | Read | Write |
|---|---|---|
RAW / TEXT |
Cached text | Arbitrary text |
COLOR |
RGB triplet | red green blue |
MAP |
Cached coordinate text | latitude longitude or TEXT <value> |
LEVEL |
Integer | Integer |
SLIDER |
Newly received integer (-1 when empty) |
Integer |
SWITCH |
Boolean | TRUE/FALSE |
PUSHBUTTON |
Boolean | TRUE/FALSE |
LED |
Boolean | TRUE/FALSE |
PHOTO |
Cached text | Text |
Examples:
EXEC WIDGET WRITE COLOR light 255 0 0
EXEC WIDGET WRITE SLIDER brightness 128
EXEC WIDGET READ SLIDER brightness
EXEC WIDGET READ MAP location
Color conversion
COLOR HEX_TO_RGB #00AAFF
COLOR RGB_TO_HEX 0 170 255
The first form prints COLOR RGB r g b; the second prints COLOR HEX #RRGGBB.
SD card commands
The bridge initializes SD during setup(). SD BEGIN can retry
initialization. File paths may be absolute or relative according to the
selected board's SD library.
SD BEGIN
SD EXISTS <path>
SD MKDIR <path>
SD TOUCH <path>
SD REMOVE <path>
SD WRITE <path> <text>
SD WRITE_LINE <path> <text>
SD APPEND <path> <text>
SD APPEND_LINE <path> <text>
SD OPEN <path> [r|w|a]
SD READ <path>
SD READ_B64 <path>
SD LIST [path]
SD WRITE replaces a text file and SD APPEND adds text at the end.
WRITE_LINE and APPEND_LINE add a newline automatically. SD READ
prints the contents between BEGIN_SD_READ and END_SD_READ. SD LIST lists
the entries in the selected directory (the root directory is used when the
path is omitted):
SD MKDIR creates a directory and SD TOUCH creates an empty file; both
operations fail when the target path already exists.
EXEC SD WRITE /message.txt hello from MyDot
EXEC SD APPEND /message.txt !
EXEC SD APPEND_LINE /message.txt A complete line
EXEC SD READ /message.txt
EXEC SD LIST /
Directory output is delimited by BEGIN_SD_LIST and END_SD_LIST; each entry
is reported as FILE <name> FILE size=<bytes> or FILE <name> DIR.
READ_B64 is the Dev Studio safe-transfer variant. It returns any file,
including binary data, Base64-encoded between BEGIN_SD_READ_B64 and
END_SD_READ_B64.
The runtime file is always /MyDot.run. It contains a versioned
header, an XTEA-CTR encrypted command payload and a CRC32 checksum. The key is
compiled into the firmware, so this is protection for data at rest rather than
a secure key store. Credentials are stored in the runtime payload only when
you explicitly add commands such as ADD WIFI BEGIN ... or ADD CLOUD BEGIN ...; EXEC commands are not recorded.
Complete sequence example
CLEAR
ADD SET LIMIT 2200
ADD LABEL LOOP
ADD ANALOG_READ A0 SOIL
ADD SERIAL soil=$SOIL
ADD IF_VAR SOIL > $LIMIT GOTO DRY
ADD BRIGHTNESS 32
ADD GOTO WAIT
ADD LABEL DRY
ADD BRIGHTNESS 255
ADD LABEL WAIT
ADD WAIT_BUTTON B CLICKED 60000
ADD REPEAT 3
ADD PIXELS_RANDOM
ADD DELAY 250
ADD ENDREPEAT
ADD GOTO LOOP
SAVE
RUN
Use STOP to terminate this sequence and switch outputs off.