Print This Post Print This Post

Converting a Proxxon MF70 Milling Machine To CNC – 3

Controlling the MF70 Spindle Speed

Updated 28th April 2012 with Eagle Schematic and Printed Circuit Board Design.

This post in one in a series. Other posts you may be interested in are as follows:

I’ve already mentioned that I’ve attempted to automate as much as is possible, so as to avoid tedium and the inevitable problems with repeatability when human intervention is involved. It would be useful to define required Tool speed alongside the tool definitions, so that when a tool is selected by gcode, the speed suited to the tool and work is automatically selected and implemented.


The MF70 comes equipped with speed control based, to put it bluntly, on a lamp dimmer. As a picture is always worth at least a thousand words, I’ve included my impression of the MF70 speed controller in the schematic below.

Authors impression of Proxxon MF70 Speed Controller

Author's impression of Proxxon MF70 Speed Controller

The circuit is ubiquitous, but I’ll glance over the operation.
Control over the firing angle of the TRIAC is managed by the 500K pot, together with the associated capacitors, assisted by the DIAC, hence altering the effective voltage across the bridge rectifier which supplies power to the DC brushed motor. The circuit is popular because it is cheap, and relatively problem free, the only mechanical component being the 500K pot.
Proxxon have marked the dial on the speed control knob in a range from 5000 to 20000 rpm. I have not checked this, but indications are that though a little rough, the calibration is adequate, given that the control over speed using a pot in this way is not linear, with greater incremental increases in speed as the knob is rotated clockwise.

Given my very healthy respect of mains-level voltages, and un-isolated ones in particular, I originally intended leaving things exactly as they are, and affixing a geared model-control servo motor to the side of the motor casing. I subsequently decided that this would end up as a mechanical monstrosity, which was difficult to keep free of metal swarf, and promising myself to be ultra careful, decided on interfacing directly with the electronics of the motor controller itself.

I haven’t ‘played’ with TRIACS in any serious sense, my experience pre-programming days was solely with Thyristors, so some time has been spent reading Application Notes. Not much has changed though, and the simple requisites for phase control are the determining of the zero-cross point in the AC supply, and the production of a GATE_ON signal after a pre-determined delay, depending on speed required.
Below, the Blue trace shows the zero-crossing pulse, (note that this occurs every 10ms here in the UK, where we have a 50Hz supply) whilst in red the ACTIVE LOW Triac control signal is shown, well delayed until just over 8ms after zero-crossing. The reason why the Triac control signal is ACTIVE LOW will become apparent in the next schematic.

Phase Control of Proxxon Motor @ approx 5000rpm

Phase Control of Proxxon Motor @ approx 5000rpm

Now contrast the above oscillogram with that below taken at a speed of 20,000 rpm.
Here, the ACTIVE LOW Triac control signal is triggered at around 5ms after zero-crossing, thereby turning the triac on much longer, hence delivering more power to the motor.

Phase Control of Proxxon Motor @ approx 20,000 rpm

Phase Control of Proxxon Motor @ approx 20,000 rpm

As well as controlling the speed of the motor, our additions should cater for turning the spindle motor on and off, as well as allowing for original manual control, and probably most important, shutting off spindle motor power when the BIG RED SWITCH is hit by the user, as mentioned in the 1st post on this subject.
Last, but most certainly not least, control signals should be isolated from the mains voltages on the existing speed-control board.

So a shortlist of requirements so far:

Detection of zero-crossing of the AC supply.
Generation and provision of the TRIAC gate signal.
Emergency shut-down.
Provision for manual control.
Complete isolation of mains-connected electronics from controlling electronics.

I came up with the following:

Proxxon MF70 Milling Machine Automated Speed Controller

Proxxon MF70 Milling Machine Automated Speed Controller

Don’t be put off by the apparent complexity of the above – look at each part individually.

First, the ‘original’ speed controller is retained on the right of the diagram, with only 3 small changes:

1. The connection between the DIAC and TRIAC has been severed, and flying connections taken to contacts on RELAY 2.
2. A flying lead has been added to A2 of the TRIAC, which connects to resistor R6.
3. A flying lead has been added to A1 of the TRIAC, which connects to capacitor C7.

A phase-control signal PHASE_CONTROL supplies ACTIVE LOW pulses to the opto-isolated TRIAC MOC3020, whose supply and snubber are connected as mentioned in (2) above, and whose output is taken from pin 4, via RELAY 2, to the TRIAC, whenever RELAY 2 is activated.

A zero-crossing detector circuit comprises R9, BR2, a zener diode, R10, LED2, C7, R11 and a 6N137. This generates a positive-going pulse every 10ms, ZERO_CROSS, which is opto-isolated from the mains supply.

A spindle motor ON/OFF circuit is comprised of Q1, D1 and RELAY 1. An ACTIVE HIGH on MOTOR_ON, will turn on the spindle motor if the Manual/Automatic switch (top-left of schematic) is set to ‘Automatic’.

Most importantly, the ‘Controlled 5V+’ supply comes from the ‘+5V supply to motors’ shown on the BIG RED SWITCH diagram in 1st post of this series. This ensures that when the user hits the ‘PANIC’ switch, not only will the X, Y and Z stepper motor supplies be cut, but the spindle motor will also be deprived of power.

Note I’ve shown the relays in their ‘de-activated’ state, which would be so if the Manual/Automatic switch was set to ‘Manual’, or the user has hit the PANIC button. In this state, the original Speed controller can be used, switching on the supply using the original (and retained) switch.

A suitable printed circuit design in Eagle is now available. Component & foil sides look like this:

MF70 Spindle Control from PIC Microcontroller - Component Side

MF70 Spindle Control from PIC Microcontroller - Component Side

MF70 Spindle Control from PIC Microcontroller - Foil Side

MF70 Spindle Control from PIC Microcontroller - Foil Side


As mentioned above, the relationship in AC control, between time and speed is not linear, and I had no wish to make exact, and complex calculations in software. Instead I decided on allowing the use of the ‘S’ gcode to select spindle RPM to the nearest 1000, in a range 1000 to 20,000 – a little better than the 5000 to 20,000 allowed by the original controller. The plan is to parse the input speed gcode, then divide this by 1000, to give an index into a look-up table containg effective phase-delays (TMR0 counts), the contents of which could later be tweaked with the use of a tachometer.

So the look-up table will look similar to this:

const rom unsigned int phaseval[] = {20000,21000,22000,23000,24100,24450,24750,25000,26000,26750,27500,28000,28500,29000,29500,30000,32000,35000,38000,41000};

G-code speed parsing like this:

		if (gcode.present & GCODE_S)
			int temp;
			// accept 1000 - 20,000
			// convert to 1 - 20
			// and look up tmr0reload in table
			// rough? yes, but later, calibrate with tachometer
			temp = gcode.S / 1000;
			if (temp > 0 && temp < 21)
				temp = phaseval[temp-1];
				// tmr0reload is volatile so disable interrupts
				INTCONbits.GIEL = 0; // low priority/peripheral ints
				INTCONbits.GIEH = 0; // enable high priority ints

				tmr0reload = temp;

				// re-enable interrupts
				INTCONbits.GIEL = 1; // low priority/peripheral ints
				INTCONbits.GIEH = 1; // enable high priority ints

And the interrupt system which processes the zero-cross signal and generates the PHASE_CONTROL signal:

InterruptHandlerHigh ()
	if ( INTCONbits.INT0IE == 1 && INTCONbits.INT0IF == 1)		// test for RB0 edge interrupt - ZERO-CROSSING
		// clear INT0 interrupt flag
		INTCONbits.INT0IF = 0;

		PORTBbits.RB1 = 1; // drive phase control HIGH (OFF)

		TMR0H = tmr0reload >> 8;
		TMR0L = tmr0reload & 0xff; // reload TMR0

		INTCONbits.T0IF = 0; // clear TMR0 interrupt flag.
		INTCONbits.T0IE = 1; // enable TMR0 interrupt

        // TMR0 interrupt
        if (INTCONbits.TMR0IE == 1 && INTCONbits.TMR0IF == 1) // test T0 rollover
		INTCONbits.TMR0IF = 0; // clear TMR0 interrupt flag
		INTCONbits.T0IE = 0; // disable TMR0 interrupt

		PORTBbits.RB1 = 0; // turn phase contol ON

A photo album exists showing my experiments in the development of the prototype speed controller. This can be viewed here:
I’ve also embedded a Shockwave viewer of the album below. The photos are best viewed full-screen.

Datasheet/Application Notes. I have provided copies of the following PDF documents for your convenience:
6N137 – opto-coupled Schottky Transistor
Opto-coupled TRIAC MOC3020

Suppliers: Everything I used here was available at my local friendly Electronics Store ESR. The relays were actually 6volt units – they run quite happily on 5volts.

Update 28th April 2012
The Eagle schematic and board files are here: and here:

Copy the code below to your web site.
  • Share/Bookmark
Create PDF    Send article as PDF   

You must be logged in to post a comment.