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.
- 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. |
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.
- 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 |