A few posts ago, I displayed a few photos of a depressing walk around Gateshead Town Centre, and appended a link to a zip file containing the complete set of photos I took on the walk.
As a (stark) contrast, this post shows one or two photos of the Newcastle and Gateshead Quayside development, and again I’ve appended the full set of photos as a zip archive should anyone wish to look at these.
As with the walk last month, I’ve included an annotated map, showing my stroll, and also provided a text description for each photo.
I leave you to make your own mind up regarding comparisons that can be drawn from the two walk’s photos.
I’ve just spent most of the morning recovering one of my machines that I had foolishly allowed Microsoft to automatically update.
It’s an XP machine, and after the ‘upgrade’ yesterday was almost unusable this morning, with huge delays in accessing Explorer, and much, much worse, hanging when any attempt was made to shut down.
This successfully prevented me from doing a system restore, as this useless piece of crap will not run unless a clean automatic shutdown is achieved.
Eventually, I persuaded the machine into safe-mode – the only way of doing this successfully was from msconfig! Then restored the machine to the 28th April (last week).
I now have a fully-functional machine again. Oh yes, and one in which I’ve now turned off Automatic Updates – forever.
The only reason I’ve stuck with Windows, is that most of the development tools I used, had no Linux equivalent, and that is no longer true. Very soon, I will ditch Microsoft completely – nothing they have to offer tempts me to upgrade from XP, it’s just more of the same with expensive wrapping.
For the record, I’m running a dual-core AMD Athlon 64, 5000+ at 2.61Ghz, with 3.25GB of RAM.
Updated @ 16:28 13th April 2012
(see supplemental)
I’m playing catch-up here. The contents of this post refer to work over two days old, delay in writing it up is due to other, more pressing matters.
The good news is that after using LineGrinder to generate the G-Code from my little PCB, the two mysteriously-missing areas on the PCB are correctly rendered. I halted cutting of the traces due to the fact that a) there was insufficient depth-of-cut, and b) because of (a) the convex shape of the board made undercut inevitable.
RH Side: HV_OPAmp top foil - cut 2 using gcodes from LineGrinder.
Just about everything is better in this attempt. !st, the ‘JB’ and ‘1′ completely missing from the previous try are clearly visible. The pad outlines are a better shape, and not chewed to ribbons by repetitive tracing as in pcb-gcode. All that remains is to ensure correct depth-of-cut and present as flat a surface as is possible to the tool. This means a better clamping method than I used to-date.
Clamping used to-date
Above you can see my test board, sitting atop a sacrificial fibre-board. The aggregate thickness of these is around 4.5mm. I cut and milled one side of some 20mm gauge-angle so that the inside width of the cut side is 6mm – sufficient to generate a small angle when tightened to the mill table. I drilled 6mm holes to correspond to the mill table slots, and opened these slightly with a 6mm slot drill. The result is as you see above.
Probing the surface shows up a distinct, but slight convex hull, highest in the centre – furthest from the clamps. I will be investigating two methods of overcoming this, the first and most obvious of clamping the sides of the board as well, the second using pre-probing of the tool-route, outputting a compensating Z-axis dimension, and re-combining this with the original gcode. ( a little ‘z’ if you like)
This is not a new idea, and as I’m currently ‘logging’ the g-codes in the file-system as they are sent to the controller, it is a simple matter to send adjustments as the probe run is done, so to this end I’ve implemented the code, but have yet to try it out in anger.
As for pcb-gcode? Well I won’t bother investigating further, as the results from LineGrinder are just far superior. You may be interested to know that proper arcs (in gcode) are output for the pad ends, using LineGrinder, whereas rough polygons are output in pcb-gcode. Also, the drill holes are ’spotted’. I’m convinced which is the winner.
Below is the VEGA DATA simulator output.
VEGA DATA simulation from LineGrinder gcodes
I’ll report on my pre-probed cut in the next post of this diary.
JWB 12th April 2012
Supplemental – added April 13th 2012
No, I haven’t done the probing yet, but did try out re-arranging my setup.
First of all, I used a longer piece of circuit board.
Secondly, I didn’t tighten the clamps so enthusiastically as previously.
I then ran a clock gauge across the surface. No discernable distortion was evident in the centre two-thirds of the board.
Setup for flatness test of circuit board
Next, I increased the depth of cut in the gcode file to 4 thou.
The result is as below:
Third attempt at cutting traces
This is useable!
A few comments:
1st, the space there should exist between the pad with ‘1′ to it’s right and the SMD pad immediately below didn’t make it – it was always very fine, and adjustment of the Eagle project will sort this out.
Secondly, the apparent S/C between bottom-row pad 3 and isolated scrap is simply swarf – it dusted away.
Third. Although I like the DIL socket and SIL pin-holes ’spotted’, some of these ’spots’ are deeper than I would have preferred. (Edit: This is entirely my fault, due to my over-enthusiastic global-replace of the Z-axis dimension!)
These are simply niggles, and the machine can now be considered fully-operational.
Downloads
The Eagle project I based these tests on is linked elsewhere, but the gcode file I used to generate these cuts is here: http://joebrown.org.uk/images/MillTable/Diary/t2.nct Links
The 1mm cone cutter I used is available from ESR: Order Code 275-140, Description 1.0mm Miller Cutter – Conical, priced GBP £0.84.
I took a walk in Gateshead this morning. I had business at the Civic Centre, so thought I would check on progress (if any) that Gateshead Council had made in tidying up the disgraceful state of the once-proud Gateshead High Street. I documented my walk with pictures, all 250Mb of which are too much to load individually up to my album site. I give a taster here, but if any former Gateshead dweller would like to see this ’snapshot’, a zip archive is available.
First below I show my short walk:
Gateshead Walk 11th April 2012
I suppose the lowest point in the walk is the site of the Odeon Cinema – wasteland now for many years. Trouble is, things don’t actually get much better.
Odeon Wasteland - 'We come along, on Saturday Morning. Greeting everybody with a smile'
The once-proud Co-op has now been completely superceded by the Mamon Behemoth. The building below used to contain the Co-op ‘Food Hall’, where I was sent for the Saturday shop. You stood in a queue, until someone took your list, then he did all of the running around. Nowadays, you do all of the running around, and then you stand in a queue. Progress?
Site of the former Gateshead Co-op
The photo below shows new development on what became cynically described as the “set for the film ‘Get Carter’”. In other words, the infamous multi-storey car-park and it’s cafe that never sold even one cup of tea. I worked in Barkers (Radio store), which was just on the left down here, and we watched the film being made.
I wonder if this new development will fare any better than the late-60’s monstrosity?
A great deal of what we see on the Web, project-wise, is the ‘finished’ product. Every questionable decision has been ‘revisioned’, and what warts remain are carefully hidden, or presented as ‘features’. Yeah, I know this is a pretty cynical view, but unfortunately, nearer the truth, than even I would like to admit.
One of the great lessons I found, in a long career of software engineering, was to document every ‘failure’, every ‘good’ idea that turned out to be just plain bad, and attempt to make this collective wisdom available to the whole software group, so that when new ‘brooms’ came along, the same tedious business of making the same mistakes again was avoided. Well, it didn’t always work, but most of the time it proved very useful.
I could have documented my experiences alongside the Project Development posts, but I feel that would be the wrong place to do so, hence this separate diary.
Yesterday, I cut my first traces ‘in anger’ on a piece of copper-clad circuit-board. This was two copies of the bottom pads of the small HV_OP_AMP project I’ve been using as a test-set for the Proxxon MF70 CNC Conversion Project.
The results of this were encouraging.
This morning I cut the top trace of the same small board. Again the result is encouraging, but not without issues. So, rather than simply quietly sorting out these issues, I thought it might be a good idea to share these with others, contemplating similar projects.
1st take a look at the photo of the bottom pads, cut yesterday. (on a scrap piece of FR4 board)
HV_OpAmp Circuit Board - bottom foil.
And now, the bottom foil, together with a blow-up print-out of the foil as it should be.
HV_OpAmp Circuit Board - Top foil and print-out blow-up
Now, in my opinion, the upper photo shows excessive depth-of-cut, using the ‘default’ values in the pcb-gcode.ulp program. This sets the Z depth to -0.254mm, in Imperial units that’s 10mil. Considering FR4 board with 1oz copper is quoted to be around 2.08mil thick, 10mil seemed excessive. So some juggling required there. Also, as a result of excessive cutter depth, and the cone profile of the 0.5mm cutter I used, some loss of area can be noted around the pads – especially the small link pad. (The Mickey-Mouse ear of the pad 2nd-row, 4th from left) Despite these comments, these are matters which can clearly be cleared up with attention to the set-up.
Now moving to the 2nd photo, this too, has several issues. Ist of all, I reduced tool penetration to 0.102mm – or 4thou in Imperial measure. Removal of copper was still retained, but the setting showed up the sensitivity to a non-flat (slightly-convex) circuit board, in that the area closest to the left-hand clamp has not been completely cleared of copper where required. This led to short-circuits etc. Again, this is a matter of setup, and one I’m not unduly concerned about.
I marked the traces I was happy with on the blown-up print-out with small red ticks. As you will see a large percentage of the board I considered satisfactory.
What was a mystery were the two areas, both left and right, that I’ve surrounded with dotted lines and question marks. These two areas are supposed to contain SMD pads – instead they have been ignored.
Up until this point, I had trusted the output of the pcb-gcode program. I began to suspect that maybe that trust had been misplaced.
I downloaded and installed a trial version of VEGA DATA, and after a lot of fiddling managed to get the simulator to run. Yes, you’ve guessed – with exactly the same results, in that the two areas mentioned above are not machined as they should be.
VEGA DATA View of simulated trace cut of HV_OpAmp Top Foil
So. My Milling software and CNC conversion works – leastways it follows the instructions given to it, without protest or error.
Before I go further I need to investigate why pcb-gcode is ignoring parts of my PCB layout. When I do know, then I’ll let you know too.
At the start of this series of posts, I said I did not want a PC to control my Milling Operations, so some local delivery method of supplying the gcode files is required. Having said that, the system is ‘open’, and a simple XON/XOFF terminal program running on a PC can be used if required. G-Codes can also be typed in on a terminal keyboard, though this method could prove tiresome with even moderately-sized circuit boards. It is, though very useful for simple tests.
Whilst deliberating the problem, I first considered the Vinculum, from FTDI, but naturally (for me) would have preferred a PIC-based OTG (on-the-go) system. I had been carrying on email conversations regarding this with Gert Bouland in Holland, and he had suggested the Elektor USB Logger project (from December 2011) as one possible candidate. Gert subsequently kindly sent me a fully-built board, complete with PIC installed. I downloaded the logger firmware into the device, connected it up to the serial port of the Mill Controller and established that it worked. I then set about demolishing most of the original source-code, and developed the simple File System I describe below.
Before doing that is would be useful to briefly describe the original ‘logger’ hardware as presented in Elektor. If you haven’t already got a copy of Elektor December 2011, I recommend you purchase one, and read the full article by Thomas Fischl, if you intend to follow my route.
The schematic for the Elektor logger has been reproduced below:
The Elektor USB Data Logger - December 2011
The schematic shows a PIC24FJ64GB002 connected as a USB ‘host’ to the USB type ‘A’ socket. Interface (via the internal UART) is made by a dedicated set of peripheral pins to the 2-row 10-pin header.
Four connections are brought out in this way, sufficient for RX,TX and RTS,CTS if required. My application uses only RX and TX, handshaking being achieved with the software protocol XON/XOFF.
Circuit operation is simple, with a one-button/one LED (not shown on diagram) user interface.
On power-up, if a thumb drive is present, the unit will self-configure a baud-rate from a ‘config.txt’ file on the thumb drive, then start logging characters received on the RX input line. When desired, logging can be stopped by hitting S1, and then the thumb drive can be removed, and a file ‘LOGGING.TXT’ can then be accessed by plugging the drive into a PC.
Use of the logger hardware for providing access to gcode files can be made with no changes to the hardware whatsoever – but I added a reset switch between MCLR and GND – a necessary addition I felt. Update 15th April 2012.
I have removed the setting of the baud rate from ‘config.txt’, and also removed any support code for this. My application uses 19,200 Baud as a ’standard’, so I’ve hard-coded this in ‘main’.
I also added 2 LEDS to the hardware, one to signal when XOFF is in operation (which is most of the time), and one toggled on a byte send to the Mill Controller. These LEDs are connected to RA1 and RA0 respectively. (see source-code for operation of these LEDs)
Milling of circuit boards will require access to three types of files:
1. A drill file.
2. Top-trace routing.
3. Bottom-trace routing.
Using the gcode-producing facility on Eagle files produces different names for each file, but I wanted to keep the system as simple as possible, and most importantly, avoid long filenames. I plumped for three filters for the three file types above:
Furthermore, these are known only within the file system itself – I see no need to propagate fixed alpha strings into the Mill controller, so that the Mill controller only knows of files of type 1,2 or 3. That means, when you decide on a different naming convention, only one change to one set of software needs to be done.
We need the following facilities on the Mill Controller and File system then:
Ask the file system to give a list of files of a given type, 1, 2 or 3.
Ask the file system to send the contents of a file, line by line.
Additionally, the file system should recognize a signal for temporary halt (XOFF), and when to re-start sending the file (XON)
Finally, the file system should recognize an abort signal. (CAN)
Currently, because of the limited scope of the Mill Controller keypad, most of the ’special’ facilities are accessed as so-called functions. In the table below, I have described the actions for each of these in turn, with appropriate reaction by the File System.
Function No.
Purpose
File System Action
Result
50
List files in group 1, one at a time.
File system searches on drive, and presents 1st file to Mill Controller (if found) from group 1
Filename displayed on Mill controller LCD
51
List files in group 2, one at a time.
File system searches on drive, and presents 1st file to Mill Controller (if found) from group 2
Filename displayed on Mill controller LCD
52
List files in group 3, one at a time.
File system searches on drive, and presents 1st file to Mill Controller (if found) from group 3
Filename displayed on Mill controller LCD
53
Fetch next file in list.
File system searches on drive, and presents next file to Mill Controller (if there is one) from current group.
Filename displayed on Mill controller LCD
54
Execute current file.
File system presents contents of current file to Mill Controller, line by line.
Lines of gcodes executed by Mill Controller.
55
Abort current operation
File system aborts current operation, closing any open files.
Action on Mill Controller halted.
Software handshaking, using XON and XOFF is carried out transparently, by the software.
A code snippet from the software main loop running inside the file system, should give some clarity to one side of these transactions:
if (deviceAttached) // stick inserted in orifice?
{
// check for incoming data from Mill Controller
if (rx_in_index != rx_out_index)
{
// there's a char
ch = rxbuf[rx_out_index++];
if (rx_out_index == BUF_SIZE)
rx_out_index = 0;
switch (ch)
{
case XOFF : // stop sending to controller
stop = 1;
break;
case XON : // re-start sending to controller
stop = 0;
break;
case STX : // start of text command
for (cmd_index = 0; cmd_index < CMD_SIZE+1; cmd_index++)
{
cmd[cmd_index] = 0x00; // zeroise command buffer
}
cmd_index = 0;
break;
case ETX : // end of text command
ExecuteCmd(cmd);
break;
case CAN : // cancel current sequence
if (myInputFile != NULL)
FSfclose(myInputFile); // close any open input file.
tx_out_index = tx_in_index = 0; // cancel anything buffered
stop = 0; // cancel any current XOFF
break;
default: // place char in cmd buffer
cmd[cmd_index++] = ch;
if (cmd_index == CMD_SIZE)
{
cmd_index = 0; // CMD BUFFER FULL
}
break;
}
}
if (tx_in_index != tx_out_index) // if there's data for the Mill Controller, send a byte of it
{
// there is stuff to send to controller
if (!stop) // not stopped by previous XOFF?
{
// output a char to UART
while(U1STAbits.TRMT == 0); // wait 'til last sent
{
unsigned char ch = txbuf[tx_out_index++];
U1TXREG = ch;
if (tx_out_index == BUF_SIZE)
tx_out_index = 0;
}
}
}
else // no data? Are we executing a gcode file currently?
{
if (myInputFile != NULL)
{
// then get next line to send to UART
if (!FSfeof(myInputFile)) // check for end of file
{
chsread = freadln(line, BUF_SIZE-1, myInputFile); // read line until CR/LF
if (chsread != 0)
{
for (i = 0; i < chsread; i++)
{
SendBufferedChar (line[i]); // place line in TX output buffer
}
SendBufferedChar(CR); // Mill g-code interpreter needs these
SendBufferedChar(LF);
// debug - log it as well
Log(line);
LogChar(CR);
LogChar(LF);
}
}
else // end of file, so close it.
{
FSfclose(myInputFile);
}
}
}
}
It can be seen from the 1st section of code (the switch and case statements), that commands from the Mill Controller are split into two groups. Those that manage the flow of data between the Mill Controller and the File System, and those that respond to commands regarding the file system itself.
The 1st group is reasonably self-explanatory, the second may not be immediately obvious. A file-system command is sent from the Mill Controller bracketed with STX and ETX – in other words each command must begin with the control code STX and finish with ETX. The command is assembled, byte by byte received in the buffer ‘cmd’, and only when ETX is received is an attempt made to service it. This is shown in code snippet 2, below. It might prove useful to point out that ‘ext_strs’ is an array containing the 3 filters previously discussed (*.ncd, *.nct, and *.ncb)
///////////////////////////////////////////////////////////////////////////////
//
// Execute command for Mill controller
//
// Set up execution of a command
//
// commands are simple:
// a letter possibly followed by a number in some cases
// Example sequences:
// "D1" : search directory for drill files (extension .ncd); response: if none found return 'NAK'
// else return ACK then STX and retrieve and send the filename and extension . then ETX
// "N" : retrieve and send next filename found; same as for "F". If list exhausted, return 'NAK'
// "E" : retrieve and send each line of the (current) file (name in rec) (terminated CR/LF) in sequence;
// response: do this until instructed to stop with "CAN" or told to halt (temporarily) with XOFF etc.
//
// The control code 'CAN', if received, will stop execution, cancelling any sequence, and close any open file.
//
void ExecuteCmd (char * cmd)
{
int n = 0;
int attr;
switch (cmd[0])
{
case 'D' : // need a number specifying file extension
n = atoi(cmd+1);
attr = ATTR_MASK;
filefound = 0;
if ((n > 0) && (n < 4)) // accept ONLY 1 - 3
{
filetype = n - 1; // (lookup array is zero-indexed)
// do Findfirst
if (FindFirst (ext_strs[filetype], attr, &rec) == 0 )
{
SendByte(ACK); // success , got a name
SendBufferedString(rec.filename);
filefound = 1;
}
else
{
// none, indicate failure
SendByte(NAK);
}
}
else
{
filetype = 0;
// number not acceptable
SendByte(NAK);
}
break;
case 'E' : // begin sending current file contents to controller
if (filefound == 1)
myInputFile = FSfopen(rec.filename, "r"); // open the file
else
SendByte(NAK);
break;
case 'N' : // send next (or subsequent) filename for filespec given in N command
if (FindNext(&rec) == 0) // yes, there's another
{
filefound = 1;
SendByte(ACK); // success , got a name
SendBufferedString(rec.filename);
}
else // no more? then tell Mill Controller so.
{
filefound = 0;
SendByte(NAK);
}
break;
}
}
As you will see from the above, everything is kept simple and brevity is considered virtuous. I’ve left my comment field intact on the above which describes examples of use. Note that only 3 ‘commands’ are needed or used by the Mill Controller:
‘D’ followed by a group number 1,2 or 3 asks for the ‘directory’ listing of the group specified. (starting with the 1st file found)
‘N’ tells the file system to send the next filename in the group.
‘E’ tells the file system to send the contents of the file, line by line.
You can quickly relate the lettered commands to the function numbers given in the table above.
A discussion of the gcode interpreter itself will cover the Mill Controller aspects of commanding the filesystem, and this will form a later post.
With acknowledgements to Elektor Magazine and Thomas Fischl, for the application, and warm thanks to Gert Bouland for his kind support in providing ready-built hardware.
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.
Hardware
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.
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
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
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.
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 - Foil Side
Software
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:
A photo album exists showing my experiments in the development of the prototype speed controller. This can be viewed here: http://cullercoats.joebrown.org.uk/#53.22
I’ve also embedded a Shockwave viewer of the album below. The photos are best viewed full-screen.
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.
My layout is shown below. It may not be as intuitive or informative as the layout on a PC display, but contains everything I have found necessary for control of the Mill. (and previously the DRO’s on my other Milling Machine and Lathe.)
I should stress here, that this is an overlay – i.e. a plastic-faced, easy-to-clean front which has a cut-out for the LCD display on the left, space for ON/OFF switches and Edge-detection LED below that, and on the right, covers over a set of TACT switch buttons, which protrude slightly through the container front.
It is cheap and easy to make. (I laminate mine after printing the design on paper) It is also easy to change, should you want to alter the colours, wording, and even position of the legend, after changing the switch layout. (and detection in software if necessary) First and foremost then, it is adaptable.
Let me now describe briefly how the above is used to control the Mill functions.
Jogging an axis. Any axis can be jogged a pre-determined distance (number of stepper-steps) in both directions of travel. For a single jog, the relevant jog key is depressed and released, and for continuous jogging, a press-release then press and hold. The jog keys are the and on the same line as the axis you wish to jog.
Setting Absolute Zero for an axis. This is a common operation, and so has been made as easy as possible. First of all the pad is pressed, then the axis , , or , is required. You then have a choice of methods you can employ to set the zero:
Press again, to select the current position of the axis you have selected as the new Absolute Zero. Or:
Start entering a decimal value using the numeric keys, (optionally preceded by) an optional decimal point at any position, and complete entry of the number by pressing the pad. Or:
Press the axis key again to select setting the absolute zero by edge-detection. Then using the and pads co-responding to the axis you are setting, jog the axis until the tool hits the work. A flashing ‘E‘ will be displayed alongside the relevant axis display on the LCD, until the edge is found. The tool will auto-retract when an edge is detected, and the position at which the edge was detected will be stored as the Absolute Zero for that axis.
Setting a preset value for an axis. This is also a common operation. First of all the axis for which we want to set a preset is pressed: , , or . You are then invited to select a preset number 0-9. When this is done, you then have a choice of methods you can employ to set the preset value:
Press to select the current position of the axis you have selected as the new preset value. Or:
Start entering a decimal value using the numeric keys, (optionally preceded by) an optional decimal point at any position, and complete entry of the number by pressing the pad. Or:
Press the axis key again to select setting the preset value by edge-detection. Then using the and pads co-responding to the axis you are setting, jog the axis until the tool hits the work. A flashing ‘E‘ will be displayed alongside the relevant axis display on the LCD, until the edge is found. The tool will auto-retract when an edge is detected, and the position at which the edge was detected will be stored as the selected preset value for that axis.
Selects between the use of Absolute and Incremental co-ordinate values.
Selects between the use of Imperial (inches) and Metric (mm) method of measurement.
Is used to clear a number, or cancel an operation if one is in progress.
Is the multi-purpose entry key for a wide variety of operations and data entry. This will be discussed later, with each function detailed in a table.
Implementation
Currently, and as has been briefly mentioned above, the keypad is implemented as a matrix of low-cost, but robust, TACT switches. The rows of which are driven low in turn, by 4 outputs from PORT D of the PIC Micro-controller. The values of each column is tested in turn by 5 inputs on PORT A of the PIC Microcontroller.
Schematics of the keypad and controller board are given below:
MillTable Keypad Matrix Schematic
Mill Table Controller Schematic using PIC18F4620
Worth mentioning here, is that the ‘gaps’ on the 1st column of the keypad schematic, can be regarded as ‘phantom’ keys. Use of this is made in implementing the edge-finder, which occupies the ’slot’ immediately above S20 on the keypad schematic, and is thus activated by RD5 and detected on RA0. Special code is executed every time the keypad is scanned, to test this location 1st, and it therefore takes priority over every other key.
This project has been driven by a desire to free myself from the lengthy, expensive, fiddly, and extremely dirty, business of producing printed circuit boards. (PCBs)
The name, and it’s acronym have already become a misnomer in forward-thinking British Schools and elsewhere, where the production of circuit boards is being done by a wholly mechanical process, rather then photography and etching with acid. This process has been given the title ‘isolation routing‘, and the waste product – a mixture of copper and circuit board substrate – be it SRBP or fibreglass, is far easier to reclaim and recycle than the disgusting result of etching copper with Ferric Chloride solution, or it’s even more noxious alternatives. As important is the question of quality and repeatability – readers of my posts may remember several occasions when I complain that my home-made circuit boards do not live up to expectations, especially in winter when my ‘chemical’ lab (a walled-off section of my garage) is cold.
There were several constraints on my project, not the least of which was cost. I could not afford a CNC milling machine capable of the accuracy required, nor lash-out on expensive suites of software to drive proprietory drivers.
Secondly, I do not want a PC in my workshop, they are a liability, prone to crashing, and limit choices too much.
Thirdly, I wanted to make use of software tools I already have, in my case the Eagle Editor, plus tools that as well as tried and tested, were available free on the Web.
My modus-operandi is relatively straight forward:
Select a small, reasonably-priced Milling machine and convert it to CNC i.e fit stepper-motors to each of the axes X, Y and Z.
Design and construct MOSFET driver boards for the stepper motors using readily-available and reasonably-priced components.
Design and construct a controller-board that accepts as it’s input a text-file containing G-Code instructions, and which generates control signals to the stepper-drivers as it’s output.
Use Eagle as my circuit-board design tool, and use the plug-in ‘pcb-gcode.ulp’ to convert the Eagle files into G-Code drill and routing files.
Note that there’s nothing particularly novel about my list above, all of these things have been done before. Further, almost each of the stages mentioned can be substituted by the purchase of a commercial equivalent.
Difficulty and Facilities
Anyone contemplating treading a similar path to mine will probably wish to avail themselves of the short-cuts a commercial offering might bring, due either to their lack of facilities or feeling that their skill-set precludes parts of the path I have chosen.
I have to be honest here. I have a well-equipped engineering workshop (my garage has no room for a car anymore). It will be possible to do the mechanical conversion of the MF70 to CNC without the use of a lathe, but more difficult.
The electronics, though relatively trivial, needs to be produced to a reasonable standard – after all, it will be driving machinery. So you must be able to solder correctly, and follow a circuit diagram and printed-circuit layout.
What you don’t need, is any software-engineering skills, though if you did, these would be useful for customising the code.
Oh yes, you will need to brush-up on your understanding of g-codes, as you will probably want to edit in some small way, the files produced after running pcb-gcode.ulp in Eagle.
It would be useful to point out that this post is only the first of many on this topic. I will attempt in this post and all others that follow, to explain everything I’ve done, so please be patient. Email requests for information not yet presented may be politely ignored, though comments and queries on what has already been presented are welcome. There is a photo album which will be updated from time to time, and this can be found here: http://cullercoats.joebrown.org.uk/#49.81
so that your question(s) may be answered by referring to it. A Shockwave viewer to the album is embedded below. Photos are best viewed full screen.
A Photo Album documenting the experiments whilst developing the Spindle Speed Controller is also available here: http://cullercoats.joebrown.org.uk/#53.22, and a Shockwave viewer to this album is embedded below.
Mission Impossible?
“Good morning, Mr. Phelps. Your mission, Jim, should you choose to accept it..”
The art of the possible is to break down a complex task into it’s constituent parts, analyse these, deciding on inputs and outputs from each task, and devising a solution to attain this. So as a taster, let’s look at what we have to deal with as an output of the circuit-board design process:
High-Voltage Op-Amp PCB
High-Voltage Op-Amp Board - drill layout only
For my example, consider only the drilling process of the holes shown on the rightmost picture above.
Running pcb-gcode.ulp in The Eagle editor will produce some files, in amongst which is the drill file – containing a list of g-code instructions to perform the drilling operation. The file isn’t very big, but even so, I’ll list only the 1st part of it which shows all relevant g-code content we need to process.
I’ve added line numbers to the original file, so that I can refer to these in what follows. I have also broken the text in to meaningful chunks, each chunk performing a discrete mini-task.
I’ll briefly discuss some of the above, leaving the reader to fathom the remainder, using a good g-code reference. In the following, please ignore the bracketed code in the text.
First of all, two aspects of the above may have occurred to you as a little strange, the first being that some of the X-coordinates are negative, the other that the Y-coordinates have a large offset applied to them.
The first phenomenon results from Eagle insisting that my board is drawn upside down – and yes it is, my track is on the ‘top’ of the board. The second is easy, in my layout I cropped the board from it’s original Euro-card size to the top left corner, rather than the bottom left. (mea culpa) This will be clearly seen if you load my board into your Eagle Editor.
N13 thru N18 represent a tool-change sequence – a set of instructions to the controller to effect the loading of a tool – tool number 1 in this case.
The M05 instruction on line N13 tells the controller to switch off the spindle motor
The G00 instruction on line N14, instructs the controller to move the axes to the X, Y and Z positions given, so as to effect easy change of the tool.
On line N15, the M06 instruction, followed by the tool identity T01 indicates that the controller should load Tool 1, in this case a drill 0.6mm in diameter.
Line N16, a G00 instruction tells the controller to lower the tool to a position 0.508mm above zero, where zero is the surface of the workpiece.
The M03 instruction, on line N17, tells the controller to switch the spindle back on.
On line N18, the G04, followed by a pause period P3.0, tells the controller to wait. (until motor comes up to speed)
The above sequence will be repeated every time a tool change is required.
Now following the above, there is a drilling operation:
On line N19, the Z-axis is lowered to 0.508mm above zero – yes, this is probably superfluous, but I didn’t write/produce this code!
The G00 instruction on line N20, tells the controller to move to the position X-11.1125, Y94.2975.
Line N21 is the drilling operation. G01 instructs the controller to lower the tool into the work for a distance of 3.048mm, at the specified feed-rate of 127mm per minute.
When this is complete, line N22 instructs the controller to raise the tool back to 0.508mm.
The above action is repeated for each hole required in the board, with tool-changes when hole diameter changes.
The codes I have emboldened above, plus one or two more for setting absolute/incremental mode, and dimensional units inches/millimeters, are all that are required to drill a board.
I am not intending to provide a reference here, so you should discover for yourself exactly what is meant by the above-used codes, paying particular attention to the difference between G00 and G01.
In the above I refer to the controller at almost every other phrase. Put simply, this chap/gal/entity is an ideal controller – one who will interpret and carry out the instructions given in an safe, precise and expeditious manner, in other words carry out the operations in both spiritand substance.
Of course in the real world, there will be some instructions which cannot be carried out by the machine, without some human intervention, so that our controller refers to the machine/man meld.
In practical terms then, the controller will actually be somewhere between simply a human automaton, sitting in front of a manual milling machine equipped with DRO, reading the above file, and twiddlling the knobs, to a fully-blown automatic monster, in which every operation is fully automated.
My project aims for as much automation as is possible, given the constraints discussed above. On the MF70 CNC conversion discussed, the only operation in which there will be human interaction, once a g-code file execution is taking place, will be in the tool-change process, and this will be made as simple as unloading the current tool and fitting the one indicated.
So the execution of g-codes is conditional on the facilities available on the system running them, but there are also other matters to consider. Taking the apparently simple instruction of turning on the spindle motor, M03 in the above code. How fast should we run the motor at?
If the spindle motor will only run at one speed on your machine, then do you really care? As an engineer though, you should be matching the spindle speed to that required for correct operation with the tool diameter, and the material you are cutting – anything less will lead to less-than-perfect results.
So satisfactory execution of your g-code will rely on your correctly pre-programmed information taking regard of these parameters.
Again, I have tried to program as much facility into the controller to automagically select the correct speed, given tool diameter and materials, but bear in mind that the first (and currently only) aim of the project is the small-scale production of circuit boards. Source-code will be available for those who wish to extend and/or modify any functionality.
Command, Control, & Safety
Before beginning this project I trawled the Web for ideas. In most of the home-brew designs offered, it appears to be expected that the human be a constant spectator to milling operations, ready to intervene when ’something goes wrong’. The designs offer very little in the way of elementary protection against the self-destruction of stepper-motors for example. This project implements limit-sensing and also edge-sensing as aids to safety and security. The edge-sensing should be considered an essential, as without it, tool-changing will be boring and tiresome.
Stepper Control
Control of each of the stepper motors is via a MOSFET driver board, Parking & Sense Board and ancilliary wiring. Although these items are separate, they should nevertheless be considered together as an aid to understanding.
MOSFET Stepper Driver V2.00
There is really not much to say about this circuit. It simply converts the TTL voltage-levels from PIC controller, into a high-current drive for each of the 4 phases of a stepper motor. Requirements of each MOSFET are a very low RDS, and a Gate-Source turn-on voltage of less than 4.5volts.
Stepper Wiring
The 4 phases from the board above should be connected to the corresponding inputs here. GND is self-explanatory, but Sense, Normal & Park have the following significance. Sense should be regarded as an output from the wiring, and reflects the state of the 5volt supply to the motor. This is taken to a sampling node on the Parking Sense wiring shown below. Park & Normal are two distinct 5 volt supplies, only one of which will be active at any given time. Both these lines are output from relay contacts on the Parking/Sense wiring below.
The two micro-switches form the limit switches on each axis e.g. Left & Right on the X-axis.It will be seen the the ‘Normal’ supply is made available to the motor, when these switches are not activated, and the ‘Park‘ supply when one or other of the switches are activated i.e. at the limit-of-travel of an axis. A fuse protects the motor windings from stall currents.
Parking & Sense Wiring
Under default conditions, the line PARK_ON from the PIC controller is LOW, so that the MOSFET is switched OFF, and hence the relay is de-energised. Motor supply in these circumstances is available via NORMAL.
Consider the following scenario: One of the limit-switches on the above wiring has been activated. We can follow the path of the 5volt supply from it’s source on this wiring, via the ‘NORMAL’ route and discover it broken by the activated switch. ‘SENSE‘ will fall to zero volts.
This negative-going signal is filtered by R3 and R4 and given to a control pin on the PIC Controller via /LIMIT.
What happens next, depends on what the context of the operation being carried out was.
Most importantly it is worth noting that if the controller took no action, power has been removed from the motor, so it will not stall when a limit is reached.
Special provision is made here for the case where an axis has been ‘deliberately’ driven to a limit – such as a parking position. Should it be pertinent, the PIC will activate the PARK_ON line to the small MOSFET relay-driver, hence switching the 5volt supply to PARK. Referring back to the stepper wiring above, there is now a path via the activated limit-switch and control of the situation is re-asserted by the controller software.
Edge Finder Wiring
Although very important in enabling the automation of tool height measurement, and lateral position with respect to the work, the Edge Finder has an important safety and protection role also. Attempting to drive a tool downwards through work whilst the spindle is not revolving will inevitably result in the tool shattering and/or the Z-axis stepper stalling, or worse – both. The thought of high-speed steel tool fragments flying about is not one to be taken lightly, and should be avoided at all costs. A simple interlock between spindle on/off and the edge finder should proscribe against such an event happening.
The MF70 motor housing is earthed, so that the tool-tip will also be earthed, whilst the table is isolated i.e. currently not connected to anything.
Conveniently then, using the arrangement on the left, we can arrange for the opto-isolator transistor to turn ON, when the tool tip touches the Mill Table and/or work.
Motor Supply Master Switching
There is no doubt that the ability to quickly, and with minimal force or dexterity, break the supply voltage to a motor, has saved many a limb, if not life.
Even though the forces available are pipsqueak compared to a standard Mill or Lathe, I strongly advise the fitting of some form of PANIC button, one that is easy to find, and requires just a touch to activate.
The POWER ON button, by contrast, should have minimum profile, and require reasonable force to activate.
Here I have shown the simple scheme I use. A small micro-switch acts as the PANIC button, its actuator being a large red knob, conveniently sited, whilst the ON switch is a standard low-cost, low profile indented push-button.
If control of the motor-supply is to be implemented, then the 5V output from this circuit should form an OFF function for this also.
I discuss control of the MF70 motor unit at a later date.
To be continued This post, and the several to follow, will be edited and amended as I make further information ready for publishing.