<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: AllenLiao</title>
    <description>The latest articles on DEV Community by AllenLiao (@allenliao).</description>
    <link>https://dev.to/allenliao</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3873617%2F316d2beb-0479-4c05-9ea4-2fef2ab4a6ab.png</url>
      <title>DEV Community: AllenLiao</title>
      <link>https://dev.to/allenliao</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/allenliao"/>
    <language>en</language>
    <item>
      <title>I Built a Local Web Debug Tool for Serial, TCP, and UDP</title>
      <dc:creator>AllenLiao</dc:creator>
      <pubDate>Sat, 11 Apr 2026 14:20:11 +0000</pubDate>
      <link>https://dev.to/allenliao/i-built-a-local-web-debug-tool-for-serial-tcp-and-udp-133a</link>
      <guid>https://dev.to/allenliao/i-built-a-local-web-debug-tool-for-serial-tcp-and-udp-133a</guid>
      <description>&lt;h2&gt;
  
  
  What SerialNet Debug Studio does
&lt;/h2&gt;

&lt;p&gt;Right now, the project supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Serial&lt;/strong&gt; connection for local COM / USB devices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TCP client&lt;/strong&gt; mode for network-connected devices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UDP&lt;/strong&gt; sending and local listening&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time log panel&lt;/strong&gt; with &lt;code&gt;[RX] / [TX] / [SYS] / [ERR]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Real-time multi-channel charts&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Command sending panel&lt;/strong&gt; with text / HEX modes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Line ending options&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Checksum support&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Command history&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Local storage for recent connections and commands&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multi-language UI&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is designed to stay local and lightweight:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no login&lt;/li&gt;
&lt;li&gt;no database&lt;/li&gt;
&lt;li&gt;no cloud dependency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Under the hood, the current stack is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;FastAPI&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Uvicorn&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebSocket&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pyserial&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTML / CSS / JavaScript&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apache ECharts&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The browser handles the UI and charting, while the backend handles Serial / TCP / UDP communication and streams logs and parsed data to the frontend in real time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I made it web-based instead of desktop-only
&lt;/h2&gt;

&lt;p&gt;I wanted something that felt lightweight, easy to iterate on, and convenient to use.&lt;/p&gt;

&lt;p&gt;A browser UI gives me a lot of flexibility for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;log layout&lt;/li&gt;
&lt;li&gt;real-time chart rendering&lt;/li&gt;
&lt;li&gt;command panel interaction&lt;/li&gt;
&lt;li&gt;future extensibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the same time, this is &lt;strong&gt;not&lt;/strong&gt; a pure frontend app.&lt;br&gt;
The backend runs locally and handles hardware and network communication, so the browser gets the convenience of a web UI without losing access to serial ports and sockets.&lt;/p&gt;

&lt;p&gt;That combination ended up being a really good fit for this type of tool.&lt;/p&gt;


&lt;h2&gt;
  
  
  How I use it in practice
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. As a better serial monitor for embedded boards
&lt;/h3&gt;

&lt;p&gt;For Arduino, ESP32, STM32, and similar devices, the flow is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;choose &lt;strong&gt;Serial&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;select the port and baud rate&lt;/li&gt;
&lt;li&gt;connect&lt;/li&gt;
&lt;li&gt;watch logs on the left&lt;/li&gt;
&lt;li&gt;watch charts on the right&lt;/li&gt;
&lt;li&gt;send commands from the bottom panel&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What I like most is that logs, charting, and command sending all happen in the same place.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. For TCP debugging on Wi-Fi devices
&lt;/h3&gt;

&lt;p&gt;Once a device moves to Wi-Fi, debugging is no longer just a serial problem.&lt;/p&gt;

&lt;p&gt;In that case I can switch to &lt;strong&gt;TCP mode&lt;/strong&gt;, connect to the target host and port, and keep the same workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;live logs&lt;/li&gt;
&lt;li&gt;command sending&lt;/li&gt;
&lt;li&gt;charting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That consistency is one of the main reasons I built this tool.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. For lightweight UDP testing
&lt;/h3&gt;

&lt;p&gt;Some devices report data over UDP, or sometimes I just need to listen on a local port quickly.&lt;/p&gt;

&lt;p&gt;The tool currently supports UDP sending and local listening, so it works well for lightweight packet-based debugging too.&lt;/p&gt;


&lt;h2&gt;
  
  
  Live charting is one of my favorite parts
&lt;/h2&gt;

&lt;p&gt;A lot of embedded output is easier to understand as a graph than as raw text.&lt;/p&gt;

&lt;p&gt;Typical examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;temperature and humidity&lt;/li&gt;
&lt;li&gt;ADC values&lt;/li&gt;
&lt;li&gt;motor control signals&lt;/li&gt;
&lt;li&gt;encoder feedback&lt;/li&gt;
&lt;li&gt;IMU data&lt;/li&gt;
&lt;li&gt;voltage and current telemetry&lt;/li&gt;
&lt;li&gt;internal state values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of copying data into another plotting tool, I wanted to see it immediately.&lt;/p&gt;

&lt;p&gt;That is why the chart panel supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dynamic multi-channel plotting&lt;/li&gt;
&lt;li&gt;pause / resume&lt;/li&gt;
&lt;li&gt;zoom selection&lt;/li&gt;
&lt;li&gt;reset zoom&lt;/li&gt;
&lt;li&gt;CSV copy / export&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For my own workflow, that has been much more useful than a basic serial plotter.&lt;/p&gt;


&lt;h2&gt;
  
  
  Screenshots
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Serial mode with live logs and charts
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F56sxo0i1kggxrvc2o2oh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F56sxo0i1kggxrvc2o2oh.png" alt=" " width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  TCP debugging interface
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdry72xhmgn6a3t4vphxf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdry72xhmgn6a3t4vphxf.png" alt=" " width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Chart zoom / brush selection
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv9ufxswr7t8wifnh41qp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv9ufxswr7t8wifnh41qp.png" alt=" " width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Command history
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq2a847ua1rdhpclup3s0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq2a847ua1rdhpclup3s0.png" alt=" " width="800" height="142"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  How to run it
&lt;/h2&gt;

&lt;p&gt;If you want to try it locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/xiayus/SerialNet-Debug-Studio.git
&lt;span class="nb"&gt;cd &lt;/span&gt;SerialNet-Debug-Studio
python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
uvicorn app:app &lt;span class="nt"&gt;--host&lt;/span&gt; 127.0.0.1 &lt;span class="nt"&gt;--port&lt;/span&gt; 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://127.0.0.1:8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you do not want to run it from source, you can also download a prebuilt release from the repository.&lt;/p&gt;




&lt;h2&gt;
  
  
  Who this project is for
&lt;/h2&gt;

&lt;p&gt;I think this tool is especially useful for:&lt;/p&gt;

&lt;h3&gt;
  
  
  Embedded developers
&lt;/h3&gt;

&lt;p&gt;If you work with Arduino, ESP32, STM32, or other microcontroller-based systems and often switch between logs, commands, and data plotting.&lt;/p&gt;

&lt;h3&gt;
  
  
  People debugging network-connected devices
&lt;/h3&gt;

&lt;p&gt;If your device uses TCP or UDP and you want logs, sending, and charting in one place.&lt;/p&gt;

&lt;h3&gt;
  
  
  Developers who like local-first tools
&lt;/h3&gt;

&lt;p&gt;If you prefer lightweight tools that run locally without accounts, databases, or heavy setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Builders looking for architecture ideas
&lt;/h3&gt;

&lt;p&gt;If you are interested in combining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a Python backend for communication&lt;/li&gt;
&lt;li&gt;WebSocket for real-time streaming&lt;/li&gt;
&lt;li&gt;a browser frontend for charts and control panels&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What I may add next
&lt;/h2&gt;

&lt;p&gt;I am trying to keep the project focused, but a few directions I am exploring are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MQTT&lt;/li&gt;
&lt;li&gt;BLE&lt;/li&gt;
&lt;li&gt;more protocol adapters&lt;/li&gt;
&lt;li&gt;plugin-style protocol parsing&lt;/li&gt;
&lt;li&gt;more chart types&lt;/li&gt;
&lt;li&gt;custom JavaScript parsing support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I do not want to turn it into a bloated all-in-one platform too early, though.&lt;br&gt;
For now, the priority is to keep the core debugging workflow smooth.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;This project came from a very practical frustration:&lt;/p&gt;

&lt;p&gt;I was tired of switching between multiple tools just to debug one device properly.&lt;/p&gt;

&lt;p&gt;So I built something that fits my own workflow better:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;connect → inspect logs → send commands → watch charts → iterate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If that sounds useful for your workflow too, feel free to check it out:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/xiayus/SerialNet-Debug-Studio" rel="noopener noreferrer"&gt;SerialNet-Debug-Studio on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback, issues, and suggestions are always welcome.&lt;br&gt;
And if you find it useful, a star would mean a lot.&lt;/p&gt;

</description>
      <category>arduino</category>
      <category>esp32</category>
      <category>opensource</category>
      <category>python</category>
    </item>
  </channel>
</rss>
