UART (Any MCU) + ASI Biont: Connect Arduino, ESP32, or STM32 to an AI Agent via COM-Port

Forget the dashboard. ASI Biont is designed around a chat interface for a reason: you should be able to connect hardware in the same way you order a pizza — by describing what you want. UART (Universal Asynchronous Receiver/Transmitter) is the most common serial protocol in the embedded world. It's the RX/TX pins on an Arduino, the Serial object on an ESP32, and the debug terminal on almost every STM32 board. This guide shows you how to connect any UART-capable MCU to the ASI Biont AI agent using the Hardware Bridge over a COM port, and how to build useful automations without leaving the chat.

We are going to cover the exact architecture, the bridge launch options, and three working code examples: firmware on the MCU side, the AI-side reading/writing via industrial_command(), and a universal Python connector. If you have an Arduino, an ESP32, or any board with a USB-UART adapter on your desk, you will be able to reproduce the full chain by the end of this article.

Why a Microcontroller Needs an AI Agent

UART is reliable but ignorant. It blindly transfers bytes between two devices; it has no idea whether a temperature reading of 24.8 is normal. An AI agent adds context: it knows the thresholds, remembers historical values, can call external APIs, and can make decisions. Combined, UART becomes a remote-controlled "sensory nervous system" for your MCUs.

The main benefits:

  1. Natural-language control: type "turn on the pump if soil moisture is below 30%" — no firmware reflash.
  2. Intelligent logging: the AI parses serial logs, detects anomalies, and summarises them in the chat.
  3. Orchestration: many MCUs on different COM ports, all managed from one conversation.

According to the Arduino UART documentation, UART is the simplest and most battle-tested way to communicate with sensors and actuators, which is why this integration is the foundation of many IoT prototypes.

Architecture: How ASI Biont Reaches the COM Port

ASI Biont runs in the cloud, so it cannot see your local port until a small client bridges the gap. That client is the Hardware Bridge (bridge.py), downloaded from the ASI Biont dashboard. It opens the COM port, reads the serial stream, and keeps an outbound WebSocket connection to the cloud. No inbound firewall rules are needed because the connection originates from your machine.

┌──────────┐   UART   ┌──────────────┐   WebSocket   ┌─────────────┐
│ Arduino/ │<========>│ bridge.py    │<=============>│ ASI Biont  │
│ ESP32    │ RX/TX    │ (your PC)    │   (encrypted) │ Cloud + LLM │
└──────────┘          └──────────────┘               └─────────────┘

The AI communicates with the bridge through industrial_command() — a low-level function that can read, write, and query ports. The user never edits a configuration file; the sequence is always: describe the device in the chat, and let the AI figure out the exact parameters.

Connecting the Hardware Bridge

This is the only step you do manually. Go to the ASI Biont dashboard, download bridge.py, and run it from the command line:

python bridge.py --token=YOUR_TOKEN --ports=COM3 --baud=115200 --rate=10
  • --ports is the COM port name. On Linux it might be /dev/ttyUSB0, on macOS /dev/cu.usbserial-0001.
  • --baud must match the firmware's baud rate (9600, 57600, 115200 are typical).
  • --rate sets the number of serial polls per second. For a DHT22 sensor, 10 is more than enough; for a high-speed IMU you might need 100.

After a few seconds, the chat shows that COM3 is online. From this point on, you can ask the AI to "read the temperature from COM3" or "watch for errors on the serial monitor". The bridge is not a generic terminal; it is a secure tunnel to the AI's command interface.

Using industrial_command()

The AI uses industrial_command() to interact with the bridge. Even though you rarely write this by hand, it is useful to understand the shape of the API. Here is a minimal example of reading one line and writing a command:

# Read a line from COM3
response = industrial_command(
    protocol="com",
    command="read",
    port="COM3",
    params={"lines": 1, "timeout": 2},
)

# Write a command to COM3
industrial_command(
    protocol="com",
    command="write",
    port="COM3",
    params={"data": "RELAY_ON\n"},
)

The read command returns the raw bytes decoded as text; the write command sends a string. The AI can then parse the response using Python's standard string methods or JSON. This is the core pattern behind every automation in this article.

Use Case: Temperature-Controlled Relay

Let's make it concrete. Take an Arduino with a DHT22 temperature sensor and a relay module controlling a 12 V fan. The firmware is deliberately simple: it prints a JSON line with the temperature every two seconds and listens for two text commands.

#include <DHT.h>

#define RELAY_PIN 7
#define DHT_PIN 4
DHT dht(DHT_PIN, DHT22);

void setup() {
  Serial.begin(115200);
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);
}

void loop() {
  if (Serial.available()) {
    String cmd = Serial.readStringUntil('\n');
    if (cmd == "RELAY_ON")  digitalWrite(RELAY_PIN, HIGH);
    if (cmd == "RELAY_OFF") digitalWrite(RELAY_PIN, LOW);
  }
  static unsigned long lastSent = 0;
  if (millis() - lastSent > 2000) {
    float t = dht.readTemperature();
    Serial.print("{\"temperature\": ");
    Serial.print(t);
    Serial.println("}");
    lastSent = millis();
  }
}

Upload this to the board, connect the USB to the computer, start the bridge with --ports=COM3 --baud=115200. In the ASI Biont chat, write:

"Read the temperature from COM3. If it exceeds 25 °C, send RELAY_ON to turn on the fan; send RELAY_OFF when it drops below 23 °C."

The AI will generate a trigger flow that uses the same industrial_command() shown above. Each time the bridge delivers a new line, the AI extracts the temperature, compares it against the threshold, and if necessary writes RELAY_ON or RELAY_OFF. It also keeps a short history in the conversation, so you can ask "what has the average temperature been since noon?" and the AI will answer from the data it has seen.

Automation Scenarios You Can Build Now

The temperature/relay example is just the beginning. Because the AI can read arbitrary strings and react to them, the same mechanism supports:

  • Uptime monitoring — "tell me if the serial port goes silent for more than 10 seconds."
  • Command macros — "at 10:00 send CALIBRATE to COM3, then read the response."
  • Anomaly detection — "alert me if the temperature readings jump by more than 5 °C within two samples."
  • Multi-port aggregation — "summarise the values from COM3 and COM5 into one table."
  • Human-in-the-loop control — "ask me before toggling the relay."

All of these are configured through the chat, not by writing event handlers. The AI writes the underlying Python code, runs it in a sandbox, and uses the bridge for I/O.

The Universal Connector: execute_python

The Hardware Bridge is designed for COM ports, but ASI Biont doesn't force you to wait for a plugin. Every integration can be handled by execute_python, where the AI writes a Python script using pyserial, paramiko, paho-mqtt, pymodbus, aiohttp, or opcua-asyncio and executes it in a secure sandbox.

For example, if your UART device is connected to a Raspberry Pi that runs ser2net to expose the serial port over TCP, you can tell ASI Biont: "Read the temperature from 192.168.1.10:7000". The AI will generate something like:

import serial

ser = serial.serial_for_url("socket://192.168.1.10:7000", timeout=2)
ser.write(b"TEMP\n")
print(ser.readline().decode())

The sandbox runs the script, captures stdout, and returns it to the chat. In this case, no bridge is involved at all — the AI just wrote the connector itself. That is the core idea: you don't need a set of pre-built integrations; the AI is the integrator.

Bridge vs. execute_python: When to Use Which

Criterion Hardware Bridge (bridge.py) execute_python
Best for Physical COM ports, RS-232/RS-485, local MCUs Remote serial over TCP, MQTT, Modbus, any network protocol
Setup effort Download and run the bridge No bridge; only network access to the device
Latency Polling rate can be tuned (--rate) Sandbox execution time, usually a few seconds
Use cases Continuous monitoring, low-latency control One-off commands, integration testing, custom protocols

The bridge is the right choice when you need continuous bidirectional communication with a local board. execute_python is perfect for ad-hoc requests, remote devices, or exotic protocols that no standard connector covers.

Security and Reliability Notes

  • The bridge uses an outbound encrypted WebSocket — nothing is port-forwarded to the internet.
  • Use a dedicated --token and revoke it in the dashboard if you stop using a machine.
  • The polling --rate is an upper bound, not a hard requirement; the bridge batches messages to avoid flooding the chat.
  • If the COM port disappears (USB cable unplugged), the bridge automatically reconnects when the port returns. This behaviour is built into the bridge, so you don't have to code around it.
  • For production use, set the baud rate explicitly in the chat so the AI configures the bridge with the correct value.

When Not to Use UART via Bridge

UART is physical: the MCU must be connected to the computer running the bridge. If your device already has Wi-Fi or Ethernet, an MQTT or HTTP connection is more practical because it works over the network without a local machine. UART also has a limited cable length — a few meters for plain TTL, and up to about 1200 meters with RS-485. For long distances, consider Modbus/TCP or MQTT. The beauty of ASI Biont is that you can mix all of these protocols in one chat: one device on COM3, another on MQTT, and the AI coordinates both.

Try It Now

You don't need to learn a new API, write a plugin, or wait for a vendor SDK release. Download bridge.py from the ASI Biont dashboard, plug in your Arduino or ESP32, and after a few seconds the device will be visible to the AI. Then simply describe the automation in the chat. The AI will write the Python code, run it through industrial_command or execute_python, and walk you through the result. Connecting a microcontroller has never been this close to natural language.

← All posts

Comments