Penguin CNC'n

Work in progress... Last modified 22.8.2004 (22th August 2004) / Henry Palonen

If you are interested in electronics and Linux, then maybe you would like to see Penguin PIC'n also...

Table of contents


Maybe you would like to look at new version, v2 of this project.


I'm using P333 PC with RTLinux installed to control a small CNC-type machine. The CNC software what I use is EMC, Enhanced Machine Controller made by NIST, National Institute of Standards and Technology, an agency of the U.S. Department of Commerce. EMC is free software developed under "open source" strategy, meaning that you can obtain full sourcecode and modify that as much as you want.

Basics of operation

EMC works with RealTime Linux, an linux where kernel runs in smaller thread and user applications can get much more I/O time. In this document I'm talking about small setup, just 3 motors (X,Y,Z) and 3 controllers.
Operator-GUI-EMC-RTLinux-CNC machine

Steps needed to setup a working system

Obtaining and installing RealTime Linux

In case you can't find suitable RTLinux at their site, here are some useful versions of them:

If you are using version that is not prepatched, you must first grab a fresh kernel-source (I used kernel 2.2.14 with RTLinux-2.2a) and then patch it. Patching is quite simply thing to do, basically it's "cd linux && patch -p1 < ../kernel_patch" kind of thing. If that is not enough, you can see more detailed instructions from RTLinux website.

Obtaining and installing EMC

Exellent manual at I followed that partially and one change I noticed was that with RedHat 7.0 you must do following before kernel compiles:
 mv /usr/bin/gcc /usr/bin/gcc_new
 ln -s /usr/bin/kgcc /usr/bin/gcc
 mv /usr/bin/g++ /usr/bin/g++_new
 ln -s /usr/bin/kgcc /usr/bin/g++
Reference information at

And after kernel compiled, I had change the links back so that rcs and emc could be compiled. They made errors like this:

#   The following errors and warnings were logged while building the RCS library.
/usr/local/nist/rcslib/plat/linux_2_2_14/lib/testpmcpp.o: In function `testPrint(void)':
/usr/local/nist/rcslib/src/posemath/ undefined reference to `cout'
/usr/local/nist/rcslib/src/posemath/ undefined reference to `ostream::operator<<(char const *)'
/usr/local/nist/rcslib/plat/linux_2_2_14/lib/testpmcpp.o: In function `testPrint(void)':
/usr/include/g++-2/iostream.h:106: undefined reference to `endl(ostream &)'
/usr/local/nist/rcslib/plat/linux_2_2_14/lib/testpmcpp.o: In function `testPrint(void)':
/usr/local/nist/rcslib/src/posemath/ undefined reference to `cout'
/usr/local/nist/rcslib/src/posemath/ undefined reference to `ostream::operator<<(char const *)'
/usr/local/nist/rcslib/plat/linux_2_2_14/lib/testpmcpp.o: In function `testPrint(void)':
/usr/include/g++-2/iostream.h:106: undefined reference to `endl(ostream &)'
/usr/local/nist/rcslib/plat/linux_2_2_14/lib/testpmcpp.o: In function `testPrint(void)':
/usr/local/nist/rcslib/src/posemath/ undefined reference to `cout'
/usr/local/nist/rcslib/src/posemath/ undefined reference to `ostream::operator<<(char const *)'
But after reverting the gcc-changes I made before kernel compiling, I got it compiling. So the command needed for this were:
 rm /usr/bin/gcc 
 ln -s /usr/bin/gcc_new /usr/bin/gcc
 rm /usr/bin/g++ 
 ln -s /usr/bin/g++_new /usr/bin/g++
After this, I added lines

#include < string.h >

to following files:


and line

#include < stdlib.h >



because they needed it. After that it compiled nicely, and I was able to run test-program, as can be seen from this picture ;-)

Configuring EMC

I'm now using steppermod.o for controlling the motors. It can be either "steppermot.o" or "freqmot.o", both can drive steppers. But steppermot.o is fine for me for now. You can download the configuration what I'm using.

Making electrical connections

Electrical connections from PC to CNC are explained in a small part of EMC documentation:
The pinout for the EMC stepper motor interface is as follows: 

Output        Parallel Port
------        -------------
X direction   D0, pin 2
X clock       D1, pin 3
Y direction   D2, pin 4
Y clock       D3, pin 5
Z direction   D4, pin 6
Z clock       D5, pin 7

Input         Parallel Port
-----         -------------
X/Y/Z lim +   S3, pin 15
X/Y/Z lim -   S4, pin 13
X/Y/Z home    S5, pin 12
I have connected my stepper-controllers (home-made circuit from "304 Circuits" book) to PC just like the diagram above says.. I have also connected the limit switches to port. All the - and + switches are connected in parallel. So that when any of switches close, it causes EMC to go special "E-STOP" state. In that state all movement is stopped and user must manually press "Override Limits" and "drive" the millinghead away from limit. Every time when EMC is at "E-STOP" state, the big numbers representing the current position are red.

Software needed to produce G-code

I found that Eagle's new version can do also output for milling machines. It's quite interesting program indeed. I have a sample setup where you can see what I mean. Just click on image below, and you'll get the larger picture. At the left there is simple schematic for some circuit. At the right, there is corresponding board-file. And at the middle you can see board-file after it has gone through "outlines.ulp" (you can run that from Eagle-menu by File->Run->outlines.ulp) with 0.1 mm setup. Blue lines are where milling head is supposed to move.

Instructions for producing suitable G-code from Eagle

  1. draw board what you are going to mill
  2. from menu, select "File - Run" and choose "outlines.ldp"
  3. from popup menu choose device as "Script", width as width of your drill or similar (in mm's) (I used 0.1 so that I could clearly see what it did.). Choose layer (usually it's "Bottom") and choose output file (it should have .scr - end since it's a script, eg. "output_outlines.scr" is ok.
  4. Close this board (don't save changes in this stage)
  5. Create new board (just click "File - New")
  6. run a scrip you just created, click "File - Script" and find your script from file-selection menu. After running that, there should be outlines of your board.
  7. get a "cam-job" for this board and print it out. I use Gerber and Gerberauto23 formats, I'm not sure which is more correct.
  8. (For EMC only...) Edit the gerber file. Remove "*" markings from end and convert every coordinate from X011234 format to X01.1234 format since there are no decimals in output of Eagle. You can also use automatic converter.

Using EMC from remote computer

I wrote this "chapter" for EMC Handbook and therefore you can read this in separate page if you want.

Project history

This part of this document describes a little how I got it working and what was difficult etc.


Today I got EMC's backslash settings configured. Seems that it can do pretty nice job, as you can see from this test-drawing made with just pencil as the tool. As you can see, after Z-axis was made more gently, better results could be achieved. Final drawing is made by small program drawing just saw-wave at 1mm and then with 0.5 mm. I must test this further, but this seems very promising.

I did calibration by just driving axis to 0.0 and then I put my finger to that axis and in turn drived it to -0.5 and to 0.0 and then to -0.5 and so on. Of cource I did minor changes all the time to backslash-value of configuration. When I finaly feeled the motion, just a bit, I started to move back and forth with just 0.1 mm moves. It could be done much much better than this, but for now it's enough for me.


Well, I found that Eagle 4.0 can output nicely GERBER-code. And it has ability to mill just outlines. So I had to test that right away. Here's the result:

There is 1 D9 and 1 resistor connected to each end of D9. One of resistor connections (left) is broken because it didn't quite rise up to Z as fast as supposed. There were couple of things with Eagle's output before I could produce even this:

After those changes I managed to produce above PCB. It's my first try, so it's not nearly as clean as it could be. For one, I think I must get even thinner drill. Now it's 0.8 mm, and it seems to be too much.


Now I have made a small Perl script to convert those things automaticaly. You can use it from the web also. Just copy and paste the G-code output what you get from Eagle to the web-form and press "Convert". Output should be plain text-file which is in such a format that EMC likes it. You can also download the converter for your own use if you like. Just untar it (tar xzvf eagle2emc.tar.gz) and read the source-file. Then just use it:

./ inputfile.cnc > outputfile.cnc


I bought better motor for my setup. It's a Bosch 600W router, 12000-27000 rpm. It's should be quite easy to attach to machine because it has nice round area just above the head. Below are couple of pictures of it. I decided that motor should be a) strong enough to mill some wood and b) it should last even when used continously hours. I was thinking about Dremel mini-drills, but after talking to one guy who has build many routers and CNC machines and after reading the CAD_CAM_DRO mailinglist I decided that Dremel was not good for this setup. The drill/motor is the most expensive part of this setup and it's no good to spoil whole thing by just using unsuitable motor. I hope I made the right decision. We'll see that after I attach it to my machine ;-)


I added negative limit switches to machine. They are connected in parallel to paraller-port's pin 13 and if one of them closes then EMC's coordinate letters turn red and machine goes to "E-stop" state. I also draw an cad picture of part that's going to attach new motor to setup. The picture is drawn with QCad program's free-version. It was quite nice to use and more than sufficient for these little drawings. The output-dxf file didn't load correctly to autocad, possibly because of lettering problems. But I transferred the picture by jpg-file and it was sufficient for my father-in law to produce the part.


I changed the control box to aluminium case. It's an old NMT 450 case and it provides quite nice cooling area to attach IC's. I'm driving my motors nowdays with 10V and approximately 5A (that's what whole setup is getting, 3 motors and 3 controllers). I'm also attaching the positive limit swithces and thinking about how to best route all the wires in this setup. The new control box helped a bit because it provides a setup that can be easily took apart from machine. Also 30 pin flat cable that is connecting the controlbox and machine helped a little to keep the setup less messy. But it would be nice if the wires between the motors and "D9<->30pin"-part also would be somehow more cleanly. I'm thinking about using some kind clips or similar to route the wires where I want them to be.


I made my first cuttings to wood with the new motor and motor attachment. It produces quite nice path with 6mm bit and 4mm deep cut. I also modified xemc's display to show everything in black. I also added a little translation to Finnish so that I can use program more easily. It's working better than TkEmc because I like to use just keyboard without mouse. In xemc I can switch modes with function keys and open the files with just "o" command. Of course it's not as pretty as it could be but I'm prefferring the superior "feel" of the program. It's so quick and still quite easy to use after learning keyboard-shortcuts. I have also upgraded configuration packet to match my current configuration what I'm using. The configuration allows now about 180mm/min movement and it's enough for me just now.


FIRST PCB's made ! I got my drill's (0.5mm) and my father in law has been Easter time here. We tried to make PCB's with new drills, and it was quite nice result, as you can see. It needs a little bit more tuning and a lot more sound dampening. I made a little sound dampening case for machine. After all, we live at concete flathouse and cannot afford neighborhs to blaim us for being too noisy... More PCB- and case pictures at pictures page.


The target of the project is getting to be very near. Today I got working PCB and holes to it. I drilled holes manually because I didn't have suitable drill to mount to mill. I got drill-files out from Eagle, they seem to need a little perl-script too for EMC to understand them. PCB what I made just needs soldering and then I can say that I have fully working PCB-milling machine. I also made wooden sign, "OH6KFT" (my radioamateur callsign), for my "hamshack". I'm quite satisfied for the result.


I'm nowdays milling PCB's and plastic with ease and with nice results. General feel of the process is every day getting to be more familiar. I'm using BDI EMC with RTLinux 3.0 and kernel 2.2.18.


I'm maintainer of FAQ on EMC with


With BDI (Brain Dead Install) distribution you can easily install EMC in your machine within hours. Try it, you'll love it ;-)


Siemens ISA-board driver for using with EMC. The board has 3 outputs for +10/-10 V, 3 inputs for encoders and lots of digital I/O's. The board is manufactured by Evosoft Germany for Siemens and I managed to write a small driver for it. It's now usable in EMC.


V2 of this project has started.


Pictures are on separate page because they are better accessed there and because they require a little bit more download time than plain text (like this page is mostly).


Some links to similar pages that I have liked a lot:

Feel free to mail me: Henry Palonen, Say NO to Power Line Communication !