Pen Plotter
A machine that draws an user defined image using a pen.
Author: Andrei Stan
GitHub Project Link: https://github.com/UPB-PMRust-Students/proiect-andreistan26
Description
A pen plotter is similar to any 2.5-3 axis machine like a CNC or a 3D printer, it works by moving a pen in cartesian coordiantes in order draw something on a piece of paper.
Motivation
I thought this would be a challenging, yet fun project that requires different skills to pull of, it has software, electrical and mechanical complexities. It would also make me do more CAD work.
Architecture
Log
Week 20 - 27 April
- started making the CAD and looking for online resources
- started to order the mechanical components and 3D printed some prototypes
- tested the electronic components like the power supply, voltage regulator and stepper motors
Week 28 - 4 May
- tested the 3D printed parts and iterated on them
- finished the documentation
Week 5 - 11 May
- assembled the mechanical parts
- made some more 3D prints (display mount, improved pen holder)
- finished prototyped electrical wiring
Week 12 - 18 May
- finished final assembly
- base software for moving to coordinates, parsing GCode, uart communications and optimizations for line plotting
- got a fully working version capable of plotting streamed Gcode
Week 19 - 25 May
- added a progress bar to the display and also modified the UART client to send M73 commands for updating the progress bar
- improved the code for better plotting performance
Hardware
-
Mechanical:
- Steel 8mm rods
- Brass 4mm rods
- GT2 Timing belt
- Tooth timing pulleys and idler pulleys
- 3D printed parts
-
Electronics:
- AC-DC Power Supply 12v 10A
- DC-DC Voltage regulator 12v-5v
- SG90 Servo Motor
- 2 x Nema-17 Stepper motor
- 2 x DRV8825 Stepper Motor Driver
- R-PI Pico 2
- LCD Display
- 2 x 100uF capacitors
- Other small components (wires, breadboards, etc.)
Schematics
Pictures
Bill of Materials
Device | Usage | Price/Unit |
---|---|---|
Raspberry Pi Pico 2W | Microcontroller | 39.66 |
2 x DRV8825 Stepper Motor Driver | Driver for the stepper motor | 14.49 |
2 x Stepper Motor 17HS8401S | Stepper motor driving each axis linear system | 34.99 |
LM2596 Voltage Regulator | Converting the ouput of the power supply (12V) to 5V | 16.49 |
TFT-LCD Display 1.44" | LCD Display for displaying information about the plotter | 29.99 |
SG90 Servo | Servo that lifts the pen on the Z axis | 11.99 |
Power Supply 12V 10A | Power supply for the porject | 41.6 |
8 x Linear Bearing 8mm | Linear bearings for sliding the gantry | 4.07 |
2 x GT2 Timing Belt | Belt for moving the gantry | 3.96 |
2 x Tooth timing pulley | Transmits power from the motor shaft to the belt | 4.50 |
2 x Smooth pulley | Guides the timing belt and keeps tension on the timing belt | 9.32 |
1.5 x 8mm Steel Rod | The gantry will slide on it | 49.00 |
2 x 4mm Brass Rod | For sliding the pen holder | 19.99 |
2 x Breadboard 830p | For wiring stuff up | 9.99 |
Software
Library | Description | Usage |
---|---|---|
embassy-* | Async framework for embedded systems in Rust | Framework used for the whole system including rp235x specific drivers |
mipidsi | Display driver for ST7735 | Used for the display for the Pico Explorer Base |
embedded-graphics | 2D graphics library | Used for drawing to the display |
defmt | Deffered logging | Logging for the plotter during testing |
heapless | Static allocated containers | Allocate data structures for holding GCode commands |
format_no_std | Formatting library for no_std environments | Used for formatting the progress bar text |
display_interface_spi | SPI interface for displays | Used for communicating with the display |
Software Design
The software that runs on the pico was designed using the embassy framework. Thus I've separated all the hardware subsystems into tasks that are run on the default executor.
These tasks communicate via channels, simply, tasks produce values for other tasks to consume. For example the command manager task produces coordinates for the stepper and servo tasks.
The tasks running are:
- servo task
- stepper x and y task
- display task
- command manager task
- UART task
When the plotter starts reciving data the following steps are usually performed:
- The plotter is initialized and all the tasks are spawned.
- Data from an UART connection in the form of G-code commands.
- G-code commands are parsed and sent to the command manager.
- The command manager plans the path of the plotter.
- Lines are drawn using Bresenham's algorithm in order to avoid hockey stick lines.
- The plotter then sends positions to the stepper and servos and waits for them to finish before sending new ones.
- Once we receive M73 commands, the plotter updates the progress bar on the display.
- This is repeated until all uart commands are processed.
Brasenham's line drawing algorithm helps us sample the line in the correct pixels that need to be drawn. The idea is that when we need to write a line at a 20 degree angle, the X component is bigger than the Y component. If we sent the commands to the X and Y components at the same time, we would get a 45 degree line then a straigt line. By using Bresenham's line drawing algorithm, we limit the number of pixels drawn at a time by the plotter thus making the line more precise. This could have been done by just modifying the RPM of each stepper, but this solution has been unsuccessful empirically.
For streaming GCode to the plotter I am using a python client that also preprocesses the plotter commands before sending them via UART. The GCode is generated by Lightburn, inkscape or vpype.