A wireless pen plotter with simple, purpose-built code. Control it from any device with a web browser - draw on almost any device, hit send, and watch your creation plot in real-time.

It has custom firmware that does exactly what a WiFi pen plotter needs - nothing more, nothing less. The entire system is about 500 lines of C++ code that:

Hardware Setup

The electronics are intentionally simple:

Total electronics cost: under $15 if you shop around.

Software Architecture

Motor Control (motor_control.h): Direct GPIO manipulation using half-step sequences. Simple variables track current position in mm, and a basic moveTo(x, y, z) function handles motion planning with pen up/down logic and simultaneous X/Y movement. No fancy acceleration curves needed for a pen plotter running at reasonable speeds.

G-code Parser (gcode_parser.h): A straightforward string parser that handles G0/G1 moves, G28 homing, M3/M5 pen control, and M114 position reporting. It's intentionally minimal - unsupported commands are simply ignored.

Web Interface (web_interface.h): An MS Paint-style drawing canvas built with vanilla JavaScript and HTML5 Canvas API. Touch/mouse drawing with four tools (freehand, line, rectangle, circle), real-time preview, and client-side G-code conversion. The entire interface is stored as a string literal in PROGMEM - no filesystem required. The ESP32 serves it via a simple web server on port 80.

WiFi Setup (main.cpp): Configures the ESP32 as an access point with a captive portal that guides users directly to the interface when they power on.

The User Experience

  1. Power on the plotter
  2. Connect phone/tablet to "PlotterBot" WiFi (password: plot2025)
  3. Browser automatically opens interface, or navigate to 192.168.4.1 or plotter.local
  4. Draw something with your finger
  5. Tap "Send to Plotter"
  6. Watch it plot

No apps to install, no drivers, no configuration. Works on iOS, Android, laptops - anything with WiFi and a browser.

Technical Challenges Solved

Motor Synchronization: The cheap 28BYJ-48 motors have significant mechanical variance with 3D printed parts. A simple simultaneous stepping algorithm keeps X and Y axes synchronized by stepping them in the same loop iteration.

Calibration: The firmware includes easily-adjustable calibration constants like STEPS_PER_MM_X/Y/Z and X_INVERT/Y_INVERT to match your specific mechanics without rewiring. These are set to a safe limit for the 3d printed frame we are suing, but can be fine tuned or scaled as desired.

Touch Interface: Careful handling of both mouse and touch events with proper coordinate translation accounting for canvas scaling. The interface tracks drawing state and converts gestures to shapes in real-time.

Memory Constraints: The entire web interface had to fit in ESP32 flash. Minimal HTML/CSS/JS and no large libraries kept the embedded interface to ~15KB.

Why This Matters

This project helps demonstrate you don't need complex CNC firmware for every motion control application. Sometimes a simple, purpose-built solution is better than a general-purpose tool.

The code is intentionally readable and well-commented. If you want to understand how stepper motor control works, how to parse G-code, or how to build a web interface on an ESP32 - this is a great learning resource.

Plus, it actually works well for drawing. The wireless control is surprisingly convenient - sit on the couch, doodle on your tablet, and send plots to the machine across the room.

Future Improvements

Attribution

This project has 3D parts and inspiration from: