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

The standard parallel port "pulsing" setup in Mach3 uses a set "kernel speed" (25-100kHz) and this is the rate at which it decides to output a step pulse (or not). It is therefore also the maximum pulsing rate. The implementation details are specific to Mach3, but how would you determine an "even" pulsing pattern?

Let's rephrase our problem: How do you evenly take Y steps over X periods (or, determine which points in a 2 dimensional raster should be plotted in order to form a close approximation of a straight line between two given points). Bresenham's line algorithm is a way to achieve this.

At the start, we're already 1/2 way to crossing into the next Y position. For each increment in X, we move Y/X closer. Once we cross into the next Y position, we're another 1 away from the next crossing.

Below is an example of 3 & 7 (yellow top & blue bottom) pulses per 10 periods being generated by an AVR micro.

When we produce a continuous stream of these pulses, the pattern repeats (prior & next pattern shaded below)

So, how much processing power is consumed by this? I'm using a 256 cycle ring-buffer to precalulate 4 output channels, and inserting a 10ms delay when the buffer fills. To help measure calculation duration, I toggled a line (yellow) high during buffer re-fill. One of the output channels is display below (it's 25kHz signal is not decernable at this resolution).

Of a 16.80ms cycle, 10.40ms is "available" for other tasks. Pattern generation currently consumes ~40% of "available" CPU time. I say "available", since the CPU is constantly interrupted for short periods to update the output.

ADSL Modem/Routers like the TP-Link TD-W8960N must maintain connection information between internet (WAN) and local (LAN) machines.

I'd been having issues with connections "freezing" after a minute or so:

MS-Outlook failing to send/receive

MS-Access connections to a remote SQL database would give errors

Our VOIP phone would fail to ring on incoming calls

RDP connections

I could re-establish the connection, and everything would be fine... until some period of inactivity. This smelt like a network/firewall issue, and the only thing in common was our TP-Link TD-W8960N.

Many ADSL Modem/Routers run a cut-down version of Linux, and the TP-Link TD-W8960N is no exception. Handily, it provides telnet console access and includes BusyBox with sh. NAT services are provided by netfilter's iptables.

For me, this returned 2024 & 2024. The router was tracking the maximum number of connections it could. This isn't as much of a problem as it sounds, since once two-way communication happens, connections are marked as ASSURED, and are retained over other connections when the table fills. This stops "active" connections being dropped to preserve connections that were never actually established.

The actual connections can be seen with:

cat /proc/net/nf_conntrack

When I did this I got quite the surprise - ALL of my connections were ASSURED. This means my Outlook, Access, VOIP, RDP connections were eligible to get dropped - and were after enough inactivity. Why? What were the other two thousand ASSURED connections? And why were they all in the TIME_WAIT state?

They were the continual stream of incoming (and quickly closed) BitTorrent connections. But why were they still being tracked?

When a TCP connection is closed down, the connection enters the TIME_WAIT state (which is per default set to 2 minutes). This is used so that all packets that have gotten out of order can still get through, even after the connection has already closed. This is used as a kind of buffer time so that packets that have gotten stuck in one or another congested router can still get to the other end. I was hosting torrents with DHT, and could get 15 connections a second (held for 2 minutes=1800).

2 minutes is complete overkill. If you don't see a packet within a couple of seconds, it's not coming. Also, the "connection" limit of 2024 is far too small (and the TD-W8960N appears to have plenty of free memory to store more connections).

Changing it...

Luckily, it's very very easy to change. Telnet into your TD-W8960N, enter your username & password (default: admin/admin) and then issue the following commands:

Making the change stick...

I couldn't find a way to issue custom commands to the router on startup. So, instead I looked for a way to automate issuing the commands. What I needed was a simple tool that took text and sent it over the telnet session.

As mentioned previously, the output from the opto-isolator is inverted from the input signal. It's also clear that the switch on/off characterists aren't the same. The 5V signal falls in ~1µS, but takes ~3µS to rise. Passing this thru digital logic chips may help square up the transitions.

After passing thru the inverter (NAND gate), the edges certainly are squarer. The slowness of the low-high transition at the opto-isolator (~3µS) has resulted in a noticable (~0.5µS) slope on the high-low transition out of the 4011 NAND gate. I really don't think this is a problem, but could be addressed by using a 4093 (Schmitt Triggered) version of the NAND chip (a whopping $0.02 extra per chip).

The gate drive to the lower mosfet. As soon as the 3.3V input goes high, the lower mosfet is switched off. But when the 3.3V input goes low, there is a slight delay before switching on - to allow the upper mosfet time to fully switch off(deadtime),

The gate drive to the upper mosfet. As soon as the 3.3V input goes low, the upper mosfet is switched off. But when the 3.3V input goes high, there is a slight delay before switching on - to allow the lower mosfet time to fully switch off(deadtime).

The dead time is blatantly obvious here. You can see the ~1µS delay between switch off of one mosfet & switch on of the other. I've heard that 500nS should be plenty, and this could easily be adjusted by changing the deadtime resistor connected to the IR21884.

Up until this point, I hadn't supplied any voltage on the motor supply terminals. Therefore (referenced to ground), the voltage on the upper gates was simply the gate supply (12V). To turn on N-channel mosfets you must provide a positive voltage at the gate relative to the source. For a high-side mosfet, where the mosfet source is intended to supply the motor at full motor voltage, this means the gate voltage must be above the motor supply voltage.

The taller of the two pulses is the high-side gate (the smaller, the low-side gate). With 12V for gate supply, and 10V motor supply, you can see the boot-strap circuitry is producing a ~20V (relative to ground) gate voltage for the high side, and ~12V for low side.

I'm not sure about the ringing that's visible. It may be coming from the motor that was connected at the time, or it could have been EM picked up by the probes - I'm not really sure.

Catching the comparator's output on my analog scope provded quite tricky (maybe I need a new DSO), because as soon as the comparator switched on, the mosfets switch off and the comparator switched off again.

So this is the current sense & output from the latch (being reset by the comparator). The current reference was set to 50mV which thru a single 20mΩ current sense resistor is 2.5A. 0V on the top trace is the 4th horizontal line from the top.

When the current sense voltage reached 50mV, the enable line to the mosfet drivers was shut-off (which stopped further current increases). The enable line would then by set high again by the next rise in the A or B inputs.

Here's a perfect shot the current limiting in action. During the first cycle the gate switches on and off as commanded. During the second cycle, the current limit is exceeded resulting in the enable line being sent low (switching off the mosfet). The 3rd cycle (left most side - we can only see the start of it) sets the enable line high again, and switches the mosfet on again.

It's all appears to be functioning as designed... Yippee! But if I did this for a living (especially documenting it)... a nice big 4 channel DSO would be in order.

Ok So I laid out a board. This is layout for the prototype board. I'm going to make a single-sided PCB on the mill, so bottom side tracks only and jumper minimisation was the goal.

I certainly haven't perfected PCB isolation routing, so a single track between 0.1" DIP pads was the smallest width I allowed. I'll admit the component placement was largely manual (into relevant sections), but the routing was 95% auto-router. A couple of adjustments were made after the first prototype - this is pretty close to the layout.

Basic H-Bridge Layout in Eagle

I printed the layout and stuck it on the board before routing & drilling, it is a handy guide when inserting components. I certainly wouldn't advise a paper-overlay (absorbing moisture, catching fire, etc) but it's fine for a simple prototype.

Bottom
of completed board

It's pretty ugly. I had numerous problems with the isolation routing (breaking tips, very wide). I've been using a Dremel 300 Series. The standard collet setup was just awful (massive run-out), I'd heard about using the Dremel 3-jaw chuck since this was more accurate. I put one in, and measured its run-out... yes, it is much better than the collet arrangement, so that's what I used on this board. After finishing the board (and breaking 2 tips), I rather accidentally was watching the tip of the spindle side-on and discovered that, when spinning, the bit was prone to break into periods of vibrating wildy (visually estimated at ~1mm). This explained the broken bits and wide cuts. Whilst invaluable as a hand tool, a Dremel is simply not a precision machine tool.

A Proxxon Professional drill/grinder IB/E has been ordered. With hardened steel collets and a manufacturer stated run-out of 0.03mm (1 thou), these seem to be preferred by the PCB routing hobbyists.

Top of completed board

So, besides a forgotten pullup resistor, decoupling capacitor and 2 x 1K resistors in series to make 2K, it's pretty close to the original design.

For an initial prototype - it'll do. When the design is a little more stable & tested, some cheap Chinese factory PCBs (ITead Studio or Seeed Studio) may be in order.

Alright... most of the thinking has been done. Here's what we'll need:

Input Opto-isolators

MOSFET Drivers

MOSFETs

Current sensing

Adjustable "current" reference

"Current" comparator

Over-current latch

Logic/Gate/Motor supply voltages

Miscellaneous support circuitry

Our overall goal is to translate two 3.3V inputs (A & B) into two high voltage, high current outputs (M+ & M-).

Input Opto-isolation

Role: Protect the source of the inputs & convert 3.3V signal to 5V.

Input: 3.3V @ 12mA, Output: 5V

Although it shows the HCPL2530, I'm actually using a HCPL2531. The HCPL2531 has lower propagation times (roughly half) and a higher Current Transfer Ratio (50% more).

R1 & R2 are current limiting resistors to deliver the correct current the the emitter within the opto-isolator. The HCPL2531's emitters have a typical forward voltage of 1.45V, and we'll be looking to take a signal from a chip producing 3.3V @ 8mA (far below HCPL2531's maximum current of 25mA).

A current limiting resistor to suit is R=(VS - VF)/I=(3.3V - 1.45V)/8mA=231.25Ω, a close E6 series resistor is 220Ω, giving 8.4mA.

The outputs of the HCPL2531 are an "Open Collector" arrangement. When the input is "on", the internal transistor will conduct to ground. By connecting this output "collector" to a current supply (a current limiting resistor to a voltage supply) a signal is produced.

Unfortunately, the signal is inverted. When the input is low, the transistor is off and the output goes high. When the input goes high, the transistor conducts and pull the output low. Further processing will to required to (un)invert the signal.

R3 & R4 are pull up resistors to place current on the output pins that the internal transistor will overcome. The HCPL2531's Current Transfer Ratio (output collector current to the forward LED input current) is 30%. So, with 8.4mA to the LED, only 2.52mA will be sunk to ground during the "on" condition. With a 5V supply, R=V/I=5V/2.52mA=1984Ω. A close E6 series resistor is 2.2KΩ, giving 2.3mA.

Input Conversion

Role: Take the output signals of the opto-isolator, and prepare signals suitable for other parts of the system.

As mentioned previously, our A & B inputs were inverted by the opto-isolators. We need to (un)invert them back to original high/low states as inputs to the H-Bridge driver chips. We also need combined A OR B signals to be fed to the reset mechanism of the current control section. So, two NOT (inverter) gates and an OR gate. This could be achieved with one 4069 hex inverter, and one 4071 quad 2-input OR gate chip. But there is another way. We have NOT A & NOT B signals, and want A OR B. De Morgan's laws state that P OR Q = (NOT P)NAND(NOT Q). Therefore we can use a NAND gate to produce A OR B from NOT A & NOT B. NAND gates can also function as inverters, by appying the signal to both inputs (or one input, and the other fixed high). By using the same gate type for both operations, a single 4011 Quad 2-Input NAND gate chip can be used for all logic conversion. A pin-compatible 4093 Schmitt Triggered Quad 2-Input NAND could also be used, with it's inputs being less suceptible to noise (our opto's output shouldn't be too noisy).

H-Bridge

This is the heavy lifting part of the circuit. 5V logic signals come in, and high voltage, high current signals go out.

The heart of the system are two IR21844 Half-Bridge Drivers (one for each side). They provide: output source/sink current capability 1.4A/1.8A, under voltage protection (gates won't drive with less than ~8V), adjustable dead-time (turn off one MOSFET vs turn on the other), floating high-side (up to 600V).

Let's look at a single side (A's, which is at the top of the diagram).

C1 & C3 are bypass capacitors to keep the voltage supply stable.

R6 is the adjustable dead-time resistor, and 39K provides ~1µS.

R5 & R7 are current limiting resistors for the IR21844. Giving that we have 12V to drive the gates, 22Ω will give 545mA - quite conversative given the IR21884 is rated to source 1.4A.

C2 & D2 provide the "bootstrap" mechanism. This is used to provide a gate voltage above the motor supply. It relies upon the lower gate Q1 conducting (the standard low state), then current flows from the gate supply (12V) thru D2 and charges C2 to 12V. When the output goes high, Q1 shuts off and the charge in C2 is connected to HO, driving (thru R5) Q3 on. The charge in C2 must be enough to supply gate voltage for the duration off the high state, since it's only recharged during the low state.

Sizing of this capacitor needs to account for: turn on required gate charge, gate-source leakage current, floating section quiescent current, floating section leakage current, bootstrap diode leakage current, desat diode bias when on, charge required by the internal level shifters, bootstrap capacitor leakage current & high side on time. International Rectifier's Design Tip DR04-4 proviodes details and examples of bootstrap sizing. In my calculations, I found it was dominated by the gate charge (70nC for the IRF540), and that 3 times the gate charge (3 x 70nC = 0.210uF) was a good guide.

D2 must switch fast enough to allow C2 to charge during the low period (~1uS), and high enough reverse breakdown to fend off the high motor supply voltages. My selected 1N4004 @ 400V may be too slow and high-speed UF4004s may be required instead.

Finally, current thru the motor must flow via U$1 & U$2 current sensing resistors. It's important that these are low value (to reduce power and voltage drop), accurate, non-inductive (giving the high-speed PWM) and capable of disapating the required power. Open air current sense resistors are suitable for this purpose. If we want to sense 30A as 0.3V, we need 10mΩ resistance @ 9W. This is achieved with 2 x 20mΩ %1 5W resistors in parallel (or a single one for <15A).

The /SD (enable) signal is supplied from the current limiting system and shutsdown the outputs.

Adjustable Current Reference

Role: Provide a user adjustable reference voltage

We need a user adjustable reference to compare the voltage from the current sense resistors against to determine an "over-current" situation.

I'm looking for a 25A limit, so adjustment across the 0-0.25V range. A voltage divider from a 39K resistor & 2K pot give a 5V/(39KΩ+2KΩ)*2KΩ=0.24V range (changing this resistor to 33KΩ would give 0-0.29V for a 29A limit).

C8 provides some filtering to avoid ambient & adjustment noise.

Current Compare & Cutout

Role: When the sensed current rises above the reference level, disable the MOSFET drivers until A or B goes high again.

A 4013 D-type flip-flop provides the /SD (enable) line for the H-Bridge driver chips, which must be high for the drivers to operate. When A OR B goes high, the flip-flop samples it's data value (always high, since we tied D to 5V) and placed it on the output Q, thereby switching the drivers on. This happens at the start of every A OR B pulse.

The H-Bridge driver goes to ground via
current sense resistors providing a voltage @ CSENSE. To keep out noise, we pass this thru a low pass filter made by R13 & C7 with a cut-off frequency of 1/(2πRC)=1/(2π 100Ω x 0.001uF)=1.5MHz.

D3 protects the comparator from the filtered CSENSE signal going negative. It is a BAT85 schottky diode providing a lower forward voltage and fast switching.

The filtered current sense voltage is compared with the user reference voltage by a LM393 comparator. When the voltage (sensed current) exceeds the user preference, the comparator will go "high". Like the opto-isolators, this is also an "open collector" device - when the comparator's output is "high", the output pin will conduct to ground (overwhelming the R14 pullup resistor) and go "low". This low signal on the flip-flop's Reset input will switch Q off, disabling the H-Bridge driver chips until the current drops below the threshold and the next A OR B pulse starts.

Introduction

Off the shelf servo controllers are quite expensive, that's why I decided to hack together my own. But if you want to apply some muscle - lower voltages (12V) just won't cut it.

To get high power (>1hp/735W) from 12V you'll need to draw high current ~61 Amps. Put simply, that's a 0.2Ω load. This presents some challenges:

A 61Amp 12V power supply. They're rare.

A power supply, connectors, wiring, controller & motor with a total resistance of <0.2Ω.

A 1hp 12V motor. Those that exist are rare, expensive and heavy.

These are some of the reasons why higher power commercial servo motors start at 24V and progress to 36, 48, 60, 70, 90 & 180V.

My plan calls upon a modular H-bridge unit to take care of turning logic level signals into high power motor drive.

The design of choice is a MOSFET H-bridge. MOSFETs are simple enough, by inducing a voltage between the Gate and the Source, current can flow between Drain and Source. There's two types of MOSFETs: N & P channel, which are basically mirror images of each other (in terms of positive and negative voltages).

Simple N & P Channel MOSFET H-bridge

Gotchas

To turn a MOSFET on, apply more than the threshold voltage "VGS(th)" to the gate. But MOSFETs aren't perfect devices, they have limits, including a limit on the gate voltage. For quick switch-on/off the gate voltage should be towards the maximum allowable without going outside MOSFET limits. A stroll thru International Rectifier's MOSFET list shows 71% of their devices have a maximum gate voltage "VGS(MAX)" of 20V, 20% are 16V or less, and the remaining 9% are 30V. This means, once you go beyond a 30V supply, you can't simply use the supply voltage on the MOSFET gates.

For a motor supply of VMOTOR and gate drive of VGS (minus for p-channel, plus for n-channel), you'll need to switch:

High side MOSFET gate between VSUPPLY and VSUPPLY±VGS

Low side MOSFET gate between GND and ±VGS

That's two extra supply voltages, ±VGS & VSUPPLY±VGS (which could be the same for VSUPPLY< 2 x VGS(MAX)). Oh yeah, an extra thing - P channel MOSFETs simply aren't as "good" as N channel MOSFETS. (Since P-Channel majority carrier holes have lower mobility than N-Channel electron carriers, the on-resistance of P-Channel devices is two or three times higher than that of an N-Channel of the same area). International Rectifier's lowest RDS(ON) for a p-channel device is 4.7mΩ, whereas n-channel is 0.7mΩ. Current? 74A vs 429A.

You can't turn on both the high & low side MOSFETs, that's a short circuit and will destroy devices. That's straight foward enough... but they don't turn on & off instantly, so you need a delay between switching off one, and switching on the other.

Don't supply a gate voltage below the threshold voltage "VGS(th)", that'll partly turn on the device, and it will turn the power it's throttling into heat. We want it on or off, not in the middle.

Enter the MOSFET drivers

The complexity of this isn't lost upon semiconducter manufacturers and numerous components are available to assist. But unfortunately, they didn't get together to come up with a standard name for this device.

One of the great things about them, is they often include the ability to help generate a voltage above the motor supply voltage allowing use of N channel devices all around (typically at the expense of 100% drive - ongoing switching is needed to generate that higher voltage).

The difference between these (IR2183 & IR2184) seems to just be the turn on delay. I think this could be handy for overcoming the gate capacitances of larger MOSFETs which could take longer to turn off (got to avoid that shoot-thru!).

I've seen many designs filled with resistors & diodes parralleled along the gate drive line. This appears to be to avoid shoot-thru by allowing the MOSFET to turn off quickly (via the diode) but on slowly (via the resistor). Both the IR2183 & IR2184 also have a variant (IR21834 & IR21844) where the deadtime is programmable via an external resistor (up to 5000ns vs 400ns). To me, that sounds like a much better alternative (especially since it appears I can source the more featured IRS21844PBF at half the price the lesser IRS2184PBF would cost).

Add a quartet of IRF540N (44mOhm 100v 33A) or IRFP260N (55mOhm 200v 46A), and we're getting close to a solution.

Limiting Current

Delivering 30A with the possibility of stalling the motor means that we should have current limitting. A standard current limiting method for inductive loads is to measure current and switch off when the limit is exceeded, and back on when it falls below. The inductive load smooths the current change so this is a reasonable method (it won't race too fast). Unfortunately when dealing with boot-strapped high-side drivers each "on" transition consumes charge in the bootstrap capacitor. If we switch off & back on 10 times in a cycle before the capacitor is refilled, we'll drain it to a point where it won't supply enough voltage to switch the MOSFET on "hard" enough (risking the MOSFET).

What we'll need to do is recognise exceeding the current limit and switch drive off until the next rising edge input. This might stop us delivering maximum levels of continous power - but this is current limiting for safety, not current control for performance.

Detecting over current

Probably the easiest way is to use a current shunt and measure the voltage drop against a reference. Let's check what we can achieve with a pair of 0.02Ω 5W current sense resistors in parrallel.

P = 10W = I²R = I² 0.01Ω = 31.6A

V = IR = 31.6A x 0.01Ω = 0.316V

Maybe use a LM393 to compare against an adjustable reference voltage, and indicate when it's exceeded.

Staying off

By using a D flip-flop (CMOS 4013) we can switch the output off on over-current (reset), and have it reset by the next rising edge for a leg (clk).

Isolating inputs

It's a good idea to electrically isolate incoming signals to this high current, high voltage board.

Let's look at an example: 50kHz PWM, 1% duty cycle: 20μS cycle with a 200nS pulse. But your standard off the self 4N25-28 has typical 2μS rise and fall times. That's just not fast enough to accurately pass the inbound waveform.

It's worth noting, the 6N136 is 20V, whilst the 6N137 is a 5V device. I think, treated right, we can probably get the required performance from a 6N136, and run all components from a 5V/12V supply (the IR21844 has a maximum 10V logic input voltage, and we want more that 10V to drive the gate voltage).

One of the signals needed in my servo controller is a PWM signal to control the motor driver. From the Papilio FPGA board I plan to use, comes a 3.3V signal and there's two things that it will need.

Isolate it from the "nasty" high voltage/current sections

Translate it from 3.3V to 5V+

I had an 8 channel PC817 based Futurlec Opto-Isolator Mini Board ($5) lying around (it uses 560Ω series input & 1kΩ output pull ups), and wondered how it would perform. I rigged it up and was initially pleased.

PC817 based opto @ 1Khz

The bottom trace is the 3.3V input, and the top trace is the 5V output (both 2V/div).

Then I moved the frequency from 1Khz up to 25Khz...

PC817 based opto @ 25Khz

At 20Khz the output is barely exceeding 3V and certainly couldn't be called a square wave. At 20% duty cycle, it's basically off, and at 80% - completely on. If we produce a 25kHz signal, and want ~1% accuracy on the duty cycle, we'll need an opto capable of switching in around 1% x 25Khz Cycle = 1% x 40μS = 0.4μS. The PC817 has a quoted 4µS rise & fall time.

It was time to find a higher performance opto, and "common" DIP optos include the 6N13n family (manufactured by Fairchild, Vishay, Avago, etc):

6N138 & 6N139 - 0.1Mbs 10/35μS (High-Low/Low-High) switching

6N135 & 6N136 - 1.0Mbs 1.5 & 0.8μS switching

6N137 - 10Mbs - 0.1μS switching

It looks like the 6N136 should perform as required. A dual channel version, the HCPL2531 is available as well (and so I ordered a couple).

The HCPL2531 has a stated Input Forward Voltage of 1.45V and maximum average mitter current of 25mA. Passing 3.3V thru 220Ω will give IF=(3.3-1.45)/220=8.4mA. Maxium Average Output Current is a paltry 8mA (vs slower 6N138/9's 60mA), so the output side required a 2.2KΩ pull up to 5V (2.2mA). HCPL2531's propagation delay charts show the best "standard" results for IF=16mA & RL=1.9KΩ (close enough to my 8.4Ma/2.2KΩ setup).

HCPL2531 based opto @ 25Khz

The HCPL2531 was much better, and much more suitable to the PWM signals. Top is 3.3V input and the bottom is 5V output (the upper & lower traces are swapped from previous photos before).

The PC817 would still be suitable for slower signals (errors,home switches, etc), and will probably get used for exactly that.

One of the issues I've had during development of my servo controller are the limitations around accurate signal creation & capture.

A 1440 pulse per revoltion encoder at a modest 3000 RPM results in 72,000 transitions a second - every 14μS.

A PWM cycle @ 40Khz lasts just 25μS, with a 1% duty cycle adjustment being 250nS.

Input step signals from controllers such as Mach3 are often expected to capture pulses as short as 1μS.

My Atmel AVR based design used hardware interupts to detect input changes (and fire a capture routine), and hardware timers to initiate output changes (and fire an output update routine). With these routines written in assembly, it's quite efficient, but there's still overhead in firing such routines, and that limits minimum delay between events. With multiple servos at higher speeds, there's event contention, with multiple input events firing very near (or during) the same time output events need to happen. I'd love to record your clocking pulse, but I'm busy pulsing these outputs....

Enter field-programmable gate arrays (FPGAs). If you're not aware, FPGAs are chips filled with "logic blocks", and reconfigurable interconnects. A hardware description language (HDL) or schematic tool is used to describe the desired function. "Synthesis" then converts this into a "netlist" of gates and connections. "Place and route" finally maps the design into the targetted FPGA device - which "logic blocks" to use for what and how to connect them (this is the most complex and time consuming part of the "build" process). The resultant bitstream can then be loaded into the device.

So, how much can you achieve with such a device? With enough real-estate for about two basic AVR processors, Xilinx's XC3S250E with 5,500 logic cells & 66 I/O can be had for ~$15. Meanwhile, a single XC6VLX760 chip with 760,000 logics cell & 1,200 I/O pins and will set you back ~$20,000 (and they've just announced a 3 times larger XC7V2000T with ~2 million logic cells!).

This all sounds good, but these high-tech devices can often be a right pain for the DIY hacker - expensive or difficult to source in small quantities, requiring complex support circuitry, physically difficult (fine pin pitch or BGA), etc. What you want, is someone to do the dirty work for you - put together everything in a nice module.

I've found a few options on development boards/modules (rough prices - only devices I can afford):

Introduction

The standard signalling for hobby CNC axes is know as STEP/DIR. Two lines, one indicating direction (High/Low=Fwd/Rev), and the second is pulsed (Low to High to Low) to indicate a single step. A problem with this scheme is the possibility of this STEP pulse going by unnoticed.

While hardware based schemes for capturing this pulse may have no trouble dealing with fairly short pulses (1µS or less), in a solution where the signal is "captured" by software (even one initially triggered by a hardware interrupt) may not respond quickly enough to catch these fleeting pulses.

I've seen numerous discussions about getting reliable pulsing from Mach3 to the external device (stepper or servo driver). There's usually claims of accuaracy or reliability from certain setting changes... usually without providing any basis for such claims.

Kernel Speed

Manual:"The Mach3 driver can run at frequencies from 25,000 Hz (pulses per second) up to 100,000 Hz, depending on the speed of your processor and other loads placed on it when running Mach3. The frequency you need depends on the maximum pulse rate you need to drive any axis at its top speed."

That sounds fair enough. The kernel can produce at most 1 pulse per cycle - the maximum pulse rate is the kernel rate.

Pulse Width

Manual:"Pulse width is another consideration. Most drives will work well with a 1 microsecond minimum pulse width. If you have problems with the test moves (e.g. motor seems too noisy), first check that your step pulses are not inverted (by Low active being set incorrectly for Step on the Ports and Pins>Motor Outputs tab), then you might try increasing the pulse width to, say, 5 microseconds. The Step and Direction interface is very simple but, because it can still 'sort of work' when configured badly, it can be difficult to fault-find without being very systematic and/or looking at the pulses with an oscilloscope."

On my copy of Mach3, I can alter the step pulse width (Config->Motor Tuning->"Step Pulse 1-5 us") between 1 and 15 (values greater than 15, are reverted back to 15). This is three times greater than the UI or manual might lead you to believe. How do these changes present in the real world?

Watched on an ol' silly-o-scope, my machine produced step pulse widths matching this setting, but with a minimum width of 3µS (entering 1, 2 or 3, all produced a 3µS pulse).

"Sherline 1/2 Pulse mode"

1/2 a pulse? If you can't even catch the short duration pulse currently produced, why would you want a shorter pulse?

The name is misleading because what it performs is actually half of the pulse change on each kernel cycle (ignoring the pulse width setting). The pulse rises at the start of one kernel cycle and falls on the next, so that the pulse duration is a full kernel cycle duration. With a kernel set to 25kHz, that's a full 40µS of pulse width - much greater than the UI would let you set.

Timing of various pulsing sizes & methods

What's the catch? The downside is that a full pulse cycle (rise & fall) will now take 2 full kernel cycles - effectively halving your maximum pulse output rate. That said... you could always up the kernel speed if your hardware has the grunt to support it. Even at 65kHz, the pulse width will still be slightly longer (15.4µS) than the maximum configurable width with standard pulsing (15µS).

Kernel Speed (kHz)

25

35

45

60

65

75

100

Standard

Pulses/S

25000

35000

45000

60000

65000

75000

100000

Pulse Width µS

As per config

Sherline 1/2 Pulse mode

Pulses/Second

12500

17500

22500

30000

32500

37500

50000

Pulse Width µS

40

28.6

22.2

16.7

15.4

13.3

10

Kernel speed & pulse widths

"Enhanced Pulsing"

What's this do? Well... it doesn't affect the pulse duration. So it's not about "recognising" steps.

Manual:"Enhanced Pulsing, if checked, will ensure the greatest accuracy of timing pulses (and hence smoothness of stepper drives) at the expense of additional central processor time. You should generally select this option."

It turns out, that Mach3 calculates movement in sets of 5 kernel cycles - "In the next 5 cycles, I need 2 steps", "In the next 5 cycles, I need 4 steps", etc, etc. "Enhanced Pulsing" distributes these steps more evenly within the sets of 5 (e.g. wait-STEP-wait-STEP-wait instead of STEP-STEP-wait-wait-wait). It takes more processing, but a "smoother" stream of steps it the result.

Art wrote:"Shifter is a bit special, it tells the engine how to space the maximum of five steps the move represents to keep them as well anti-aliased as possible in time. Smoothness is the result. This 'Shifter' variable is what you are turning off or on when you select 'Enhanced Pulsing' in the App configurations."

So, "Enhanced Pulsing" helps with smoothness, and this may be more important for stepper based systems (where each step results in a physical actions), than servo based systems (where a step just updates the desired position).

For my controller (and probably everyone else's) it probably makes sense to push the pulse width as close as possible to half the cycle duration. For 25 or 35kHz, that's the maximum 15µS available in standard (non-Sherline) mode, and 11, 8, 8, 7 & 5µS for 45, 60, 65, 75 & 100kHz respectively.

This makes sense to me... but of course, there could be some reason internal Mach3 that would make this a "bad thing".

Standard Notepad Just Isn't Enough

For a technical user like me, Windows build in Notepad.exe sucks. It's better than nothing, but it's missing a stack of features:

line numbers ("status bar")

line numbers (it's worth mentioning twice)

line ending LF (Unix), CR/LF (Windows) & CR (Mac) handling

whitespace display

line ending display

regular expressions in search & replace

adjustable tab width

Don't use it then? I don't. I use Notepad2. Unfortunately, the standard Notepad.exe in Windows is embedded in a million different places - "Open With...", open ".txt" files, edit ".bat" files, edit SQL scripts, view HTML source, and many more. Sure, you could try a search and replace excercise in the registry, but you'll probably install a new product that will try and utilise the original Notepad. Simply copy Notepad2.exe over Notepad.exe? The file protection mechanisms in Windows will automatically switch back to the original. Replace the protected version? It's possible if, a little tricky, but a future service pack or hotfix may simply overwrite it. What we need is EXE redirection.

Image File Execution Options

Windows offers a neat way to automatically start a process within a debugger. Before execution, the Windows CreateProcess function checks for a registry key at "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\filename.exe". If that key has a string value named "debugger", then that value is executed instead with the existing command line added to the end (this could be [notepad] or ["C:\Windows\system32\notepad.exe"]). This means instead of "notepad hosts.txt", it will execute "debugger.exe notepad hosts.txt". So, you could run a substitute executable as long as you can get the new executable to ignore the first parameter. Notepad2 4.0.24 has introduced the "/z" switch, which means "ignore the next parameter" (this also exists in Programmer's Notepad) just for this purpose.

Configuring for Notepad Replacement

Start a command prompt (cmd.exe) as Administrator, and execute the following (replacing "C:\Program Files (x86)\Notepad2\Notepad2.exe" with the full path to your Notepad2 executable):

The "debugger" executable to run (quotes are escaped with backslashes).
Change this to the full path to your Notepad2 executable (I'm on a x64 system).

/f \"^%LOCALAPPDATA^%\Notepad2.ini\"

Notepad2 will use config file in user's profile directory (percent signs are escaped with carets)

/n

Always open a new Notepad2 window

/z

Notepad2 will ignore the next parameter (will always be the original Notepad.exe name)

"

end of quotes around the data

/f

forces reg.exe to overwrite any existing value

The first time you run it, the user specific config file won't exist (and won't automatically save on exit). If you want to keep your config settings, you'll need to explicitly save settings (F7) once, and from then on your settings will be saved.