Python Bridge System Documentation

Detailed Technical Breakdown of the Serial-to-CAD Scan Processing System

1. System Overview

This Python application acts as the central communication bridge between the embedded microcontroller scanning hardware and the software visualization system.

The program receives scan geometry data through serial communication, converts the incoming coordinates into engineering geometry, generates DXF CAD files, stores JSON scan data, and maintains a historical scan archive.

The software effectively functions as:
  • Serial Communication Controller
  • Scan Data Acquisition Engine
  • CAD Geometry Generator
  • JSON Data Server
  • Historical Scan Database
  • Live Visualization Synchronization System

2. Imported Libraries

import serial
import json
import time
import ezdxf
import os
Library Purpose
serial Handles serial communication with the Arduino/XIAO microcontroller.
json Reads and writes structured scan data in JSON format.
time Creates timestamps for filenames and scan history tracking.
ezdxf Generates engineering DXF CAD geometry files.
os Handles folders, file paths, file checking, and filesystem operations.

3. Configuration Variables

PORT = 'COM7'
BAUD = 115200
TINE_PITCH = 3.0
MAX_TRAVEL = 50.0
JSON_FILE = "data.json"
LOG_FILE = "scans.json"
DATA_DIR = "scans"

Variable Breakdown

Variable Description
PORT Defines the COM port connected to the microcontroller.
BAUD Defines the serial communication speed.
TINE_PITCH Defines spacing between mechanical sensing tines.
MAX_TRAVEL Defines maximum allowed scan extension distance.
JSON_FILE Main live JSON file used for visualization.
LOG_FILE Stores historical scan metadata index.
DATA_DIR Folder containing archived scan JSON files.

4. Automatic Scan Folder Creation

if not os.path.exists(DATA_DIR):
    os.makedirs(DATA_DIR)

Before the system starts operating, it checks whether the historical scan storage directory exists.

If the folder does not exist, Python automatically creates it using:

  • os.path.exists() → checks if folder exists
  • os.makedirs() → creates folder structure

5. Serial Communication Initialization

ser = serial.Serial(PORT, BAUD, timeout=1)

This line establishes serial communication between the PC and the microcontroller.

Parameter Breakdown

Parameter Function
PORT Selects the hardware COM port.
BAUD Defines communication speed in bits per second.
timeout=1 Prevents blocking forever if no serial data arrives.
The Python program waits for the Arduino/XIAO controller to begin transmitting scan data.

6. update_master_index() Function

def update_master_index(new_filename, timestamp):

This function updates the master historical scan index.

Every completed scan is added to the top of the history file, allowing the visualization interface to display previous scans.

Main Tasks

  • Load existing scan history
  • Insert newest scan entry
  • Write updated history back to disk

JSON History Structure

[
  {
    "timestamp": "2026-05-16 20:15:32",
    "file": "scans/scan_20260516-201532.json"
  }
]

7. atomic_write() Function

def atomic_write(filename, data):

This function safely writes JSON data to disk.

Instead of writing directly to the final file, the system first writes to a temporary file.

Once writing completes successfully, the temporary file replaces the original file.

This prevents:
  • Corrupted JSON files
  • Half-written files
  • Empty visualization data
  • Concurrent file read failures

8. Main Program Loop

while True:

The program runs continuously forever, constantly listening for incoming serial data from the scanner hardware.

Serial Read Operation

line = ser.readline().decode('utf-8', errors='ignore').strip()
Operation Purpose
readline() Reads one serial line
decode() Converts bytes into readable UTF-8 text
strip() Removes newline characters and spaces

9. Scan Sequence Detection

if line == "START_DATA":

The Arduino sends the keyword:

START_DATA

This acts as a synchronization handshake between the hardware and Python.

Once detected, Python begins processing an entire scan sequence.

10. DXF CAD Document Creation

doc = ezdxf.new('R2010')
msp = doc.modelspace()

A new AutoCAD-compatible DXF document is created.

Purpose

  • Store scan geometry
  • Create engineering contour lines
  • Export measurable CAD data

11. Incoming Scan Data Format

Expected serial format:

SCAN:Index,X1,Y1,X2,Y2

Example

SCAN:12,0,15,5,20
Field Description
12 Segment index number
0,15 First coordinate point
5,20 Second coordinate point

12. Parsing Scan Coordinates

content = data.split(":")[1]
parts = content.split(",")

The incoming serial string is separated into usable coordinate values.

p1 = (float(parts[1]), float(parts[2]))
p2 = (float(parts[3]), float(parts[4]))

These coordinates are converted into floating-point engineering values.

13. DXF Geometry Generation

msp.add_line(p1, p2)

Each scanned segment becomes an actual CAD line entity.

This allows the contour profile to be opened directly in:

  • AutoCAD
  • DraftSight
  • LibreCAD
  • Fusion 360
  • SolidWorks

14. JSON Point Storage

points_list.append({"x": p1[0], "y": p1[1]})

The geometry is also converted into web-compatible JSON format.

Purpose

  • Live browser visualization
  • JavaScript plotting
  • Historical scan loading
  • Web dashboard integration

15. Finalizing the Scan

doc.saveas(dxf_path)

Once all scan segments are processed, the final engineering DXF file is exported.

Additional Outputs

  • Historical JSON scan archive
  • Updated scan history index
  • Latest live-view JSON file

16. Final System Outputs

Generated File Purpose
contour_timestamp.dxf Engineering CAD geometry
scan_timestamp.json Historical scan archive
data.json Live visualization file
scans.json Historical scan index