ESP32-Based Grbl CNC Control Board

EstlCAM

Last time I checked, that requires proprietary firmware running on an Arduino.

Yep. Estlcam can not directly control any of our boards anymore. It can still create gcode which can be used on any of the Marlin or grbl boards.

1 Like

I love this controller. However, I have not been able to get it to work correctly. The best I’ve done is to get three steppers to work, but the extra X and Y steppers won’t turn their steppers. I’m certain this is a software problem and I just need to select the correct options in the CONFIG.h file. What did you all do to get this to work?

Turns out it was a small problem on the board. A little solder fixed right up. Thanks Bart!

 

hi, i am trying to build @Bart Dring’s Grbl ported Esp32 CNC . i installed the firmware but cannot turn off the DEMO mode. Anybody please guide me . Also can this firmware be used for 4 axis CNCmill with fewer modification ?

In the config.h, you set the board type.

#define CPU_MAP_MPCNC

Set it at the bottom of the config.h here:

That will set all of this:

I was just going through this a few days ago. Instructions are here: https://github.com/bdring/Grbl_Esp32/wiki/Compiling-the-firmware

Sorry to future readers, these links will probably end up out of date.

1 Like

Been following this thread, very helpful.

I’ve run into a similar problem-I’m not able to upload to my ESP-32s if I enable the CPU_MAP_LOWRIDER. I can upload using CPU_MAP_ESP32 but I’m trying to take advantage of ganged y-axes and the autosquare function.

I’ve set CPU_MAP_LOWRIDER at the bottom of the config.h.

// Paste CPU_MAP definitions here.
#define CPU_MAP_LOWRIDER

// Paste default settings definitions here.

  // This is the CPU Map for the Buildlog.net MPCNC controller
  // used in lowrider mode. Low rider has (2) Y and Z and one X motor
  // These will not match the silkscreen or schematic descriptions  
    #define CPU_MAP_NAME "CPU_MAP_LOWRIDER"
  
  
    #define USE_GANGED_AXES // allow two motors on an axis 
    
    #define X_STEP_PIN      GPIO_NUM_27     // use Z labeled connector
    #define X_DIRECTION_PIN   GPIO_NUM_33   // use Z labeled connector
    
    #define Y_STEP_PIN      GPIO_NUM_14
    #define Y_STEP_B_PIN    GPIO_NUM_21   // ganged motor
    #define Y_DIRECTION_PIN   GPIO_NUM_25 
    #define Y_AXIS_SQUARING
    
    #define Z_STEP_PIN      GPIO_NUM_12   // use X labeled connector
    #define Z_STEP_B_PIN    GPIO_NUM_22   // use X labeled connector
    #define Z_DIRECTION_PIN   GPIO_NUM_26   // use X labeled connector
    #define Z_AXIS_SQUARING
    
    #define X_LIMIT_PIN       GPIO_NUM_15  
    #define Y_LIMIT_PIN       GPIO_NUM_4  
    #define Z_LIMIT_PIN       GPIO_NUM_2  
    #define LIMIT_MASK        B111
    
    // OK to comment out to use pin for other features
    #define STEPPERS_DISABLE_PIN GPIO_NUM_13    
    
        
    // Note: if you use PWM rather than relay, you could map GPIO_NUM_17 to mist or flood 
    #define USE_SPINDLE_RELAY
    
    #ifdef USE_SPINDLE_RELAY    
      #define SPINDLE_PWM_PIN    GPIO_NUM_17
    #else
      #define SPINDLE_PWM_PIN    GPIO_NUM_16
      #define SPINDLE_ENABLE_PIN  GPIO_NUM_32
    #endif
    
    #define SPINDLE_PWM_CHANNEL 0
    // PWM Generator is based on 80,000,000 Hz counter
    // Therefor the freq determines the resolution
    // 80,000,000 / freq = max resolution
    // For 5000 that is 80,000,000 / 5000 = 16000 
    // round down to nearest bit count for SPINDLE_PWM_MAX_VALUE = 13bits (8192)
    #define SPINDLE_PWM_BASE_FREQ 5000 // Hz
    #define SPINDLE_PWM_BIT_PRECISION 8   // be sure to match this with SPINDLE_PWM_MAX_VALUE
    #define SPINDLE_PWM_OFF_VALUE     0
    #define SPINDLE_PWM_MAX_VALUE     255 // (2^SPINDLE_PWM_BIT_PRECISION)
    
    #ifndef SPINDLE_PWM_MIN_VALUE
        #define SPINDLE_PWM_MIN_VALUE   1   // Must be greater than zero.
    #endif
    
    #define SPINDLE_PWM_RANGE         (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)   
    
    // Note: Only uncomment this if USE_SPINDLE_RELAY is commented out.
    // Relay can be used for Spindle or Coolant
    //#define COOLANT_FLOOD_PIN   GPIO_NUM_17
    #define PROBE_PIN         GPIO_NUM_35  
    
    // The default value in config.h is wrong for this controller
    #ifdef INVERT_CONTROL_PIN_MASK
      #undef INVERT_CONTROL_PIN_MASK      
    #endif
    
    #define INVERT_CONTROL_PIN_MASK   B1110

    // Note: check the #define IGNORE_CONTROL_PINS is the way you want in config.h
    #define CONTROL_RESET_PIN         GPIO_NUM_34  // needs external pullup
    #define CONTROL_FEED_HOLD_PIN     GPIO_NUM_36  // needs external pullup 
    #define CONTROL_CYCLE_START_PIN   GPIO_NUM_39  // needs external pullup

During compiling I get many errors about not finding “Defaults”. These all have to do with the defaults.h file. Compiling is successful when using just CPU_MAP_ESP32. What could be the problem? Thanks.

sketch\settings.cpp: In function 'void settings_restore(uint8_t)':

settings.cpp:63:35: error: 'DEFAULT_STEP_PULSE_MICROSECONDS' was not declared in this scope

     settings.pulse_microseconds = DEFAULT_STEP_PULSE_MICROSECONDS;

                                   ^

settings.cpp:64:39: error: 'DEFAULT_STEPPER_IDLE_LOCK_TIME' was not declared in this scope

     settings.stepper_idle_lock_time = DEFAULT_STEPPER_IDLE_LOCK_TIME;

                                       ^

settings.cpp:65:33: error: 'DEFAULT_STEPPING_INVERT_MASK' was not declared in this scope

     settings.step_invert_mask = DEFAULT_STEPPING_INVERT_MASK;

                                 ^

settings.cpp:66:32: error: 'DEFAULT_DIRECTION_INVERT_MASK' was not declared in this scope

     settings.dir_invert_mask = DEFAULT_DIRECTION_INVERT_MASK;

                                ^

settings.cpp:67:35: error: 'DEFAULT_STATUS_REPORT_MASK' was not declared in this scope

     settings.status_report_mask = DEFAULT_STATUS_REPORT_MASK;

                                   ^

settings.cpp:68:35: error: 'DEFAULT_JUNCTION_DEVIATION' was not declared in this scope

     settings.junction_deviation = DEFAULT_JUNCTION_DEVIATION;

                                   ^

settings.cpp:70:30: error: 'DEFAULT_ARC_TOLERANCE' was not declared in this scope

     settings.arc_tolerance = DEFAULT_ARC_TOLERANCE;

                              ^

settings.cpp:72:24: error: 'DEFAULT_SPINDLE_RPM_MAX' was not declared in this scope

     settings.rpm_max = DEFAULT_SPINDLE_RPM_MAX;

                        ^

settings.cpp:73:24: error: 'DEFAULT_SPINDLE_RPM_MIN' was not declared in this scope

     settings.rpm_min = DEFAULT_SPINDLE_RPM_MIN;

                        ^

settings.cpp:75:32: error: 'DEFAULT_HOMING_DIR_MASK' was not declared in this scope

     settings.homing_dir_mask = DEFAULT_HOMING_DIR_MASK;

                                ^

settings.cpp:76:33: error: 'DEFAULT_HOMING_FEED_RATE' was not declared in this scope

     settings.homing_feed_rate = DEFAULT_HOMING_FEED_RATE;

                                 ^

settings.cpp:77:33: error: 'DEFAULT_HOMING_SEEK_RATE' was not declared in this scope

     settings.homing_seek_rate = DEFAULT_HOMING_SEEK_RATE;

                                 ^

settings.cpp:78:38: error: 'DEFAULT_HOMING_DEBOUNCE_DELAY' was not declared in this scope

     settings.homing_debounce_delay = DEFAULT_HOMING_DEBOUNCE_DELAY;

                                      ^

settings.cpp:79:31: error: 'DEFAULT_HOMING_PULLOFF' was not declared in this scope

     settings.homing_pulloff = DEFAULT_HOMING_PULLOFF;

                               ^

settings.cpp:82:9: error: 'DEFAULT_REPORT_INCHES' was not declared in this scope

     if (DEFAULT_REPORT_INCHES) { settings.flags |= BITFLAG_REPORT_INCHES; }

         ^

settings.cpp:83:9: error: 'DEFAULT_LASER_MODE' was not declared in this scope

     if (DEFAULT_LASER_MODE) { settings.flags |= BITFLAG_LASER_MODE; }

         ^

settings.cpp:84:9: error: 'DEFAULT_INVERT_ST_ENABLE' was not declared in this scope

     if (DEFAULT_INVERT_ST_ENABLE) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; }

         ^

settings.cpp:85:9: error: 'DEFAULT_HARD_LIMIT_ENABLE' was not declared in this scope

     if (DEFAULT_HARD_LIMIT_ENABLE) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; }

         ^

settings.cpp:86:9: error: 'DEFAULT_HOMING_ENABLE' was not declared in this scope

     if (DEFAULT_HOMING_ENABLE) { settings.flags |= BITFLAG_HOMING_ENABLE; }

         ^

settings.cpp:87:9: error: 'DEFAULT_SOFT_LIMIT_ENABLE' was not declared in this scope

     if (DEFAULT_SOFT_LIMIT_ENABLE) { settings.flags |= BITFLAG_SOFT_LIMIT_ENABLE; }

         ^

settings.cpp:88:9: error: 'DEFAULT_INVERT_LIMIT_PINS' was not declared in this scope

     if (DEFAULT_INVERT_LIMIT_PINS) { settings.flags |= BITFLAG_INVERT_LIMIT_PINS; }

         ^

settings.cpp:89:9: error: 'DEFAULT_INVERT_PROBE_PIN' was not declared in this scope

     if (DEFAULT_INVERT_PROBE_PIN) { settings.flags |= BITFLAG_INVERT_PROBE_PIN; }

         ^

settings.cpp:91:37: error: 'DEFAULT_X_STEPS_PER_MM' was not declared in this scope

     settings.steps_per_mm[X_AXIS] = DEFAULT_X_STEPS_PER_MM;

                                     ^

settings.cpp:92:37: error: 'DEFAULT_Y_STEPS_PER_MM' was not declared in this scope

     settings.steps_per_mm[Y_AXIS] = DEFAULT_Y_STEPS_PER_MM;

                                     ^

settings.cpp:93:37: error: 'DEFAULT_Z_STEPS_PER_MM' was not declared in this scope

     settings.steps_per_mm[Z_AXIS] = DEFAULT_Z_STEPS_PER_MM;

                                     ^

settings.cpp:94:33: error: 'DEFAULT_X_MAX_RATE' was not declared in this scope

     settings.max_rate[X_AXIS] = DEFAULT_X_MAX_RATE;

                                 ^

settings.cpp:95:33: error: 'DEFAULT_Y_MAX_RATE' was not declared in this scope

     settings.max_rate[Y_AXIS] = DEFAULT_Y_MAX_RATE;

                                 ^

settings.cpp:96:33: error: 'DEFAULT_Z_MAX_RATE' was not declared in this scope

     settings.max_rate[Z_AXIS] = DEFAULT_Z_MAX_RATE;

                                 ^

settings.cpp:97:37: error: 'DEFAULT_X_ACCELERATION' was not declared in this scope

     settings.acceleration[X_AXIS] = DEFAULT_X_ACCELERATION;

                                     ^

settings.cpp:98:37: error: 'DEFAULT_Y_ACCELERATION' was not declared in this scope

     settings.acceleration[Y_AXIS] = DEFAULT_Y_ACCELERATION;

                                     ^

settings.cpp:99:37: error: 'DEFAULT_Z_ACCELERATION' was not declared in this scope

     settings.acceleration[Z_AXIS] = DEFAULT_Z_ACCELERATION;

                                     ^

settings.cpp:100:37: error: 'DEFAULT_X_MAX_TRAVEL' was not declared in this scope

     settings.max_travel[X_AXIS] = (-DEFAULT_X_MAX_TRAVEL);

                                     ^

settings.cpp:101:37: error: 'DEFAULT_Y_MAX_TRAVEL' was not declared in this scope

     settings.max_travel[Y_AXIS] = (-DEFAULT_Y_MAX_TRAVEL);

                                     ^

settings.cpp:102:37: error: 'DEFAULT_Z_MAX_TRAVEL' was not declared in this scope

     settings.max_travel[Z_AXIS] = (-DEFAULT_Z_MAX_TRAVEL);

                                     ^
'DEFAULT_STEP_PULSE_MICROSECONDS' was not declared in this scope

Yeah, it looks like a bug in cpu_map.h. You can see these setting defined in the mpcnc section above:

You can copy each mpcnc value into the low rider section. I bet if you asked Bart nicely in his buildlog slack, he would do it for you.

But they aren’t defined in the CPU_MAP_ESP32 section, either. Worst case, defaults.h should be getting pulled in by grbl.h, which is included just about everywhere (including settings.cpp).

Should probably define some of those values for the LRV2 on general principles, but the defaults.h backstop should still be there.

1 Like

@jeffeb3 thanks. There are 12 maps and only 5 have actual “default definitions”. I’m not really sure what I’m doing but two MPCNC maps don’t have defaults, they are using:

		#ifdef DEFAULTS_GENERIC
			#undef DEFAULTS_GENERIC
		#endif
		#define DEFAULTS_MPCNC

I see the following:

#ifndef cpu_map_h

#ifdef CPU_MAP_ESP32

#ifdef CPU_MAP_ESP32_ESC_SPINDLE

#ifdef CPU_MAP_PEN_LASER
Contains "Defaults definitions"

#ifdef CPU_MAP_MIDTBOT
Contains "Defaults definitions"

#ifdef CPU_MAP_POLAR_COASTER
Contains "Defaults definitions"

#ifdef CPU_MAP_SERVO_AXIS
Contains "Defaults definitions"

#ifdef CPU_MAP_SM
Contains "Defaults definitions"

#ifdef CPU_MAP_MPCNC_V1P2

#ifdef CPU_MAP_MPCNC_V1P1

#ifdef CPU_MAP_LOWRIDER

#ifdef CPU_MAP_TMC2130_PEN

@jeffeb3 should I copy each mpcnc value from defaults.h? Is that what you meant?

If I can’t get Grbl to flash on my board I may try this board is anyone using it on a machine actively and what where your thoughts if so? Thanks

I’m using one of the other Grbl_ESP32 boards on my sandify machine, and I like it a lot. But I also always like ESP32 boards.

It is definitely harder to flash than a rambo. But it has builtin wifi and SD card support, Grbl (which has it’s advantages) and a ton of nifty features. The 5 port board is limited to drv8825 style drivers.

There is also a slack for buildlog, and Bart (the creator of Grbl_Esp32) is very active. I’ve had good luck there.

I keep hoping Ryan will try it out and start selling preflashed ESP32 boards and this breakout in his store. I think it would be a pretty good option if they came preflashed.

4 Likes

I’ve had a Grbl_ESP32 MPCNC CNC Controller for a while now (version 1.1).
Out of the box, it flashed fine and 3 axis stepper motion was solid and the web interface was awesome. After the initial trial I switched back to my RAMPS controller until I could shore up the wiring of the GRBL_ESP32 limit switches and such and am giving it another go.

So far so good, but I have tried to add laser control via the PWM output pins without success.
I cannot get any PWM output with M3 SXXX commands.
Taking a step back, even when I configure for Spindle Relay control, or map the relay to coolant control of the on-board relay, I do not seem to be able to get the relay to fire with M3 or M7.
The board is awesome, so I am sure I am doing something wrong, but would love to hear from someone that has either the relay working or the PWM spindle/laser speed control functioning.

Ideally I would be able to establish PWM control of a diode laser and use the relay to control air-assist.

Note: I am using an ESP32 I procured through Amazon (HiLetgo ESP-WROOM-32 Development Board) instead of Bart’s pre-programmed option, but it flashed fine and otherwise works flawlessly.

I’m not against getting an ESP module directly from Bart or a newer V1.2 GRBL_ESP MPCNC board with different pin mappings, but figured I’d start here first.

I have been trying to bring up a GRBL_ESP MPCNC board on a MPCNC and have been having some issues with homing. Has anyone managed to get this board to work on a MPCNC and get homing to work? If so could you share your configuration.

I have one, but I haven’t flashed it yet. I could take a look, but the buillog.net slack is probably going to be more helpful.

Bart has been really helpful on his slack channel but I’m trying to figure out if I found a bug or if I’ve just done something dumb. My money is on the second. I don’t think that too many of his MPCNC boards are up and running yet.

If you have a config, I can look at it. I have one, but it is getting dusty, because I like to keep Marlin on my LR to be more helpful here.

1 Like

Thanks Jeff but I think I am closer to a solution. I think it’s a noise issue, I should be able to confirm tomorrow.

Solved the homing issue with Bart’s (big) help. It was a noise issue so I need to shield the limit switch wiring. I can confirm that the Gbrl ESP_32 MPCNC controller does dual axis squaring during the homing cycle. Bart has added a new feature where $HX and $HY homes an individual axis with dual motor alignment using both limit switches. I haven’t tested it yet but I’ll report back when I have. If anyone is considering Grbl then the ESP_32 MPCNC controller is certainly worth a look.

1 Like

I have my cnc shield v3 working with Arduino. I have an esp32 cam ( tinkercam ) I don’t want to change that, just want to add the esp to act as a serial connection / web server , that utilizes the esp32 cams sd card, to act as a stand-alone headless unit.and I guess I could have the cam working too… cam not worth a damn to be quite honest, but it’s there why not tap into it. Before I go and compile the web-ui, which has a web server feature in it, which I assume I can add .h to camera , has anyone done this already, or have some pointers. I understand this project is utilizing the esp32 to actually run the whole thing with the functionality - the cam due to lack of ports, my goal is to keep Arduino and v3 shield running the GRBL , just rx tx to send commands, which free up ports to allow sd card and cam to work?

The idea of having the cam to work, is in the case that I put a vac boot or whatever it’s called with the brushes, then i can see inside the boot, to see what’s going on