A New, Fully Modular CNC Controller


The blog post details a new CNC controller I designed. I have probably designed 40-50 different controllers over the years, but this one has me really excited. My past controllers were generally application specific. My recent controllers have all been for the Grbl_ESP32 firmware. The I/O on the ESP32 is very flexible, but somewhat limited in pin count. There have always been enough pins to control the machine, but not enough to make a general purpose CNC controller that can target any machine.

Recently, support for I2S shift register chips has been added to the firmware. The shift register scheme supports high-speed (125 kHz step rate), jitter-free stepping with up to 32 output pins (28 on this board due to connector limitations). To show off this new capability I designed the universal controller I always wanted. A universal CNC controller covers a huge variety of options so I quickly realized I would have to add some modularity to the design. This would allow you to pick the features you wanted and not have to pay for the ones you don’t need. It would also allow for some amount of future proofing. As new requirements are identified, new modules could be added

Here is the board I came up with. Along the bottom edge are (6) stepper motor modules. Along the top and right sides are (5) CNC I/O modules. On the left side is a micro SD card slot. There are (2) fan connectors. There is even a JTAG interface. With a $10 Esp-prog interface board you can do some real debugging. The size is 134mm wide and 132mm tall.

Stepper Motors

The six stepper channels can use either common “Pololu modules” or external drivers.  The terminal blocks are pluggable and can be plugged in horizontally or vertically.

The modules support:

  • Basic step and direction modules like A4988 and DRV8225
  • Trinamic modules in standard or SPI mode – with sensorless stall detection
  • Individual per-motor enable signals

For external drivers, you can replace the stepper module with a simple/low-cost jumper module that routes the step/dir/enable signals to the external connectors:

  • External drivers are driven from shift register chips that can drive optocouplers directly at 5V (jumper selectable) and 25mA, thus getting around the problem that ESP32 GPIOs are out-of-spec for directly driving many optocouplers.
  • The jumper modules can be configured for either common low or common high.
  • In addition to the 6 stepper modules, there are some uncommitted shift register outputs that could be used to drive even more motors.  It would be possible, with some re-purposing of pins, to drive 14 external-driver motors!

The Grbl_Esp32 firmware lets you use the motors very flexibly.  You could have a 6 axis machine, or gang two motors on any axes with squaring. With external drivers, you could have a 6-axis machine with dual motors per axis

CNC I/O Modules

The (5) sockets are for use with CNC I/O Modules. CNC I/O Modules are designed to interface with your machine. Each module socket has 4 independent I/O pins and 4 bused pins. The bused pins could be used for an I2C, SPI, etc. The primary input (motor) voltage, 5V and ground also go to the module. The voltages are only for powering the basic electronics. If you want to make a high current DC spindle speed controller, for example, you should add a separate power connector for that.

There is a spec for these modules. By following some basic pin usage rules, we hope even I/O limited controllers can support a lot of modules. The modules are open source. This could help people create their own modules.

We currently have (5) types of modules available. Note: Not not all of them have the final terminal blocks. They will match the main board.

There are some limitations on the use on modules, due to a few pins being input only and some being output only, but in general you are free to select what you want and double up on some like multiple inputs or multiple relays.

4x Switch Input Module

This module is designed to be very robust against noise and voltage spikes on (4) switch inputs. The signal enters through an optocoupler, goes  through a little filtering and then through a Schmitt trigger. It has 3 terminals per switch (Signal, 5V and Gnd). This can be used with basic 2 terminal switches, 3 wire reprap style switches, 3 wire optical vane type switches and 3 wire, 5v, proximity switches.

Relay Module

This could be used to control a spindle, coolant/vacuum, valve, etc. It has a 3 position terminal block and an LED to indicate when the coil is on.

RS485 Modus

This is designed for use with VFD Spindle controllers. Currently the Huanyang types are supported, but others could be added in the future.


This outputs a 0-10V signal for spindle speed control. The module also has 2 opto isolated output for controlling the direction signals that some VFDs require.

4x 5V Buffered Output module.

This has up to 4 5V signals. This could be used for a speed controller with enable and direction signals. It would also work great with a laser engrave power supply. It has an LED for each channel to indicate when it is on.


We have a lot of ideas for future modules

  • Display
  • Pendant
  • Additional stepper motors
  • Hobby servos
  • Solid State Relays
  • Closed loop motor controllers
  • I/O expansion. One module could act as a host for additional modules.
  • Support for 3D printer items like heaters, etc could be added, but right now Grbl_ESP32 has no support for 3D printing. The module concept could also be used with 3D printer firmwares like Marlin, etc.

If You Want One…

The design is open source. The files are on Github. You can build one yourself or I will be selling them via my Tindie store soon.

The design has been fully tested on hand assembled prototype hardware. I have a small prototype production run of controllers and modules on order to make sure that goes smoothly and then I will order larger batches.

The Future

This was designed as a universal controller, but hopefully the CNC I/O module concept takes off and other controllers are designed to use them. Very robust, well tested and supported application specific controllers could be quickly created. You don’t have to plan for every spindle, because you can just swap out a module.


Many of the ideas for this controller came from discussions on the Slack we use to develop Grbl_ESP32. Special thanks goes to @odaki for theI2S shift register support and @MitchBradley for hardware and firmware design. 

Adding Step and Direction (CNC) Control to the Cheetah Motor

Robot Dog Motors

The proliferation of dog like robots has spawned a new generation of servo motors. These motors combine Brushless DC motors from the RC/Drone world with encoders, motor controllers and gearboxes in one small package. They are very compact, super strong and are in an easy to use package. Some of these are open source and are now being made cheaply in China.

I am interested in exploring the possible CNC uses of these motors. The appeal is the simplicity. You only need to run power and motion signals to them and one set of power wires can be daisy chained to the motors. With stepper motors, you need to run 4 heavy power wires to each motor. There are also potential EMI benefits because the stepper motors use long runs of fast switching high current.

To make them compatible with basic CNC machines you need to have step and direction signals, similar to what stepper drivers use. My initial goal was to add these inputs without changing anything to the physical motor. I will only touch the firmware.

Open Source FTW

Fortunately the motors I have are open source and the firmware is shared. While I only know the basics of Field Oriented Control (FOC), which is how these 3 phase brushless DC motors are controlled, the rest of the software is pretty easy to follow. The MCU is an STM32F446.

Existing I/O

There are 5 connectors on the controller board that are exposed through the side.

  • 24VDC In This is the primary motor power.
  • 5VDC in/out This can be used to power the board during programming. The 24VDC will create 5V on this if present.
  • CAN Interface
  • UART. This presents a menu that can be used to setup and calibrate the motor.
  • SWD. This is the programming interface.

I decided to use the UART connector. I would allow it to be optionally used as a UART for setup or for step and direction. I made an interface connection with some 1k resistors in line. This would save me if I screwed up. This would limit any current to a couple of milliamps. Any delays due to capacitance seem to be negligible. The UART still works fine at 921600 baud.

I can connect a UART to the input (left side) or a source of step and direction signals.

The RX and TX lines are changed to inputs. The step signal input will generate an interrupt. In the interrupt, the direction pin is check and the desired position is either incremented or decremented.

There is a defined constant called STEPS_PER_REV. This can be any reasonable value. The firmware works in radians, so that is converted to RADS_PER_STEP. Each step input alters the desired location by that amount.

Currently the CAN is also used to control the modes of the motor and it can also return the current motor position. That is a nice feature to allow a manual mode of a CNC machine and the motors will act as a DRO (Digital Read out) source. I plan to add a few extra can commands that allow the motor to default the proper modes at turn on.

My Test Rig

Here is a photo of my test rig. The motor needs a lot of weight to keep it from jumping around. Even with the weight of this 400 watt power supply it can do some serious jumps. I have the motor limited to 10A (40A is the max) to settle it down a little.

  • The ESP32 near the power plug is acting as a USB to CAN adapter. It goes through the skinny blue CAN PCB near the motor.
  • The red PCB is a 3.3V FTDI USB UART
  • The purple breadboard has the current limiting resistors.
  • The blue dongle in the middle is the programmer.
  • Not shown is another ESP32 running Grbl_ESP32 that generates step and direction signals. It plugs into the breadboard instead of the FTDI when in step/direction mode.

Next Steps

  • Right now there are two versions (by #define) of the firmware. One with the UART and one with the step and direction.
  • Do some accuracy testing
  • Release my firmware changes. It is a little messy right now and I am about to go on vacation, so I will probably wait about 2 weeks.
  • Build some sort of a machine with the motors. I might make a SCARA, so I only need 2 motors.


I am been keeps a few docs up to date on all my findings.

Dynamixel Servos in Grbl_ESP32

Dynamixel Servos

Dynamixel servos are a series of robot servos from Robotis. They are controlled using a daisy chained serial port with a 3 or 4 wire cable. Each servo has 2 connectors, so you can link one servo to the next.

The servos I used are XL430_250T. These use a 3 wire cable. (Power, Ground and Data). The data is a 5V TTL signal. This allows you to connect directly to a microcontroller’s UART in a half duplex setup. Half duplex means you send a command, give control of the data line to the servo and wait for a response. Each servo has a unique address. The basic specs of the XL430-250T are below.

  • Rotation: 360° (or continuous)
  • Resolution: 4096 count contactless absolute encoder
  • Torque: 1.5 n-m (212 oz-in)
  • Speed: 61 RPM max.
  • Voltage: 6.5V-12V
  • Price: $49 USD

ESP32 Half Duplex Mode

ESP32 has a basic half duplex mode. It still uses a separate TX and RX pin. It also requires a data direction pin. The direction pin goes high when you transmit and then goes low after all characters are sent. The servos are now free to use the data line.

Here is what that looks like. The second channel is the data pin on the servos. It has both TX and RX data. The last channel is the direction pin. You can see going high while the ESP32 is transmitting.

This requires some external hardware to combine the TX and RX lines. I used a 74LS241. This chip is a little overkill, but is cheap and easy to solder. It has tri-state drivers where half of them have an enable and the other have a not enable. This allows the direction pin to enable half of the gates and disable the other half. Here is what the circuit looks like.

The ESP32 has 3.3V I/O and the servos use 5V. The 74LS241 is OK with the 3.3V signal, but the 5V RX out of the 74LS241 needs to be dropped down to 3.3V. I used a simple voltage divider to do this. Here is a snippet of my schematic.

My Controller

Here is an image of the controller I designed. The capacitor on the ESP32 fixes the bootloader problem many ESP32 have.

  • ESP32 Dev Module Socket (extra connectors for testing)
  • 74LS241 This is the large IC to the right of the ESP32
  • Power Connector This is the main voltage for the servos.
  • Dynamixel Connector. White connector in the upper right.
    • Extra stuff (not needed for Dynamixels)
      • 5V DC-DC P/S. This is the circuit in the lower right.
      • (3) Hobby Servo connectors along the right edge
      • (3) High current MOSFETs for relays, solenoids, etc along the top edge.
      • (6) Switch inputs along the left edge.
      • I2C connector for a display at the top left.
      • SD Card under the ESP32

ESP32 UART Setup

Here is the code you need to setup the UART on the ESP32.

#include "driver/uart.h" 

#define DYNAMIXEL_TXD           GPIO_NUM_4
#define DYNAMIXEL_RXD           GPIO_NUM_13
#define DYNAMIXEL_RTS           GPIO_NUM_17
#define DXL_BUF_SIZE            127
#define DXL_BAUD_RATE           57600 // 57600 is the XL430 default
#define DXL_RESPONSE_WAIT_TICKS 20 // how long to wait for a response

 // setup the comm port as half duplex
uart_config_t uart_config = {
	.baud_rate = DXL_BAUD_RATE,
	.data_bits = UART_DATA_8_BITS,
	.stop_bits = UART_STOP_BITS_1,
	.rx_flow_ctrl_thresh = 122,

// Configure UART parameters    
uart_param_config(uart_num, &uart_config);
uart_driver_install(uart_num, DXL_BUF_SIZE * 2, 0, 0, NULL, 0);
uart_set_mode(uart_num, UART_MODE_RS485_HALF_DUPLEX);

ESP32 Communications

My servos use Robotis’ protocol 2. I won’t full go into the implementation here, but you can look at my code. The protocol uses a few header bytes, a servo address, some data and a CRC. The packet of byte is first sent. You need to wait for the servo to respond before you send another packet or the 2 sides might try to send at the same time.

With a real time motion controller, waiting cannot be done with basic delays. Fortunately the ESP32 uses an RTOS, so there is a way to safely wait for a specific length of data to be received. Here is some basic code on how to do that.

// transmit the packet
uart_write_bytes(uart_num, msg, msg_len);

// wait for expected number of characters
rx_length = uart_read_bytes(DYNAMIXEL_UART_PORT, 
			dxl_rx_message, resp_length, 

// validate the response length and process the response					
if (rx_length == 0) {
	// Error no response
} else if (rx_length != resp_length) {
	// Error wrong response length
} else {
	// process response

Grbl_ESP32 Integration

Grbl_ESP32 runs virtual (no I/O) stepper motors for a 3 axis machine. A 33Hz (rate adjustable) task is setup to sync the servo to those axes. Each time the task runs it sends a position target to the servos based on where the virtual axes are at that time.

If the virtual stepper motors are disabled, the servo torque is turned off. This allows the servos to be moved manually. Each time the task runs it will query the position of the servos and update Grbl_ESP32. The XYZ numbers on your GUI will update as the servos are moved. When the steppers are enabled, the servo torque is turned back on locking them into their current location.

Example Project

The Dynamixel integration was done for a delta project. Here is a video of that machine. The motion is quite smooth and reasonably accurate. The servos only use half of their travel. This means the resolution is 2048 counts and that is mapped over an work area of about 200mm x 200mm x 150mm

TO DO List

  • Wifi, Bluetooth Issues: Currently the servo communication uses the same core as the Wifi and Bluetooth. When I have either of those on, they interfere with the servos. I hope a little tweaking/tuning will fix this.
  • Better Grbl_ESP32 Integration. Allow you to easily select the use of Dynamixels servos for any axis via the cpu map file, like is done with steppers and PWM servos.
  • Smaller Chip. The 74LS241 is huge. I noticed the Dynamixel shield uses a tiny little NC7WZ241 chip that has the perfect number of gates.

#Inktober Project 2019 – Post 5


My Atari 1020 Pen Plotter retrofit project is done. My project for the month of October (#inktober) was to convert a 35 year old Atari 1020 to Grbl_ESP32 control. My goal was to not change, modify or add any parts other than the controller.

Atari 1020 Overview

The Atari 1020 is a tiny pen plotter. It is based on an ALPS mechanism. That same mechanism is used on several other plotters, including the Commodore 1520.

It plots on 115mm wide paper from a roll using 4 tiny ball point pens. It uses a pistol revolver type mechanism to change the pens. It sold for about $299 in the mid 1980’s

It connects to the host computer via an Atari SIO (Serial Input/Ouput) connector.

Grbl_ESP32 Advantages

  • Plot from standard Gcode
  • Standard USB/Serial port
  • WiFi
  • Bluetooth
  • Web Server with UI
  • Print from SD Card

I knew Grbl_ESP32 was far from being ready for this out of the box. This challenge would force me to learn a lot of new things and add new features to Grbl_ESP32. Here is a list of things I had to do.

  • Add unipolar stepper motor support
  • Add custom homing sequence support.
  • Add M6 tool (pen) changing support
  • Add solenoid support, with reversible voltage and current control
  • Add support for M30 (end of job) command.
  • Custom button functions

Unipolar Stepper Motors

Unipolar stepper motors are super low cost stepper motors. They often cost less than $1. Unlike the bipolar hybrid stepper motors we see in our 3D printers, these use 5 wires. The 5 wire setup creates 4 coils. All 4 coils have one end as common. These are typically controlled by putting the positive voltage on the common and using transistors on the other 4 wires to switch them to ground in a sequence. One a 4 wire motor, you need to be able to reverse the voltage through the coils at each step. The 5 wire method makes that a lot simpler. You cannot use the Pololu/StepStick style stepper motor drivers unless you cut the connection between coils that the common makes. That violates my goal of no changes.

The Atari 1020 has 2 of these motors. One moves the pen and the other moves the paper feed roller. I used a ULN2003 darlington transistor array for each stepper.

I added the option of using bipolar stepper motors to Grbl_ESP32. It is very simple to use. You just need to tell it to use the unipolar motor feature and define 4 I/O pins for each motor. This is the code you add to your machine definition.


#define X_UNIPOLAR  
#define X_PIN_PHASE_0   GPIO_NUM_13
#define X_PIN_PHASE_1   GPIO_NUM_21
#define X_PIN_PHASE_2   GPIO_NUM_16
#define X_PIN_PHASE_3   GPIO_NUM_22     

#define Y_UNIPOLAR
#define Y_PIN_PHASE_0   GPIO_NUM_25
#define Y_PIN_PHASE_1   GPIO_NUM_27
#define Y_PIN_PHASE_2   GPIO_NUM_26
#define Y_PIN_PHASE_3   GPIO_NUM_32

This definition method allows you to mix unipolar, bipolar and servos on the same machine.

The unipolar feature supports full and half step mode. Half step is the mode I used. This new feature could spawn a bunch of super low cost machines.

Custom Homing Sequence

Normally, when you home an axis in Grbl_ESP32, the axis moves until it detects a limit or home switch. There is no home switch on the Atari 1020. It also also needs to also find pen number 1 during the homing operation.

To do this I added optional custom homing routines to Grbl_ESP32. You add a #define USE_CUSTOM_HOMING to your machine definition. That tells Grbl_ESP32 to skip the normal homing and run a function called void user_defined_homing(). That is a function that is written for the machine.

In the case of the Atari 1020, that function starts a state machine in an RTOS task. That task sort of works like a little gcode sender that takes control of the machine until the homing is complete. There is more on that here.

The feature could be used on any machine that cannot use regular homing or needs to make sure the machine is ready to be homed, etc.

Tool (Pen) Changing

Previously, Grbl_ESP32 only tracked the tool number and ignored the M6 command. Now if you #define USE_TOOL_CHANGE, you add a function void user_tool_change(uint8_t new_tool). Here you would place all the code you need to do a tool change.

On the Atari 1020, it just needs to bump the left side of travel 3 times per pen. If you have pen 1 and need to get pen 3, it bumps the left 6 times.

Solenoid Support

The Atari 1020 uses a solenoid coil and a magnet to control pen up/down movement. If you energize the coil one way, it attracts the magnet and places the current pen on the paper. If you reverse the voltage, it repels the magnet and pulls the pen away from the paper.

I was afraid the coil would get hot, so I wanted to use a PWM to lower the duty after 1 second. It did my testing using a Pololu DRV8838 motor driver. To speed up prototyping, I just plugged that into my controller.

In the image below, the solenoid is where the motor is.

M30 Support

I wanted the pen carriage to return to the right end of travel at the end of each job. There are 2 reasons for this. That is where the pens are removed. The second reason has to do with how the homing works. There is no limit switch, so you have to crash into the left end. If you are close to the left end at the start of the home, the steppers will still try to drive it for a while after it hits the end. The closer you are to the right end when you start, the less step skipping there will be.

Unfortunately, many gcode files don’t have an end of file marker. There is an M30 command for this, but Grbl previously didn’t do anything with it. I added support for custom handling of the M30 command. If you #define USER_M30, you can add a void user_m30() function. For this project, I have it move the carriage to the right.

Button Support

Recently, custom button support was added to Grbl_ESP32. This is a simple way to fire a custom function when a button is pushed. The 1020 has 4 buttons.

The first button is simply a latching power button. I used that the same way. It breaks the incoming 5V.

The next button is labeled “PEN”. I made that a homing button. Normally the 1020 homes at power on, but I wanted a button to do it. That will allow me to home the machine before each job. That will be an easy way to reset the Y axis zero as the paper is ejected after each job.

The next button is labeled “COLOR”. I use that button to change to the next pen and move under the pen eject lever. Normally software controls the pens. This will be an easy way to unload the pens.

The last button is labeled “PAPER”. I use this button to feed out 25mm paper. You push this a few times to the point where you want to tear it off.

The Controller

A controller was designed as a direct, drop in replacement for the original controller. Here is a picture of the before and after.

It is very simple with very few parts. It has the ESP32, the (2) single chip transistor arrays and the Pololu motor (solenoid) driver. The rest of the parts are just connectors and capacitors. I use an external 5VDC power supply, so no additional power handling is needed.

The source files for that controller board are on this Github repo.


The original unit did not come with a power supply, but I think it was a 9VAC wall wart. It was rectified and feed two 5V linear regulators on a giant heatsink. One feed the solenoid and the other did everything else.

I used a 5VDC 2A wall wart. The current appears to peak at about 1.50A,

The Firmware

The firmware is currently a branch called unipolar. The changes will be merged to the master branch soon. If you don’t see the unipolar branch when you read this post, it has probably been merged into master.

GCode Generation

The machine will now run standard gcode that isw compatible with Grbl. I used Carbide Create, because it supports tool numbers. It also adds an M30 to the end.

I created tools with tool numbers 1 through 4. I create a separate tool path for each color with the appropriate tool number. If your CAM program does not support tool numbers, you need to insert M6 Tx to change pens. M6 T2 would change to tool (pen) number 2.

  • Tool 1 = Black
  • Tool 2 = Red
  • Tool 3 = Green
  • Tool 4 = Blue

Pens and Paper Sources

eBay has the pens, but they are quite pricey. I found some cheaper ($6) set s here. Search for “Atari 1020 Color Plotter color pen set” on that page.

I bought the paper rolls on eBay. They were expensive at $18 for (2) rolls, but they fit perfectly and came with an axle. The axle could be a simple rod 6mm dia. x 130mm long. The paper is 115mm (4.5″) wide. I don’t know the length, but the roll is about 50mm in diameter.

Final Thoughts

As I was building this a few thoughts of other ways to do things occured to me….

A single ULN2803 (8 transistors) could have been used instead of two ULN2003 (7 transistors).

It would have been fun to try to make an adapter so the ESP32 plugs right into the existing controller socket. It would use all the existing electronics to driver the motors, etc. That would have taken a lot more reverse engineering, but I am sure I would have learned a lot.

The actual plotter mechanism is really small. It only represents about 1/8 of the volume of the 1020. I could have made a much smaller controller bolted to the bottom of it and 3D printed a case. It would have made a really tiny printer.

I would LOVE to do this on another pen plotter, seismograph, etc. The older and more obscure, the better. So, please send any leads or ideas my way.

#Inktober Project 2019 – Post 4


I intend to replace the stock controller board with an Grbl_ESP32 version. Here is an picture of the existing controller.

Power Input

The power input to my board will be 5VDC. I will not need any power conversion on my PCB, because everything runs off 5V. Measurements suggest I will only need about 2A.

Stepper motors

The stepper motors are unipolar 5 wire motors. I have been testing with a ULN2003 (darlington array) board I got with some motors a while ago.

This worked fine, so I will be using the SMT version of the IC in my controller.

Pen Up/Down Solenoid Driver

A solenoid coil is used with a small magnet mounted to a bar that controls the position of the currently selected pen. Sending the current one way attracts the magnet and sending the current the other way repels it. That controls the up/down state of the pen. I thought a simple DC motor driver would be a good way to control it.

The solenoid runs at 5V and draws about 0.8A of current. I found a nice little motor driver at Pololu that works great. I use one pin to set the direction and the other is used for PWM. I can do an initial full current pull on the solenoid, then switch to a much lower hold current. This prevents overheating of the solenoid.

I decided it was easiest to just put a socket on my controller for the Pololu board, since I already bought a few of them for testing.

SD Card

One of my favorite features of Grbl_ESP32 is the SD card support. That, paired with the WebUI (Web User Interface) is a great way to run gcode. You can upload gcode via WiFi and simply click “play” in the WebUI.

I put a micro SD socket on the board that is accessible though one of the connector holes in the back of the chassis.


The standard USB serial connection of Grbl_ESP32 will also be accessible through one of the connector holes in the chassis

ESP32 Controller PCB

The design is done. I just need to order some. China is on a national holiday, so that will add a few days to the delivery. Here is a screen shot of the design.

The PCB is way bigger than it needs to be. I wanted it to use the same mounting holes, have the same connector locations.

Here is a link to the schematic.

Inktober Project 2019 – Post 3

Setbacks and Homing Issues

Status Update

Read Post #1 and Post #2 here

I have a breadboard version of the controller running. So far, it can control the motion of the pen, feed roller and check the homing (reed switch).

Broken Gears.

I noticed a little clicking sound and rough motion when running the motors. Looking carefully, I could see that the gears on the motor shafts were both cracked.

After searching around, I found that this is a common problem. The gear is pressed on and 35 years of stress probably cracked it. Fortunately someone sells them via Shapeways On Demand printing service.


At startup, the machine needs to home the X axis and locate pen #1. It does this in a clever way, so that it does not require any motors or sensors on the pen carriage.

The pen carriage has a little bar magnet. This will only trigger the reed switch in one orientation of the rotating pen carriage. Each time the carriage goes to the left end a little metal tab pushes the carriage 12th of a rotation.

As far as I can tell, on the first move, it moves to the left the full width of the X travel. If the carriage started in the middle of travel, the motor just stalls for the rest of the move. It then checks the reed switch. If the switch is not activated, it backs off to the right, comes back, rotating the carriage another 12th turn. It checks the switch and repeats the sequence until the magnet is detected.

Here is a video of that.

Grbl Homing

A standard Grbl homing sequence is not going to work. It will go to the end, not see the switch and fail. I will need to program this multi-move, check, repeat sequence into Grbl.

#Inktober 2019 Project – Post 2

Reverse Engineering the Atari 1020

The field service manual is quite helpful, but the pin numbers of the connectors are not labeled and there are no part number.

Between the manual and some measurements with my meter, I think I have it figured out.

Power Supply.

I do not have the original external (wall wart) power supply. You can tell it is AC from the schematic. I did some research and found out it is 9VAC. That goes through (2) 5V volt linear regulators (with a huge heatsink). One powers the stepper motors and all the logic. The other powers the pen up/down solenoid.

Basically, I should be able to power everything with a robust 5VDC power supply. I’ll probably use this style.

Switch Panel

This connects via a 6 pin molex SPOX 10013066 connector. The PCB side is Molex p/n 10321061. The power switch is a latching switch that connects the incoming 9VAC voltage.

The function switches are normally open, momentary switches that close to ground.

Here is the pinout of that cable.

Pin #DescriptionWire color
2Pen Change SwBlue
3Paper Feed SwPink
4pen Change SwYellow
5Power (in)Red
6Power (out)Red

Pen Solenoid

Then pen moves to and away from the paper using a solenoid. The schematic is amazingly complex here, but basically the voltage flows one way through it for pen up and the for pen down. It is a 5V coil with a resistance of 5.2 Ohm.

Stepper motors

There are (2) stepper motors. One is for the paper feed and the other moves the pen carriage. These motors are 5 wire unipolar motors. These are typically used by connecting the common to voltage+ and the other wires to transistors. If sequenced on one at a time, you get 4 independent coils.

The coil resistance of the paper feed stepper coils is 50 Ohm and the carriage is 60 Ohm.

Pen Change, Homing switch

There is a reed switch activated by a magnet in the pen carriage.

Printer Mechanism Cable

There is a 13 pin cable that connects everything in the plotter mechanism to the controller PCB. This uses a Molex connector p/n 511911300. The mate on the PCB is Molex p/n 22041131. The pinout is here.

Pin #DescriptionColor
1Reed SwBlack
2Reed SwOrange
3Carriage Stepper #1White/Red
4Carriage Stepper #2Pink
5Carriage Stepper #3Blue
6Carriage Stepper #4Red
8Feed Stepper #1Purple
9Feed Stepper #2White/Blue
10Feed Stepper #3Yellow
11Feed Stepper #4Brown
12Pen SolenoidGray
13Pen SolenoidLight Blue

#Inktober 2019 Project – Post 1

#Inktober is a hashtag I have seen popping up over the past few years. Inktober was apparently started in 2009 to encourage people to do an ink drawing everyday in October. The #plottertwitter generative art community has joined in recently.

I am not much of a hand drawing person or even a generative art person, but I do like to make drawing machines. I decided to use Inktober to work on a new plotter. I am getting a little head start, so I can actually do some plotting in October.

Atari 1020

I decided to try to convert an old Atari 1020 plotter to use Grbl_ESP32 as the controller. It would give the plotter Bluetooth and Wifi support and use gcode to plot. I could talk to the existing controller via the Atari 1020 serial protocol or I could completely replace the controller with the ESP32.

I decided it would be more fun, challenging and great opportunity to learn some things by replacing the controller. I set the following goals.

  • Do no harm. I want to avoid damaging any parts. Cut no plastic and cut no wires.
  • Change only the controller. I will use the existing, unmodified switches, stepper motors, etc.
  • Clean implementation. Try to make it look original. Use the existing mounting holes. Use existing holes for connectors, etc.

About the Atari 1020

The Atari 1020 was sold in the early to mid 1980’s. It was designed by ALPS Electric. It uses the same ALPS DPG1302 mechanism as the Commodore 1520, Tandy CGP-115, Sharp CE-150, Atari 1020, Mattel Aquarius 4615 and Texas Instruments HX-1000

Useful Links

MPCNC Grbl_ESP32 Controller

Thank you to all the people who gave me feedback. The design of the prototype is done and is on order. Here are the choices I made in the design

ESP32 Controller

The board will use the 2×19 pin style controllers. It will support the (2) common pin widths of 0.9″ and 1.0″.

Power Input

The voltage range is 12VDC to 24VDC. The power input will be via a (2) pin, 5mm pitch, screw terminal block. I decide to not use a barrel jack or Molex style connector, because these are primarily 12V types and many people will choose to use 24V.

Stepper Motor Drivers

I decided to support simple Pololu/StepStick style plug-in modules. I decided to not support SPI controlled versions like the TMC2130. These required significantly more I/O. I did not want to add external I/O expanders.

There are 5 stepper motor driver sockets. (2) each for X and Y and (1) for the Z. The (2) X drivers have separate step control pins, so the firmware can perform a squaring function at the time you home the machine. The same is true for the Y axis. This is optional, these axes can also be ganged together. All motors wire the same. The controller takes can of reversing the direction of the second motor and X and Y

Limit Switches

There are (2) connectors for limit switches on the X and Y axes. (2) switches are required for the squaring function. These switches are wired in parallel and use a single I/O pin. The extra connector is just for ease of wiring. If you like you can wire them in parallel off the controller. Limit switches can also be added at the other ends of travel if you like. All switches must be normally open (close when limit is reached)

Squaring uses the motors to pull the gantries square with the rest of the machine. Squaring is performed when the machine is homed. The axis moves towards the lower end of travel with both motors until it hits either switch. It then backs off the switch. It does not know which switch hit because they are wired to the same I/O pin, so it now homes each side independently. The location of the switches sets the squareness. As long as the motors stay energized, it will stay square.

Spindle / Laser

The basic spindle feature is a relay to turn on and off AC and DC spindles. It can handle 120VAC – 240VAC 10A and up to 30VDC at 10A.

There is also a 5V PWM function than can be used for laser power control and PWM controlled variable speed spindles. There is a safety interlock for this which would typically be used by a laser. (2)s pin need to be connected together, typically through a switch in order for the device to be connected to the PWM signal.

Control Switches

Grbl has the ability to do a nearly immediate feedhold without loss of position. It will decelerate the machine as soon as you click the button, even in the middle of a gcode command and if the buffer is full of moves. You can then click start to resume the job. If you want to cancel the job without any loss of position, you click the Grbl Reset button. This clears out any remaining things in the buffer.

All these functions are available of the serial, WiFi, etc, but sometimes it is nice to have a dedicated button when you need a quick stop.

5V Fan Power Output

There is a (2) pin header connector that can be used to add a cooling fan. A fan can allow the steppers to output more current and should also be used if the controller is mounted in an enclosure.

Project Status

The boards are on order. I expected to have testing and firmware changes done by the end of the month (March 2019). I will sell a few prototypes on Tindie, while working on getting a larger quantity built.

I will release all my source files as soon as testing is complete and the design is verified. Here is the current schematic.


  • Can this be used as a (5) axis controller? No, the extra X and Y axis stepper drivers use the same direction pin as their paired motor. They have separate step pins. Note: Grbl_ESP can be extended more axes, but not with this controller.

MPCNC ESP32 Controller Ideas

I have been thinking about designing a custom Grbl_ESP32 controller for the MPCNC (Mostly Printed CNC ) machine. The MPCNC is a simple and low cost CNC machine. The MPCNC is primarily used as a router, but many people often use it for laser cutting and engraving. A custom controller would address the design features of the MPCNC, make it very easy to hook up and the ESP32 would add Wifi, Bluetooth and higher speeds.

The goal would be to create a low cost, open source controller. It would directly address the needs of the MPCNC, but avoid expensive additional add-ons.


It will use the low cost plug in ESP32 development modules. It will support the 2×19 pin types only, with both 0.9″ wide and 1.00″ wide types supported.

Power Input

I think most people would use 12V, but I’ll size the parts so 24V can also be used. I think a 2 position 5mm terminal block is best. It can handle higher currents than a DC barrel connector.

There will be a small 5V 3A DC-DC power supply on the controller. This will power the MCU when not connected via USB. It will also power a few other things. You will be able to communicate with the MCU via USB power, but most other stuff on the board will not work without the primary 12V power.


  • USB: This will use the micro USB connection on the ESP32 module. In this mode you can use just about any gcode sender that supports Grbl
  • WiFi: You can stream gcode over Telnet. You can also use the WebUI to control the machine, upload to the SD card, run and monitor jobs.
  • Bluetooth Serial: This is a Bluetooth mode that presents itself as a serial port on connected devices. There are a lot of senders that support this.
  • SD Card: Running jobs from an SD card is my favorite feature of Grbl_ESP32. When used with the WebUI, you can’t beat it. Also, we may be adding web browser “plugins” that would load pages from the SD card. This could be gcode visualizes and gcode generators.

Stepper Motor Drivers

The MPCNC uses (2) stepper motors each for the X and Y and (1) motor for the Z, for a total of (5) stepper motors. Ganging (2) motors for an axis can be done with (1) driver or (2) drivers. It think it is probably best to use (2) drivers each for the X and Y axes.

I think it is best to use the standard Pololu footprint drivers to simplify things and lower cost, I would hardwire all microstep selection pins to the highest setting. The Grbl_ESP32 can still run crazy fast at high resolutions. I don’t think it is worth supporting drivers with firmware control of current, microstepping and other features. The firmware does not yet support these anyway.

Spindle / Laser Control

I think most people use an AC router for these machines. That means an on board relay is probably the best way to control that. I will also provide a 5v PWM signal on a header connector, for those who want to try controlling the speed.

The laser will also use the PWM for power control. I am worried about people accidentally PWM’ing the relay circuit, so I will use separate I/O pins for the relay and the PWM. That would also allow the relay to be used for other functions when using PWM.

I/O Inputs

  • Limit Switches: X, Y and Z limits switches. These can be used as simple homing switches. The firmware also supports putting both max and min limit switches on each axis.
  • Control Switches: Feedhold, Cycle Start and Grbl Reset (end job, without position loss).
  • Touch Probe: This can be used to zero your bit on the work.

All input pins will have low pass filters on them to improve noise immunity. Optocouplers have been considered, but are probably overkill and technically require an extra, isolated power supply.

Update: In the comments, Drew mentions auto-squaring would be a big improvement for the MPCNC. Is it worth giving up an spare I/O (requires 2 extra pins)

Extra I/O

There will probably be a few extra I/O pins. These will be brought out to a header connector and can be used to add your own features.

Mounting / Enclosure

I am not quite sure about the shape and mounting right now. It will probably be rectangular due to (5) drivers along one edge. I’ll put mounting holes in the corners. I’ll add a connector for a small fan. You probably only need the fan if an enclosure is used. I would love some feedback here.

Question #1: What is more important, small size or detailed, easy to read labeling of the pins?

Probably Not Included

  • Local Display (LCD, OLED, etc.): Local displays have been avoided on the Grbl_ESP32 project. The connectivity options eliminate the need for this. A smartphone is a much better interface that allows you to get status, control jobs, upload jobs, act as a pendant, etc.
  • Vacuum, Coolant Relays: These are expensive and take up a lot of board space. There are a few extra I/O pins that will be brought out to connector if you want to add these features.


Please add comments if you think I should change anything or consider some other features.

Update: 3/4/2019

A schematic and layout are now done. I probably wait to order it, so it arrives about the same time I get back from a vacation 3/18/2019.