The story of building a vertical plotter.
Building and improving a Raspberry Pi Pico-based, wall-hanging vertical plotter.
To make the experience fit your profile, pick a username and tell us what interests you.
The story of building a vertical plotter.
We are part of Wimbledon Art Fair this weekend, and the plotter (which I have named "Picoplot" for the sake of having a title!) is hanging just inside the studio door, as a nice way to draw folks in. Blinky lights and moving robots!
I've painted the MDF back board as the original greenish colour was a bit jarring on the wall, and I also "upgraded" the cotton lines for the gondola to an extra strong thread (and also made them a bit longer). We put a fishing line across underneath the plotter to hang pieces from - although several of the plots in the picture below are from the AxiDraw on the table across the studio.
I thought I'd write down some real-world lessons learned.
Finally, the reliability has proven a bit hit-and-miss. I'm not certain of the cause - I think loose wire connections are part of it (I'll likely switch to soldered connections in place of the Dupont connections after the show), but I also noticed some static discharges happened when I came near the radiator a couple of times. I don't particularly want to hide the circuit inside a sealed box as this is currently a nice talking point, but if that is the issue then I might work more on the 3D printed elements to make it prettier (and hopefully, less susceptible to external static discharge).
The project heavily depended on Ben's original article and 3D printed parts including the motor holders and the pen gondola.
It was never completely clear how the electronics were attached to the board in the original design. I've now merged some other 3D parts together into an "all-in-one" frame that contains the protoboard with Pico W and buttons, which attaches the two motor driver boards on either side. That is then screwed onto the MDF backboard. I also printed off a couple of "feet" that I've glued onto the back of the board along the base, that will hold it away from the wall at a slight angle to give the pen more of a purchase to press against the paper.
I used Tinkercad to merge the parts, and printed them in the same basic PLA I used for the other pieces. The objects are available on Printables and also in the GitHub repository. I have black nylon standoffs connected to the PCB in each of the four corners that sit on the lugs inside the corners of the box, but it is generally all press-fit into the case otherwise.
I'm thinking of printing some slightly larger / more obvious caps for the buttons, but that's no more than a nice-to-add.
For now I'm still going to be driving this via USB serial with a very long extension cable over to my desk, so I'd like to move on to figuring out how to enhance it to receive commands via wifi instead. As mentioned in the previous log, that will wait until after the art show.
I'm happy with the output right now. I thought the right-hand motor was slipping / behaving inconsistently, but I've re-done the GPIO connections and I think one of those may have been loose previously. One thing I don't yet have fully worked out is the dimensions of the drawings - I've tried resizing in Inkscape, and also providing a larger plot area to the
gcodeplot Python program used to convert to gcode, but I'm still not achieving the sizes I'd like.
As mentioned in a previous update, I've now trimmed the board down to 60cm x 60 cm in size and I'm nearly ready to put it up on the wall.
I designed a new holder for the circuit and motor driver boards, but the first print was a bit too tight so I'll add a few mm and reprint shortly. I also made a couple of small printed "feet" for the bottom of the board so that it will stand slightly tilted away from the wall at the bottom and give the pen a better surface to drop onto.
From here, I'll also need a fairly lengthy USB cable (at first) since the process to plot is still direct gcode commands over serial. Once the upcoming art show is over, I'll look into ways to have this work over WiFi, to take advantage of the Pico W.
One final thing I'd like to do is to set up a way to record the plot process... will have to figure out an appropriate way to mount and point a camera at the whole setup!
In the previous test, I was getting output, but the alignment and direction was all wrong.
After several iterations (switching m1<->m2 wiring, and also, diving back into the firmware code), I figured out that the firmware needed to be set up to invert one of the motors.
#define INVERT_M1_DIR 1 // -1 #define INVERT_M2_DIR -1 // -1
I also needed to tune the angle for the servo to ensure that the pen was properly lifted. Merged into my fork of the original code.
There have also been a few annoyances with the wiring (the Dupont cables kept popping apart where I'd extended things so I lost power to one of the motors midway through a plot, for example). Also, motor 2 seemed to be slipping / not moving as smoothly as motor 1... I think I've now resolved that by reseating all of the connections. Lots of tidying up to do.
CNCjs has worked out well to drive the plotter. For the studio logo, I took an existing SVG, broke it down into paths, used the AxiDraw plugin for Inkscape to add hatching to fill, repositioned the whole thing over the corner of the page (because the plotter expects a centre-aligned image), and used Ben's fork of gcodeplot to output a gcode file that I could use with the plotter. It looks like gcodeplot could actually send the commands directly to the printer, as well.
I'm happy that I've got to here from the original article and materials i had to hand! There are a number of things I want to work on next:
... and then if we start thinking about mode switches, I might need to redo the electronics, and then I might want a board that takes a Pico as a controller, with the motor drivers and buttons attached... and hey, I've built a CNC machine. And we are back to "why am I not using GRBL/grblHAL here?". Well, because this is interesting.
For something that was intended as a learning exercise, I've learned a lot, and have different directions I can go! I'm not marking this as completed just yet, but I count it as "mostly done".
I printed a small case for the protoboard, but need to design something that will also hold the motor drivers, currently attached via tape...
While looking for more GCode sender alternatives to UGS, I also stumbled across Inkcut. I had an installation issue where it needed a newer version of enamlx than my Python version supported, but got that resolved. Looks really nice. I'm sticking with CNCjs for the most part.
First runs involved some adjustments, for example, the thread holding the gondola slipped from the bobbins a couple of times, but I've now threaded it through the hole in the 3D printed holder so that's less of an issue.
It is definitely doing something mostly right, but I need to make some changes to the motor wiring - looks like I have things reversed here somehow. I think it's potentially as straightforward as having M1 and M2 swapped around, but super annoying as I've tried to be very attentive to wiring as I've proceeded with this build.
So close to getting things running. I am waiting on a longer cable for the pen servo (I've tested with some Dupont connections but want something a bit better before running it in place on the hanging plotter).
I've been trying to get the computer to talk gcode to the plotter.
In the original article, Universal GCode Sender (UGS) is the recommended and documented way to get things going. The firmware code is written so that when the start button is pressed, the Pico outputs a couple of lines of information to the serial connection, identifying as a build of the GRBL firmware for CNC machines. The idea appears to be that given those two lines of information, UGS should say "OK, that's a machine running GBRL", and then you should be able to hit the "play" button to send the gcode file across.
I've spent a fair bit of time trying to follow Ben's description in the article, with the latest version of UGS on macOS, and it just will not open a clean and complete connection to the board. I've been as far as checking the debug logs from UGS; putting a build of grblHAL on another Pico and trying to get UGS to talk to that (UGS doesn't properly support grblHAL at the moment, AFAIUI); and comparing the serial output and conversation sequence between UGS and other CNC machines, based largely on blog posts and reports from GitHub issues and wiki descriptions.
It looks as though UGS sends
$I followed by
$$ followed by
$G to check on board capabilities.
I've added a small amount of GRBL command handling to the firmware. I have the Pico respond to these commands in a meaningful(ish) manner, but the connection never seems to fully resolve to a point where UGS will let me hit play. This is fair, because the controller is not running full GRBL, but it is a bit annoying that the recommended software cannot be persuaded to act as a simple sender and pipe gcode over serial.
(I believe the controller is doing its job, though; I've pasted in some of the gcode commands from one of the sample files at the serial prompt in the terminal, and had the servo and stepper motors start to move around, indicating that they are being driven by the commands)
Basically, either my setup is behaving differently to Ben's system from the HackSpace article; UGS has been updated since May 2022 (very likely); or, something else. There's a possibility it's an OS-specific thing, too - I'm trying this on macOS Sonoma; the article appeared to use Windows (?); I do have a Linux machine available as well, but I haven't tried on there as yet.
I've tried bCNC (a Python GUI); but for some reason that is not even wanting to find my USB serial port. As an aside, it also looks absolutely terrible / barely readable in dark mode on macOS.
I finally hit potential success with CNCjs, an Electron-based GUI, which is letting me connect... which I installed using homebrew. I did have to make a small tweak (specifically, turning off system quarantine for the app via
xattr -d com.apple.quarantine /Applications/CNCjs.app) to get it to run without complaints. When I have the last piece of wiring, I should be able to try one of the test plots.
In the end though, this minimal approach may be too little, and it may be that I should switch across to a more functional (grblHAL?) firmware of some kind, assuming that I'd be able to figure out how to have that drive a hanging wall plotter...
Getting the firmware (code on the Pico) into shape was one of the more interesting parts of this project.
The code shared alongside the HackSpace magazine article is incomplete, forked and modified from a repo that is primarily in Chinese, and over a year old.
I've created my own fork of Ben's fork, and inside that right now there's a pico-w-build branch which is getting commits as I get to grips with the code.
Quick run-down of changes and approach:
All of this took a fair bit of build/reset/upload work, with the motors and servo wired to the Pico, in order to confirm that the firmware is good. That's a large part of why I ended up adding the (white) reset button to the protoboard.
At this stage I'm able to compile and upload the sketch to the Pico W, and also, have the buttons trigger the expected actions (motor 1 & 2 up and down, pen up and down, and switching into GCode command receiver mode). I've been checking serial output using tio, Serial.app for macOS, and Arduino Serial Monitor. Assuming that the code supplied with the article will in fact plot from a GCode file as intended, this means that I'm most of the way there.
In theory, the final steps here are getting desktop software to talk to the plotter, and having the plotter do something useful.
I have some ideas for changes to the firmware if I stick with this minimal, sub-GRBL implementation:
The electronics side of the project was where I started to hit some bumps in the road from the original article.
First of all, although the article contains a list of required components, I don't think it's fully accurate.
... so that's 7 buttons, then 🤓
I've mounted the Pico (W) on a protoboard and laid out 7 buttons, with a bit of colour-coding since I had some coloured ones to hand - orange for the "up" buttons, and green for "start". After a bit of testing with the firmware, I also added an 8th button as a broken-out reset for the Pico.
I also decided to make a diagram to help me to sort out the wiring, since the original project didn't contain one (although it does helpfully explain which pin connects to what, as above). I created this using Fritzing, which needed me to track down parts for the Pico W and the motors. The Fritzing sketch is inside my fork of the original GitHub project, on the pico-w-build branch.
A possible future revision could include a nicer, possibly custom-designed PCB to contain the Pico, the buttons, and maybe even with space for the ULN2003 motor drivers to be attached so that it's an all-in-one control panel. Just an idea.
Back in April 2023, I built a Brachiograph, which set me off down a rabbit hole around pen plotters and mechanical drawing machines. I subsequently purchased an AxiDraw SE/A4 (and then upgraded it with a coreless servo).
I've been wanting to build a vertical plotter for my studio wall for a while, and remembered an article from Ben Everard in HackSpace magazine issue 55 (now available online).
I printed the 3D parts from Ben's Printables page, and ordered the various parts I needed - specifically I needed to order a pair of stepper motors. I already had a Raspberry Pi Pico W - which was an upgrade on the Pico that was used in the original piece, and got me thinking along the lines of updating the project to support wifi uploads for plots further down the line. I also already had a spare servo from the Brachiograph project, and a selection of push buttons.
The 3D prints were pretty straightforward - loaded straight into Bambu Studio and printed on the Bambu X1C in basic PLA. Two mounts for the stepper motors, and a gondola (that Ben had borrowed from elsewhere) for the pen. I realised that I wanted to be able to adjust the pen slightly more comfortably than directly adjusting a screw so I added another part that I found on Printables to make it easier to turn the bolt.
Become a member to follow this project and never miss any updates
By using our website and services, you expressly agree to the placement of our performance, functionality, and advertising cookies. Learn More