PicoMatic
A compact CNC plotter controlled by a Raspberry Pi Pico 2W, moving a pencil in 3 axes (X, Y, Z) using stepper motors and drivers.
Author: Aliwi Walid
GitHub Project Link: https://github.com/UPB-PMRust-Students/project-AliwiWalid
Descriptionβ
This project consists of building a CNC plotter machine that uses a pencil as its tool head. It is designed to move across three axes: X, Y, and Z, using stepper motors and motor drivers. The system is controlled by a Raspberry Pi Pico 2W microcontroller, which receives G-code commands via USB serial communication. The commands are parsed on the Pico and translated into precise movements of the motors, allowing the machine to draw complex shapes automatically on paper. An external power supply is used to power the motors, providing enough current without overloading the Pico.
Motivationβ
Initially I wanted to build a 3D printer, but due to the high cost, complexity and potential dangers with heating elements and mechanical failures, I decided to scale down the project to something safer and more achievable in the desired price range. The goal remained to build something which involves motion control and automation, where mechanical movement is precisely driven by software. And that is how I ended up choosing the CNC plotter as my project idea, as it shares a bunch of fundamental principles with a 3D printer, but clearly a lot cheaper and safer to build at home. This will help me continue my journey of learning about embedded programming and real time systems.
Architectureβ
Log (not final version)β
Week 7 β 14 Aprilβ
Since I had a clear idea of my project well before Week 7 and had already received approval, I ordered all the necessary components from AliExpress. This week, I 3D printed the structure of the CNC plotter and assembled the mechanical frame. I also created the initial architecture schematic and began researching which Rust crates I would need for motor control, serial communication, and other core features. One obstacle I encountered was that the STL file source I used did not specify the required screw sizes, which delayed the mechanical assembly. Here's how the build looked at this stage:
8 β 21 Aprilβ
This week, I began work on the software side of the project. I wrote and tested code to control the stepper motors: first individually, then all three simultaneously. After that, I hardcoded some simple G-code movements to verify that the motors responded correctly for each axis. I also tested the USB-to-UART converter using a Python script to confirm that G-code could be sent correctly from the host to the Raspberry Pi Pico. In parallel, I finalized both the KiCad schematic and the overall system architecture diagram.
9 - 28 Aprilβ
After receiving the correct screws, I completed the physical assembly of the CNC plotter. With the hardware finalized and the software functional, I tested the full pipeline:Create a vector image, use JS-Cut to convert it into G-code, send the G-code to the Pico via a Python script over UART, the Pico reads and executes each command line-by-line to control the motors and draw the image on paper, this was the first complete end-to-end test, and it worked successfully!
(yes i know the usb to uart converter should not be on the breadboard, i just put it there because otherwise i will lose it :) )
Hardwareβ
3Γ 28BYJ-48 Stepper Motors Each stepper motor is used to drive movement along one of the three axesβX, Y, and Z. They are each controlled by a dedicated ULN2003 driver board, with signal lines connected to the Raspberry Pi Pico via GPIO as follows:
Stepper 1: GPIO 15, 14, 16, 17
Stepper 2: GPIO 18, 19, 13, 12
Stepper 3: GPIO 20, 21, 11, 10
CH340G USB-to-UART Converter This module establishes serial communication between the Raspberry Pi Pico and a host computer. It is used to send G-code commands from the host (via a Python script) to the Pico for real-time stepper control. The pin connections are:
CH340G TX β Pico GPIO 1 (UART0 RX)
CH340G RX β Pico GPIO 0 (UART0 TX)
External Power Supply A separate 5V external power source is used to power the stepper motors through the ULN2003 driver boards. This is necessary to avoid overloading the Raspberry Pi Pico, which cannot provide sufficient current for motor operation. Ground from the external power supply is tied to the system ground to ensure a common reference.
Schematicsβ
Bill of Materialsβ
Device | Usage | Price |
---|---|---|
Raspberry Pi Pico 2W | The microcontroller | 39.66 RON |
Debug Probe | The debug probe | 66.17 RON |
CH340G | The USB to UART convertor | 2.52 RON |
28BYJ-48 + ULN2003 | Stepper motors + drivers | 27.1 RON for a set of 3 |
Male to male/female jumper wires | Wires | 0.1 * 23 = 2.3 RON |
Breadboard Power Supply + battery | External power for motors | 4.69 RON |
Softwareβ
Library | Description | Usage |
---|---|---|
embassy-executor | Async/await executor optimized for embedded systems | Runs asynchronous tasks without an OS |
embassy-time | Timekeeping, delays, and timeouts | Used for non-blocking delays and timeouts |
embassy-rp | HAL for Raspberry Pi RP2040 using Embassy | Interfaces with RP2040 peripherals (GPIO, UART, etc.) |
defmt | Lightweight and efficient logging framework for embedded systems | Provides low-overhead debug output |
defmt-rtt | RTT backend for defmt logging | Sends logs from device to host over RTT |
heapless | static -friendly data structures without heap allocation | Used for queues, buffers, and collections without alloc |
cortex-m-rt | Minimal runtime for Cortex-M microcontrollers | Sets up vector table, stack, and entry point |
//TODO add stuff for python script also