One small step for man.

I am currently building a CNC mill -- one small step at a time. A lot of people ask me what I need a CNC mill for: I don't, but I thought it might be a fun project to learn about controlling machinery, programming microcontrollers and learning a bit of electronics. If I get a working CNC mill out of it: great! If I am able to build something that works with any reasonable precision it means I'll be able to mill stuff that I can draw -- which might come in handy for my other hobbies.

It also struck me that if I replace the milling head with what is in practice a glorified glue gun I can probably find some way to turn the thing into a 3D printer, but we'll investigate that opportunity if and when I get a CNC machine working properly.

Yesterday I finally hooked up my EasyDriver v4 stepper motor driver to my Arduino Mega. I soldered riser pins to the connections on the EasyDriver so I can mount it on a breadboard and access all the pins that are broken out. I used the pictures from Daniel Thompson's tutorial on hooking up an Arduino to an older version of the EasyDriver plus some other tutorials as a guide.

After writing a short test program to generate pulses for the stepper and setting the direction pin I got the motor moving. Before hooking it up to the 12 volt regulated power-supply from which the stepper should be driven. Hmm, that's odd. Either I have done something wrong or I didn't understand how the EasyDriver works. It can't be good if the stepper is driven from the Arduino power.

In any case, from here on I need to be a bit more structured and keep proper notes of what I am doing. I should probably use Fritzing to document how things are hooked up so I can get some input on what I am doing. After all, I am a software person and I really know very little about electronics.

I did some experiments with the stepper to see how it behaved. From Thompson's tutorial I gathered that if you pulse the motor more frequently than every 200 microseconds it will stall -- which I verified. I just halved the period and it did indeed stall. The code to perform nSteps steps looks something like this:

for (i = 0; i < nSteps; i++) {
digitalWrite(stepPinX, LOW);
digitalWrite(stepPinX, HIGH);

It can't possibly be that simple :-).

I am not entirely convinced that a constant pulse frequency is what you would want to feed the motor in all situations. Since we are talking about physical objects that have inertia I would assume that you need to account for acceleration and thus have a way to ramp up and ramp down the pulse frequency. I also suspect that the motor will be more prone to stall at low revs or from a standstill -- meaning I can probably pulse it faster than 5kHz once it is up to speed.

I hope that the books I have ordered will contain some answers.

My current assumption is that I should use the Arduino to implement some sort of high level interface (G-code?) which can be reachable via a serial connection. I have seen people use the parallel port of their computers to pulse the stepper drivers, so I could of course go down that route. However, using a serial connection and offloading the work to the Arduino seems much more elegant.

My short term plan:
  • Implement an asynchronous serial line text protocol interface that can be used to export a command interface from the Arduino. I've seen a lot of examples where people have loops with delays in them for reading the serial input. If I am going to use the Arduino to control multiple steppers in real time I do not want to block while waiting for IO.
  • Figure out what I need to move development of the software to GCC and Emacs. The Arduino software package is nice for playing around, but I would rather use tools that I am more familiar with for more serious development.
  • Familiarize myself with the G-code protocols and figure out if there are open source implementations that I can study and possibly re-use.
  • I also suspect I have to implement some sort of scheduler so I can translate high level commands into precisely timed outputs, queue them up and have the scheduler execute them with correct timing. Since I have no prior experience with programming microcontrollers I guess this could get hairy. I probably need to build a test rig (using a second Arduino or a logic analyzer) to run tests.
  • Figure out what high level primitives I have to implement myself. For instance: does G-code imply that I need to be able to calculate and execute motion along arcs? How painful is it going to be to do this in a numerically sound way on the microcontroller?

Anyway. I have a lot of learning left to do. What great fun! :-).


  1. Looking forward to updates on this project.
    How about mounting a laser head instead of a Dremel ? I wonder if it's possible to combine one of these babies (http://tinyurl.com/yc96cb6)with some kind of optics to make a home brew laser cutter (probably unsuitable wavelength for such an application, but it's cheap enough to try. Something is _bound_ to happen if you manage to focus the output from the 20W array into a narrow beam...)

  2. @HansJ: I did think about various options such as laser and plasma cutter. After reading a bit about suitably high powered lasers I concluded that a) I would need to learn a lot more about lasers, b) they are more dangerous than I thought, and c) it gets real expensive real quick.

    (I was mostly reading about CO2 lasers)

    Using a laser for cutting would sort under the "to be revisited" heading. A laser with lower power output might be usable for engraving though.

    If you figure out the laser parts you would be more than welcome to mount it to my CNC machine :-)

  3. Good stuff Borud. All the best with your project.
    I'm using an Arduino and easydrivers for a video motion-control rig. I'm awaiting some ED4.2s to arrive so I can move forward. Controlling the ED boards from the Arduino is wonderfully simple. You'll find that you can run your steppers at a higher frequency if you ramp the speed up.

  4. Hey Borud,

    Good luck with your project. Looking forward to following you CNC journey.

    I'm particularly interested in the scheduler thing you mentioned. I have always wanted to lean how to read data from an SD card to the Arduino in small chunks and store them in the chip's memory for fast execution. Much like a print cue in an ink jet printer I imagine.

    Just don't know where to start?

  5. @Marcel: Since I am new to building CNC machines I've ordered some books that I hope will inform me a bit on how to calculate proper ramp-up -- among other things. Failing that I guess nothing beats experiments. Do you have any pictures of your rig online?

  6. @Dan Thompson: I need to familiarize myself a bit more with the Atmel chip to see what is possible. I also need to understand timing problems better. The main reason I wanted to use some sort of command queue and a scheduler was to avoid having lots of waiting states in the code. Rather than just spinning, the microcontroller could be doing useful things, like IO.