The Mini Plotter is a desktop-sized, Wi-Fi-enabled pen plotter that can draw any vector graphic on A4 paper. You connect to it from your phone or laptop browser, upload an SVG file, and watch it draw. No cables, no special software, no drivers needed. Everything runs through a sleek custom web interface hosted by the plotter itself.
It moves a pen across two axes (X and Y) using stepper motors, and lifts or lowers the pen on the Z axis using a servo motor. This is the classic three-axis architecture of any CNC machine, shrunk down and made accessible.
Why Did We Build It?This project was built as a product prototype by a team at Fab Lab Kerala, a fabrication laboratory focused on digital making, open hardware, and hands-on learning.
The motivation was straightforward: pen plotters are fascinating machines, but most are either expensive commercial units or complex hobbyist builds that require a laptop tethered by USB and a chain of software tools. We wanted to strip all of that away.
Our goals were:
- Make the plotter completely wireless and self-contained (no PC required after setup)
- Make it accessible to anyone: if you can upload a file to a website, you can use this plotter
- Build it with affordable, hackable components (28BYJ-48 steppers, an ESP32, 3D-printed structure) so that anyone at a fab lab or makerspace could replicate it
- Prove the concept as a product prototype: a real, polished device rather than a proof-of-concept wire bundle
At a high level, the workflow is:
- Power on the Mini Plotter. The ESP32 boots and creates a Wi-Fi access point.
- Connect your phone or laptop to that Wi-Fi network.
- Open a browser. You are automatically redirected to the plotter's built-in web app (captive portal).
- Upload an SVG file in the web interface.
- The web app parses the SVG and converts it to G-code entirely in the browser using JavaScript.
- The G-code is sent back to the ESP32 over Wi-Fi.
- The ESP32 firmware interprets each G-code command and drives the stepper motors and servo accordingly.
- The pen moves across the paper and draws your design.
No cloud, no app store, no driver installation. Just a browser and an SVG file.
The plotter uses a Cartesian XY motion system:
- X-axis: A 28BYJ-48 unipolar stepper motor moves the pen carriage left and right along a horizontal rod, driven through a GT2 belt and pulley.
- Y-axis: A second 28BYJ-48 moves the entire X-axis assembly forward and backward, giving full 2D coverage across the A4 drawing area.
- Z-axis (pen lift): A small SG90 servo motor raises and lowers the pen holder, allowing the plotter to move without drawing (pen up) and draw (pen down).
The 28BYJ-48 is a small, low-cost unipolar stepper motor with a built-in planetary gearbox, giving it high torque relative to its size. Each motor is driven by a ULN2803 Darlington transistor array, which translates the low-current GPIO signals from the ESP32 into the current needed to drive the motor coils.
A4 (approximately 210 x 297 mm), full standard paper size coverage.
The entire frame is 3D printed. Every structural bracket, carriage, motor mount, belt tensioner, and pen holder was designed for FDM printing and assembled without any metal machining. This makes the design fully replicable at any fab lab or makerspace with a desktop 3D printer.
Key design considerations:
- Rigidity vs. weight: Parts are designed with enough wall thickness to prevent flex during drawing, while keeping the moving carriage as light as possible to reduce motor load.
- Belt path: The GT2 belt routing is integrated into the printed carriage design, with a tensioner to eliminate backlash.
- Pen holder: The Z-axis pen mount grips standard marker pens and connects directly to the servo arm, so the servo's rotation directly lifts or lowers the tip.
The frame uses standard linear rods (smooth steel) with printed bearing holders, keeping the motion axes straight and low-friction. The two axes are perpendicular, giving the classic CoreXY-adjacent layout where one motor controls one axis independently.
The ESP32 is the brain of the plotter. It handles:
- Hosting the Wi-Fi access point and captive portal web server
- Receiving G-code over Wi-Fi from the browser
- Parsing and executing G-code commands in real time
- Generating step pulses for both stepper motors via the ULN2803 drivers
- Sending PWM signals to the servo for pen up/down
The ESP32's dual-core architecture is well-suited here: one core handles the Wi-Fi/HTTP stack while the other handles time-sensitive motor stepping, preventing communication delays from interrupting smooth motion.
The ULN2803 is an 8-channel Darlington transistor array. Each 28BYJ-48 motor has 4 coil inputs, so one ULN2803 handles one motor (using 4 of its 8 channels). The ESP32 GPIO pins connect to the ULN2803 inputs; the outputs connect directly to the motor coils.
The 28BYJ-48 motors operate in half-step mode for smoother motion and higher effective resolution, giving 4096 steps per full revolution through the gearbox.
ESP32 GPIO 12, 13, 14, 15 -> ULN2803 (Motor 1, X-axis) -> 28BYJ-48 X
ESP32 GPIO 16, 17, 18, 19 -> ULN2803 (Motor 2, Y-axis) -> 28BYJ-48 Y
ESP32 GPIO 23 -> SG90 Servo signal pin -> Pen lift
All powered from 5V supplyNote: The ESP32 runs at 3.3V logic, but the 28BYJ-48 and servo run at 5V. The ULN2803 is 5V-compatible on its output side, making it an ideal interface between the two voltage levels.
Note: The ESP32 runs at 3.3V logic, but the 28BYJ-48 and servo run at 5V. The ULN2803 is 5V-compatible on its output side, making it an ideal interface between the two voltage levels.Firmware
The firmware runs on the ESP32 using the Arduino framework (via Arduino IDE or PlatformIO).
What the Firmware Does- On boot: Initializes Wi-Fi in Access Point mode, starts the HTTP web server, and sets up motor and servo GPIO pins.
- Serves the web app: The HTML/CSS/JS of the web interface is stored in flash (SPIFFS/LittleFS) and served to any connected browser.
- Receives G-code: The browser POSTs G-code lines (or a full G-code program) to an HTTP endpoint on the ESP32.
- Parses G-code: The firmware reads commands like
G0(rapid move),G1(linear move),M3/M5(pen down/up) and translates them into motor actions. - Executes motion: Stepper pulses are sent to the ULN2803 drivers in the correct sequence for half-step operation; the servo is positioned to 0 degrees (pen down) or 90 degrees (pen up).
- Captive portal: Any HTTP request to an unrecognized domain is redirected to the plotter's web app, making the experience seamless (no need to type an IP address).
- G-code queue: Incoming G-code is buffered so the web app can send commands ahead of execution.
- Acceleration: Basic trapezoidal acceleration is implemented to prevent the geared 28BYJ-48 motors from stalling on fast moves.
- Homing: On startup, the carriage moves to its home position (origin corner) so all subsequent coordinates are consistent.
Command -- Action
G0 X__ Y__ -- Rapid move (pen up) to coordinates
G1 X__ Y__ -- Linear draw move (pen down)
M3 -- Pen down (servo to draw position)
M5 -- Pen up (servo to travel position)
G28 -- Home all axes
Software: The Web AppThis is where the Mini Plotter really differentiates itself. Instead of requiring the user to install GRBL senders, Inkscape plugins, or Python scripts, everything happens in the browser.
How the Web App WorksThe web app is a single-page application written in vanilla JavaScript, served directly from the ESP32's flash storage. When a user connects to the plotter's Wi-Fi network and opens a browser, they see the interface immediately.
The user selects any SVG file from their device. The file is read in the browser using the FileReader API and never leaves the device at this stage.
Step 2: SVG to G-code ConversionThe JavaScript app parses the SVG DOM, extracts all path elements, and converts them to G-code:
<path>elements are converted using theirdattribute. Bezier curves and arcs are approximated with short linear segments.<line>,<rect>,<circle>,<ellipse>elements are handled as special cases and converted to their equivalent linear toolpaths.- Each contiguous path becomes a pen-down segment (G1 moves); moves between disconnected paths become pen-up rapid moves (G0 + M5/M3).
- The coordinate system is scaled and translated to fit within the A4 drawing area.
The resulting G-code is displayed in a preview pane so the user can inspect it before sending.
Step 3: PreviewA canvas-based visual preview renders the toolpath directly in the browser, showing exactly what the plotter will draw, including which segments are drawn moves (shown in color) vs. rapid travel moves (shown as dashed lines).
Step 4: Send to PlotterWhen the user clicks Plot, the G-code is sent line-by-line (or in batches) to the ESP32 via HTTP POST requests to the /plot endpoint. The web app tracks progress and shows a live status indicator.
- No installation: Works on any phone, tablet, or laptop with a browser.
- Offline: Fully functional without an internet connection (the app is served from the plotter itself).
- Fast iteration: Updating the web app is as simple as reflashing the SPIFFS partition; no firmware recompile needed.
- Extensible: Future features like path optimization, fill patterns, or multi-layer plotting can be added purely in JavaScript.
Print all STL files from the repository at:
- Layer height: 0.2 mm
- Infill: 30-40%
- Material: PLA (PETG for better rigidity)
- Supports: Required for the carriage bearing holders
- Thread the linear rods through the printed bearing holders
- Mount the stepper motors into their printed mounts
- Route and tension the GT2 belts
- Attach the servo to the Z-axis pen holder carriage
Connect according to the wiring diagram in the repository:
- ESP32 -> ULN2803 inputs (4 pins per motor)
- ULN2803 outputs -> 28BYJ-48 motor coils
- ESP32 GPIO 23 -> SG90 servo signal wire
- 5V power to all components
bash
# Clone the repository
git clone https://github.com/fablabkerala/mini-plotter
# Open in Arduino IDE or PlatformIO
# Select board: ESP32 Dev Module
# Upload filesystem image (SPIFFS) first
# Then upload firmware sketch5. First Run- Power on the plotter
- Connect your device to the Wi-Fi network "MiniPlotter"
- Open a browser. You will be redirected to the web app automatically.
- Upload an SVG and click Plot





_4YUDWziWQ8.png?auto=compress%2Cformat&w=48&h=48&fit=fill&bg=ffffff)


_t9PF3orMPd.png?auto=compress%2Cformat&w=40&h=40&fit=fillmax&bg=fff&dpr=2)


_Ujn5WoVOOu.png?auto=compress%2Cformat&w=40&h=40&fit=fillmax&bg=fff&dpr=2)


_3u05Tpwasz.png?auto=compress%2Cformat&w=40&h=40&fit=fillmax&bg=fff&dpr=2)
Comments