Wednesday, 29 June 2011

Multiple touch sensitive inputs

In a previous post we talked about how to use a darlington transistor to create a touch sensitive switch.

For a device with multiple touch-sensitive inputs, it seems obvious that we repeat the single input for each pin we want to use as a touch sensor:



However, for each input our component count increases.
In the example above, we're using PORTB on the microcontroller, which has a built-in pull-up resistor on each input pin. If we need to use a different port, or want to use more than 8 inputs, we're going to have to add a pull-up resistor on each input pin. Also required - though not shown on the diagram above for the sake of simplicity - is a 1M pull-down resistor on the base pin of each darlington transistor.
So for each additional input, we're introducing three extra components.

It's worth noting, at this point, that for each touch sensitive input, we need two pads per input: one pad connected to the base pin on a transistor, and one pad connected to the 5V supply (the user touches and effectively creates a bridge between the 5V supply and the base input pin).

However, we can simplify our design massively by swapping the pads around:
instead of a fixed 5V supply and multiple darlington transistors, we can use a single transistor and multiple, variable 5V supplies. How to do this?
We turn each potential input pin to an OUTPUT and use this output to drive what would otherwise be a fixed 5V supply on the first pad. So each pair of pads that make up a touch-sensitive switch consist of an output pin (from the microcontroller) and a pin connected to the base of the darlington transistor.

a simple PIC/usb device with 16 touch sensitive inputs

Every touch contact would consist of a pair of pins/pads - one going to each of the numbered pads (PAD1, PAD2 etc) and the other a common input (COM_INPUT) so there would be a total of 16 COM_INPUT pads all tied together.

The pseudo-code would go something like this:
  • turn off all outputs
  • turn on output RA2 (PAD1)
  • has RA0 gone low? (yes=finger present across PAD1 + COM_INPUT)
  • turn off output RA2
  • allow time for input to return high
  • turn on output RA3 (PAD2)
  • has RA0 gone low? (yes=finger present across PAD2 + COM_INPUT)
  • turn off output RA2
  • allow time for input to return high
  • etc.

It depends on the type of darlington transistor you use (different transistors have different response/switching times) and the size of the pull-down resistor on the base pin, but in practice, with a 1M pull-down resistor, we found that 0.5ms (500us) worked well. Using this approach, we were able to poll all pins in under 10ms (0.5*16 = 8ms). At 100 times per second, this was more than responsive enough for our needs!

Until we can use the CNC again....

...the most exciting thing about getting a CNC machine working is the ability to quickly and easily drill our home-etched PCBs. But also, the ability to carve shapes and make enclosures for forthcoming projects is pretty cool too.

We've a few projects in the pipeline, which make use of some pretty simple but powerful underlying technology. After running a few workshops in and around Brighton and receiving a few emails from previous posts on other projects, we're going to document these in their entirety.

We'll be using the 18F2455 and 18F4550 PIC microcontrollers to create USB/HID devices. And we're also incorporating a simple touch-sensitive interface. At the minute, capacitive touch sensors are all the rage. What this basically means is that each touch pad connects to a microcontroller and when the user places their finger over the pad, a simple capacitor is created. The relative capacitance of the pad is compared over time and when the capacitance changes, the microcontroller can detect whether a finger has been placed near or removed from the pad.

The downside of capacitance touch sensing is the need for relatively large pads - or dedicated capacitive sensing hardware.

To keep our project simple - both in writing the firmware (capacitive sensing firmware can be quite convoluted and multiple readings averaged over time to smooth out any rogue analogue readings) and in sourcing the hardware - we're going to use an alternative approach:

A transistor is often used as an electronic switch, but it can also be used as an amplifier. A tiny current onto the base pin of an NPN transistor allows a much larger current to flow through the collector and emitter pins.



Whatever current is directed onto the base pin is amplified onto the collector pin.
By "feeding" the output from one transistor into the base pin of a second transistor, we can amplify the input signal many thousands of times over



In fact, by feeding one transistor into another, even the tiny amount of current that passes over the surface of your skin can be used as a switch. Such transistor pairs are available in a single package, known as a Darlington transistor.

Here's an example of how we can use a darlington transistor as a touch sensitive input device for a PIC microcontroller:

The schematic above uses a darlington transistor, such as a BC517 as a single discrete component. Although a darlington transistor is actually two transistors connected as shown above, we will draw it as a single transistor for simplicity.

Touching the two pads - however large or small they may be - causes the transistor to switch, forcing the current to flow from the input pin to ground. While this may seem counter-intuitive (normally you might expect voltage to flow into an input pin to indicate an input switch) the reason for this should become clear: on a lot of controllers (and had we put this input onto PORTB) you can use internal pull up resistors on the inputs, removing the need for the external resistor as shown in this example. If your controller does not have internal pull-ups, the resistor is there to stop the input pin "floating" when no finger is present on the contacts. The resistor should be quite a high value, say 100K.
Now, when the pads are touched, a tiny current flows from 5v on PAD1, over your finger, onto PAD2 and into the base of the darlington transistor. The transistor amplifies this current, creating a "switching effect" and causes the input pin to go low.
When the finger is removed off the pads, no more current flows into the base pin, the transistor closes the "switch" and no current can flow from the input pin to ground. The pull-up resistor causes the input pin to go high when the pads are not touched.

Although the above gives us a working touch-sensitive switch, we're not quite done. If you try the schematic out, you might find - depending on the type of darlington transistor used - that while the "on" trigger works (i.e. the input goes low immediately after touching the pads) the "off" time can be quite slow (i.e. the input pin remains low for a second or more after removing your finger from the pads).

The reason for this is that the darlington transistor can amplify even the tiniest little current - even residual electrical noise can be used as a trigger; it's a bit like leaving an input pin floating - the base pin of the transistor is so sensitive it can switch on and off almost at random. And like a floating input pin, it can remain active even when the input is removed.



The answer is to put a pull-down resistor on the base pin.
Now, when your finger is removed, any residual current on the base pin has a path to ground, and the switch closes. The size of the resistor determines the response time. If the resistor value is too low, it may stop the transistor switching on at all (the human body has an electric resistance of around 40k-100k so this base resistor needs to be much higher) but too high and the residual current on the base pin may take too long to be pulled to ground, resulting in slow response times. In practice, we found that a resistor with a 1M resistor on the base pin (R2), with a 100K pull-up resistor (R1) on the input pin worked well and gave reasonable response times.

Setting the scale on the CNC machine

So far we've managed to create our own g-code from ExpressPCB layout files and got our CNC machine moving to our own home-built g-codes. Now the last piece of the puzzle is to get our machine to move according to the g-code created from the ExpressPCB layout. Sounds simple?

It should be - but so far the CNC machine seems to be making up it's own scale! Sometimes a command of G0 X5 Y0 (move 5 "units" in the x-axis) causes the gantry to travel a few cm, and other times, it tries to travel further that the maximum distance available!

What we're aiming for is a CNC that moves in inches.
To calibrate our machine, we want to be able to draw dots at 0.1" intervals.
The idea being that after replacing the pen with a 1mm drill bit, we can make our own PCBs with a 0.1" pitch that fit perfectly into the breadboard prototyping boards.

Here's how we got on....

The first thing was to get the CNC machine to draw something, using a known scale.
Unfortunately we didn't know anything about the machine - we discovered that the stepper motors we 1.8 deg/step with micro stepping (they were originally painted over!) but without details on the lead screws, we had no idea how many steps per mm were required. So the plan was to draw a shape - or series of shapes - using g-codes to draw one unit lengths (e.g. GO X1 Y0 would draw a horizontal line in the x-axis, one "something" in length).



From here we measured our "one unit" using some digital calipers and found it to be 0.821 inches in length. We decided to use inches as units (since we know that breadboard and vero board uses 0.1" pitch, it made sense to stick to inches). So with our current Mach3 set-up showing 2000 steps per mm and knowing this produced a line 0.821 inches long, changed the steps per mm to (2000/0.821) = 2436.05

With this new setting, we drew a grid of dots, each 0.1 "units" apart.
We also, for comparison, drew grids using 2400 steps and 2500 steps per mm.





After drawing the grid, we compared the output to some 0.1" pitch vero board.
The grid drawn at 2436 was ok for a small area, but much beyond 10 holes, and the drawn dots and the actual dots on the vero board started to drift. This means we need a value either slightly higher or slightly lower than 2436 (actually, we expected this to be the case, which is why we'd already drawn extra grids at 2400 and 2500).

At 2500 the dots in the grid seemed to drift out of alignment quite quickly, after four or five dots:

(The angle of the photo reduces the effect of the drift, but it is very noticable when viewed from directly above)

At 2400 we seem to have a perfect match. The grid of dots remained perfectly in line along the full length of the vero-board.

The angle of this photo does not really make the perfect alignment obvious, but each of the dots stays in the exact centre of each hole on the vero board.

So it looks like we've finally got the CNC set up and working properly!
The real test will be when we pre-drill some copper board BEFORE etching.
In theory, the press-n-peel transfer and the drilled board will line up perfectly.
But since it's gone midnight now, and BuildBrighton is closing it's doors for another few days, that'll have to wait until next time........

Sunday, 19 June 2011

Calibrating the XAML to Drill application

We've added a calibration PDF to the xaml2drill files posted earlier. We used this to work out what our "scaling" value should be, when converting xaml into g-code.

It turns out it's pretty simple (and obvious) but here's what we did anyway:
In ExpressPCB we placed a number of pads in a small square



Print top copper layer to a PDF and open in Inkscape, then save as .xaml
Load the .xaml into our VB app and set the scaling to one
(so we can see the exact output from the .xaml before it is modified)

The resulting g-code:


G0 Z0
G0 X0 Y0
G0 Z2
G0 Z0
G0 X0 Y60
G0 Z2
G0 Z0
G0 X0 Y120
G0 Z2
G0 Z0
G0 X0 Y180
G0 Z2
G0 Z0
G0 X180 Y180
G0 Z2
G0 Z0
G0 X120 Y120
G0 Z2
G0 Z0
G0 X60 Y60
G0 Z2
G0 Z0
G0 X60 Y0
G0 Z2
G0 Z0


Just by looking at these values, we can see that in our conversion, a value of 60 is the same as 2.54mm. Or, more simply, 0.1". This means that to convert our .xaml into g-code that uses inches as units, we need to set the scaling to 600 (60 divided by 600 = 0.1)

This suddenly seems quite obvious. If our images are drawn at 600dpi, it makes sense that we should set the scaling to 600 to get from screen pixels to inches!

From this simple test we concluded:
To convert the .xaml to g-code in inches, scaling = 600
Since 1 inch = 2.54mm, to convert inches to mm we should multiply by 2.54
So to convert .xaml to g-code in mm, scaling = (600/2.54) = 236.2204724409449

How accurate you want to be when scaling is a matter of how accurate your CNC machine cuts. As far as we're concerned, deviation of up to 0.3mm per hole is still quite tolerable, so we use scaling 236.22 for millimetres and 600 if we want the g-code in inches.

Why use ExpressPCB?

If you're an Eagle aficionado, you'll probably find ExpressPCB a little simple for what you need - but that's exactly why we love it; there are no complicated rules and sub-menus to wade through: simply fire up the software and start drawing!

ExpressPCB is brilliant for making PCB layouts ready for home-etching (with the toner-transfer method). Some Eagle users still have problems with mirrored layouts and transferred images coming out the wrong way - we've never yet had such a problem with ExpressPCB!

Simply draw all your PCB layout components and traces on the top (red) layer. Draw them as you would expect to see them on the final board - as if you were looking down on the assembled PCB. Don't worry about pin alignment, mirroring and all that other stuff that seems to blight Eagle users so often. So long as pin1 on any microchip is in the top left-hand corner, and your drawing is in red, there should be no problems!

For home etching, we like to use big fat 0.5mm traces. Although we use a laminator for our projects, which does allow smaller/thinner traces to be used (we've successfully gone down to 0.2mm before now) we appreciate that not everyone has access to such hardware, and may be using more crude methods of transferring toner to copper (e.g. a household iron). Because of this, we found 0.5mm traces give the best results for anyone wanting to follow our board layout designs.



Because we do a lot of hand-drilling and sometimes even use a Dremel with bendy-attachment, we need quite chunky pads too (to allow a little bit of leeway if the drill is not perfectly centred). We've found that a 2.03mm pad with 0.89mm hole is ideal for us (and most other people) when using a standard 1mm drill bit



One last thing - ExpressPCB doesn't have an auto-route option.
Some people find this a problem - we've never bothered with it anyway (when we used autoroute in Eagle, we found we had to amend the final layout that it generated to make best use of the board space, so figured we'd be as well doing the board layout by hand). For home etching, we try to cram all our components together as tightly as possible - some people like to space things out: it's all about personal preference!
Here are a few common tricks you can use to help with board layout;



If you need to connect two sets of pads, keeping the numbering the same, but without regard for orientation (which way up the pads go) you can use simple "C-shaped" traces - each trace passes around the outside of the previous one. The pad numbering keeps the original order, but the final set of pads are "upside-down".
If you need to keep all pads in the correct sequence AND the right-way-up, use "S-shaped" traces. This connects, for example, the right-hand side of one pad to the left-hand side of another, but ensures that the resulting pads are laid out in exactly the same way as the originals.

Before printing your PCB layout, create a filled plane to fill in the gaps between traces. If you just print out your copper traces, your Ferric Chloride will have a lot of work to do, removing all the material between traces. This means etching takes ages and also saturates the FeCl much more quickly than is necessary (once Ferric Chloride has etched a lot of copper away, it becomes weaker and weaker, taking more time to etch each subsequent board)

Note anything on the silkscreen/yellow layer will not get printed in the final design - so overlapping things on different layers is quite acceptable

Select the filled plane tool and draw a rectangle over the entire PCB layout.
Right-click to stop drawing the plane and your board should appear something like the image above.
Change the board properties (menu Layout -> Board properties) and set the clearance around holes to 0.5mm to match the size of your traces.



The final printed design will have nice clear traces and big fat chunky pads which are easier to solder onto. Even if you're using a household iron to transfer the toner from the press-n-peel onto the copper board, the relatively thick traces and spacing between them should allow you to get away with a little movement during ironing (always a problem, and can cause smudged and broken traces when thinner lines are used).

When you transfer the image onto the copper board, it will, naturally be reversed. For example, pin1 on all your microchips is suddenly on the top-right hand corner, not the top-left. Don't panic - this isn't a mistake! That's exactly what you want, because the PCB image is on the bottom of your board. If you turn it over and place the components on the top (non-copper) side of the board, you should find that all the pads line up with the components perfectly (pin1 on the top side of the board is on the top-left, but turn the board over and it magically appears on the top-right side of a set of pins - because you're looking at the bottom of the chip, not the top).

Why use ExpressPCB?
It's free.
It's easy.
You can create drill files from it!

Creating drill files from ExpressPCB

Here's a simple VB app that will parse an xaml file generated from an ExpressPCB PDF and plot the points for drilling in a separate file, and a g-code.
That's sound like more than it is, so let's look at what's involved:

Firstly, create your schematic and PCB layout in ExpressPCB. When placing pads, use pads with 2.03mm size and 0.89mm hole:



Print the top copper layer to a PDF file using CutePDF



Open the PDF file in Inkscape and save as .xaml
The .xaml file should open with later versions of Internet Explorer (amongst others) so you can check the conversion worked properly. Open the file in Notepad to see all the complex XML shape descriptions.



Now start up the VB app and provide it with the path to the .xaml file



There are a few parameters to mess about with here. The main one is the code that describes a circle. If you've used 2.03mm pads with 0.89mm holes, this should be c -7 0 -12 -5 -12 -11 0 -7 5 -12 12 -12 6 0 11 5 11 12 0 6 -5 11 -11 11. You should see this set of commands repeated throughout the .xaml file, each time preceeded by [mX Y] type commands. If you've used different pad sizes, look for something similar - a repeating set of draw commands at different positions, with a fill colour of #FFFFFFFF (the [mX Y] commands are movement commands, the fill colour is white: basically we're looking for the repeating white circles that make up the centre of all the pads).

At the minute, we're not sure what units the .xaml file uses compared to our CNC machine - it will take a bit of messing about to get this right, so there's a scale multiplier parameter. As the app finds all the drill holes, it applies this multiplier, to convert from screen units/co-ordinates to whatever units the CNC machine uses. The final parameters to set at the Z-axis movement axis. The app will create some G-Code which can be loaded straight into the CNC controller software (we use Mach3 but may change once the demo version runs out!). Depending on whether the machine is set up to use inches, mm, or some other unit, this value may need to be changed - it defines the start (retracted) and end (plunged) position of the Dremel for drilling.

Pressing the "create files" button generates two files - one an amended .xaml file, so you can see a preview of the drill pattern generated. Load this into Internet Explorer (or some other software that lets you view .xaml) so see the final output.

The original and amended .xaml files showing drill hole positioning

The VB app also creates a CNC-ready G-Code file with the points plotted, complete with "move-to" commands and "extend/retract drill head" commands.



Load the G-Code into the CNC controlling software and let it go!

Download the VB app here

Friday, 17 June 2011

Building a drilling milling machine

With the arrival of our CNC machine, all kinds of ideas starting springing to mind. But the idea behind getting a machine like this was to help speed up the production of PCBs - to easily create kits of components for workshops, like those run by BuildBrighton, or even to produce products for an online shop or to sell on eBay.

So that's where we're starting - to get the CNC machine to drill a series of holes that match up with a PCB circuit/design.

Following Tom's excellent research into g-code files, we're pretty confident that we can get the CNC to move to specific points above a sheet of copper-clad board, and activate the z-axis (up-and-down axis) to get it to thrust a Dremmel drill into the board. The most challenging part is to create the g-code to begin with!

So far, we've resisted all attempts to learn Eagle for designing and producing PCBs. But it looked like this was on the cards, since it already includes export options for drilling and milling PCBs. The only trouble with Eagle is, well, it's just not very nice. The software we use for schematic design and PCB layout is the excellent (and free) ExpressPCB.



It's just easier and all round nicer to work with - no confusing menus, sub-menus, things hidden inside other windows and so on. It has a really neat library of existing components, and if you can't find what you're looking for, creating your own is a doddle. Because we do a lot of home-etching, you can make big fat pads and traces really easily, and the final boards produced are easy to solder and work with. Eagle, on the other hand, was just confusing and produced boards with nasty lozenge-shaped pads and thin traces that were easily broken during etching.
The problem with ExpressPCB is that although the software is free, it's provided by a fab-shop who want you to send your designs to them for manufacture. As a result, there are no export options supported.

To date, we've always printed a PCB layout either straight to the printer (where the press-n-peel is already loaded and ready to do) or - using CutePDF - to a PDF file for editing.

Inkscape is a great program for editing graphics-heavy PDF files. So naturally we loaded our PCB into Inkscape and choose the "ungroup" command to break the board up into lots of lines and circles.
Then we selected the (black) centre circles found at the centre of each pad and copied them all to the clipboard. By creating a new image and pasting the copied shapes into the top-left hand corner, suddenly we had the basis for our drill file:


From within Inkscape we saved this new image as an .xaml file


This created an XML document, filled with plot and curve commands.
The curve/shape commands are of little consequence to us, but the plotting commands are just what we're after:


<?xml version="1.0" encoding="UTF-8"?>

<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Name="svg5395" Width="744" Height="1052"><Canvas.Resources/><Canvas Name="layer1"><Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path4253" Fill="#FF000000" Data="m 44.142826 61.717113 c 0 -1.05 -0.75 -1.8 -1.65 -1.8 -1.05 0 -1.8 0.75 -1.8 1.8 0 0.9 0.75 1.65 1.8 1.65 0.9 0 1.65 -0.75 1.65 -1.65"/><Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path4255" Fill="#FF000000" Data="m 44.142826 70.717113 c 0 -1.05 -0.75 -1.8 -1.65 -1.8 -1.05 0 -1.8 0.75 -1.8 1.8 0 0.9 0.75 1.65 1.8 1.65 0.9 0 1.65 -0.75 1.65 -1.65"/><Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path4257" Fill="#FF000000" Data="m 44.142826 79.717113 c 0 -1.05 -0.75 -1.8 -1.65 -1.8 -1.05 0 -1.8 0.75 -1.8 1.8 0 0.9 0.75 1.65 1.8 1.65 0.9 0 1.65 -0.75 1.65 -1.65"/><Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path4259" Fill="#FF000000" Data="m 44.142826 88.717113 c 0 -1.05 -0.75 -1.8 -1.65 -1.8 -1.05 0 -1.8 0.75 -1.8 1.8 0 0.9 0.75 1.65 1.8 1.65 0.9 0 1.65 -0.75 1.65 -1.65"/>


As you can see, every hole drawn in the .xaml file begins the Data tag with "m" followed by two digits. This is the "move" command. The digits that follow are the curve commands to draw a filled circle. We're not bothered about that - but what is of interest is the co-ordinates of the m command (i.e. where the hole is placed).

In fact, because every single hole on the board is drawn by the same filled circle shape, it should be possible to simplify this process in future. If we save the original PCB as .xaml (without first selecting all the hole points and copying them to a new image file) we should be able to pick out the drill holes, even from a complex PCB image.
As you can see from the .xaml example above, every hole has a move command, co-ordinates to place it, then exactly the same sequence of drawing commands - "c 0 -1.05 -0.75 -1.8 -1.65 -1.8 -1.05 0 -1.8 0.75 -1.8 1.8 0 0.9 0.75 1.65 1.8 1.65 0.9 0 1.65 -0.75 1.65 -1.65"

So in theory we should be able to parse the original PCB image file, even with all the traces and filled plane backgrounds and everything else, and just look for any shapes that include "c 0 -1.05 -0.75 -1.8 -1.65 -1.8 -1.05 0 -1.8 0.75 -1.8 1.8 0 0.9 0.75 1.65 1.8 1.65 0.9 0 1.65 -0.75 1.65 -1.65" in the Data tag. Any shape with this data in it we can say is a black filled circle (a 1mm hole that needs drilling) so our parser can strip out the co-ordinates from the "m" command. All other shapes can be ignored.

Results of a test app will be posted here soon.
If all goes to plan, maybe we won't have to shell out on an Eagle licence that we didn't really want in the first place.....