"Programming, like chess, women, and music, has the power to make men happy" - Gerald Weinberg

To start: Re-arm the "E-STOP", switch it to "Drilling/Milling" and press the "Start" button (spindle turns clockwise)

To stop: Switch it to "Stop" or press the "E-STOP" (spindle stops)

To restart: Re-switch to "Drilling/Milling" and/or re-arm the "E-STOP", and then press the "Start" button again (seems a little redundant).

Tapping:

To start: Switch it to "Tapping" and press the "Start" button (spindle turns clockwise).

To reverse out: Lower the quill until it triggers the bottom switch (spindle suddenly turns counter-clockwise).

To stop: Raise the quill until it triggers the top switch (spindle stops).

To restart: Press the "Start" button (spindle turns clockwise).

I can see that if you were tapping at the same Z height all day, that this could be a handy option. But the setup to get the quill switch to engage at the right point would be far too fiddly for small jobs.

In making the mounts for the motors, there's been a few tricky spots to drill holes for. One of the first projects I wanted to try was to make a corner drill. You know... one that can drill around corners.

I didn't realise that under Mach3, an M0 program stop wasn't "terminate", but "pause", and that pressing Run (Alt-R) again would continue on from the next line.

High on the list for the next project is that emergency stop button I should have...

I was keen to attach my home brew servo motors and see the mill move. The shaft on the mill's screws is 17mm, whilst the motor's 12mm shafts are designed for a small chain gear (small section of keyed shaft and a left hand thread), and I needed to grasp below this.

Since I'm coupling the motor directly to the shaft, a figured a coupler with a little flex was in order. My immediate solution was some vinyl hose and a pair of hose clamps. Affixing and tightening the coupler was tricky. The uneven shaft sizes (17mm & 12mm) made it difficult, and I destroyed several hose clamps trying to get it tight enough. That would work for a little while, but it wasn't able to handle the torque and would eventually twist in the middle. I added some support in the middle with a section of hard plastic tube to help prevent this.

But the length of the vinyl tube was too great, and its twisting added extra backlash to the system. Not only that, the backlash amount was unpredictable, increasing during use as the vinyl warmed up. It was always meant to be an interim solution, and the purchase of a 1m length of Ø40mm acetal rod ($55AUD) was the start of something better.

Technically, this was my first CNC machining experience. It was only 2 axes, and involved numerous manual interventions, but to see it moving automatically to perform the desired machining operation was very rewarding.

I've already made two couplers (X & Y), and shortly will make a third to automate the quill (Z). With that, I'll have full 3 axis control and should only need to stop for tool/fixture changes.

After months of putting it off, I jumped in and slapped two motors on to my mill.

I've already identified that the XY mechanisms on my mill aren't going to be up to the task (they have excessive backlash in both the bearing mount & the nuts).

Therefore, it's not worth spending too much time on the installation, as I'll need to redo it when I upgrade the mechanisms. I still hadn't done a "real world test" on my DIY servos & controller, and was keen to see the mill's table move.

Enter the angle grinder, 2 short pieces of RHS and some hose clamps...

So, what did I learn?

Keyboard: The wireless flexible keyboard I got is great. Chuck it where you need it.

Current Draw: It's not unusual in my 1:1 setup to see the motors draw 10A @ 12V. Hopefully this should drop when we switch to 36V. w

H-bridge Temperature: The H-bridge chips got hot. Real hot. I couldn't keep my finger on the heat sink, hot. Since pairs of H-bridges share heat sinks, I swapped the Y axis onto a different pair than the X axis. Then they both got hot... How hot? Not that hot: 57°C. I put a small fan near and let it continue to run: 32°C (ambient was 25°C). Not neccessary, but a larger heat sink or small fan would keep it cool.

Encoder Inputs: Since I only used 2 of 4 servo channels on my controller, the other 2 encoder inputs were left floating. Phantom transitions on these lines fire interrupts and unnecessarily consume controller time.

Limit Switches: This was a simple test, and no limit switches were installed. Luckily, the flexible coupling slipped when it attempted to go beyond the table's travel. Limit switches are a must.

DIY Flexible couplings: OK, small length of hose with hose clamps. While there is some twist in the soft hose I used, when you consider the 0.2mm of existing screw backlash (@ 3mm/rev) equals 24°, the <10° of hose twist & <6° of servo error is quite acceptable (for now).

The Z axis hasn't had anything done yet, but that's OK. Baby steps. Although it would be easier, I don't want to automate the quill since it's got a lot of play in its rack & pinion setup. I should get moving on the ball screw upgrade and automate the column.

Even with only the X & Y axes done, the machine is transformed. I'm happy to perform any required Z movement manually for the time being.

All in all... I'm pleased, and it's quite exciting (chips will fly soon).

These are used by the H-bridge boards I've currently got (packing a lot of power in to a small space). I was initially scared by SMD devices like this, but having seen people achieve amazing resultswithout specialised equipment, I think it's worth the effort.

The only feature I feel is missing is current limiting. The VNH3SP30-E has internal thermal, over-voltage and over-current protection, but that won't stop it delivering 30A to your stalled 2A motor. Dropping a resistor between the VNH3SP30-E and GND would allow you to determine the current by measuring the voltage at VNH3SP30-E's GND pins and combining that with your knowledge of the resistor's value.

Let's use a low 0.01Ω resistor:

V = IR = 30A x 0.01Ω = 0.3V

P = I²R = (30A)² x 0.01Ω = 9W

Therefore, for a 30A draw to show 0.3V, a 0.01Ω 9W current sensing resistor is needed: let's say 2 x 0.02Ω 5W resistors in parrallel.

For low current systems (<3A), the 0.03V drop may be too small to adjust. Let's use a slightly higher (but still very low) 0.1Ω resistor:

V = IR = 3A x 0.1Ω = 0.3V

P = I²R = (3A)² x 0.1Ω = 0.9W

A single 1W 0.1Ω current sensing resistor could be used in low current situations to make the drop more pronounced.

Add an LM339 to compare the 4 drops against a reference voltage and pass that thru a 4081 quad 2-input AND chip with the PWM signal for the H-bridge.

Well, it's done. I now have a self "contained" version of my 4 channel servo controller.

I've made PCBs for the controller, encoder & driver boards and mounted them all with the CNC4PC break out board I bought.

Controller Board (Top Left) - This was my first DIY PCB, and the design is a bit rough (no nice mounting holes, board shape, etc). The firmware can be updated via serial, so I didn't add an In System Programming connector (uC is in a ZIF socket in case of fuckup).

PC Break Out Board (Top Right) - This is a CNC4PC C10 Bidirectional Breakout Board. It's a basic BOB with buffered I/Os. Gets data from the PC into the servo controller.

Driver Board (Bottom Left) - It takes the 4 PWM+DIR signals from the controller and maps those into 2 dual H-bridge Pololu boards. I've added a couple of heat sinks to the H-bridge driver chips, which should help their cooling.

Accurately controlling the position of rotating elements is the heart of a motion controlled system. Often stepper motors are called upon to complete this task. Although cheap and plentiful at lower power levels, more powerful versions are expensive and difficult to source.

More vibration than other motor types, as the discrete step tends to snap the rotor from one position to another.

Generally must be over engineered, so that there is no possibility that the motor will lose steps.

Another device is the servo motor. This combines a standard electric motor and position feedback sensor with a controlling circuit. The electric motor can be DC (brushed) or AC (brush-less).

At the hobby level Gecko (US$114) drives appear to be the norm. The Gecko appears to be a analogue unit with gain & dampening trim-pots. A test-point reflecting the error (as voltage) is available to assist in tuning with an oscilloscope.

There are a couple of fundamental components to these servo drives:

Actual position conditioning & decoding

Desired position conditioning & decoding

Error calculation (from actual-desired)

Error filtering (PID calculation)

PWM generation

H-Bridge

Actual position conditioning & decoding
Function: This is the feedback sensor to determine the current position. They are built in to industrial servo motors, and industrial external sensors cost many $100s.Hobby Option: A low cost optical encoder can be had for US$20, and with a little effort these can be fitted to a standard permanent magnet DC motor. The output from these incremental rotary encoders, is "quadrature" encoded (two output wave forms 90 degrees out of phase). Decode quadrature input with a microcontroller.

Desired position conditioning & decoding
Function: The servo controller must be instructed of the desired position. Hobby Option: Derived from stepper motors, the defacto standard is STEP & DIRECTION signals. A "step" line is pulsed, and each pulse represents an increment or decrement depending on the state of the "direction" line. Software such as EMC2 & Mach3 can generate these signals. Decode quadrature input with a microcontroller.

Error calculation (from actual-desired)Function: From the actual and desired position, an error level must be derived. This can be done via analogue, or digital means.Hobby Option: Calculate with a microcontroller.

PWM generation
Function: From processed error calculate an output level.Hobby Option: Generate with a microcontroller. This is a logic level PWM signal (or signals) that control the H-bridge.

H-bridge
Function: Produce a high power PWM DC signal.Hobby Option: The H-bridge needs to match the motor. A simple 100mA unit can be constructed with BC548 NPN and BC558 PNP transistors. At 160A the 16 MOSFET Open Source Motor Controller project is the other extreme. Most setups will lie somewhere in between.

The most variable component is the motor. Different uses will require different motors, and different motors have different drive requirements. A number of DIY controllers, Elm Chan Servo, UHU Servo, Dspic-Servo, were all designed for the specific purposes of their creator, and integrate the H-bridge into the controller PCB. A modular approach, with a separate controller & H-bridge would be much more flexible.

I've created a prototype controller (PCB & firmware), and I'm using an off-the-shelf H-bridge.

I've setup Mach3 to drive the 4th axis tangential to the XY plane. This feature is used by vinyl cutters and such where the tool's orientation must follow the direction of travel. This includes lifting the tool before large changes (>45°), and lowering it before continuing.

This setup allows me to test my 4 axis servo controller in a "real world" situation. The motion appears a little jerky, but this appears to be Mach3 coming to a full stop before changing the 4th axis' direction (The RoadRunner test is not good for this since it's composed of lines and not arcs).

I've started making the mounts for the motors, but there is more tuning and testing to be done before final mounting of these motors on the mill.

When I'd picked up the motors, they had some heft. So out of interest, I put those motors on the scales... a total of 3kW (4HP) and 16.5kg (more than airline carry-on allowance).

I've mentioned previously that I think it's beyond me to visually judge the performance of the PID tuning values in use in my servo controller.

I had created a simple program to test the response, but wasn't happy with the point to point style test it was carrying out. It's more important for a CNC machine to follow curves closely, than have outright movement speed.

To fix this, I've added a feature to the microcontroller, a sine wave test. The test was added to the controller, because for a good test, a position update needs to be present every time the PID loop recalculates. By placing the sine wave path generation in the controller, a new movement value is present every single PID update. I couldn't achieve this sort of high performance timing by sending updates down a serial line.

Also, the standard point to point test produces massive errors when the set-point jumps, masking the fine detail of an "error" plot. I've added it now (on it's own axis), and it's very helpful in seeing exact levels of error (the large scale of the movement would otherwise hide this relatively small error).

Rotate 1 revolution forward and back in 1 second

Rotate 1 revolution forward and back in 5 seconds

In the above images you can see the reduction in error during a slower test (from +/-10 to +/-3). On the slower test, that's within 0.9 degrees.

I've also included a "steady state" option. This doesn't instruct the controller to make any movement, but it does record and display it. This lets you see the response to an external disturbance on the servo (the handy shifter!).

Armed with this new information... I still haven't gone back and re-tuned the PID values.

The nice thing about making your own PID controller, is that it's easily modified to add extra features. The nice thing about having PC software development skills, is that it's easy to whip up a small program for a particular task.

I've mentioned on a number of occasions, that I hadn't yet tuned the PID settings in my controller. I didn't want to do this because I could spend all day tinkering with values without being able to accurately judge the exact effect. What I needed was a way to monitor the servo response.

It took less than a dozen extra lines of microcontroller code, and a couple of dozen lines of C# (WinForms) to make a GUI application to test and monitor the servo. Once I had this, I could change values and with a mouse-click see the results. This made it very quick to tune by trial and error.

I used this method and it appears to work well, but this was a simple test on an unloaded motor. It will be interesting to try this once fitted to a more complicated system.

There is an issue with the current test... this a step-response scenario. That's great for a system which needs to move from A to point B as quick as possible. But in a CNC machine, it doesn't just move from one point to another. The motion controller (e.g. Mach3 or EMC2) will produce "smooth" motion with a constant stream of position updates. What is more important, is that the servo accurately follows this acceleration, than achieve high outright point to point speed.

In the future, I think I'll need to add a "Curve Follower" tuning option. Instead of jumping from point to point, this will drive the servo as if it was tracing a circle (a sine wave pattern).