Introduction: ACRO Openbuilds Pen Plotter (Arduino With GRBL and Raspberry Pi With Universal G Code Sender)

About: My background and previous career was in engineering but I recently changed tack and now I am training in the medical field.

I have had an interest in building a CNC machine for quite a while but having lived in small flats/apartments there have always been barriers whether it be space, noise or dust! This instructable details my build of a CNC plotter using an OpenBuilds ACRO system frame. I have not covered every single step however I hope it gives an idea of the process, some resources that I found helpful and also what can be achieved! A summary of the CNC tool chain is shown and this instructable will cover:

      1. The ACRO Frame
        1. The Z axis
        2. Arduino and CNC Shield with GRBL
        3. Power: On/Off switches and E-Stop
        4. Limit switches
        5. Headless Raspberry Pi with Universal G Code sender
        6. Connections and calibration
        7. Future improvements

        The supplies I used will be documented at the start of each section. As well as these I have used the following equipment and some standard electronics supplies including:

        • Screwdriver set (flat head and Phillips head)
        • Needle nose pliers
        • Wire cutter and strippers
        • Ruler
        • 2.45mm crimping set
        • Single and Multi core wire (various colours)
        • Soldering iron

        Step 1: The ACRO Frame


        The ACRO system is described on the OpenBuilds website:

        A System Like No Other!

        The OpenBuilds ACRO was developed to be the most accurate and cost effective system in its class. The ACRO System incorporates the OpenBuilds V-Slot system and, therefore, has the unique ability to expand to multiple sizes creating a size configuration custom to your needs.

        The frame is designed for lightweight applications in which the forces are not too high e.g. lasers, pen plotter, pick and place etc. This is mainly due to the acrylic gantry plates. There are some discussions in the OpenBuild forums that suggest that you could put a Dremel or similar rotary tool on the Z axis. I am not convinced but also, I haven't tried mounting a Dremel to this frame. If a CNC router is what you are after a more robust frame would be a better. Given I am building a pen plotter it seemed like an ideal choice for me!

        I haven't included a description of how to put the frame together as the OpenBuilds team have already done so in video form. I just followed along with the video! Once I assembled the frame I attached it to an MDF sheet using some m3 self tapping screws. It just so happened that this size of MDF sheet available had some space spare at one end. I aligned the frame to make use of this space for the electronics without any overhang of the motors and to allow routing of the cables.

        As the frame is made up of v-slot extrusion, there are many places to hide the wires and cables from view. I used both the central hole of the gantry and the exterior groove to hide some of the motor and limit switch wiring and route it to the electronics end of the board. The cables that come off the Z axis are routed through a flexible plastic tube to the outside of the frame and then run to the electronics end of the MDF board.

        Step 2: The Z Axis


        • 3D printed ACRO 1 axis pen holder version 1
        • 1 x SG90 9g servo motor
        • 2 x 55mm 8mm linear rail
        • 2 x LM8UU linear bearings
        • 1x small elastic band/hair band

        The ACRO system comes with a Z-axis mounting bracket with a number of holes in it in order to support a number of different items. The example given on the OpenBuilds website is the installation of a laser module. In this case I am mounting a pen for the plotter.


        My specification was to:

        • Hold a pen (up to around 10mm in diameter)
        • Allow for slight variations in the mdf sheet by producing continuous downward pressure
        • Able to lift the pen off the page
        • Be mounted to the gantry on the ACRO Frame.

        Scouring the internet for a suitable pen holder the closest I could find was the 1 axis pen holder from Tech2C on Thingiverse. This was designed for the Hypercube 3d printer that has a moveable z axis bed and so the mount did not have the ability to move the pen off the page.

        I decided to modify this design by adding a mounting plate for a servo motor on the side. Modelled using Fusion 360. Like the Tech2C design it uses an elasticated band (I used a hair band) to provide the continuous downward pressure. The settings for how far the servo moves is covered in the next step. These settings give a Z axis travel of approx 5mm but all that is needed is to take the pen nib off sheet of paper. A smaller Z axis travel also protects the pen nib as it come back down to the page, so 5mm is more than enough.


        The final design was sent to a local 3d printing company as I was unable to get into my local makerspace. The linear rail was bought as a 300mm length and after a failed attempt to use a hacksaw to cut it I had to borrow an angle grinder to cut the 55mm lengths. After jumping those two hurdles I thought the assembly would be relatively straight forward however I noted the following issues with v1 of my design, namely:

        1. The hole for the servo motor is a fraction too small.
        2. The slider rubs up against the servo mounting plate.
        3. The hole for the tightening nut on the slider is not deep enough for an m3 nut.
        4. If the slider is at the very bottom of its travel the servo struggles to lift it.

        I solved all of these problems (see below) in the interim but a redesign that addresses these issues would be better in the longer term.

        1. Filing away some of the plastic.
        2. Filing away some of the plastic.
        3. Using an m2.5 nut and bolt.
        4. Adding some cable ties to lift the carriage off the bottom of the travel.

        Step 3: Arduino Uno/CNC Shield and Grbl Install


        • 1x Arduino Uno
        • 1x Protoneer CNC Shield v3.0
        • 3x A4988 Stepper Motor Drivers
        • 2.54mm header jumpers
        • Grbl firmware adapted for a servo in the Z axis

        I chose the Arduino/CNC shield as my controller board simply as I already had an Arduino and was familiar with the Arduino IDE. Grbl is a widely used, open source, CNC controller software that can be found at the heart of many DIY and commercial builds. Likewise, the Protoneer CNC shield is likewise a commonly used DIY controller board with many Chinese copies available. The A4988s are quite loud when running and so I plan to swap to TMC2208 drop in replacements soon.


        1. Install the CNC shield into the Arduino. The CNC shield simply lines up with the headers on the Arduino and slides straight in.
        2. Install the micro stepping jumpers. This CNC shield allows for up to 1/16 micro stepping. All the pros and cons of driving a CNC machine using full steps or fractional steps including smoother torque profiles etc. etc. are described in varying amounts of detail across the internet... I won't go into them here. I opted for 1/16 micro stepping and this is achieved by using 3 jumpers as shown in the picture
        3. Install the motor drivers into the CNC shield. Each motor driver drives one motor and given the gantry is driven by two motors, one on each side, a decision needs to be made which one this is going to be. I opted for this being the Y-axis (see picture). Motor drivers are therefore installed in the X, Y and A positions. The "A" motor is going to be the same output as the Y motor and therefore jumpers need to be installed as shown on the headers above power connector.
        4. Connect the stepper motors. The different ways of wiring a stepper can be read about here. In this case were each stepper motor has 4 wires, green, red, yellow and blue. The motor cabling came with the ACRO kit (as an extra) and I just matched the cable colours across the connectors and then each one is installed in the same orientation to the stepper motor drivers as (shown in photo)


        The version of Grbl that I used can be downloaded here and compiled using the instructions here.

        Compiling and uploading Gbrl to the Arduino through the Arduino IDE allows you to modify the source files before compiling. If you followed the instructions in the link above, the Grbl source files should be in your Arduino home folder (by default something like .../Arduino/libraries/grbl, see photo). These files can then be opened in a text editor (I use Sublime text, available here). Once you have made any changes they will need to be saved and the source code recompiled and uploaded to the Arduino in the same way that is described above. The files that I made changes to are:

        config.h - This configuration header file holds definitions for various settings that can be turned on and off by commenting in/out the lines as necessary. Line 109 gives the order in which axes are homed, in the unmodified version X will home first and then Y. I wanted both X and Y to home at the same time.

        • Uncomment: Line 110
        • Comment: Lines 112 and 113

        N.B Commenting you add "//" at the beginning of the line so it goes grey, Uncommenting you remove "//" from the beginning of the line as shown in the pictures.

        spindle_control.c - This file is the reason why we use this version of Grbl. It uses the PMW output that would normally used to control the speed of a router spindle to control the up down movement of our z-axis. Lines 47 and 48 define the PWM signal sent to the servo to control its position. This took a bit of playing around but essentially you want the the PEN_SERVO_DOWN position to be out of the way of the travel of the z-axis slider but close enough that when it starts to move to the UP position it moves the pen off the paper immediately. PEN_SERVO_UP should be in a position that the servo arm is able to hold the slider up. For my build these were set at:

        • PEN_SERVO_DOWN 20
        • PEN_SERVO_UP 10

        These numbers may be different if you do this for yourself!

        Step 4: Power: PSU, On/Off Switches and E-Stop.


        • 12V 10A Power Supply Unit
        • Adjustable LM2596S DC-DC Buck Converter 12v to 5v
        • 13A plug and cable.


        I wanted the whole system to be powered from one plug and cable... I didn't want cable spaghetti every time I came to use it!

        The major current draws come from:

        • The motor controllers. These can provide a maximum of 2A per motor and the CNC shield requires a supply voltage between 12-36V.
        • The Raspberry Pi requires. The data sheet states that it should have 3A at 5V available. The power to the Arduino is included in this amount as it will be powered from the Pi's USB port.

        (3x 2amps) + 3amps = 9amps... so a 12v, 10A supply seems to be more than enough. There are probably better ways of doing this and I have probably over specified the PSU here however 12V 10A supplies are readily available so this seemed like a good choice.


        The PSU I used came from Amazon, designed sold as an LED lighting PSU, there are plenty to choose from on eBay/banggood/aliexpress etc. It has two 12V connections. I used both; one as a dedicated supply to the motors, the other for the stepped down 5V supply for the electronics. This way the emergency stop button can be added to the motor power supply to kill the motors quickly without shutting off the entire system. There is a power switch for each power line, the wiring of which is discussed below. I used an illuminating "missile control" toggle switches for no other reason than I think that they looked pretty cool.

        The 12V supply for the motors is routed through the screw terminal header on the CNC shield. This only supplies the motors so the Arduino Uno must get its power from somewhere else, in this case the Raspberry Pi's USB port.

        The use of an adjustable (rather than fixed) step down converter to provide 5V, 3A to the Raspberry Pi was purely because of purchasing options. The ones I got came in a pack of 5 and I wanted the flexibility of voltage control for future projects!


        It may seem like overkill to include an emergency stop button in this project but given that I will be using a headless Raspberry Pi there is the possibility that there will not be a GUI open to provide a soft stop during operation... also everyone loves a big red button. The E-stop that I used has both a Normally Open and a Normally Closed switch. The NC switch is wired inline with the power supply so that when the button is pressed the switch will open and cut the power to the motors. The NO switch is wired to the emergency stop pin on the CNC shield, when pressed this switch will close and ground this pin indicating to the controller that the E-stop has been pressed and to halt the current program.

        Illuminated Toggle Switches

        The toggle switches are from Adafruit, their website says:

        "If you want to use the switch to turn on/off something, you can use the toggle to connect and disconnect the two pins on the bottom. If you want the LED to always be on, provide 3-12V between the ground and headlamp pinIf you want the LED to be on only when the switch is connected, provide 3-12V on the (+) pin and connect ground to the ground pin."

        In order to get them to toggle the power to each part of the board AND have the LED go on and off the connections shown in the picture were needed.

        Illuminated Push button Switch

        This is covered in step 6.

        Step 5: Limit Switches


        • Limit switches from Open builds (included with ACRO)
        • Low pass filter PCB
        • Resistors (300R and 3k3)
        • Capacitors (10uF)
        • 2 way and 3 way, 2.54mm PCB screw header blocks

        The use of limit switches allows the CNC machine to home to a known location and also stops the gantry crashing at the ends of the travel. Limit switches can be plagued with difficulty as the electrical noise generated from the motors can be very large and can cause false trips of the switch causing programs to randomly stop for no reason. This blog had a simple analogue solution to the problem using a low pass filter at the end of the switch to filter out the high frequency noise associated with the motors running.

        I took this idea and created a low pass filter board for the X and Y end stops and the emergency stop. I also used this board to connect the servo to its required power supply.

        In the schematic, R1,R2,R3 are 300R resistors, R4,R5,R6 are 3k3 resistors. The capacitors used are 10uF NOT 100uF as the schematic indicates.

        Note: The video shows the machine homing using the RC low pass filters on a breadboard before the PCB was designed and made.

        Step 6: Headless Raspberry Pi


        • Raspberry Pi 4
        • Raspberry Pi 4 heatsink
        • 1 x Illuminated momentary switch

        Note: This step could be a whole Instructable on its own! The process was quite simple and there are many resources out there for the Raspberry Pi. I am a novice at command line control and I managed to get it working so I have included the links and resources that I mainly used.

        Firstly, the reason for including a Raspberry Pi in this project is that I wanted to make a system that didn't require me to plug my laptop into the machine every time I wanted to use it. A Raspberry Pi is more than capable of running the Universal G Code sender program and sending the commands to the Arduino via USB. It can also be controlled headlessly through either the terminal via SSH or a graphical interface using VNC. The remote control options for the Raspberry Pi can be found here. A Raspberry Pi 4 is probably overkill for just this application but if I decide to put other applications on in the future, fingers crossed it is future proofed!

        The steps I took to achieve this were:

        1. Download and install Raspberry Pi OS to a micro SD card. I used the Raspberry Pi Imager on my MacBook and just followed the on screen instructions to install on to to a 32GB card.
        2. Add Wifi setup. In a headless Pi there are no input devices attached so you need to add a file to the boot partition on the sd card that tells the Pi which wireless network to join. Instructions on how to do this are here.
        3. Add SSH folder. This will enable SSH on the Pi and you will then be able to access the terminal on the Pi remotely to install the GUI and VNC. Instructions on how to do this are here, starting at step 3.
        4. Add VNC. Once you have access to the terminal on the Pi you can install and set up VNC. Instructions on how to do this are here. The sections required are "Installing VNC", "Enabling VNC at the command line" and "Connecting to your Raspberry Pi using VNC viewer".
        5. Install Universal G Code Sender. Using VNC open a browser and download and install UGCS from the website here. There are a couple of issues about the UGCS viewer not displaying properly that are covered in this article, however I havent implemented these changes on my machine yet.

        You can now access your Arduino/Grbl by wirelessly connecting to Raspberry Pi via VNC, opening UGCS and connecting via USB to the Arduino!

        Shutdown/Reset Switch/Status LED

        Again this could be a Instructable all of its own! The Raspberry Pi doesnt come with its own on off switch. Adding one that will allow a scheduled shutdown, rather than just pulling the plug, will hopefully protect your files from corruption. As I have said previously I am a bit of a novice at the command line so this project has been a bit of a learning curve for me.

        The illuminated momentary switch has 4 pins. The larger two connect across a NO switch that does not latch when you press it. The smaller two are marked + and - denoting the positive and negative sides of the LED. I wanted my set up to:

        1. LED On/Off to reflect the status of the board.
        2. Shutdown on a short press
        3. Reboot on a long press

        For the external status LED, I essentially followed these instructions. The led requires a 330ohm resistor (in the picture mine is a 33ohm) attached to the negative pin and then flying leads attaching; + to a GPIO pin on the Raspberry Pi and the resistor to GND on a GPIO header. As described in the link the GPIO pin that is used is the UART Tx, when we enable this communications service on the Pi it will take the GPIO pin high when it is turned on and it will go low when it turns off... ideal for our status LED! To enable this, "enable_uart=1" needs to be inserted into "config.txt" @ "boot/config.txt"

        The duration of a press for shutdown and reboot is a little more involved and requires a script to be run when the Raspberry Pi turns on that will listen for any button presses and execute the shutdown or reboot commands dependent on the length of the button presses. The python script is attached and has some brief comments to indicate which bits of the script does what. This script should be placed into a folder somewhere (I put it in the home folder, /home/pi/) and made so that it can be executable (at the command line you can use "chmod X+ /home/pi/").

        To make this useful the python script needs to be automatically run when the Raspberry Pi is turned on. To do this a command needs to be added to one of the start up files called "rc.local". This is found at "/etc/rc.local" opening this in a text editor and add the line "sudo python /home/pi/ &" before "exit 0". This instruction will run the script when rc.local is called during start up. The "/home/pi/.." points to the directory or file that you put the Power_Interrupt script in before.

        To connect to the Raspberry Pi I used, GPIO pins 3 and 14. The two ground pins were soldered together and the three flying leads crimped into a 2x2 connector that covered GPIO header pins 5-8.

        Step 7: Connecting Up and Calibration

        Acrylic mounting plate

        To keep everything tidy I designed and laser cut some acrylic sheets to mount everything to. The standoffs are all m3 in size apart from the Raspberry Pi which uses m2.5. 4mm holes were drilled in the correct spacing into the pdf which then accepted 10mm hex standoffs. This allowed some cables to be routed underneath the black acrylic shown in the picture. The boards were mounted with 20mm hex standoffs and secured with a nut on the bottom side of the acrylic.

        Cable routing and Connecting up

        Instead of using cable chain I used cable ties to join cables together and route them where I needed them. It naturally fell into a cable chain style arrangement and it seems to work well with no interruption of movement in the x-axis. The connections were made as shown in the schematic in the previous section. The motor cables are still a bit long and untidy for my liking ... I will add it to the to do list to shorten them ... at some point.


        The Universal G code sender has its own calibration wizard which is very easy to use. And after all that... it was ready to go!

        Step 8: Future Ideas

        I will be using this to draw generative art that I am in the process of programming/designing, see pictures/video. I am sure this is just version 1 of the machine and I have some ideas already for future improvements including:

        • Screen for the Pi or make it truly headless using Octoprint
        • Webcam to video the prints as they take place.

        Looking forward to see what I can do with it!

        First Time Author Contest

        Runner Up in the
        First Time Author Contest