Skip to content

Setting Up the I O Pins

Lê Chí Tuyền edited this page Nov 29, 2023 · 22 revisions

Setting Up the I/O Pins

ESP32 is a powerful processor, but it does not have a lot of I/O pins. There are enough pins to make a wide variety of useful CNC machines, but for any given machine, the assignment of pins to features must be chosen carefully. Some pins are preassigned to specfic functions like the serial port and SD card. A few of the pins can only be used for input, and still others have special meaning during startup; they can often be used for other purposes later, but you must take into account their special startup characteristics. Misusing a special pin could result in damage to the ESP32 or in unsafe machine operation. The next section details the special considerations.

Most I/O setup is done in a machine definition file. There are many such files, for shields that you can purchase, in the Machines/ subdirectory. The Machine.h file selects a machine definition file via a #include statement. You can use a predefined machine definition file or make your own. The primary purpose of a machine definition file is to assign ESP32 I/O pins to functions like stepper control, spindle control, limit switches, and the like, but it can also, optionally, configure many other things, for example default feedrates. This page tells how to make your own machine definition file, with emphasis on the pin assignments.

Note: All ESP32 I/O pins are 3.3V, not 5V tolerant, and the current capability is rather low. They cannot directly drive relays, solenoids, etc. In some cases they can directly drive optocouplers for external stepper drivers, but it is usually best to buffer them with an external chip or transistor. They can directly drive the control pins on "Pololu module" stepper drivers. You must not feed any 5V signals into an ESP32 input - limit switches and the like must use 3.3V signaling.

Usable I/O pins

Input Only (no pullup/pulldown)

If you do not have external pull up or pull down resistors. Do not use these pins!

  • GPIO_NUM_34
  • GPIO_NUM_35
  • GPIO_NUM_36
  • GPIO_NUM_37 (not typically available)
  • GPIO_NUM_38 (not typically available)
  • GPIO_NUM_39

Don't Use (or not recommended)

  • GPIO_NUM_0 - This is used for the bootloader
  • GPIO_NUM_1 - Used for Serial Data
  • GPIO_NUM_3 - Used for Serial Data
  • GPIO_NUM_6 - Use for External Flash
  • GPIO_NUM_7 - Use for External Flash
  • GPIO_NUM_8 - Use for External Flash
  • GPIO_NUM_9 - Use for External Flash
  • GPIO_NUM_10 - Use for External Flash
  • GPIO_NUM_11 - Use for External Flash
  • GPIO_NUM_20 - This is not available on ESP32s
  • GPIO_NUM_24 - This is not available on ESP32s
  • GPIO_NUM_28 - This is not available on ESP32s
  • GPIO_NUM_29 - This is not available on ESP32s
  • GPIO_NUM_30 - This is not available on ESP32s
  • GPIO_NUM_31 - This is not available on ESP32s

Making Your Machine Definition File.

If none of the predefined machine definition files in the Machines/ subdirectory is suitable for your machine, you can make your own. You could start from scratch, but it is probably easier to copy an existing file that is similar and edit it to reflect your changes. Choose a new filename that identifies your machine. The various predefined files can serve as examples for how to handle various situations like additional axes (Machines/foo_6axis.h), external stepper drivers (Machines/external_driver_4x.h), Triaminic SPI drivers (spi_daisy_4axis.h), etc.

Having created a new machine definition file, you can use it by putting a line like this in machine.h:

#include "Machines/my_machine.h"

Optional Features affecting I/O Pins

SD Card

The SD card uses 4 GPIO pins. They are currently only supported on the pins listed above. You can free up all these pins by commenting out #define ENABLE_SD_CARD in config.h (this is an example of a configuration choice that is not controlled by the machine definition file).

Coolant

Flood and Mist control are output signals that can be used to drive a relay circuit via a suitable external driver circuit on the shield. To use them, include lines like this in your machine definition file to choose the assigned pins.

#define COOLANT_MIST_PIN GPIO_NUM_21

#define COOLANT_FLOOD_PIN GPIO_NUM_25

You can define either pin, or both, or neither. If one of the pins is not defined, trying to use the corresponding feature will result in an invalid gcode error.

Spindle

To control a spindle, assign pins like this:

#define SPINDLE_OUTPUT_PIN GPIO_NUM_25

#define SPINDLE_ENABLE_PIN GPIO_NUM_22

#define SPINDLE_DIR_PIN GPIO_NUM_18

The most important one is SPINDLE_OUTPUT_PIN. If it is not defined, Grbl_ESP32 will still behave like it has a spindle, but will not output a spindle signal. This can help with machines like pen plotters that don't use a spindle.

Spindle Enable and direction are typically not used on most machines, but can be enabled by assigning them a pin. If SPINDLE_DIR_PIN is not defined, the M4 command is not supported (except that, when Grbl is set for laser mode, M4 does not mean spindle direction, but rather motion-dependent laser power).

All spindles are variable speed. If you use an on/off spindle, just set the $30 max RPM setting to 1. That will mean any RPM will be full on.

Number of Axes

By default, Grbl_ESP32 is set up for 3 axes, X, Y and Z. You can configure for more axes, up to 6, like this:

#ifdef N_AXIS

#undef N_AXIS

#endif

#define N_AXIS 5

If your machine has fewer than 3 axes, do not set N_AXIS, but instead leave it alone, to default to 3 axes, and do not define pins (see below) for the unused axes. Grbl will simply ignore (not output signals for) motions on axes that do not have pins.

Step and Direction Pins

Step and direction pins for stepper motors are assigned with lines like:

#define X_STEP_PIN GPIO_NUM_26

#define X_DIRECTION_PIN GPIO_NUM_16

#define Y_STEP_PIN GPIO_NUM_25

#define Y_DIRECTION_PIN GPIO_NUM_27

#define Z_STEP_PIN GPIO_NUM_17

#define Z_DIRECTION_PIN GPIO_NUM_14

You can free up pins for other uses by defining pins only for the axes that your machine actually uses. For any of the axes X, Y and Z where pins are not defined, Grbl will still accept GCode that refers to those axes, but will not output the signals. This could be used, for example, for hobby servo driven axes.

Ganged Axes & Axis Squaring

Many CNC machines use dual motors on one or more axes. For example, a gantry machine often has a separate motor on each side of the moving gantry, the two motors normally moving in unison. In some cases you can gang these in hardware, so a single step/direction pin pair controls both motors at once. In other cases you might want to control the motors separately to square the axis during homing.

Squaring uses the motors and homing switches to separately home each motor. To reduce the number of I/O pins needed, there is a special trick. Each axis uses two step pins, but only one home switch pin and one direction pin. Each motor has its own home switch switch, but they are wired to the same I/O pin. The homing sequence drives both motors towards the switches. As soon as one switch is touched, each motor homes separately. As long as the switches are square, the axis should now be square. The $1 setting (step idle delay) should be set to 255 to prevent the motors from turning off, thus preserving the squareness held by the motors. If the motors turn off, residual stress in the mechanical system could cause the axis to "relax" out of square.

See Machines/mpcnc.h as an example of a ganged setup.

Clone this wiki locally