I recently repaired a Macintosh IIx I bought on eBay. It wouldn’t power on at all–both the rear power button and the keyboard power button did nothing. I was already aware that this system needs fresh batteries in order to boot, and I had removed the old batteries and replaced them with new ones, which didn’t make a difference. The real culprit: all of the surface-mount aluminum electrolytic capacitors had leaked electrolyte all over the logic board. This is a very common problem in older computers. These capacitors have a nasty habit of leaking after about 20 years or so. The electrolyte ate away at traces and several traces near capacitors were broken. Several IC pins were corroded really bad as well and had lost contact to their solder pads.

It was quite a journey figuring out how to fix it. The power button didn’t do anything, so I didn’t have a clue where to look. Luckily, an important figure in the Classic Mac community, Gamba, created a schematic of the power circuit. Sadly, Gamba passed away, but his site is still operational. I think there is a small error in his schematic, so I went ahead and fixed it. The fixed schematic is depicted below. The only change is the positioning of J18-15 and TS1 on the right side:

macIIsch_fixed

I began looking at this schematic and realized I didn’t have a clue what was going on in any of it. All of those NAND gates, diodes, and transistors looked intimidating. I buckled down and did my best to read the schematic and figure out what every piece does. After lots of experimentation and research, I feel like I understand this circuit pretty well now. I’ve decided to write this post to help explain the circuit and maybe help people in the future who are trying to figure out why their II/IIx won’t start up. Note: I am not an electronics expert. I’m trying my best, but I could be wrong about some details. Corrections would be appreciated!

Note that the diagram’s component numbering is for the Mac II. The IIx is slightly different. I would provide more detail, except my IIx logic board is a prerelease one that has the same component numbering as the II. So my IIx’s logic board’s component numbering matched this diagram. Other IIx systems do not match.

Let’s get started!

Overview

Here’s a broad overview of the different pieces of the circuit:

Overview

The ADB portion of this circuit is unrelated to this discussion, so I will skip it. Don’t worry–I have included the keyboard power button as part of my description of the power on circuit.

When I first looked at this diagram, for some reason I thought the top half was for the keyboard and the bottom half was for the rear power button. I was totally wrong. The keyboard and rear power button share most of the same power on circuitry. Now, I’m going to cover each section in more detail.

Batteries

Batteries

The two batteries B1 and B2 (3.6V 1/2 AA lithium) are in series with each other. This means they combine together to create a 7.2V voltage across ground and the positive terminal of B1. The three diodes seem to serve two purposes:

  1. Drop the voltage a little bit
  2. Protect against reverse polarity (putting the batteries in backwards)

In particular, D5 and D6 take the 7.2V voltage from the batteries and drop it down to about 7V or so. Normally these diodes would have a higher voltage drop, but you will see that while sitting idle, there isn’t much current being drawn from them, so the diode voltage drop is pretty low. D4 drops the 3.6V voltage a little bit, but I think its main purpose is to protect against reverse polarity. If you put B1 and B2 in backwards, D4 and D5 will prevent negative voltages from making their way to any other part of the logic board.

The 1000 μF capacitor is (I believe) the capacitor on the battery replacement board, and it can be found on both the II and the IIx, despite what Gamba’s diagram says. These computers originally came with the two batteries soldered directly to the logic board. When they needed to be replaced, there was a little circuit board that a service provider would solder on to replace the original batteries. It had two battery holders and a 1000 μF capacitor. I don’t fully understand the purpose of the capacitor, but it might be to make life easier on the batteries when the power button is pressed.

So this portion of the circuit takes two batteries as input, and as output provides a 3.3V-ish voltage rail and a 7V-ish voltage rail. I say “-ish” because I measured anywhere from 6.8V to 7V when I was debugging this circuit. But it’s somewhere in that ballpark. The 3.3V voltage is for powering the PRAM and clock while the computer is turned off. The 7V voltage is for turning the power supply on when you press either of the computer’s power buttons.

If you’re troubleshooting this portion of the circuit, make sure the cathode of D6 has 7V or so, and the cathode of D4 has 3.3V or so. If not, there’s something wrong with some of the traces and/or components pictured above. Check continuity between everything in the diagram above, and if needed, test D4, D5, and D6.

Clock/PRAM

ClockPRAM

This portion of the circuit is responsible for powering the clock and PRAM. On most (all?) of the Macs that came after the II/IIx, this is the *only* thing the single 3.6V battery is used for, at least as far as I know.

Recall that I already explained that there is about 3.3V on the cathode of D4 coming from battery B2. The 4.7KΩ resistor R17 is limiting the amount of current that will be supplied to UB6, the clock/PRAM chip. So…when the computer is turned off, the battery B2 is powering UB6. D3 is preventing the battery voltage from going into the +5V rail (which will be 0V when the power supply is turned off).

When the power supply turns on, the +5V rail actually has 5V on it. D3 will allow the 5V to go through into UB6, so the +5V rail will power UB6. I believe the 4.7KΩ resistor (R17) makes it so that the 5V rail does most of the work powering UB6 instead of the battery when the power is on. D4 is also (I believe) preventing the circuit from sending +5V into the battery circuit when the computer is powered on.

This part of the circuit is pretty simple! I don’t think a problem in here would necessarily prevent the computer from turning on, but it might prevent settings from being remembered while the power is off.

Power On

PowerOn

OK, here is where things really get interesting and more complicated. This is also where it will become obvious that both batteries must be installed in order for the II/IIx to boot. Recall that the cathode of D6 has about 7V on it or so. It powers UB2 (which is a 74HC132 containing four NAND gates–three are used, one is unused). UB2 doesn’t draw much current, so that’s why the diodes mentioned in the battery portion of the circuit don’t have much of a voltage drop. Without the batteries, these NAND gates will not be powered at all, and therefore the power circuit won’t work. It’s a good thing UB2 doesn’t draw much current, because otherwise the batteries would run out of juice too quickly.

Supplying 7V to the 74HC132 is a bit risky — it’s within the allowed range, but the datasheet I have recommends a maximum of 6V. Whatever–it seems to work.

The 7V rail also goes to the emitter of transistor Q3, which is a PNP transistor. We’ll see in a minute, but when the power button is not being pressed, the transistor is turned off, so it shouldn’t be drawing any current.

Additionally, the 7V rail is directly connected to one of the inputs on each of the three NAND gates. In effect, it means each one of these NAND gates is really acting as an inverter (e.g. a logic 0 at the other input becomes a logic 1 at the output, and a logic 1 becomes a logic 0). This is because:

  • 1 NAND 1 = 0
  • 0 NAND 1 = 1

I’ll go into this in a bit more detail when I describe what happens when you press the power button.

Finally, the 7V rail goes through the 100KΩ resistor R18 to the second input of the leftmost NAND gate. This is a pull-up resistor that keeps the second input of the NAND gate pulled up to a logic 1 by default. The 100Ω resistor R3 is also connected to this part of the circuit, but the other end of it is floating when both power buttons are not being pressed, so it doesn’t really affect the circuit until a power button gets pressed.

So in the default state when the system is plugged in but no power button has been pressed:

  • The leftmost HC132 NAND gate has both inputs at 7V. This means its output will be 0V.
  • The output of that first NAND gate is fed into the other two NAND gates.
  • Each of those NAND gates has one input at 0V, and one input directly wired to 7V, so they are both outputting 7V.
  • Since 7V is going into the left side of R14, there is no current between the emitter and base of the transistor. The transistor is turned off.
  • Because the transistor is turned off, the power supply control pin (J18, pin 15) is left floating (remember, the +5V output is not supplying 5V yet, since the power supply is off).
  • Thus, the power supply stays off.

When the keyboard power button is pressed, the left side of R3 is grounded. This pulls pin 2 of the HC132 NAND gate to ground through the 100Ω resistor R3. So:

  • The leftmost HC132 NAND gate has one input at 0V, and one input directly wired to 7V.
  • The output of that NAND gate is thus 7V, which is fed into the other two NAND gates.
  • Each of these NAND gates has 7V going into both input pins, so they are both outputting 0V.
  • Since 0V is going into the left side of R14, current is flowing from the emitter of the transistor to the base of the transistor. The transistor is turned on and allowing current to flow from the emitter to the collector.
  • Because the transistor is turned on, the power supply control pin is driven to 7V or so (just assume that TS1 is a short circuit for now–it will be described in more detail in the power off circuit description)
  • Thus, the power supply turns itself on.

As soon as the power supply turns itself on, it begins outputting 5V. 5V goes through D2 and R10, pulling the power supply control pin up to +5V (minus the diode drop) through the 220Ω resistor. As soon as you release the power button, this mechanism keeps the power supply control pin high. Otherwise, the power supply would immediately turn itself back off.

The rear power switch does essentially the same thing as the keyboard power switch. When you press it:

  • It completes a circuit to allow the battery to begin charging up capacitor C3, which is discharged when this process begins.
  • The left side of R3 starts at 0V and slowly starts raising up as C3 charges.
  • Since C3 starts at 0V, the same steps are followed as when the keyboard power button was pressed, and the power supply turns on.
  • After the power supply turns on, 5V is available through R9, so C3 will charge up to 5V.
  • C3 charging up to 5V is an important detail. If the button is later used for turning the computer off, the rear power switch won’t try to turn on Q3 at the same time it tries to turn the power supply off. It also gives you some time to release the power button before the system tries to turn itself back on again.

Wow! I may try to add some more diagrams in the future to depict it a bit more clearly. It’s a lot to digest.

You may be wondering: what is the point of the three NAND gates? At first glance, all they are effectively doing is repeating the input value that came out of R3. The purpose seems to be to allow better current drive capability for controlling the transistor, and a clean output that ensures that the signal controlling Q3 is either on or off, and not somewhere in between as capacitors charge up.

The three NAND gates essentially combine to create a buffer with double the current drive capability of a single NAND gate’s output. As long as all of the NAND gate pins are connected together and the NAND gates are working, you can assume that a low value at pin 2 of UB2 will turn the transistor on, and a high value at pin 2 will turn the transistor off.

Power Off

PowerOff

Just like the power on part of the circuit, the power off part of the circuit uses NAND gates that make it look way more complicated than it really is. These NAND gates are powered by the power supply’s +5V line. The two leftmost NAND gates form an SR latch. The SR latch’s top “set” input is connected to UB11, pin 13 (and the power button’s second pole). I believe this line is pulled up to +5V by a pull-up resistor inside the 6522 VIA (UB11), keeping it high (deasserted) while the computer is running. UB11 pin 13 is the /POWEROFF signal. At startup, C5 is fully discharged to 0 volts, so the SR latch’s “reset” input is low (asserted), which sets the SR latch’s stored “Q” value to 0. Then, C5 charges up, so the “reset” input goes high (deasserts itself) and stays deasserted while the computer is powered on. So the entire time the computer is running, the SR latch’s “Q” value is 0.

The !Q output of the SR latch is connected to the next two NAND gates, which act as an inverter just like in the power on circuit as I described earlier. So the output of the dual-NAND-gate inverter connected to R15 is really just the noninverted Q output of the SR latch, but with twice the maximum current. Thus, the voltage on the left side of R15 is 0V while the computer is on, keeping the NPN transistor Q2 turned off. Remember that the power supply control pin (J18, pin 15) is being pulled up to +5V in the power on circuit, keeping the power supply turned on.

Let me explain TS1 now. TS1 is a temperature switch. During normal operation, it acts like a short circuit. If the temperature gets too hot, it becomes an open circuit. If it becomes an open circuit, the power supply control pin is no longer pulled up to +5V, so the power supply shuts off (I’m pretty sure the power supply has a weak internal pulldown on that pin). During normal operation, TS1 will act like a wire.

When you tell the computer to shut down, the computer drives UB11 pin 13 (/POWEROFF) low. This causes the SR latch’s “set” input to go low, so it’s now asserted. This makes the !Q output low, which makes the inverter output high, so Q2 turns on, connecting R11 to ground. Now there is a 27Ω pulldown pulling the power supply control pin low, and a 220Ω pullup pulling the power supply control pin high (in the “power on” portion of the circuit). This is a voltage divider, so the voltage at the power supply control pin will be approximately 0.5V. This is low enough to tell the power supply to turn off.

If you press the power button on the back of the computer, the same thing happens — it connects the SR latch’s top “set” input to ground, and the exact same thing happens.

Troubleshooting

OK, so I have tried my best to explain what’s going on in each portion of the circuit. If you have a broken power circuit, how do you fix it?

The system will not power on

First of all, there are a few traces that have a tendency to go bad because they run nearby leaky capacitors:

Of course, make sure you have removed, cleaned around, and replaced all of the electrolytic capacitors on the logic board.

Make sure that all of the connections between R3, UB2, R14, and Q3 are OK. If you can, use a voltmeter to verify that the NAND gates are operating as expected when you press either of the power buttons. You can do this with the logic board out of the computer as long as the batteries are installed.

Check the power supply control pin (J18, pin 15) to see if it’s correctly getting a voltage when you press either of the power buttons. If it is, there’s a chance that the power supply is at fault.

UB2 is somewhat near a capacitor. There’s a good chance that some of its pins have lost connectivity due to corrosion. Check every pin on UB2 and make sure it has connectivity as shown in the schematic.

The keyboard power button works, but the rear power button doesn’t

There are only a few parts of the circuit that could cause this. Make sure R9, C3, the rear power button, R3, and the keyboard power button pin of L2 are all connected as shown in the schematic diagram. For the rear power button to not work when the keyboard does, one of the connections between those components has to be broken.

The system powers on, but it won’t power off

UB1 is extremely close to a capacitor. There’s an extremely good chance that it has lost some connectivity due to corrosion. Verify all connections.

See if the output of UB1 pin 8/11 is correctly going high when you press the rear power button while the system is on. If not, follow the circuit and see where the broken trace is.

Final thoughts

I thought this would be a good idea to explain the circuit in more detail. This has turned into quite a long-winded explanation, and it doesn’t have quite as many pictures as I would have hoped. Maybe this would be better as a video or an animation that shows what the circuit is doing. For now, I hope this is enough to help someone out there troubleshoot their Macintosh II/IIx power circuit.

In my particular case, a trace was broken in the R3-R18-C6-UB2 group of pins that should be connected together, and UB1 was completely covered in capacitor leakage, which had very badly corroded its pins and solder pads. I ended up replacing both UB1 and UB2 to be safe. A trace between a via and C5’s positive end was also broken and needed a patch wire. I had to run several patch wires to repair broken traces:

UB1_UB2_before_after

 

UB1_UB2_after

By the way, this wasn’t the only problem with my IIx. This was actually the last part of the logic board that I fixed. The whole power on circuit can be bypassed by tapping a 3.6V battery between ground and the power supply control pin, so I did that for testing until I repaired this circuit. The power supply would turn on, but nothing would happen. It turns out that there were a ton of other traces that were corroded. The 53C80 SCSI chip (again, near a capacitor) was very badly corroded, so I removed it, cleaned the solder pads, and replaced it with a new one. One of the solder pads had a break from its trace, so I had to run a patch wire. I also found several other broken traces on solder pads near two chips on the board.

Corrosion2

UB8_before_after

It’s been a wild ride, but I now have a working IIx!

When I wrote Parallel Port Tester, I discovered that detecting parallel ports and their I/O addresses in Windows is a pain in the butt. I have received several inquiries asking about how I did it, so it’s obvious that others agree with me. Hopefully, this post will help everyone learn how to automatically detect their parallel port addresses. I certainly don’t claim to be an expert, and there may be better ways to do it, but this method seems to work for me.

Don’t use Win32_ParallelPort

One of the strategies I’ve seen recommended is to do a WMI query on the Win32_ParallelPort class. This is originally how I started implementing Parallel Port Tester, but I quickly discovered that it sucks! Sometimes it gets the I/O address for the wrong port, and sometimes it doesn’t even find your parallel port at all. It seems to depend on the version of Windows and the chipset manufacturer. In particular, I found that it would not detect a parallel port implemented by a Moschip chipset in Windows XP. It also was returning incorrect I/O addresses on a user’s system running Vista. Anyway, I’d highly recommend that you avoid this class. I could not get it to work correctly. Maybe I was doing something wrong…but I’m pretty sure it just sucks. It sucks so bad that I disabled this method of discovering parallel ports in version 1.0.0.1 because of a report that it was returning erroneous information.

Instead, find objects belonging to the Ports class manually

For more reliable results, what I do is search for all devices that are ports (which also include COM ports). The GUID for this class is {4D36E978-E325-11CE-BFC1-08002BE10318}. I only pay attention to returned ports that are LPT ports. On each found LPT port, I request all of the port resources to determine the I/O addresses.

How do you do that? Here’s some sample C# code using .NET. Note that I’m only showing relevant bits and pieces, so you will have to fit them into a class and function as appropriate.

using System.Management;

private static readonly ushort SPPIOLength = 8;
private static readonly ushort ECPIOLength = 4;

SelectQuery portsQuery = new SelectQuery("Win32_PnPEntity",
    "ClassGUID=\"{4D36E978-E325-11CE-BFC1-08002BE10318}\"");
ManagementObjectSearcher portSearcher = new ManagementObjectSearcher(portsQuery);
foreach (ManagementObject port in portSearcher.Get())
{
    // Grab its name. This will be in the form "Blah Blah Parallel Port (LPT1)".
    // We're going to get ugly now...
    string name = (string)port.Properties["Name"].Value;

    // Skip ports that are not parallel ports. This is UGLY...I'd much rather
    // do this a cleaner way, but it seems that different parallel ports do
    // things differently.
    if (!name.Contains("(LPT")) { continue; }

    // and extract the parallel port name by looking for everything inside
    // the parentheses. I don't know how else to do it...
    int beginLoc = name.IndexOf("(LPT") + 1;
    int endLoc = name.IndexOf(')', beginLoc);
    name = name.Substring(beginLoc, endLoc - beginLoc);

    // Grab the device ID so we can find all the associated port resources.
    string deviceID = (string)port.Properties["DeviceID"].Value;
    // Replace single backslashes with double backslashes to be suitable
    // to use in a query. Note that I also had to escape it myself in
    // code...so \\ represents a single backslash.
    // TODO: Any other escaping necessary?
    deviceID = deviceID.Replace("\\", "\\\\");

    // Now search for I/O ranges of this port.
    ObjectQuery resourceQuery =
        new ObjectQuery("ASSOCIATORS OF {Win32_PnPEntity.DeviceID=\"" +
        deviceID + "\"} WHERE ResultClass = Win32_PortResource");
    ManagementObjectSearcher resourceSearcher =
        new ManagementObjectSearcher(resourceQuery);

    // Find the SPP and ECP base addresses
    ushort SPPBase = 0xFFFF;
    ushort ECPBase = 0xFFFF;
    foreach (ManagementObject resource in resourceSearcher.Get())
    {
        // Grab starting & ending addresses
        ushort startAddress =
            (ushort)(UInt64)resource.Properties["StartingAddress"].Value;
        ushort endAddress =
            (ushort)(UInt64)resource.Properties["EndingAddress"].Value);

        ushort rangeLen = (ushort)(endAddress - startAddress + 1);
        // If we haven't yet found the SPP base address, and this range
        // is big enough, use it as the SPP base address.
        if ((SPPBase == 0xFFFF) && (rangeLen >= SPPIOLength))
        {
            SPPBase = startAddress;
        }
        // If we haven't yet found the ECP base address, and this range
        // is big enough, use it as the ECP base address
        else if ((ECPBase == 0xFFFF) && (rangeLen >= ECPIOLength))
        {
            ECPBase = startAddress;
        }
    }
    // Although I didn't include the code here, if I fail to detect an
    // SPP address with the rules above, I grab the first returned
    // address and use it as the SPP base address. Then I set the ECP
    // address to 0xFFFF (which I treat as meaning "unable to find")

    // TODO: If SPPBase != 0xFFFF, add it to the list of discovered
    // ports -- the name of the port is stored in the variable "name"
}

I hope this code is helpful to someone out there! From this point, you can use something like Inpout32.dll to access the port registers directly.

I’m not a huge fan of the hack where I extract the “LPT#” name from the long name by searching for the “(LPT” string, but I couldn’t find a better way to do it. Suggestions would be appreciated! There also may be a better way to use parameters to do the ASSOCIATORS query instead of ugly escaping and string concatenation, but it worked and that was good enough for me on this particular project. I couldn’t find an easy way to set it up for use with parameters or else I would have done it that way.

Up until recently, I did all of my soldering the “old-fashioned” way with my soldering iron. As I began building up boards for complex projects that use a multitude of surface mount components, I started to realize how inefficient that method is. It’s a lot of tedious work to solder each individual SMD component by hand, especially tons of capacitors and resistors. It’s the same repetitive task over and over again: put solder on one of the pads, pick up the component with tweezers, heat up the solder I just put on the pad, put the component into place, optionally push the component down against the PCB while heating the solder, and finally solder the other pad. When you’re building a board that only has a few parts, it’s no big deal. When you’re building a board that has 20 or 30 capacitors and resistors, it can really get boring and slow. It’s definitely doable, but it’s also exhausting.

I investigated other methods of soldering. This research led me to solder paste. The idea is that you put solder paste onto all of the surface mount pads on your PCB. Next, you place the surface mount parts onto the pads. The paste holds the parts in place so you can move the board around without sending components flying all over. When you have all of the parts in place, you heat up the board to melt the solder and activate the flux. Some people use a hot air rework station to do this; I prefer putting the board into a repurposed toaster oven. I’ll explain in more detail later in this post.

Of course, I still use my iron for a lot of stuff I do: through-hole parts, drag soldering fine-pitch ICs, fixing problems, soldering boards that use a small number of SMD components, and probably other situations I’m not thinking of at the moment. I think there’s a point at which it becomes more efficient to use solder paste instead, particularly if you’re building up multiple boards at once. I’m not sure exactly where that “critical point” is, but you develop a feel for it as you gain more experience. If I’m doing a single board with about ten 0805 components, I’d rather do that by hand with an iron. If I’m doing five of them, or a board with 30 0805 components, I’m going to lean toward using solder paste. The main reason for this is the cost of setup time. It takes longer for me to get set up for building boards with solder paste (not to mention cleaning up when I’m finished). So if I’m going to get set up for a solder paste soldering session, I’m going to prefer if I have a lot of soldering work to do to make the setup time worth it.

There are also situations that basically require using solder paste, such as components with leads that are difficult or impossible to reach by hand. For example, many QFN packages have a large ground connection underneath the chip. Some smaller connectors like micro-USB connectors and microSD sockets are also difficult to do by hand. These can probably be done using normal solder and a hot air rework station (or in some cases, careful soldering with a small iron tip), but it’s usually easier for me to just do the whole board with solder paste in that case despite the setup time.

What I’d like to do in this post is share and describe my soldering setup. With the right tools, solder paste can be pretty fun to work with.

Solder paste

SolderPasteThere are a lot of options out there for solder paste. I can’t speak for all the options because I’m relatively new to the market, but I have had good luck with Chip Quik SMD291AX10 paste and Zephpaste. Solder paste typically has a shelf life of 6 months or less. If you refrigerate the paste it will last longer, but I don’t really care to put the paste in the same location as my food. It lasts long enough without refrigeration for me. If your solder paste dries up and quits working, you can always buy more. Keep this in mind when you buy solder paste–only buy as much as you need.

Not only are there a lot of options for the paste, but there are options out there for putting the paste on the board. Perhaps the best method is to have a stencil made. Many PCB fabrication shops can also make stencils you can use for applying solder paste. You secure the stencil over your board, put some paste on the stencil, use a squeegee to spread the paste over the holes in the stencil, lift the stencil up, and you are left with a board that only has solder paste in the places where you want it.

SolderPasteByHandIf you don’t want to have a stencil made, you can also manually apply the paste onto pads by pushing it through the syringe. If you go this route, you will also want to get a variety of dispensing needles that you can attach to the syringe. You can find these on eBay and many suppliers. I got a variety pack from Zephyrtronics (see near the bottom of the link). In addition, if the syringe does not come with a plunger, you will need to pick one up so you have something to push to make the solder paste come out.

I’m not a big fan of manually dispensing the paste by hand using the syringe. It requires much more force than you might think to push the plunger. I even bought a fancy plunger that is supposed to be more comfortable, but it’s still way too difficult to use. One thing that helps is to cut the needle length down. I use an X-acto knife to cut the needle down so it barely sticks out. You have to be careful because if you push down with too much force while cutting, you’ll squish the needle and it will be bent shut. There are also some tapered plastic tips that are easier to use, but their disadvantage is that it’s easier to accidentally smear the paste when you’re dealing with small pads that are close together.

I found a happy medium between having a stencil made and manually dispensing the paste: a solder paste dispenser! You can attach an air tube to the end of your syringe and use compressed air to push the solder through the syringe. It’s foot-operated so you push a pedal and the paste starts coming out of the needle (you will still need to get the dispensing needles). Because you no longer have to exert force pushing on the syringe plunger, it’s much easier to concentrate on aiming the paste onto the pads.

Solder paste dispenser

DispenserThe dispenser I decided to buy was a cheap (~$100) dispenser on eBay. It doesn’t have a model number on it, but it appears to be a “982” dispenser. I’ve seen this model for sale under the names KLT-982A and SP982. The eBay item didn’t specify a part number. I made sure to buy a version that was advertised as a 110V model compatible with the United States; some of the items on eBay only work on 220V power. I also made sure to buy one that operates on 24V DC power internally because I had heard that some of the older versions actually had 110V power going through the foot pedal–that sounds a little risky!

You can operate it using either a foot pedal or a hand switch. It has a manual mode where as long as you’re pushing down on the pedal, air is pushed through. There is also an adjustable auto mode where it will put out timed pulses of air. Ideally you could use this to dispense exact quantities of solder paste. In practice I’ve found that the auto mode works inconsistently, so I just dispense everything in manual mode. Once you get the hang of it, it’s not too bad. Since I’m only using manual mode, the controller is probably overkill and a clever person could put something together on their own with a valve and foot pedal (and pay a lot less money in the process). I’m too lazy to care; the pre-assembled controller is way more convenient and clean than hacking something together.

I did mention earlier that you need compressed air. This adds more stuff you have to learn about. This is actually the main reason I decided to write this post. Before messing with solder paste I knew nothing about air compressors and the different types of connectors you use to hook things up. I had to go research all of this stuff for myself and I’d like to simplify it for anybody else who buys a solder paste dispenser in the future.

Air compressor and fittings

If you’re going to use a solder paste dispenser, you need a source of compressed air, somewhere in the range of 50 psi or so. I didn’t have an air compressor when I got started, so I did some research to decide on something appropriate for my needs. I didn’t want to get the very smallest compressor available, so I went with the Porter-Cable C2002-WK. It goes up to 150 psi and has a 6-gallon tank. It was still pretty reasonably priced. I was glad I picked this one because it is big enough to handle all of my needs. When I’m going to be applying solder paste, I fill up the tank once, set the regulator to 50 psi, unplug it, and shut it off. It will have plenty of air for the rest of the day. The dispenser barely uses any air at all. The compressor is fairly loud when indoor so I don’t like being near it when it fills up. It’s nice that I can turn it on, walk away until it’s done, and then shut it off knowing that it won’t have to fill back up anymore.

I’m brand new to air compressors, so I’d like to share everything I needed to learn in order to get this system up and running. First of all, the air compressor has this type of connector for hooking something up to it:

FemaleQuickConnect

It also comes with an air hose with an identical connector. The other end of the hose plugs into the compressor’s connector.

QuickConnectHose

This connector is sometimes called a “quick-connect” or something similar. The idea behind these connectors is that when nothing is plugged into a female connector, air is not allowed to flow. As soon as you plug something in, air is allowed to start moving.  To plug it in, you pull back the sleeve on the female connector and push the male connector in. To remove it, you pull back on the sleeve and the male connector pops out. There are many types of quick-connect couplings out there; this one is called an industrial connector.

That explains the air compressor side of things, but what about the receiving end? The connector on the solder paste dispenser is pretty interesting. You see this little blue connector on the back where you feed the air in?

PushConnect

This is what’s called a push-to-connect fitting. You stick an air tube into the connector and it will stay in place. If you try to pull it out it won’t come out. To remove it, you push on the little blue ring that you can see on the connector (it’s kind of like a button). While pushing that blue ring in, you can easily pull the air tube out. It’s really a nifty setup. According to this page, this connector on a similar dispenser accepts tubing with a 6 mm outer diameter. This seems to match what my connector accepts. If you need to get tubing for it, I would definitely recommend to look for 6 mm tubing instead of a similar size in inches just to be safe.

The dispenser comes with an air hose for plugging into this connector. One end is just the bare hose that plugs into this push-to-connect fitting. The other end has a strange quick-connect coupler that seems to baffle many people online:

AsianConnector

This is not the industrial connector that my air compressor expects. I don’t really think I found a definitive answer for what type of connector this is, although I did find a lot of theories. This link was actually very helpful. It seems that this connector is some kind of Asian connector that is not typically found in the United States. After a ton of Googling, I took a gamble and bought a 30E570 coupler. On eBay this goes for about $27 plus shipping. Since the URL might change, I’m not going to link to it; just search for it. It claims to be a “1/4 inch Asian Hi Flow Interchange” adapter. This adapter provides a female connector that mates to the weird male connector on the air tubing that came with the solder paste dispenser. I don’t know if the connector is an exact match, but it seems to fit and it doesn’t leak, so it’s good enough for me!

The other end of this coupler gives you a 1/4″ female NPT. NPT (national pipe thread) is a standard type of threading commonly found in the United States. With NPT stuff, you screw the male and female connectors together, typically wrapping some teflon tape around the threads to ensure a good connection with no leaks. My compressor came with yet another adapter that converts 1/4″ male NPT to the quick-connect needed for plugging into the compressor, so I was able to screw this adapter onto the 30E570 coupler to make something that could finally hook into the compressor.

If you don’t want to buy the weird Asian Hi-Flow to NPT adapter, there is another option: you can buy an adapter that converts 6 mm outer diameter push-to-connect to 1/4″ NPT. There is a male NPT version or female NPT version of this adapter available. Then you just need some bare 6 mm outer diameter tubing and you can connect the tubing between your adapter and the dispenser. Here’s an example of what I mean if you want to try this option:

TubeAndAdapter

You’ll also need a 1/4″ NPT to quick-connect adapter so you can plug it into the compressor. I went ahead and used the Asian Hi-Flow adapter instead though, as you’ll see below.

Air filter

The solder paste dispenser’s documentation says it needs dry, clean air. Air compressors typically put some moisture and oil into the air, so it’s a good idea to add a filter. As far as I can tell, it’s not a huge problem with smaller compressors, but it’s still a good idea just in case. I bought an Ingersoll Rand F35121-400-VS air filter and put it into the chain of connections. It has 1/4″ female NPT connectors for input and output, so with a 1/4″ NPT male-to-male nipple and the 1/4″ male NPT to quick-connect adapter I mentioned earlier (this kit has a nice variety of connectors and this sealing tape worked great), I was able to assemble this final monstrosity that can hook into my air compressor’s hose:

Filter

I read that it’s a good idea to put the filter closer to the dispenser than the compressor, so I hook this assembly into the long hose that came with the compressor to add some distance. Setting up the connection between the compressor and the dispenser was definitely the hardest part to figure out about this whole setup. It would have been nice if either the dispenser had an NPT connection or the included tubing had a standard industrial connector. Either of those two options would have been great. Regardless, it’s not really a concern for me now because I have the required connections. I really hope this information is useful to other people who are considering buying one of these dispensers. This is a huge stumbling block especially for someone like me who is new to pneumatics. I honestly knew nothing about anything I wrote in this section until I researched it online in order to figure out what I needed for this dispenser.

A few more air compressor notes

If you’re going to be a new air compressor owner, I’d like to share a few tidbits. First of all, when you’re done and you release any remaining pressure, it can be extremely loud, especially if you’re indoors. With the tank mostly full, I released the air through the safety valve like the instructions mentioned, and I was very surprised by how loud it was. My ears were bothering me for several days afterward. If you’re going to do that, I would highly recommend earplugs. I prefer to hook up the included air blower tool and release the air through it; it’s much quieter.

After the tank is mostly depressurized, you need to open up the drain valve at the bottom and drain out any liquid. I typically haven’t seen much (if any) moisture come out of my tank when I only fill it up once, but I do see liquid come out if the compressor has to run a lot when I’m using it for something other than solder paste. You should always check to make sure. If you don’t drain the tank it could develop rust inside and that would be a very bad thing.

Connecting to a solder paste syringe

We have covered hooking the dispenser up to the compressor, but what about the solder paste syringe? The air output of the dispenser uses another push-to-connect fitting with the same size as the air input (6 mm outer diameter). The dispenser came with three 30cc syringes and an adapter to connect the dispenser up to a 30cc syringe. It’s basically tubing connected to a cap you can put on the syringe. The cap has an O-ring to keep the syringe sealed tightly.

AirAdapter30cc

The solder paste I bought came in a 10cc syringe, so I didn’t have an appropriate adapter to hook it up. I found some 10cc syringe adapters on eBay and bought them (this adapter on Amazon should work too). The adapters I bought looked exactly the same as the 30cc adapter, except they were smaller and had a green plastic connector instead of bare tubing at the end. I messed around with the green connector and discovered it is a very bad idea to push it directly into a push-to-fit connector. Instead, you should cut off the green connector and just use the bare tubing. Luckily, the one I found seemed to fit perfectly even though the tubing diameter wasn’t specified. The adapter fits tightly onto the solder paste syringe and then twists to lock in place:

AirAdapterOnSyringe

Dispenser needles

As I mentioned earlier, I bought a variety pack of needles. After experimenting with them, I have settled on two favorites: 21-gauge (about 0.22″ diameter) and 23-gauge (about 0.16″ diameter). The 21-gauge tip works well for most purposes. For really fine-pitch stuff such as 0402 capacitors and resistors, the 23-gauge tip is able to dispense a smaller amount of paste. Both of these sizes would take a lot of force to do by hand.

When I first put a needle onto the solder paste syringe, it takes a while for the paste to make its way through. I usually have to push down on the pedal non-stop for 15 seconds or so before the paste starts coming out. Cutting the needle shorter than its original length helps with this problem.

I’ve read that these dispensing needles are not reusable, but in my experience you can reuse them if you clean them out. When I’m finished using them, I put them on an empty syringe and hook the empty syringe up to my dispenser. Then I blow out the rest of the solder paste until only air is coming out of the needle. You can also fill the syringe with water to do a better cleaning job if you want.

Dispensing the paste

I think I’ve shared everything you need to know in order to get everything hooked up. Once it’s all hooked up and you’ve filled up the air compressor, you’re ready to dispense paste. I usually set the air compressor’s pressure regulator to about 60 psi. I’ve never needed more pressure than that. You don’t want to go higher than what the dispenser’s documentation says it can take (100 psi on mine). You can play around with the regulator on the solder paste dispenser to find your sweet spot. I usually set it to about 50 psi or so. You don’t want to go too high, but it has to be high enough to get the solder paste through the thin dispensing needle. You may find that a higher pressure makes the paste come out faster. It’s all up to your experimentation.

Like I said earlier, I don’t trust the auto mode on the dispenser. It’s a really cool idea, but what I’ve noticed is sometimes the needle clogs up and stops dispensing for a while. There are other times when the paste temporarily starts coming out quicker than usual as well. Because both of those situations happen fairly often, I’ve opted to stick with manual mode. When I press down on the foot pedal, the air starts pushing paste out. When I release the foot pedal, the air stops pushing. It may sound annoying to handle it manually, but it actually works pretty well.

I generally put a dab of paste on each SMT pad. When I’m dealing with multiple small pads, such as a QFP or PLCC package, I put a line of solder paste across the pads. This is another good application of the manual mode of the dispenser. You can see an example of solder paste across multiple pads in the picture below (this is one of my Mac ROM SIMM programmer PCBs after I have dispensed paste onto the pads).

PastedBoard

Putting the line of paste across multiple pads is pretty tough. You have to use an appropriate gauge of needle and you have to get just the right amount of paste. If you don’t use enough, some of the chip’s pins will not get enough solder. If you use too much, you’ll end up with pins shorted together. Shorting is especially a problem with fine-pitch components: 0.5 mm and less.

On the pads for the QFP device in the picture above, I got my paste a little thin near the top of the right side and too thick on the bottom of the right side. I luckily didn’t end up with a short on the part where it was too thick, but I didn’t end up with quite enough solder on the part where it was too thin. You’ll see what I mean on the finished board later on.

When I do a board with 0.5-mm-pitch components, I actually solder those components ahead of time with a soldering iron using drag soldering. I’m just better at drag soldering than paste dispensing. After I have the difficult components placed, then I dispense paste for handling the easier components. I would guess that solder paste stencils would work a lot better for getting just the right amount of paste for fine-pitch parts though. Definitely consider having a stencil made if you’re going to be building PCBs in high volumes.

Placing the components

The solder paste holds the parts in place after I drop them onto the PCB. There are many ways to place the parts. The most common way is probably to grab components with fine tweezers and drop them into place. If you’re only placing a few parts, that’s probably the easiest way to do it. At some point, I started realizing that placing a ton of components was annoying, so I searched for a better way to do it. What I’m about to describe is the best solution I came up with. Credit goes to this YouTube video for inspiring me.

The video talks about a vacuum pickup tool. The idea is you have a little pen you hold in your hand. By either pushing a foot pedal or covering a hole on the pen with your finger, you get vacuum suction that is strong enough to pick up a part. The guy in the video recommends something that is foot-operated because otherwise it’s hard to move your finger off the hole without moving the pen, thus jerking the part around that you’re trying to drop. I wholeheartedly agree, but I couldn’t find anything affordable that was foot-operated.

VacuumToolI ended up finding something that isn’t even designed with electronics in mind. It’s called the BeadSmith Pick-It-Up. It’s available from many retailers online (including Amazon). It’s actually meant for people who are doing arts and crafts to assist them with picking up small beads and stones. I’ve found that it works great for my application too! I had a concern about ESD safety since it’s not designed for electronics, but I haven’t had any problems yet.

It comes with a single tip that’s too large for picking up 0805 components, but should be OK for picking up larger things. It also has a little rubber attachment that you can put on the tip to help you get good suction on things with a large surface area. In the picture on the left, I actually have a separate tip attached that came with a different (junky) squeezable vacuum pickup tool I bought. It’s terrible, but the tip it came with is nice. You will also see in the picture that I use one of my solder paste syringe tips for picking fine components up. That blue tip is a 25-gauge needle and it works great for picking up 0805 parts. Just make sure you don’t accidentally suck up any solder paste! 0402 components are so small that I don’t think I could pick them up very reliably. I stick with tweezers for parts that small.

There is a dial on the top that you use to adjust the strength of the suction. You just have to experiment with it until you find what works. Like I said earlier, you put your finger over the hole on the pen, and then the pen should magically pick up the part. I’ve found that when you move the part onto the solder paste, the solder paste will actually grab it with enough force to snatch it from the vacuum tool. This is actually helpful because you don’t have to worry about moving your finger off of the hole when you’re ready to release the part.

I’d like to share one other related piece of advice from the video I linked above. Before I got this vacuum tool, I would take resistors/capacitors I bought from Digi-Key or Mouser or whatever out of the “cut tape” that they typically come in and dump them into little containers. With a vacuum tool, though, it’s actually beneficial to leave the components in the cut tape. With some double-sided sticky tape, you can adhere the cut tape to your workbench. Now every component will be in the exact same orientation with the correct side up. It really speeds up the process of populating the components on your board(s). The downside is that the cut tape takes up a lot of space for storage.

Here’s what the board above looked like after I placed all of the parts:

PopulatedBoard

Cooking the boards

Finally, after you have placed the components, you need some way to heat the solder paste up so it permanently solders everything to the PCB. I suppose you could do it by hand with a soldering iron, but that would be messy and you would move the parts while trying to heat the solder. You could also do it with a hot air rework station. I’ve heard that some people like to use a skillet. I prefer sticking the board into a cheapo toaster oven that I dedicated for soldering. Yeah, smoke and nasty fumes come out. Don’t cook your food in it. Preferably do this outside so the fumes don’t permeate your indoor air.

Using a regular old toaster oven instead of a specialized reflow oven presents a few challenges. Most importantly, you need some way of monitoring the temperature inside the oven to know when it’s time to quit heating. You also have to watch the oven and manually try to follow a heating profile because there’s no controller to do that for you automatically. There are temperature controller kits out there that you can use to modify a toaster oven and turn it into an automatic reflow oven. That would be nice, but it’s overkill for my needs.

To monitor the temperature, I bought a thermometer and thermocouples. The model I bought was a DM6802A+. It’s a no-name brand but it does the job. It came with two K-type thermocouples, one of which I use for soldering. You’ll see in the picture that it’s discolored, probably due to being cooked combined with the nasty crap that comes out when the solder melts and the flux activates. Anyway, I used Kapton tape (which is safe to use with high temperatures) to attach the probe to a spare PCB. I did this to try to make sure I am getting a good idea of the temperature of an actual PCB in the oven.

Thermocouple

The oven I use is a Euro-Pro TO36 convection oven, which as far as I can tell is no longer available. I’m sure you can find a cheap toaster oven somewhere if you want one. Anyway, despite the fact that this model is a convection oven, I’ve found that I have to turn the convection feature off or else the temperature has trouble getting to where I want it (around 220-230° C for solder that has lead, or 250-260° C for lead-free solder). I just use the toast function which doesn’t turn the convection fan on. It has both upper and lower heating elements, although I haven’t figured out which elements turn on in each mode–the documentation that came with the oven doesn’t do a good job of explaining it. Ideally you’d want the convection fan and both the upper and lower elements turned on. You could definitely set it up correctly if you opened it up, stripped out the original timing circuitry, and put in an automatic reflow controller instead. This oven gets the job done for me without a controller and without convection, so I haven’t had the need.

I use some spare PCBs to support the PCB I’ll actually be cooking, and of course I stick the thermocouple probe with its PCB in there too. In a real-world scenario, the red PCB I have on top is the populated PCB that I would be cooking. I would also remove the baking pan that you can see underneath; I just forgot to remove it when I took this picture.

ThermocoupleInOven

When I close the oven, the thermocouple probe sticks out and connects to the thermometer:

OvenClosed

The insulation on the thermocouple wire is good to about 260° C; if I needed to go higher than that, I would need to get a better probe that can withstand higher temperatures.

After everything is in place, I set up the oven controls. I turn the temperature knob all the way up to the maximum temperature. I put the timer knob in the “stay on” position so it doesn’t count down. As I mentioned before, I put it into toast mode. Finally, I plug it into the wall and watch as the temperature increases. I just want to repeat: I do this process outside on a sunny day. The solder paste and flux both make nasty fumes that I don’t want to smell inside.

When the temperature reaches about 10° C below my target temperature, I turn the temperature knob all the way down. It definitely overshoots, so you want to turn it down early. It’s a feel you develop over time. I believe I have discovered through my experience that the amount of overshoot can change based on the temperature outside. Once it has reached my target soldering temperature, I unplug the oven from the wall. It should do a decent job of maintaining the temperature for a while. I try to keep it at my target high temperature for 30 seconds or so. When I’m ready for the temperature to decrease, I carefully open the oven (the solder will be molten and a bump could dislodge components on the PCB) and turn on a fan that I point into it.

This is where the fumes really start coming out of the oven, so I usually walk away and wait for it to cool down.  As the “Will It Blend?” guy would say, “solder smoke, don’t breathe this!” When the thermocouple is reading 80° C or so, it has probably cooled down enough to pull the baked PCB out and inspect it:

FinalBoard

As you may be able to see, a few of the pins in the bottom row of the QFP device (an Atmel AT90USB646 AVR microcontroller, in case you’re curious) didn’t get quite enough solder. That corresponds to places where the line of solder paste was too thin. The leftmost pin in that bottom row has too much solder; that’s the place where I put too much paste. I was lucky enough to not get any bridged pins, but I definitely saw that happen on some of the other boards I built in the same batch. I had to do some touchups with my iron to fix the bridges and add extra solder in places where it looked like there wasn’t enough.

All in all, the solder joints look pretty nice. I built ten of these boards in one sitting and I’m positive that I saved a ton of time by using solder paste instead of soldering each 0805 component by hand. It took some time to bake all of the boards, but I was able to spend that time standing and walking around instead of sitting in front of my soldering workbench. However, this board has a small enough number of components that a single board would probably be easier to just do by hand.

By the way, I have successfully baked two boards at a time in my oven. It still seemed to work fine. I’d be afraid to try too many at once because I don’t know how well the heat spreads throughout the oven. Convection is supposed to help heat the entire oven uniformly, but I have convection turned off.

Cleaning up

When I’m all finished, it takes some time cleaning up and tearing down. Before letting the air out of my compressor, I put the dispensing needles onto an empty syringe and blow any remaining solder paste out of them so I can reuse them. If I really wanted to be frugal, I’d start doing this before I was finished dispensing paste to avoid wasting the paste that’s left in the needle.

Next, I let out the air. I disconnect my weird filter monstrosity from the air line and hook up the little blow gun that came with my compressor. I use this to blow most of the air out. When most of it is gone, I open up the drain valve on the bottom to let any liquid out.

After everything is depressurized, I open up my air filter and make sure to empty out anything in it. I haven’t found anything in my filter yet, and I think this is because the compressor doesn’t typically put much moisture into the air unless you’re using a lot of air and it keeps having to run.

I put away all of the air hoses and junk for connecting the compressor to the dispenser, and that’s about it!

Conclusion

Solder paste is pretty cool. Stencils are probably the way to go, but if you don’t want to use stencils because you do small quantities of many boards, a dispenser works well too. It has a bit of a barrier to entry especially if you don’t know about air compressors, but once you get the hang of it, it’s actually pretty easy. An air compressor is a good tool to have around the house anyway, so keep that in mind if you don’t have one.

Questions? Comments? Suggestions? Please let me know in the comments area below. I hope this information helps someone! Please be careful if you decide to get into this hobby. High pressures and high temperatures can both be very dangerous. Wear eye protection when you’re working with this stuff. Use common sense–don’t stick your hand into the hot oven and burn yourself, don’t blow air into your face, and make sure all air connections are nice and tight. I’m not responsible if you hurt yourself, burn your house down, or whatever else you could possibly imagine; I’m just sharing the process I use when I build PCBs.

This weekend, I finally decided to try to set up my MacBook Pro to boot into OS X, Windows XP, and Ubuntu. I ran into a few problems so I’d like to share what I did to make it all work. A lot of what I did was driven by other people’s wiki articles and blog posts, particularly this excellent blog about manually editing partitions. Without further adieu, I will describe my setup from start to finish.

Read the rest of this entry

After playing around with a ton of parallel port cards in an attempt to figure out Willem programmer compatibility, I decided it would be useful to write a parallel port tester program. Just a simple utility where you can set the output value of each output pin and read the value of each input pin. Several other test programs exist, but I wasn’t happy with their interfaces, and a lot of them weren’t prepared to easily handle PCI/PCI Express/ExpressCard parallel ports. At worst, they only supported the standard parallel port I/O addresses that new motherboards don’t have anymore. At best, they supported custom parallel ports but required you to manually look up the I/O address range of the card.

Oh, and a lot of the existing tools don’t work with newer versions of Windows. I wanted a tool compatible with newer versions of Windows, both 32-bit and 64-bit.

Introducing Parallel Port Tester:

ParallelPortTester

Simply locate your parallel port in the list that appears in the bottom right. I use several methods to discover parallel ports and their I/O ranges, so you shouldn’t need to enter them manually. If for some reason your port doesn’t show up in the list, you can manually enter the base address of your parallel port (e.g. 0x3000) and hit Enter.

You can toggle parallel port outputs on or off by clicking on the circle representing the pin you want to change. Green represents on (high), black represents off (low). The circles representing input pins are automatically updated while you have the port selected, so you can easily test your inputs. You can also choose whether to use the four control pins as inputs or outputs.

For people who are really interested, I also display the raw register values of the three standard parallel port registers. I show separate values for the control register because what you write to the control register is not guaranteed to be what you read back.

Requirements

Let’s get the requirements out of the way. You will need:

  • Windows 2000 or newer. Should work with 2000, XP, Vista, 7, 8, and the various newer server versions. 32- or 64-bit Windows are both supported.
  • Microsoft .NET Framework 2.0 or newer
  • Inpout32.dll

Note that I am linking to the best version of Inpout32.dll. It should be compatible with all versions of Windows supported by my program. If you are using Windows Vista or newer, you will need to run the InstallDriver.exe program inside the Win32 directory of Inpout32’s distribution in order to install the driver. You only have to do this once, and it’s just so you can get administrator privileges in order to install the driver. Even if you are on a 64-bit operating system, that’s OK. Still run InstallDriver.exe from the Win32 directory.

Put Inpout32.dll from the Win32 directory into the same directory as ParallelPortTester.exe. Don’t use the x64 directory; that DLL would only be for a 64-bit program, but Parallel Port Tester is not a 64-bit program.

Download

OK, so you’re ready to download it? Here you go. Make sure you also get Inpout32.dll and install it as described above, because it’s not included with my program.

ParallelPortPicture_256

Download Parallel Port Tester version 1.0.0.2

Version History

  • 1.0: Initial release
  • 1.0.0.1: Improves parallel port detection algorithm; previous algorithm was incorrect in certain cases.
  • 1.0.0.2: Fixes a bug that was causing a crash for some users.

Any problems/questions/concerns? Please let me know in the comments below and I’ll try my best to help get you going. Be careful; it might be possible to fry your parallel port if you hook the outputs up wrong. I’m not responsible for any damage done to your computer by using this software.

For sample code that describes how I detect the computer’s parallel ports in Parallel Port Tester, see my blog post: Detecting parallel ports and their I/O addresses in Windows.

My previous blog posting on this subject from a few years ago sparked quite a bit of interest, so I’d like to follow it up with the latest compatibility information I have. First a quick summary:

Traditional Willem EPROM programmers require your computer to have a parallel port, and almost no computers today have them. You can find add-on parallel port cards, but a good chunk of today’s software is written to work directly with the parallel port addresses that were found on motherboards of older computers (0x378, 0x278, and 0x3BC). Add-on PCI/PCI Express/ExpressCard parallel ports don’t use those addresses.

Unfortunately, the Willem software only lets you pick from a hardcoded list of addresses to work with. The good news, however, is that it does its port access through a DLL called io.dll. There are replacement versions of io.dll that trick the Willem software into talking to a different parallel port address:

It’s actually a good thing that multiple options exist, because sometimes one option works for someone while the other option doesn’t, and vice versa. I would like to list what I have discovered about the various options available in terms of both hardware and software.

Parallel port cards

I have tried a total of four different parallel port cards cards, some of which are hard to find at this time:

My experience with these is the following. The Syba cards both use Moschip (now ASIX) chipsets, while the Shentek and StarTech cards use Oxford (now PLX Technologies) chipsets.

Both of the ASIX-based cards seem to work fine with no messing around needed. I’ve tested them on my desktop computer with Windows 7 64-bit (my DLL) and my laptop with Windows XP (Ben’s DLL).

The PLX-based cards throw a couple of curveballs into the picture, though. First of all, their bidirectional control pins (strobe, auto/linefeed, initialize, and select printer) do not have pull-up resistors. This causes a problem because they are open-drain/open-collector outputs, so something needs to pull them up when a high value is needed. Otherwise it’s impossible to use them as outputs — and the Willem programmer uses them as outputs. The Willem programmer (mine, at least) doesn’t supply its own pull-ups for those pins either. So in order to gain compatibility with those two cards, you will need to add pull-ups somewhere. To get these cards to work, I manually soldered some 10Kohm pull-up resistors for those lines onto my Willem board. It was a pretty ugly hack, though, so I removed the pull-ups after successfully testing it. Maybe someone can find a cleaner way to do it.

I have no idea about full-size PCI Express or PCI cards that use the PLX chipset. Perhaps they would already have the pull-up resistors in place. I’m just not sure.

The second issue with the PLX cards is described in the “DLLs” section below.

DLLs

The ASIX cards seem to work great with both my DLL and Ben’s DLL, so no further comments are needed here about them.

The Oxford cards don’t behave quite so nicely with my DLL. It seems that TVicPort has trouble reading bytes from odd addresses with the PLX cards, even though it has no such trouble with the ASIX cards. Inpout32 does not have this same issue. I haven’t narrowed down the root problem, but I don’t really care at this point anyway because there’s a fix: if you’re using a PLX chipset, you should use Ben’s DLL instead of mine.

The original reason I made my DLL was because I couldn’t get Ben’s DLL to work correctly with 64-bit Windows 7. It seems that Inpout32 is now 64-bit compatible (and signed), so it may be possible to simply stick with Ben’s DLL. If you plan on going that route, I would recommend downloading the latest version of Inpout32 and grabbing the Inpout32.dll file included with that to go along with Ben’s io.dll. You’ll want to use the 32-bit version even if you’re on a 64-bit operating system. The reason for that is because the Willem software itself is 32-bit. You may need to run the InstallDriver.exe program included with it to get everything to install correctly, but I’m not an expert at Inpout32.

Testing compatibility

If you’d like, you can test your parallel port card with my Parallel Port Tester utility. Make sure all of the outputs and bidirectional pins can correctly output both high and low values. Physically check each pin with a voltmeter while you test. Every card I’ve seen so far outputs 3.3V as a high value. If your bidirectional pins don’t appear to output a high value correctly (or you get weird readbacks in the tester utility), the high value may be floating, thus indicating you need pull-up resistors on those pins. Also make sure the input pins read a high value with nothing attached and a low value when you ground them. It’s OK if the control pins don’t work correctly as inputs; the Willem programmer uses them all as outputs.

Conclusion

The information available in my original post is still very useful and should help walk you through setting up a Willem programmer with various types of cards. I just wanted to share all of my latest compatibility knowledge in a new post because it was all buried in the comments of my original post.

In the early- to mid-1990s, Apple produced their Macintosh Performa line of computers. These computers were meant for home users and typically came bundled with software such as ClarisWorks and Mario Teaches Typing, along with interactive tutorials teaching the basics of how to use the Mac OS. They were sold in places such as Wal-Mart and Sears.

One interesting thing about these computers is that at least initially, they did not come with any software restore disks. If something bad happened and you wiped out your system software (which was easy enough to do — somehow I did it as a kid), you didn’t have a supplied set of disks (or a CD) for restoring the software. Instead, these computers came with software called Apple Backup, and you were supposed to back up your system onto 1.44 MB floppies when you first got it. When you ran Apple Backup, it would let you choose to back up either the full hard drive or just your system folder:

Picture 3

The number of disks needed here is small because I ran it on a simple barebones system to make this screenshot. With all of the bundled software on a stock Performa machine, it would have taken somewhere in the ballpark of 50 floppy disks to complete the backup of the full hard drive. Seriously, how many people would have bothered to buy all of the floppies that would have been necessary, and then actually taken the time to do it? Some people definitely did, and I’m impressed by the dedication. I know my family didn’t bother when I was growing up. It would have been more realistic to only back up user-created files, and then provide a system restore disk (or set of disks) to restore any original software, but the backup software didn’t work that way. Apple obviously learned from their mistake because they began bundling Performa computers with restore CDs at some point later on. (Note: To be completely fair to Apple, it was possible to obtain restore disks from them if you needed to restore your system and your Performa didn’t come with any.)

I ran the backup process on an old Mac for fun, and it guided me through the process of backing up the system. Click the thumbnails to see the full size, if you care:

Picture 1 Picture 2 Picture 3 Picture 4
Picture 5 Picture 8 Picture 9 Picture 10

The resulting disks were normal Mac floppy disks, named “Backup Disk 1”, “Backup Disk 2”, and so on, each containing a single 1,414 KB file named Apple Backup Data.

To restore your data after a failure, you would boot up your Performa using the Utilities disk that came with the computer. The Utilities disk contained a barebones system folder along with disk formatting/repair utilities and a program called Apple Restore. You guessed it: Apple Restore was used to restore the system. You would run it and then insert your backup floppies one at a time to restore everything you backed up.

I looked at some of Apple’s later Performa restore CDs, and interestingly enough, they came with programs called “Restore All Software” and “Restore System Software”, each with a folder full of 1,414 KB files named “Data File 1”, “Data File 2”, and so on. So presumably Apple simply used Apple Backup to back up a stock system and stuck the resulting data files onto a CD to create the restore CD.

I decided that it might be useful to have Apple Backup’s file format documented in case someone out there ends up needing to restore files from their old backups (or wants to extract files from a factory restore CD). Although backup floppies from the 90s are probably going bad by now, I think it’s still cool to have the information out there. Anyway, I decided to reverse engineer Apple Backup and one of the factory CD restore programs (which does essentially the same thing as Apple Restore). I believe I have successfully reverse engineered the Apple Backup file format.

The rest of this blog posting contains the technical details about the format of the files that Apple Backup creates.

Overall layout of an Apple Backup data file

  • Type code: ‘OBDa’ (CD restore files have type ‘OBDc’ instead, but are otherwise identical in format)
  • Creator code: ‘OBBa’
  • There is no resource fork, and the data fork content is summarized in the table below:
Backup disk header
Boot blocks
File #1 header
File #1 full path
File #1 data fork data (if any)
File #1 resource fork data (if any)
Zero padding to next multiple of 0x200 bytes
File #2 header
File #2 full path
File #2 data fork data (if any)
File #2 resource fork data (if any)
Zero padding to next multiple of 0x200 bytes
File #3, 4, 5, … until data file is full

Next, allow me to describe the content of the data fork in more detail:

Backup disk header format

All offsets and lengths are in bytes. All multi-byte quantities are in big-endian format as would be expected from a Mac file format.

Offset Length Name Notes
0x00 2 Version This spec is valid up to and including version 0x0104
0x02 4 Magic number ‘CMWL’ – identifies this file as an Apple Backup file
0x06 2 This disk number Value is between 1 and the number of disks.
0x08 2 Total number of disks The total number of disks used for the backup.
0x0A 4 Backup start time In a Mac time format (seconds since January 1, 1904 00:00:00 local time)
0x0E 4 Backup start time Appears to always be a duplicate of the value above
0x12 32 Hard drive name The name of the hard drive that was backed up. Stored as a Pascal-style Str31 (1 byte length, 31 bytes of string data)
0x32 4 Total size of this file The total size of this restore file; value typically (always?) seen is 0x161800
0x36 4 Total size used in this file The number of bytes actually used in this restore file; value is typically 0x161800 except on last disk where it is probably going to be smaller.
0x3A 0x1C6 Unused Filled with zeros

Total length: 0x200 bytes

Boot blocks

These appear to be standard Mac OS boot blocks, 0x400 bytes in size. Easily seen in a hex editor because it begins with LK, and soon thereafter has names: System, Finder, MacsBug, Disassembler, StartUpScreen, Finder, Clipboard. They are written to the hard drive by the restore program when the System Folder is blessed as it’s restored. For just extracting files, they are not really relevant. They begin at an offset of 0x200 from the start of the backup file, and end at an offset of 0x600 (where the first file header begins)

File/folder header format

Each file or folder starts out with a header. Again, all offsets and lengths are in bytes, and everything is big-endian. This header will always begin on a 0x200-byte boundary; padding bytes of zero are added to the end of the previous file’s data fork/resource fork data if needed. The first file header in a backup data file is always at 0x600, immediately after the boot blocks.

Offset Length Name Notes
0x00 2 Version This spec is valid up to and including version 0x0104
0x02 4 Magic number ‘RLDW’ – identifies this as a file/folder header
0x06 2 Disk number that contains first part of this file/folder This will match the current disk number, unless this file is split across multiple disks and this is the second, third, etc. part of the file.
0x08 4 Backup start time Will be the same as the time in the backup disk header
0x0C 4 Offset of header The offset where this header begins in the disk (example: 0x00000600 in the first file header in every disk)
0x10 32 File/folder name The name of this file or folder. Stored as a Pascal-style Str31
0x30 2 Which file part this is 1, unless this is part of a file that has been split across multiple disks, in which case it will be 2, 3, etc.
0x32 1 Folder flags Bit 7 = 1 if this is a folder, 0 if this is a file.
Bit 0 = 1 if this is the system folder and it needs to be blessed [selected as the current system folder]
0x33 1 Validity flag Bit 0 = 1 if the following file info/attributes/dates are valid.
Bit 0 = 0 if this was a folder that is known to exist but its properties could not be read during the backup.
If a file’s properties cannot be read, the file is skipped during the backup process. So bit 0 = 0 could only happen with folders.
0x34 16 FInfo/DInfo about this file/folder A standard Mac FInfo or DInfo struct containing info about this file or folder (from HFileInfo or DirInfo)
0x44 16 FXInfo/DXInfo about this file/folder A standard Mac FXInfo or DXInfo struct containing info about this file or folder (from HFileInfo or DirInfo)
0x54 1 File/folder attributes Standard ioFlAttrib byte from Mac Toolbox HFileInfo/DirInfo struct
0x55 1 Unused
0x56 4 Creation date Standard Mac time
0x5A 4 Modification date Standard Mac time
0x5E 4 Length of file’s data fork Total length of data fork of the full restored file including all split parts (zero for folders)
0x62 4 Length of file’s resource fork Total length of resource fork of the full restored file including all split parts (zero for folders)
0x66 4 Length of data fork provided by this disk The length of data fork data this disk is providing for this file
0x6A 4 Length of resource fork provided by this disk The length of resource fork data this disk is providing for this file
0x6E 2 Length of full file path Maximum length of 33*50 (enough space for 50 colon-delimited path elements, with many extra bytes left over).
This is the length of the string that immediately follows this header.

Total length: 0x70 bytes. See Inside Macintosh: Files and the Mac Toolbox C headers named “Files.h” and “Finder.h” for more info on FInfo, DInfo, FXInfo, DXInfo, and ioFlAttrib. These items are where the type and creator code, invisible flag, and icon position in folder are stored, for example.

Full path format

The full path is just that: the full path to the folder or file, with the hard drive already being assumed. The components of the path are colon-delimited. The file being restored is the last component of the path. Example:

System Folder:Control Panels:Memory

(if the file being restored is the Memory control panel). It’s just printed as raw bytes, no null terminator or anything — it’s basically a Pascal string with a two-byte length, and the length is at the end of the file/folder header.

The actual file data

Immediately after the full path, the data fork bytes begin (number of bytes = “Length of data fork provided by this disk”), followed by resource fork bytes (number of bytes = “Length of resource fork provided by this disk”). It’s perfectly OK for the length of either (or both) of these to be zero. After that, there is padding (filled with “0” bytes) to the nearest 0x200 byte boundary, and then the next file/folder header begins.

When a file overflows the disk

If there is not enough space remaining on a disk for a complete file (this almost always happens at the end of each data file), the amount of file data that will fit on the disk is stored so that the full disk file size matches the size given in the disk header. Then the first file header on the next disk will be the same file’s header with the exception of the “Which file part this is” field, which will be incremented by one. It is possible for a file’s data to span several disks in this manner; the intermediate disks will only have one file header, followed by a repeat of the file path and data using up all available space on the disk.

For example: Let’s pretend you have 0x1000 bytes remaining on the current data file before its size reaches 1,414 KB. You’re ready to back up a file “Applications:TestApp” that that has a 512 KB data fork and a 128 KB resource fork. The file header will take up 0x70 of those bytes and the full path will take up 20 (0x14) of those bytes, for a total of 0x84 bytes — so there are 0xF7C (3,964) bytes left. So the file header is going to specify a data fork length in this disk of 3,964 bytes, and a resource fork length of 0 on this disk (the total lengths will be filled in as 512 KB and 128 KB though). Then the first 3,964 bytes of the data fork will be written to the file, giving it a total length of 1,414 KB. Then this disk will end. The first file header on the next disk will finish the remaining 520,324 data fork bytes and all of the 131,072 resource fork bytes, and then the next file’s header will begin on the nearest 0x200 byte boundary after that.

Conclusion

As you can see, the format is pretty simple. It’s just basically a disk header followed by a flat list of files until the end of the disk is reached. It should be possible to extract full and partial files from these backup archives even if the data files from some disks are missing. The partial files probably wouldn’t be very useful though.

The original Apple Restore utility didn’t let you pick and choose which files you wanted to restore — it just tried to restore them all, and it would ask you what to do if the file already existed and was newer than the backed up version. I see no reason why a utility couldn’t go through all of these files, give you a list of everything available, and let you selectively extract the files you want. It’s easy to detect what disk a particular backup data file came from because the disk header contains a field for what disk it belongs to.

If anyone’s interested in adding the ability to decode this format in an archive expander program, I would be happy to provide some sample data files. I may or may not decide to write a program to extract files from these backups, depending on how bored I get 🙂

I can’t remember exactly why, but I recently decided I wanted to play around with Super Nintendo games that support more than two players. I have a Super Nintendo console along with several such games — Super Bomberman, NBA Jam, and Madden 97 come to mind. The most popular adapter designed for this purpose is called the Super Multitap. It plugs into the second controller port on the SNES and provides four controller ports, so you get a total of five ports available for use.

I looked on eBay for Super Multitaps and found plenty for sale, but I decided I wanted to make things more complicated. I stumbled upon a schematic for it, found in the official Super Nintendo developer manual. Google for it if you’re interested — I don’t want to link to it just in case lawyers want to ruin all of the fun. I was intrigued by the simplicity of the circuit. It’s basically 3 chips (a mux and a bunch of tri-state buffers), eight resistors, and the controller connectors. Why buy the ready-made adapter if I could just make my own? In theory, buying the parts would be cheaper than buying a used Multitap on eBay, but in practice, the controller sockets and plugs are hard to find so it’s probably not worth it from a monetary standpoint.

But still, I think it’s worth it for the geek cred! Right?

Well, I decided to do it.

Read the rest of this entry

There are tons of instructions out there for setting up WordPress on a lighttpd server with WP Super Cache. A quick Google search will show you what I’m talking about. I’m not totally happy with them though — it usually boils down to enabling mod_magnet and using a lua script. It’s not too surprising that it requires a bit of trickery because the main instructions that come with WP Super Cache are designed with Apache in mind.

I’d like to share the setup I use on this blog, which takes more manual effort initially but no longer requires the use of a lua script.

I first obtained these instructions from a blog which no longer exists, but the original instructions are still available from the wonderful Internet Archive. Since the original page is no longer around in Google results, I feel like I need to keep the instructions alive. So…here they are, in my own words and modified for a newer version of lighttpd:

First of all, set up WP Super Cache for mod_rewrite mode. It’ll warn you that mod_rewrite isn’t installed and the rewrite rules must be updated — this is perfectly OK because we’re not using Apache.

Now, in the main WordPress directory, create symlinks to everything in the wp-content/cache/supercache/www.domain-name.com directory. Here’s an example symlink command for the “2010” directory:

ln -s wp-content/cache/supercache/www.domain-name.com/2010 2010

I had to create the following symlinks on my server:

2010, 2011, 2012, category, contact, index.html, and microcontroller-lessons

Every time you add a new page with a root directory URL or another year goes by, you will need to add an appropriate symlink or else the supercaching for that page won’t be active–it’ll be served through PHP instead, so the site won’t break if that happens — it’ll just be inefficient.

OK. Now that you have that done, disable directory listings, set the 404 error handler to /index.php, and ensure that index.html comes before index.php in the list of index file names. That last one about index.html being in front of index.php simply ensures your main blog page is served supercached correctly. Anyway, this can all be done in lighttpd.conf:

server.error-handler-404 = "/index.php"
dir-listing.activate = "disable"
index-file.names = ( "index.html", "index.php" )

That’s it! It’s about as simple as it can get.

Is it perfect? No, not at all. It doesn’t matter if you’re logged in or not — if a supercached version of a page exists and you go to its URL, you will get the supercached version rather than a newly-generated version of the page–meaning you don’t get the cool WordPress toolbar at the top. So it isn’t smart enough to look at your cookies or anything like that to only serve supercached files to non-logged-in users. In my case, I don’t really care — I can still access the WordPress Dashboard and that’s all that really matters to me.

It’s also kind of annoying that you have to create a new symlink for everything that is in the “wp-content/cache/supercache/www.domain.com” directory, but I can live with it.

It appears to work because if a supercached version of a page doesn’t exist already, a 404 error occurs, which passes the request onto /index.php, which figures out the original request.

Thanks again to the (now defunct) Zash Blag for the original instructions. There may be better solutions available than this — if there are, please leave a comment! I would definitely be interested in trying them out.

Edit: With the latest kernel updates, this hack should no longer be necessary in Ubuntu 12.04 or 12.10. I’m leaving this post in place for future reference if people run into the same issue with newer iPhone revisions as they come out.

Here’s the scenario: you’re using an Ubuntu distribution (perhaps 11.10 or 12.04 or 12.10, but I’ve only tested this on 12.10) and you’ve followed the various instructions around the internet for tethering your iPhone using a USB connection in Linux, but it just doesn’t work on your iPhone 5 no matter what you try, despite it working on an older iPhone model just fine.

What gives?

The problem is that iPhone 5 support was added to the ipheth driver in the Linux kernel in October, and that particular patch hasn’t been added to the kernel Ubuntu is using yet.

Look at the patch. All they did was add an extra item to the end of a static array. It looks exactly the same as all the rest of the entries, with the exception of a different USB device ID. If you don’t want to backport the patch and recompile the kernel module and all that, we could just modify the binary ipheth driver so one of the existing iPhone device ID entries matches the iPhone 5 instead of its original device ID. It’s a little more tricky to append to the array by just modifying the binary, so changing an existing entry in the array is an easier alternative. Let’s do it!

Make a copy of /lib/modules/<your kernel version>/kernel/drivers/net/usb/ipheth.ko and put it somewhere. We’ll mess with the copy, so leave your existing driver alone just to be safe.

Decide on an iPhone model you don’t need support for. In my case, I just picked the iPhone 3GS. In the code of the ipheth driver, find its corresponding USB device ID. For the iPhone 3GS, it’s 0x1294. Now, using your favorite hex editor (I personally like running HxD in Wine), search for that string, but reverse the bytes (unless you happen to be on a big-endian system like PowerPC). So in my case, I would search for the hex string 0x9412. Once you find it, confirm that it has 0xAC05 directly before it. This just confirms it’s part of the device ID table and not just a random chunk of code or data that happens to be the same. OK, so you’ve found it. Replace the old hex string (0x9412) with the iPhone 5’s USB device ID (it’s 0x12a8, so you will use 0xa812).

Save the file.  Manually unload the old driver if it was already loaded by typing:

sudo rmmod ipheth

Now, load the new one:

sudo insmod /path/to/new/ipheth.ko

Try plugging the iPhone 5 in now. It should be recognized as a network interface!

You’ll have to manually load this kernel module with the insmod command every time you reboot your system, and every time you install a kernel update, you should probably redo the patch on the latest version of the ipheth module, but it works! If you’re feeling extra clever, I think you could actually leave the modified version of the driver in place where the regular driver goes and add a line to modules.usbmap so it will automatically load the new ipheth module when the iPhone is plugged in, but I’m not going to get into that.

So there you have it: a quick and dirty way to make your iPhone 5 USB tethering work until Ubuntu either starts using a newer kernel or backports iPhone 5 support.