We're still not 100% au fait with the requirements for open source, GNU licences and all that kind of stuff - does everything in the chain have to be open source? Can we use our preferred PIC microcontrollers to make a USB device when the Microchip software and USB libraries are not open source? Does it really matter?
We're blundering ahead with our software, but have hit upon two potential problems - and hopefully workable answers to them:
The first is converting the NC drill file units (mm or inches) into steps on our CNC machine.
Since a big part of our design process is to make the machine easily repeated and built from spare parts (salvaged printers are a great place to get hold of cheap steppers) we're trying to work from the assumption that the end user knows nothing (or very little) about their hardware.
Rather than have the user enter all kinds of values to describe their hardware (or worse still, guess at them) we thought we'd have a simple manual calibration routine at the start of the software. Simply put, the user loads their pre-printed/etched PCB onto the cutting bed and moves the drill head above the top-left-most hole (the software will highlight one if there are multiple possibilities). This will form the origin (co-ordinate point 0,0) for our cutting routine(s).
The software will then find the bottom-right-most hole (furthest away from the origin) in the drill file, highlight it and prompt the user to move the drill head (maybe using the computer keyboard's arrow keys or similar) above this second hole. Using these two co-ordinates we can calculate two vitally important things: scale and rotation.
In the NC drill file we have co-ordinates for every point on the board. Using pythagoras theorum (a^2 = b^2 + c^2) we can calculate the distance R1 between the top-left and bottom-right points. On our actual PCB, this represents the same distances between the same two points. The only difference is the units used to measure this distance.
In the same way the same distance can be described in imperial (inches) and metric (millimetres) by multiplying one set of values by a constant, we can do the same to convert inches or millimetres in the NC drill files into steps on the CNC machine. Let's pretend both images (above) are exactly the same size. Let's say the distance R1 is measured in millimetres, but we want the same distance R2 in inches. We know that 1 inch = 2.54cm and 1cm=10mm. So we can easily compare R1 (mm) with R2 (inches) by multiplying R2 by 25.4 (or dividing R1 by 2.54 to get R2, the same distance in inches).
We don't know what this constant value is to convert our NC drill measurements (mm/inches) into number of steps, but we can calculate R2, the distance the drill head travelled between two points, in terms of steps. Knowing the value of R1 (in, say, mm) and the distance of R2 in steps allows us to calculate the
scale between the two. Scale = R2/R1
The great thing about using the first hole as our origin point is that it doesn't actually matter at this stage whether or not the PCB board on the CNC machine is dead square. If the PCB board were not aligned exactly squarely, the difference between these two
distances would be exactly the same, since they both describe the radius of a circle with it's centre point at the origin
So now we've worked out the
scale (the constant to multiply our NC drill hole positions by to convert distances in mm/inches into number of stepper motor steps) we now need to work out the
rotation of the PCB on the cutting bed
Even if the PCB on the cutting bed were badly skewed, the ratio (scaling) between R1 and R2 would be the same. We know the location of the bottom-right-most hole from the origin according to our NC drill file, and we know the distance of the same hole on the actual PCB in terms of number of steps travelled in both the x and y axis. What we need to do is calculate by how much the PCB has been rotated.
One way to do this is to calculate the angle (from the origin) of the diagonal in the NC drill file (the larger of the three angles above) then calculate the angle from the origin of the current position of the drilling head.
Since we know the position of the cutting head from the origin in terms of steps (we count the number of steps moved in both the x- and y- axes) we can calculate this angle (the green diagonal) quite easily.
Using simple trigonometry:
If we rotate the bottom triangle 90 degrees clockwise, we can see that we've described a right angled triangle, where the adjacent side is the number of steps travelled in the y axis, the opposite side is the number of steps travelled in the x-axis, so tanA = stepsY / stepsX
From here we can calculate the angle of the position of the drilling head from the origin.
Using the same principles, and with the values from the NC drill files, we can calculate the angle between the bottom-right-most hole and the origin (top-right-most hole). The opposite side of this triangle is the difference between the x co-ordinates of the two holes and the adjacent side is the difference between the y co-ordinates of the two holes, so tanA = (y1-y2) / (x1-x2)
Knowing these two angles, we can subtract one from the other to calculate by how much the PCB has been rotated on the cutting bed. Now we know the
scaling AND
rotation, we can simply apply these to every point in the NC drill file, to get the number of steps needed to move in both the x- and y- directions to reach in point on the actual PCB on the cutting bed.
Apply rotation to a co-ordinate point can be acheived by using a
rotation matrix:
What this scary looking equation boils down to is - the coordinates (x',y') of the point (x,y) after rotation are:
x' = (x * cosA) - (y * sinA)
y' = (x * sinA) + (y * cosA)
Given that we know x and y (from the NC drill file) and we've calculated the rotation of the PCB on the cutting bed, we can work out:
xSteps = ( (x * cosA) - (y * sinA) ) * scaling
ySteps = ( (x * sinA) + (y * cosA) ) * scaling
where x and y are the co-ordinates given in the NC drill file.
And all without knowing how many teeth are on the CNC belt, how many steps the motors turn per full revolution or any of that other junk, nor without any headaches lining up the PCB to get it absolutely square and accurate on the cutting bed.
In theory, this provides a really nice and easy to use - if not entirely easy to understand for everyone - way of drilling every hole on the PCB, from an NC drill file, given the user has manually located two holes on the board.