Steps per mm

It is probably documented somewhere, but I went the hard way, and checked the configuration.h file to find the place where the number of steps per mm is defined for each axis.

Then I almost went and changed it, but read about the G-code command M92 just in time.

Turns out that we can override the standard settings by issuing a M92 command before running any other G-code.

The syntax is:

M92 Xnum Ynum Znum Enum

Where num is the number of steps per mm for the corresponding axis. Because Marlin is written for 3D printing, there is also an E setting for the extruder. For CNC we can ignore E, but since it must be specified, any number will do.

I am using a lead-screw with 8mm of travel per revolution. Steppers with 200 steps per revolution and a driver with 32 microsteps per step. Hence the number of steps per mm is: 200 * 32 / 8 = 800. And since all axis are the same, my M92 command is:

M92 X800 Y800 Z800 E800

Note that it is possible to use fractional numbers if that were necessary.

In a first test I took the test shape G-code and put the M92 command in front of the entire sequence. That worked!

Of course it is not practical to manually edit all G-code files, and there is no need for it. Because there is an EEPROM that the settings can be written to. And on each reset (power-up) these settings override the default settings in the Marlin code. This is done with the M500 G-code command.

So I made an extra file, called set-movement.gcode with the content:

M92 X800 Y800 Z800 E800

Then wrote that to the micro-SD and executed it on the Arduino. It did work, but when I restarted the Arduino I discovered that it was not written to EEPROM. After some digging I found that Marlin has the option to disable the EEPROM, which is what V1Engineering has done. This option can also be found in the configuration.h file. Hence it is still necessary to update the configuration file and re-compile and re-burn the Marlin driver to the Arduino.

With this done, the proof of concept has been completed. Everything is now ready for the next step(s): design, buy and build the hardware that will do the cutting!

A rectangle

FreeCAD can generate G-code. This is one of the most important aspects for choosing FreeCAD.

I did follow a FreeCAD tutorial that created just about the shape I wanted for testing the movements of the electronics. But unfortunately I cannot find it again.

So instead I will recommend following a few tutorials until you get the hang of it. There are probably youtube tutorials as well, I did not search for them.

Next we have to define the shape for the test: it will be a rectangle of 16x32mm with a thickness of 8mm. In the top of this rectangle a rectangular pocket will be made of 8x16mm with a depth of 4mm.

Like this:


Once this shape is defined, the Path Walktrough for the impatient details the steps needed to create the G-code file.

You can see the results in a simulation in FreeCAD itself.

When done and satisfied with the results in the simulator write the G-code to a file using the extension gcode and store this on an SD-card. Then switch to the breadboard.

Switch on, and insert the SD-card. The menu on the LCD now displays that a media card has been inserted and the menu on the next page (press the button once) shows extra items, among which a Print from media, select this and select the file that must be printed. On the next screen, confirm that it should start printing. The steppers will start moving until ready. While the operation is ongoing a progress bar is shown.

So far so good. The steppers show approximately the expected behaviour with respect to sequence of events. But they do not show the appropriate rotation yet. This was to be expected as I have not yet configured V1-engineering Marlin for my breadboard.

That is next on my list.

Faulty wires

In the last post I described that the X-axis stepper worked just fine, but the Y and Z axes steppers vibrated instead of turning.

You may remember that one of the steppers that I originally received was damaged and I had to replace it. The shop did this without problems. However now it almost looks as if I have two more defective steppers. Hmm.

Since one stepper was fine, I first removed the connectors for the Y and Z steppers and checked operation of the Y and Z drivers with the X-axis stepper. As I hoped (and expected) the drivers for the Y and Z steppers worked fine. That was a relief as this would have been a more serious fault. But the RAMPS board and the drivers are fine.

Now I had to find out if the steppers are the problem. I swapped the connecting wires for the Y and Z steppers in turn with the wire used for the X stepper. And to my surprise the Y and Z steppers worked fine.

Thus it could only be the connecting wire for the Y and Z axes.

I tested the wires with an Ohm meter for proper end-to-end connections, and the wires are fine. Then I checked for short circuits, but again the wires checked out fine.

That of course puzzled me, how can the wires be fine, but not work?

Then I noticed something: a cross over of two wires. And the crossover was in the working set. The two other (faulty) sets did not have the crossover!

ok nok


How this is possible I do not know. The wires come with the stepper motors. So this must be a manufacturer error.

Anyway, it is simple to make the crossover myself, so I won’t bother with claiming a replacement set (that would probably take a couple of weeks).

Here is the result:


And I am happy to report that all axes now work as expected!

There are two things left to do before I will order the other (hardware) parts for the CNC:

First I have to be able to create a design and generate the G-code for it, and second the V1-Engineering Marlin variation must be configured to use lead screws on all axis (instead of a belt on the X and Y). It may even be necessary (or advantageous) to go back to the normal Marlin driver and fork from there. That remains to be seen.

My test approach will be simple: Since 8mm of travel is one revolution of the stepper, a design consisting of a rectangle of 32 mm x 16 mm (X by Y), has to result in 4 revolutions of the X axis and 2 of the Y axis. A clearance space of 8 mm will allow a checkout of the motion along the Z axis.

Btw, the X-axis = length, Y-axis = width, Z-axis = height.

Installing the RAMPS board

Next the RAMPS board needs to be installed in the Arduino board.

Of course we will be doing this while the Arduino board is unpowered.

Before pushing it on, make sure the pins on the RAMPS board are all perfectly aligned. If a pin is out of line, gently push it back. Once all pins are aligned, gently, but firmly push it on the Arduino board.

Next the drivers should be installed on the RAMPS board, but before that the microstepping jumpers have to be configured since these will be unreachable when the drivers are installed.

Note: Do not glue the cooling fins on the drivers just yet.

The purpose of my CNC will be to cut wooden parts from soft wood and plywood (layered wood) an accuracy of 0.1mm is enough. However cutting a curve with 0.1mm steps created a very rough shape, and even if it is accurate enough, I want to do one better and create a smooth curve. Therefore I want a resolution of minimal 0.05mm on the movement of the cutting tool.

The NEMA 17 motors have 200 steps per revolution. They drive a lead screw that has 8 mm travel per revolution. Hence one step is about 8 mm / 200 = 0.04mm tool movement. Which is even better than the resolution I wanted. So it would seem that microstepping is not needed.

However, microstepping smoothens the motion of stepper and stages, reducing wear and tear on the mechanics, and reducing noise and vibration. For this reason microstepping is advisable. How much microstepping? I have not found a very good answer on this. It would seem to me that going for the highest possible number may not be the worst approach.

The DRV8825 driver that I am using supports 32 microsteps. So that is what I will be using. This calls for the first and last jumper in the jumper field below the steppers to be inserted. The middle position does not really matter, either insert a jumper or leave it empty. The result should be the same.

Now it is time to put the drivers in, this is a bit … well, not so easy I found. When you simply use your thumb or fingers, chances are the driver will end up angled. Besides, you should try to avoid touching the driver chip since the fins must be glued onto this surface. So don’t use you fingers, but use a narrow, longish piece of wood (as narrow as the driver is long, and a total length of about 10-20 cm).

Also, the width of the pins of the driver may not align exactly with the row of sockets in which they should be pushed. In this case put the driver sideways on a flat surface and GENTLY apply some force on the pins to ensure a good fit. Then place the pins of the driver on the sockets. Place the longish piece of wood with one end on the driver and the other end sticking out. Put your thumb over de driver and grab the other end of the piece of wood with your free hand. With your free hand make sure the force that is exerted by your thumb stays level. The driver should slip in without much problems. If you encounter real resistance, make sure none of the pins is bent out of place.

Now glue the cooling fins on the driver IC. I made an error and glued it on in the wrong direction. Oh well.. I will pay more attention next time..

Note that cooling paste/glue can be used. But my fins had a sticker to peel of before glueing them on. I thus only used cooling paste (for thermal conductivity) around the very edge of the fins, not on the glue itself!. Needless to say, I used only very very little cooling paste. Hardly anything at all.

Note: Just for completeness, older versions of the Marlin driver SW also required a thermistor (or simply a resistor) to be connected to the board. I do not know which version no longer needs that resistor, but the current version (>2.0) do not need it.

The maximum driver current has to be tuned to the steppers by turning the little potentiometer either up or down to achieve the proper maximum current. This is done measuring the voltage at the little marker on the driver print or, better, on the metal of the potentiometer itself. The voltage should be half the maximum rated current for the stepper. My steppers are rated 2 Amp, thus the voltage should be 2 / 2 = 1 Volt. In order to run everything a little cooler, 10% can be subtracted, which yields 0.9 Volts. However the driver I am using (DRV8825) can only drive up to 1.5 Amp, which translates to a maximum voltage of 0.750 or 750 mVolts. This ensures that the stepper will run quite cool, but also that the stepper cannot achieve maximum power. So be it. Since I do not want to use the driver close to its maximum, I will adjust the voltage even further to 700mV (for a max of 1.4 Amp).

In order to perform the tuning, the stepper must be connected and under power, which means that the LCD and steppers must both be connected to the RAMPS board first. The next picture shows how the LCD is connected:


The picture was taken a little later when I had removed the X and Y stepper connectors. Btw: The X driver is closest to the power connector, then comes the Y driver and the last of the three is the Z driver.

Then comes the big moment: power on!

If everything works you will be greeted by the following screens:

scr1 scr2 scr3

One push on the selector/push-button (below the LCD screen on the right) gives:


Now we can proceed to select individual stepper motors and move them a little. I found this interface quite intuitive and just firing up a stepper to make a small move is enough to ensure that the tuning for that stepper-driver can be performed. Do this one axis at a time to prevent prolonged and possibly too high currents in any one stepper.

The sensitivity to movements of the potentiometer was quite high. I was unable to achieve more than 15 mV accuracy. Still, it should be close enough. I also noted that the fins on the drivers get quite hot. Almost too hot to touch. I will have to reduce the maximum current even more once the CNC is complete, such that the steppers can drive the CNC easily, but no more.

I then proceeded to see if movements selected by the LCD interface would turn the steppers as expected. That turned out not so well. Both the Y and Z steppers started vibrating instead of turning. Only the X stepper turned smoothly. More about this in the next post.

Flashing the Arduino

This post will cover the “burning” or “flashing” of the CNC driver software to the Arduino board.

For this a few things are needed:

  • A host computer with a USB port capable of providing sufficient power to the Arduino board
  • A USB cable
  • The CNC driver software
  • The Arduino IDE (Integrated Development Environment)

I will be using a host computer with Linux Mint 19.3. Mac or Windows will do as well, but the description below assumes the Linux Mint OS.

The Arduino IDE is available from, but on Linux Mint I used the SW-manager to install it nearly automatically.

Using the SW-Manager, type “arduino” in the search field. It will return a couple of hits, select the one titled “Arduino IDE” (the second from above when I did this). When the details of this SW package are displayed, click the “install” button. It will be installed in the “Programming” section.

Next we need to download the driver software. As written before I will be using the Marlin driver for 3D-printing, but adapted by V1-Engineering for CNC-applications. This driver SW is available from: (Allted is the name used by V1-Engineering on github).

The SW can be downloaded in two ways, I will be using git. Alternatively a zip compressed file can be downloaded manually.

Using git, open a command line window and navigate to a directory in which you want to install the driver SW:

$ mkdir Projects
$ cd Projects
$ mkdir CNC
$ cd CNC
$ mkdir
$ cd

Then download the repository from github:

$ git clone

Now we need to select the correct driver from the available drivers:

$ cd Marlin
$ git checkout MPCNC_Ramps_T8_16T_LCD_32step

Be sure to checkout the driver that fits your (envisioned) hardware. The one I selected is not a complete fit, thus I will probably need to make a few changes later. For the breadboard this is not a problem as long as the RAMPS board is used. On the Allted github page you can use the dropdown box to see which versions are available.

Next attach the Arduino board to the computer. The board will be powered from the USB interface, thus be sure to use a connection that can supply the necessary power.

Now follow the instructions given on the v1-engineering site in the section “How to flash firmware on the Ramps 1.4”, starting at the point “Open Arduino”. I will give the textual sequence here, for pictures see the link.

  • On the host computer, start the Arduino IDE.
  • Select menu: Sketch -> Include Library -> Manage Libraries
  • Type U8glib in the search box
  • Click the U8glib Select Version and select the highest version number
  • Click Install
  • Close the library manager
  • Select menu: Tools -> Board and then the board that will be used (mine: Mega or Mega 2560)
  • Select menu: Tools -> Processor and then the processor that will be used (mine: Mega 2560)
  • Select menu: Tools -> Port and then the port that will be used

Note: Many of the Tools menu items will already be set correctly because the IDE found the board that was connected to the computer as the IDE was started. And when multiple boards are connected, well, then you would not be reading this ;-)

Now select the driver:

  • Select menu: File -> Open and navigate to the appropriate item (mine: ~/Projects/CNC/

Next, compile and upload (in a single step) the driver:

  • Click the upload arrow in the top left of the IDE window. Now wait until the status bar displays: Done uploading.

Note: The compilation process did generate one warning “incompatible pointer type”. For now, I am just hoping that this warning will not affect operations.

That is it. Exit the IDE and disconnect the Arduino.