How to Set Up an iDraw 2.0 Plotter and a Raspberry Pi for Headless Operation

How to Set Up an iDraw 2.0 Plotter and a Raspberry Pi for Headless Operation

This article is contributed by @Erez Zukerman

I quite enjoy using my iDraw 2.0 plotter, but I like to run it slow – and so my plots can take a while. I used the out-of-the-box Inkscape setup for quite a while, but I had to keep my main computer on and connected to the plotter when it was working. This wasn’t ideal – so I decided to see if I could figure out a “headless” setup using a Raspberry Pi.
It turned out to be a fair bit easier than I thought it would be, and fun, too. Here’s what we’re going to do:
●Set up the Pi itself.
●Install CNCjs and its dependencies. This is what we’ll use to actually control the plotter, by sending GCode over the wire.
●We’ll also take a moment to set things up so that CNCjs automatically starts whenever the Pi boots, without you having to log in or do anything.
●Figure out how to convert our SVGs to GCode (with pen speed control).
Please note that this tutorial assumes you’re comfortable using the Linux command line. If you’re following along months or years after this was first published, you may run into all sorts of errors along the way – that is the nature of the beast. At the time of writing, the system described worked well for me.
Let’s start!

Set up the Pi

It’s best if you can dedicate a Pi just for this project, so it’s your “plotter controller”. If not, no worries – it’ll still work, but might be less convenient over time.
Another good reason to dedicate a Pi just for this project is that you can set it up from scratch with defaults that make sense. So that’s just what I did: I grabbed a 32GB SD card and used the official Raspberry Pi Imager tool to flash it with Raspberry Pi OS.
One thing the tool lets you do, which I would recommend, is set up some defaults right out of the box. I used the installer to configure the following:
●My username and password
●A local hostname for the plotter controller (plotter.local in my case)
●My public SSH key, so I could SSH into the machine right away
●My WLAN SSID/password, so the Pi would connect to my network when booting
I configured all of this and then let the Imager do its thing. When it was done, I ejected the microSD card and popped it into the Pi. Just for the first boot, I did connect the Pi to a keyboard and display – but this wasn’t strictly necessary. The plotter.local hostname I chose took a few moments to register on my network, so I used the keyboard and display to grab the current IP (by running ifconfig from the terminal).
I SSHed into the machine, and it was time to move on to the next step: Installing CNCjs

Install CNCjs

As you may guess from the name, CNCjs is Node-based. So we first need to install Node.
●SSH into the Pi
●Let’s install NVM:
○curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
●Exit the terminal and then ssh back in again. This loads NVM.
●Now let’s install node:
○nvm install node
●Great! Time to install CNCjs:
○npm install -g cncjs
●Assuming everything worked well up to this point, let’s run CNCjs just once. This will create our configuration file, ~/.cncrc:
○From the command line, in your home directory, run cncjs
○Ctrl+C out of it
●You are now the proud owner of a brand-new ~/.cncrc, congratulations. Let’s edit it, mainly so that we can allow remote access:
○vi .cncrc
{
    "allowRemoteAccess": true,
    "state": {
        "allowAnonymousUsageDataCollection": false,
        "checkForUpdates": true,
        "controller": {
            "exception": {
                "ignoreErrors": false
            }
        }
    },
    "secret": YOUR_SECRET HERE
}
The crucial line to add here is the first one, allowRemoteAccess.
●Run cncjs on the Pi again.
●Using your browser on your main machine, go to plotter.local:8000. It should pull up CNCjs.

Next, it’s time to plug in the plotter and see if CNCjs can talk to it.
●Connect the iDraw 2.0 plotter to the Pi’s USB port.
●Turn the plotter on.
●In CNCjs, locate the Connection widget (top-left corner by default).
○Hit the Refresh button under Port.
○Pop open the dropdown choose the port.

●Click Open. If everything worked, the Gcode console should now display some text.

Let’s move the motors!


●Using the Axes widget, hit + and - on the various axes to move the motors around. You can also enable “keypad jogging” and then use your arrow keys to move the plotter around. If you stick a pen in and lower the Z-axis, it’s like an expensive Etch-a-Sketch.


One note is that the 0 position on the Y axis is the opposite of what you might expect: It goes to the bottom of the plot area. We’ll get back to this later.

Get CNCjs to run on boot

Moving right along, we now want to get back into this sweet spot whenever the Pi reboots, without you having to do anything. So:
●Back in the SSH session to the Pi, kill CNCjs by hitting Ctrl-C.
●Make sure it’s really dead by refreshing the browser (plotter.local:8000, assuming that’s the hostname you configured above). This should now fail.
●On the Pi, install pm2: npm install -g pm2
●Start CNCjs with pm2: pm2 start cncjs --name cncjs
●Make sure it really started and works as you’d expect: Wait a few moments, then go to plotter.local:8000 and see that it loads.
●Create a startup script: pm2 startup. This will spit out a command you need to sudo, so do that.
●Save the process list: pm2 save
●Restart the Pi to see if it worked: sudo reboot
●Wait for it to come back up, maybe 3-5 minutes, then hit http://plotter.local:8000/ to see if you can get CNCjs again. If you did it right, it should just come right back up.
Victory! We’re almost there – CNCjs is now all set up. But to plot something, we need to feed it with a GCode file – it doesn’t natively handle SVGs.

Create a pipeline for converting SVGs to Gcode

To convert our SVG to Gcode, we’re going to be using Juicy-Gcode, which is a little command-line utility.
One big change here is that we are zeroing relative to the bottom left corner of your paper, not your top right! This change may take a bit of getting used to. I’ll remind you again later.
●On your main machine, download the Juicy-Gcode release binary for your operating system: https://github.com/domoszlai/juicy-gcode/releases
●Juicy-Gcode configuration is saved in something they calld a “flavor file”. This is just a yaml file. Here’s a good starting flavor file, you can copy/paste this into flavor.yaml on your machine:
begin: |
  G21 ; Set Units to Millimeters
  G17 ; Set Plane Selection to XY
  G90 ; Set Absolute Positioning
  F600  ; Set Speed to 600 mm/min -- this is really slow, you may want to edit
  G00 Z0 ; pen up
  G92 X0 Y0 ; consider current position as 0,0 -- this is BOTTOM LEFT corner
end: |
  G0Z0 ; pen up
  G00 X0 Y0 Z0
toolon: |
  G0Z6 ; pen down on paper
tooloff: |
  G0Z0 ; pen up
  
A couple of important things to note about this flavor file:
●I run the plotter at 600mm/min, which is very slow. You might want to speed this up, depending on your pens and preferences.
●The other notable line is the one that stats with G92. In this line, we’re telling the plotter “wherever you are right now, that’s home”. So to calibrate a plot, we expect you to manually (and gently) move the plotter head to the bottom left corner of the paper.
You do want your paper size set up correctly in the SVG, this is important.
To run Juicy-Gcode, the command looks something like this:
juicy-gcode -f flavor.yaml image.svg -o image.gcode
That’s a bit of a mouthful to type out every time, so I made this little script to make things a bit more convenient:
#!/bin/bash
# Usage: ./run-juicy.sh input.svg [speed]
# If speed is not provided, defaults to 600

# Check if at least one argument is provided

if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then
echo "Usage: $0 <input-svg> [speed]"
echo " If speed is not provided, defaults to 600"
exit 1
fi

inputfile="$1"

# Set default speed to 600 if not provided
speed="${2:-600}"

# Build the flavor file name
flavor_file="flavor-${speed}mm-speed.yaml"

# Generate output filename by replacing .svg extension with .gcode
outputfile="${inputfile%.*}.gcode"

# Run the juicy-gcode command

juicy-gcode -f "$flavor_file" "$inputfile" -o "$outputfile"
You can now have multiple different flavor files, each with a different run speed, and easily specify the speed by passing in the number that matches the flavor file’s filename.
Now that you’ve got a GCode file, it’s time to upload and plot!

Upload the GCode and plot

CNCjs gives us two ways to feed a GCode file in: We can upload it via the browser by clicking “Upload G-code”, or we can set up a watch directory (so that whenever a GCode file pops into it, the plotter would start running).
The latter sounds cool in theory, but doesn’t make a whole lot of sense: Every plot requires some manual setup anyway. We have to place the paper, install the pen, etc. So for me, it makes much more sense to manually upload the file via the browser.
Once you do that, zoom out to see the preview. 

This gives us a couple of important sanity checks:
●We’re reminded once more (…) that the plot will begin from the bottom-left corner of our paper.
●We get to see measurements on both X and Y axes. It’s worth taking a moment to read this and verify they don’t exceed your plotting area. If they do, there’s a problem with your SVG – don’t start plotting it, or your servos would be quite unhappy.
Assuming your pen is at the bottom-left corner of your paper and the measurements make sense, it’s time to plot! Hit the Play button and watch your plotter. You can now shut down your computer or carry it to another room while the Pi and the plotter work. Victory!

Back to blog

Leave a comment

Please note, comments need to be approved before they are published.