Let's Make Robots!

Prototyping CNC MkII

Late 2012 I started developing a 5 axis, CNC controller. The PCB was made but It was a long term project that ended up sitting on the back burners. I never had time to test it or write code. Although an Arm processor would be slightly cheaper and more powerful I have kept the design Arduino compatible as this is easier to hack for most hobbyist.

The goal of this project is to develop a compact controller that is easy for the beginner to use but powerful enough for semi-professional work. Although the primary purpose of this controller is to drive CNC machines it could also be used for 3D printing but would need custom software written for it.

MkI Prototype:

Early 2014 I finally got around to getting the prototype connected to a simple 3-axis mill and running some simple G-code. I learned a fair bit including the fact that my stepper drivers (Allegro A4988) were a bit under powered. They has a 2A rating but without a properly designed 4 layer PCB to provide adequate heatsinking they could only sustain 1.5A reliably without overheating.

Now I've redesigned the controller. All the motor driver circuitry has been beefed up and new features added. I've tried to make this controller as bullet proof as possible. The stepper motor drivers are now rated for a peak current of 3.5A each (the controller limits the current to 3.33A @100%). These stepper drivers are current regulated with thermal overload protection.

The cutting tool motor drivers are rated at 4A continuous, 8A peak. These outputs are reversable making it possible to tap threads. Blower and cutting fluid pump outputs rated at 2A continuous, 4A peak. An Atmega8A slave processor is now a dedicated motor controller for the cutting tools. The Atmega8A also monitors temperatures, power supply voltage, cutting tool fuses and emergency stop.

Although the Atmega8A is normally an I²C slave, in the event of an emergency (cutting tool stall or PTC fuse open circuit) the ATmega8A will take control of the I²C bus as an I²C master and inform the controller of the need to shut down.

MkII prototype:

As a result of the increased current handling capacity a heatsink had to be added. To minimize the size and weight of the heatsink I chose a tunnel heatsink. This is an extruded aluminum heatsink (40mm x 40mm) with cooling fins on the inside. Two 40mm CPU cooling fans are mounted either end to maximize the efficency of the heatsink.

The controller has 2 temperature sensors, one on the air intake to measure ambient temperature and another at the center of the heatsink to measure the heatsink temperature. While testing 5 stepper motors at 75% power (2.5A) the heatsink got to 80°C with the fans turned off and 40°C with both fans at 100%. Ambient air temperature was 29°C.

The stepper motor drivers will shut down on thermal overload at 170°C (die temp) so this leaves a reasonable safety margine even if both fans fail. Each fan has a tacho output that is monitored by the controller. This allows the software to detect if the fan is starting to fail (they usually run slow before they die) and warn you. Fan speed can be controlled by the software. Running the fans at 50% is usually enough to keep the temp low and extends the life of the fans.

So far I have spent a week testing all the hardware. There have been a number of small problems that had to be fixed. Some were design mistakes made by me (I connected a pullup resistor to the 5V rail instead of the 3.3V rail in 2 places). Some mistakes were made in the PCB layout (source and drain were swapped on the emegency stop power FET). Some incorrect components were installed by the assembler.

When I re-designed the controller, I changed the pin connections so that direct port manipulation could be used. This makes the code for controlling the I/O pins more efficient. For example the thermal shutdown outputs from the five stepper drivers can be read simultaneously by reading a single port rather than performing a digitalRead() for each pin seperately.

Another advantage of using direct port manipulation is that it has given me access to an additional 16 I/O pins that are not normally used by the Arduino Mega boards. This gives me 86 I/O pins of which only 3 are not used (at the moment).

I have been asked by some people why is the controller only 24V? Many CNC machines work at higher voltages (48V or higher). The main advantage is that the stepper motors can be driven at higher speeds. Aside from the fact that the stepper driver IC's I'm using are only rated for 36V maximum there is also a safety issue involved. CNC machines often use a water based cutting compound that lubricates and cools the cutting tool. If a wire gets damaged then there is the potential for the user to get an electric shock. 24V is a much safer option for beginners.

I'm sure someone will ask why I am not using a touchscreen. If you have ever worked with mills or lathes you will know it is next to impossible to keep your hands clean, especially if you are using cutting fluid. With a touch screen you would be constantly wiping oil off the screen. The final product will be splash proof and easy to clean.


Full list of MkII features:

  • 24V with 20A automotive blade fuse.
  • ATmega2560 main processor (16MHz, 256K FLASH, 8K SRAM, 4K EEPROM).
  • ATmega8A slave processor (16MHz, 8K FLASH, 1K SRAM, 512 byte EEPROM).
  • 240x128 white on blue LCD graphics display with 40x16 text display.
  • 5 stepper drivers rated at 3.5A each with current regulation and thermal overload.
  • 2 reversible cutting tool outputs rated at 4A continuous, 8A peak.
  • 2x non-reversable motor outputs for cutting fluid pump and blower rated at 2A continuous, 4A peak.
  • Cutting tool, pump and blower motors protected by PTC self resetting fuses monitored by processor.
  • 2x speed controlled outputs for cooling fans with support for tacho feedback.
  • Emergency Stop button cuts 24V power to all motors (not software controlled).
  • Emergency Stop can also be initiated by software.
  • DS1307 RTC maintains time when power is off.
  • Xbee / WiFly wireless interface.
  • Bluetooth wireless interface.
  • SD card interface.
  • CP2102 USB interface.
  • I²C bus with 3.3V and 5V interfaces.
  • ISP headers for main processor and slave processor.


I am currently modifying the MkI software to work on the MkII controller. Aside from the different pin configuration there is a lot of extra hardware and safety features that need new code written. The software provides a simple graphic interface that allows you process a job in 3 basic steps.

  1. Load the G-code.
  2. Scan the G-code.
  3. Run the G-code.

The 4th option at the bottom of the screen allows you to enter the size and configuration of your mill, set the time / date and choose metric or imperial.

Currently step 1 only allows you to load the G-code from the SD card. Later I will add options for wireless uploading. In the case of a wireless upload, the controller will still need an SD card to temporarily store the data.

Step 2 is where the controller scans through the G-code looking for commands it does not recognize and also to check the dimensions of the job. It will warn you of any problems such as the job being too big for the mill.

Step 3 is where the G-code is processed. Currently it only works with a simple version of G-code for Mach3. In this version almost all the code is simple X,Y,Z co-ordinates.

I've written some code that attempts to display an isometric view of the job based on the tool path. This allows you to check how the job will look before the machine starts.

Once the machining process has begun the isometric view is generated again in real time so you can see exactly how far the job has progressed.




6th August 2014

I've been updating the old code to work with the new board and it's slave processor, additional hardware, "port orientated" wiring and new interrupt drivent events. I've almost got all the old code working. My biggest problem is that the old code was written to work with 1/100th mm steps and Free Mill "Mach 3" G-code which is accurate to 4 decimal places.

Since most hobby CNC machines are not mechanically accurate beyond 100th of a millimeter or 1000th of an inch I am re-writing the code to work with these resolutions. Unfortunately this means a lot of debugging.

I'm sure some of you will say it is just a simple scaling problem but unfortunately Arduino floating point math is not accurate. For example, using floats, multiply 1 x 10 x 10 x10. At first you get the answers you expect. 1, 10, 100 but then you get 999.

Since accuracy is important my code uses long numbers instead. These seem to be accurate but to get a value with 3 decimal places I must multiply by 1000 and use a seperate byte to record the position of the decimal place. This system works well but makes the code more complicated.




7th August 2014

I have everything working, RTC, SD card, Configuration display, 3D simulation etc. but when I tried to run the mill it just crashed into the home position and jittered a lot. At this point debugging is a major pain because in order to get to this stage for testing I must first open the G-code and scan it which takes at least 30 seconds and a lot of button presses.

During this time I found that although the steppers jogged fine in both directions from the configuration screen they got jittery in one direction when going to home position. After half a day, checking my code, checking the schematics and checking the code again I finally found out that I needed to allow a few μS settling time after changing direction of the motor before sending the clock pulse to make the motor step.

Finally I got the machine running. Now I can tidy up the code and add some new features.

14th August 2014

Just in case they have not fixed the video in the blogs: https://www.youtube.com/watch?v=kQKiPXwWyEg

This is the MkII controller doing the DAGU logo in 3D. The plywood splits easily so I had to slow the machine down to 1/5th the speed and only 0.5mm cuts. The machine and controller can go much faster.





Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

This is way cool OB!  Keep up the good work!

Thanks Hoff70, I've now got almost all the old code adapted to the new board. I hope to post a new video this weekend.

Yes the current is the killer but it is the voltage that pushes the current throught your body. If you have wet hands and touch the terminals of a 24V battery then you might get a shock but it probably won't hurt much. If you then double the voltage the current will also double ant it will definitely hurt (I know from experience). By the time you get to 100V it starts to become deadly.