Now what could I build?

  • A camera gimble/rail  (work by isaac879 is quite inspirational!)
  • A roller drawing machine
  • A lightweight CNC machine

How about something that can be used as the basis of all of the above!

Arduino CNC Shield meets ESP32

After years of tinkering with Arduinos, I was provided with an WEMOS ESP32 D1 R32 and was frankly blown away. It is form-factor compatible with the Arduino UNO but has a decent processor, stacks of memory, WIFI, Bluetooth, ADCs, DAC outputs (not just PWM) etc etc.

It’s worth noting that the IO pin numbering is very different to the Uno and pin numbers jump around all over the place (I assume to make the PCB layout simpler).

There are libraries etc available for the Arduino IDE but I was wondering whether I could use my old Arduino compatible CNC Shield on the ESP32. A quick browse took me to a full port to support GRBL performed by Barton Dring. Amazing work! I strongly recommend spending some time reading, browsing and watching some excellent YouTube films!

One thing led to another and eventually to a project by Mr Dring on GitHub called FluidNC

FluidNC

NOTE: DO NOT ATTACH THE CNC SHIELD TO THE ESP32…. yet…

Follow the instructions to install (really nice video) – yes it really is as simple as getting your ESP32 board, plugging in the USB cable and running the script!

Great so FluidNC is on your ESP32, it includes it’s own webserver running a clean GUI including graphical jog “joystick”, CNC machine view but also a tuning/settings page for the FluidNC motor control including file up/download etc.

The whole software is designed to be driven by configuration files so no need to recompile the source code to switch between hardware setups etc.

So that’s all good but you do need to make a config file for your hardware. There are some great examples but I couldn’t find one quite for my setup so I made my own based on the examples.

The first thing you need to do is identify the mapping between the ESP32 R1 D32 board and the Arduino CNC Shield

I derived the following:

(CNC Shield name) = Arduino Pin = ESP32 R1 D32 pin name

With the board orientated so that the USB connector is at the top and you are looking down in the component side:

Right Side:

Spindle Direction = 13 = IO18
Spindle Enable = 12 = IO19
Limit Z Axis = 11 = IO23
Limit Y Axis = 10 = IO5
Limit X Axis = 9 = IO13
Stepper Enable/Disable = 8 = IO12
Direction Z = 7 = IO14
Direction Y = 6 = IO27
Direction X = 5 = IO16
Step Z = 4 = IO17
Step Y = 3 = IO25
Step X = 2 = IO26

— Left Side
Reset/Abort* = A0 = IO2
Feed Hold* = A1 = IO4
Cycle Start/Resume* = A2 = IO35    (Input to ESP only)
Coolant Enable = A3 = IO34               (Input to ESP only)
Not used/Reserved = A4 = IO36       (Input to ESP only)
Not User/Reserved = A5 = IO39       (Input to ESP only)

immediately, you can see some problems! IO34,35,36,39 are (I believe) inputs only for the ESP32

Anyway, you get the idea and you can build the file.

So now you want to install you CNC Shield?

IMPORTANT!!!! =====> NOTE if you plug in the CNC Shield – it WILL stop the ESP32 booting!

On the CNC Shield, there is one resistor R1 on the end next to the “End Stops” you must remove (or at lease disconnect one end) of this resistor! – that’s it! You can now connect it to the ESP32

StepStick Warning => be careful, info on the web says if the motors aren’t connected, you can kill your StepSticks – I haven’t tried this but It’s very possible! Also you will need to tune the pot-meter on the StepSticks – lots of info on the web on how to do this so I won’t try to repeat it here. Personnally, I remove the StepStick modules if I’m testing without the motors – its a bit of hassle but I didn’t want to find out whether they get blown up or not


Stepper Motor Hold

This is a common discussion in CNC groups etc e.g. either “why doesn’t my stepper motor hold in place unless it’s turning?” or “why does my stepper motor get hot even when it isn’t turning?”.

Basically you can choose whether you want to keep the motor coils energised or not when it isn’t turning. If you do, it will hold nicely in place but get draw current.

The tricky thing is it isnt exactly obvious how to change this!

The setting is “/stepping/idle_ms”.

If this is set to 255, the coils stay energised. If it is not 255 e.g. 250, it won’t.

With my setup, you can clearly see the difference. As I’m normally running from a 12V battery, dumping 0.6A or so continuously when the system is Idle isn’t great. The amp meter (cheap panel meter!) falls to 0.00 (yeh right!) when the idle_ms is set away from 255.

Of course with no hold current, any force on the steppers just makes them turn.


Can I use a servo on this?

Yes! I defined IO2 as an Analog pin in the FluidNC configuration file. This means that the pin on the CNC Shield labelled “Abort” will be used as an Analog(PWM) output which Fluid NC lets you control through regular G-Code. Cool.

I connected a cheap micro server with the red (+) to the 5V pin on the CNC Shield, black to GND and orange to “Abort”.

(Test Servo – my servo is controlled with PWM between 10 and 50%)
(set the PWM to 10%)
M67 E0 Q10
(wait 0.1 seconds)
G04 P0.1
(set the PWM to 10.5%)
M67 E0 Q10.5
G04 P0.1
(set the PWM to 50%)
M67 E0 Q50

etc

 


Boxing it

To make it a little nicer, I put the ESP32 + CNC Shield with 3 StepStick modules in a box.
I wanted to allow the system to run stand-alone so I added a Lidl 12V power tool battery with a holder based on a holder from Thingverse and a cheap buck step down converter board to reduce the 12V to around 6v or the barrel jack of the ESP32 (I wasn’t sure whether it would be ok with 12v and when I set the regulator to 5v the ESP32 didn’t seem to boot reliably.

I added a cheap voltage/current meter, power switch and a 4mm socket input in case we want to run it for a longer duration from an external supply.

The box has 4 D9 connectors for the steppers and accessory (I used 3xD9 socket for the Steppers and a D9 plug for the accessories to avoid pinout issues). The stepper connectors have a common pin out to allow motors to be interchanged while the accessory connector is available for adding limit switches, servo control etc.

D9 Motor Control:

Pin 1 = Red
Pin 2 = Blue
Pin 3 = Green
Pin 4 = Black
Pin 5 – 9 = Not connected (these could be used for other things e.g. motor end stops in the future)

D9 Accessory:
Pin 1 = +5V
Pin 2 = GND
Pin 3 = Abort (e.g. Servo PWM)

 

 

Finally , I added a USB socket to get to the ESP32 USB to use the FluidNC “FluidTerm” diagnostic serial terminal or UGS (Universal G-Code Sender).

OK not quite finally! I forgot it needs some cooling so I retrofitted a 40mm fan underneath.

All in all, a combination of Laser marking the box with my CNC machine (including marking the positions for the battery cutout etc), a little light “Dremmelling” and some 3d printing for the D connector panel, battery mount and the fan finger guard.

 

GRBL

I had some teething problems getting the GRBL interpretter in FluidNC to accept my G-Code (originally generated from CamBam) until I realised I was setup for Mach3 for my big CNC machine rather than GRBL.

After some tinkering, the following was accepted and could be sent by UGS:

G21 G90 G40
G0 Z0.0
( T0 : 3.0 )
(T0 M6)
( Profile2 )
G17
G1 F200.0 x0 y0 z0
G1 x5 y5 z20
G1 x-5 y-5 z-20
G1 z10
G1 Z-10
G1 x5
G1 x-5
(G1 y10)
(G1 y-10)
G1 x0 y0 z0
(Test Servo)
M67 E0 Q10
G04 P0.1
M67 E0 Q10.5
G04 P0.1
M67 E0 Q11
G04 P0.1
M67 E0 Q11.5
G04 P0.1
M67 E0 Q12
G04 P0.1
M67 E0 Q12.5
G04 P0.1
M67 E0 Q13
G04 P0.1
M67 E0 Q13.5
G04 P0.1
M67 E0 Q14
G04 P0.1
M67 E0 Q14.5
G04 P0.1
M67 E0 Q20
G04 P0.1
M67 E0 Q30
G04 P0.1
M67 E0 Q40
G04 P0.1
M67 E0 Q50
G04 P0.1
M67 E0 Q40
G04 P0.1
M67 E0 Q30
G04 P0.1
M67 E0 Q20
G04 P0.1
M67 E0 Q10
M5

My drawing machine appears to be slipping – but why????

The drawing machine is complete – time to test.
Ummm, something simple – a square and then drawing diagonals.
Very simple, 100mm square from the origin.
0,0 => 100,0 : looks ok
100,0 => 100,100 : probably ok
100,100 => 0,100 : yes also looks good
0,100 => 0,0 : yikes… it looks as though it only went to 0,3

then the diagonals:
0,0 -> 100,100 : sad face… it looks as though it goes to about 100, 106
back along base
100,100 => 0,100 : it looks like it goes to 0,106
0,100 => etc.

so it seems to be drifting only in a positive Y direction, This isn’t just back lash it is really creeping in one direction.
Make it draw again, again the same drift, and again and again!

Check everything, Google a lot, try all of the suggestions, slow down the acceleration and reduce max speeds…. the drift is identical.
Check mechanics – things seem to be tight.
Reduce microsteps -> no change just more grungy
Try with and without hold off set to 255 to keep motors powered when not in use.
Try changing pulse widths, hold delay for direction change etc.
I even changed the driver end to use completely different hardware, different types etc etc etc.
How is it possible?

One suggestion on the web is that you should check the position of the motors to see how much they are slipping.
I set the y stepper to be with the locking screw straight up, moved to y100 then back to y0 (clearly walked around 3mm) but huh!!!! the Stepper motor is still straight up.

I disbelief and to prove that it was the machine, I turned the whole machine around 180 degrees and ran it again.
AND… What the… it is still walking in the same direction IN THE ROOM not relative to the machine!!!!
Now rotate the machine 90 degrees in the room…. and the drift goes away.
OK so are you ready for this?
The source of the slipping problem is… the direction of the pile in the carpet!!!
Move the whole system to another room with a wooden floor and the machine perfectly returns to the origin each time.
So three evenings of scratching my head and it turns out to be the carpet!

(setup for mm, exact positioning and cutter compensation off)
G21 G90 G40
G0 Z0.0
G17
(setup for exact stop)
G61
(Go to zero)
G1 F500.0 x0 y0 z0
(Pen Down)
M67 E0 Q30
(Wait 1s)
G04 P1
(now move around)
(make a square)
G1 x100
G1 y100
G1 x0
G1 y0
(make diagonals)
G1 x100 y100
G1 x100 y0
G1 x0 y100
G1 x0 y0 z0
(Test Servo)
(Pen Up)
M67 E0 Q15
G04 P0.5
M5