MicroScan is a fully custom, open-source motorized microscope stage with 3-axis (X, Y, Z) precision control, live camera integration, and a desktop application for automated microscopy workflows. The entire system is designed and built from scratch: 3D-printed mechanics, hand-wired electronics, embedded firmware, and a C++ desktop application with computer vision capabilities.
Hardware
- 3-axis motorized stage using linear rails and lead screws
- 3D-printed structural components with metal base plate
- NEMA stepper motors with TMC2209 drivers (UART control)
- Teensy 4.1 microcontroller for real-time motor control
- Sensorless homing via TMC2209 StallGuard — no limit switches needed
- StealthChop for silent operation, 1/16 microstepping with 256 interpolation
Firmware
- Custom Teensy 4.1 firmware with serial command protocol (
|cmd=arg1:arg2|) - Independent X, Y, Z axis control with configurable speed and step count
- Stall detection and recovery with automatic direction reversal
- Continuous velocity mode (VACTUAL) for smooth, speed-based movement
- Driver health monitoring and automatic re-initialization
Desktop Application
- Built with wxWidgets (C++) and OpenCV
- Live camera view with real-time histogram display
- Multiple recording modes: Single Photo, Focus Stack, Panoramic, Stitch & Stack
- Manual X/Y/Z navigation controls and microscope connection management
- Project management system with organized folder structure for captured data
- Object tracking using OpenCV KCF tracker and optical flow (CAMShift)
- SQLite database for project/image metadata storage
- Configurable microscope and camera settings
Computer Vision & Image Processing
- Multiple focus scoring algorithms:
- Canny edge detection
- Laplacian variance
- Laplacian of Gaussian (LoG) — fastest at ~26 fps
- Discrete Fourier Transform (DFT)
- Auto-focus with coarse-then-fine search strategy
- Real-time object tracking (KCF and optical flow)
- Frame stacking for noise reduction
flowchart TB
subgraph DESKTOP["Desktop Application"]
direction TB
subgraph UI["GUI Layer — wxWidgets"]
FRAME["Main Frame\nImage View • Histogram\nNavigation Controls"]
RECORD["Recording Modes\nPhoto • Focus Stack\nPanoramic • Stitch & Stack"]
end
subgraph CV["Computer Vision — OpenCV"]
CAM["Camera Capture\nLive Video Feed"]
FOCUS["Focus Scoring\nLoG • Laplacian • DFT • Canny"]
TRACK["Object Tracker\nKCF • Optical Flow"]
end
subgraph DATA["Data Management"]
PROJ["Project Manager"]
DB["SQLite Database"]
IMG["Image Store\nTIFF Capture"]
end
WORKER["Worker Thread\nCommand Queue • Async Operations\nPhoto Stack • Panoramic Scan"]
FRAME --> WORKER
RECORD --> WORKER
CAM --> FOCUS
CAM --> TRACK
WORKER --> PROJ
PROJ --> DB
PROJ --> IMG
end
subgraph DRIVER["Microscope Driver Layer"]
MICRO["CMicroscope\nAbstraction Layer"]
DRV["CDriverMicroscanV1\nSerial Protocol\n|cmd=arg1:arg2:arg3|"]
end
subgraph FIRMWARE["Teensy 4.1 Firmware"]
PARSER["Serial Command Parser\nHome • Move • Speed • Query"]
subgraph MOTORS["TMC2209 Stepper Drivers — UART"]
MX["Driver X\nSerial2\nPin 9"]
MY["Driver Y\nSerial6\nPin 10"]
MZ["Driver Z\nSerial7\nPin 11"]
end
STALL["StallGuard\nSensorless Homing\nStall Detection & Recovery"]
end
subgraph HW["Mechanical Stage"]
SX["Stepper X\nLinear Rail"]
SY["Stepper Y\nLinear Rail"]
SZ["Stepper Z\nLead Screw"]
end
WORKER --> MICRO
MICRO --> DRV
DRV -->|"Serial @ 128000 baud"| PARSER
PARSER --> MX & MY & MZ
MX & MY & MZ --> STALL
MX --> SX
MY --> SY
MZ --> SZ
style DESKTOP fill:#1a1a2e,stroke:#16213e,color:#e0e0e0
style UI fill:#16213e,stroke:#0f3460,color:#e0e0e0
style CV fill:#16213e,stroke:#0f3460,color:#e0e0e0
style DATA fill:#16213e,stroke:#0f3460,color:#e0e0e0
style DRIVER fill:#0f3460,stroke:#533483,color:#e0e0e0
style FIRMWARE fill:#533483,stroke:#e94560,color:#e0e0e0
style MOTORS fill:#4a2070,stroke:#e94560,color:#e0e0e0
style HW fill:#e94560,stroke:#e94560,color:#ffffff
| Component | Specification |
|---|---|
| Microcontroller | Teensy 4.1 (ARM Cortex-M7, 600 MHz) |
| Stepper Drivers | 3× TMC2209 (UART mode, 0.11Ω sense resistor) |
| Motors | NEMA stepper motors on X, Y, Z axes |
| Motion System | Linear rails + lead screws, 3D-printed mounts |
| Microstepping | 1/16 with 256× interpolation |
| Motor Current | 600 mA RMS |
| Serial Ports | X: Serial2 (pins 7/8), Y: Serial6 (pins 24/25), Z: Serial7 (pins 28/29) |
| Enable Pins | X: 2, Y: 3, Z: 4 |
| Step Pins | X: 9, Y: 10, Z: 11 |
| Travel | ~160K steps total per axis (~80K to midpoint) |
Note: A 1KΩ resistor is needed between Teensy RX/TX and TMC2209 for reliable UART communication.
Desktop Application
- C++17 compiler
- wxWidgets — GUI framework
- OpenCV 4.x — camera capture, image processing, object tracking
- SQLite3 — project database
Firmware
- Arduino / Teensyduino — Teensy build system
- TMCStepper — TMC2209 UART driver library
- Install Arduino IDE with Teensyduino
- Install the
TMCStepperlibrary via Library Manager - Open
teensy_ctrl/teensy_ctrl.ino - Select Board: Teensy 4.1, USB Type: Serial
- Upload to Teensy
- Install wxWidgets and OpenCV (set environment variables or update project paths)
- Open the Visual Studio solution / project file
- Build in Release mode
The Teensy accepts commands over USB serial in the format |command=arg1:arg2:arg3|:
| Command | Example | Description |
|---|---|---|
| Home all | |h=a| |
Home all axes using stall detection |
| Home axis | |h=x| |
Home a single axis (x, y, or z) |
| Move steps | |x=1000:160:100| |
Move X axis: 1000 steps, 160µs delay, stall threshold 100 |
| Speed move | |xs=5000:500:100| |
Continuous X move: speed 5000, stall check interval 500ms |
| Stop | |xss=0| |
Stop X axis movement |
| Get position | |GetPosXYZ| |
Returns |x:y:z| |
| Status | |STATUS| |
Returns |STATUS=OK| or |STATUS=INIT| |
Steps > 0 move away from motor, steps < 0 move toward motor.
- Connect microscope camera (USB)
- Launch MicroScan
- Click Connect to establish serial connection with the Teensy controller
- Use navigation controls for manual X/Y/Z movement
- Select recording mode:
- Photo — single capture
- Focus Stack — automated Z-stack capture with configurable steps and increment
- Panoramic — X/Y grid scan (in development)
- Stitch & Stack — combined panoramic + focus stacking (in development)
- 3-axis motorized stage with UART stepper control
- Sensorless homing via StallGuard
- Desktop GUI with live camera view and histogram
- Manual X/Y/Z navigation
- Focus stacking capture (Z-step + photo sequence)
- Multiple focus scoring algorithms (Canny, Laplacian, LoG, DFT)
- Auto-focus (coarse + fine search)
- Object tracking (KCF / optical flow)
- Project management and image organization
- Focus stack compositing / merging
- Adaptive auto-focus thresholds for different objectives and samples
- Panoramic grid scanning workflow
- Stitch & stack combined mode
- Automated scan & identify — systematic X/Y grid scanning with ConvNet-based object detection and classification for identifying targets of interest in sample fields
- Real-time microorganism tracking — continuous closed-loop feedback to track organisms (e.g., paramecium) in X/Y/Z using a confocal dish with an inverted stage configuration
- Kalman filter for trajectory prediction and latency compensation
- PID controller for proportional stage movement
- Depth-from-defocus for Z-axis position estimation
- Linux / cross-platform support
MicroScan/
├── teensy_ctrl/ # Teensy 4.1 firmware
│ └── teensy_ctrl.ino # Motor control, serial protocol, stall detection
├── src/
│ ├── microscan.cpp # Application entry point
│ ├── microscan_worker.cpp # Worker thread (photo, stack, scanning tasks)
│ ├── microscope/
│ │ ├── microscope.cpp # Microscope abstraction layer
│ │ ├── microscope_driver.cpp # Base serial driver
│ │ └── driver_microscanv1.cpp # MicroScan V1 hardware driver
│ ├── camera/
│ │ ├── camera.cpp # Camera management
│ │ └── camera_video.cpp # OpenCV video capture & processing
│ ├── gui/
│ │ ├── frame.cpp # Main window & toolbar
│ │ ├── frame_instruments.cpp # Instrument controls panel
│ │ ├── imageview.cpp # Image display widget
│ │ └── config_view.cpp # Configuration dialog
│ ├── image/
│ │ ├── image_func.cpp # Focus scoring algorithms
│ │ ├── micro_project.cpp # Project data structure
│ │ ├── project_mgr.cpp # Project manager
│ │ └── object_tracker.cpp # KCF & optical flow tracker
│ ├── config/
│ │ └── microscan_config.cpp # Application configuration
│ └── dataport/
│ └── winserial.cpp # Windows serial port interface
├── HARDWARE_PICS/ # Build photos
└── README.md

