A couple of months ago I stumbled upon a post on Hackaday about an inexpensive open-source USB 2.0 sniffer created by Alex Taradov. This is a really cool project! Normally, USB sniffers like this can cost thousands of dollars, especially if you’re paying for fancy protocol decoding and also want high-speed 480 Mbps support. This one costs about $50 in parts to assemble yourself, although it will take hours to solder and you will need some experience with hot air (or reflow oven) soldering since the USB PHY is a QFN chip with an exposed pad underneath.

I actually have an Ellisys USB Tracker 110b that I bought on eBay many years ago, but it only does low-/full-speed decoding. I thought this would be a good opportunity to upgrade my capabilities to also be able to handle high-speed USB sniffing, while also providing some good soldering practice.

Here’s my (very long) video about the process of building up one of these and programming it. I left in all the mistakes I made along the way. Why not show the world that it’s normal to make dumb mistakes when you build stuff?

I thought I’d use this post to explain in a little more detail what exactly a USB sniffer is. Why would I buy (or make) a hardware USB sniffer when Wireshark already has software USBPcap support in Windows?

Read the rest of this entry

Update on 2023/05/19: ASUS has publicly acknowledged the issue and provided an explanation and workaround of their own (rebooting, or a hard reset if the reboot doesn’t fix it). The original post is below:

When I woke up today around 6:45 AM PDT, I didn’t seem to have internet service available. My phone told me that I was connected to my Wi-Fi network, but it didn’t have connectivity. “Hmm, that’s weird,” I thought. Maybe a fiber cut in the area or something? I looked at my IRC client on my desktop Windows PC, which is nice because it records timestamps of when I lose my connection:

03:24:23 - Disconnected (Remote host closed socket)

My connection had been down for over 3 hours at this point. Weird! I figured I would log into my ASUS RT-AC86U router’s web interface and see what was going on. Something happened that I wasn’t expecting at all — the page wouldn’t fully load. Portions of it showed the little “sad page” icon indicating a connection error.

I tried to SSH into the router instead. The first few connection attempts failed, and then finally I got in. What I found, though, was that I couldn’t run any commands. It just spit this error back at me:

-sh: can't fork

OK, so something was really messed up. I decided to power cycle the router at this point. Maybe some weird glitch happened or something. Which would be odd — this router has been pretty rock solid since I’ve had it, aside from 2.4 GHz Wi-Fi issues over time. That’s another story I don’t want to get into today.

Anyway, when the router came back up everything seemed fine. But then, 40 minutes later, my connection dropped again with the same symptoms.

07:26:23 - Disconnected (Remote host closed socket)

Read the rest of this entry

This post is going to be a bit different from my usual posts. It’s still about computers, but it’s about a different type of computer: the computer modules in my 2009 Dodge Ram 1500 pickup. Vehicles these days have lots of computers in them. I’ve historically been afraid to mess too much with them in fear of screwing them up. Something going wrong has much more serious consequences when it’s your vehicle, as opposed to a spare computer you’re dinking around with. I’m slowly getting more confident though.

Read the rest of this entry

I work on embedded devices that have the capability of installing a firmware update by plugging in a USB flash drive containing an update file. These devices can also save reports onto an attached flash drive. Historically, these devices have worked with the various drives I’ve been able to test in house, but there have been occasional reports of incompatible drives in the field. I just used the sample code provided with the microcontroller manufacturer’s USB library, so I had no idea what I could do to improve compatibility.

Sometimes the problem is outside of my control. If the drive is larger than 32 GB, Windows 10 formats it as exFAT, and I don’t currently have exFAT support enabled (it’s too expensive to license from Microsoft). But most of the time, the problem isn’t the filesystem. The problem is that each drive behaves a little differently.

I decided to dedicate some time to improving USB drive compatibility in the embedded devices I work on. I researched USB mass storage devices, the USB specification, and the SCSI protocol that flash drives speak over USB. I bought an old Ellisys USB Tracker 110b, which is capable of recording raw USB 1.1 traffic (this is suitable for my needs, because the embedded devices I work on are only capable of full speed). Then, I bought a ton of used flash drives on eBay. My goal was to try as many drives as possible and discover various quirks. I also got a USB 1.1 hub in order to limit the drives to full speed on modern computers, and recorded what happened when I plugged the drives into Windows XP, Windows 10, Linux, Mac OS X, and Mac OS 9. 

I was successful. I found lots of little differences in how USB drives work. The purpose of this post is to share my findings to help others in the future who might have trouble with USB flash drive support in their embedded products.

Specifications

Here is a list of links to relevant specifications that will be useful as a reference:

Brief overview of how USB mass storage works

Before I get into specific details, I want to start with a quick overview of how all of the protocols explained in the specifications above combine together to enable computers to communicate with flash drives over USB.

When a flash drive is plugged in, the computer looks at its device, configuration, interface, and endpoint descriptors to determine what type of device it is. Flash drives use the mass storage class (0x08), SCSI transparent command set subclass (0x06), and the bulk-only transport protocol (0x50). The specification indicates that this should be specified in the interface descriptor, so the device descriptor should indicate the class is defined at the interface level.

What does this all mean? It just means that there will be two bulk endpoints: one for sending data from the host computer to the flash drive (OUT) and one for receiving data from the flash drive to the computer (IN). Data sent and received on these endpoints will adhere to the bulk-only transport protocol specification linked above. In addition, there are a few commands (read max LUN and bulk-only reset) that are sent over the control endpoint.

The host starts out by sending a 31-byte command block wrapper (CBW) to the drive, optionally sending or receiving data depending on what command it is, and then reading a 13-byte command status wrapper (CSW) containing the result of the command. The CBW and CSW are simply wrappers around Small Computer System Interface (SCSI) commands. Descriptions of the SCSI commands are available in the last two specifications I linked above.

That’s all there is to it…except I haven’t said anything about which SCSI commands you’re supposed to use, or when. SCSI is a huge standard. Reading the entire standard document would take a ridiculous amount of time, and it wouldn’t really help you much anyway. Unfortunately, the standards don’t provide a section entitled “recommended sequence of commands for talking to flash drives over USB”.

This is where I originally hit a roadblock when I was implementing USB support, and it’s also why I simply stuck with the sample source code provided with the USB library I used. Unfortunately the sample source code was not good enough. What it comes down to in practice is you should try to do something similar to what Windows does, because pretty much every flash drive is compatible with Windows.

Initialization sequence

The first important thing to do when a USB flash drive is detected is to figure out information about it. Is it actually a flash drive? How big is it? How many logical units (LUNs) does it have? I found that if I didn’t follow a sequence with some preliminary commands that operating systems do, a SanDisk drive with a bunch of files on it would crash when I first attempted to write to it. Interestingly, the same drive didn’t have the same problem when it was empty. You may be thinking I’m an idiot and a problem like this obviously has to be in the filesystem library and not the USB library, but I swear that the problem was the USB communication to the drive itself, because imaging the drive to my computer with “dd” and using the same filesystem library on the raw drive image worked fine. The Ellisys USB Tracker confirmed the drive responded with a stall condition after the write, and after clearing the stall, it was hung up, even after a mass storage bulk-only reset command, which is supposed to prepare the drive to receive a new command.

Based on what I observed Windows, Mac OS X, and Linux doing, I changed my initialization sequence, and that problem completely went away. The sequence I do now is not an exact clone of any other OS, and it’s probably doing extra overkill commands, but hey, it works:

  1. Request the maximum LUN. If this request stalls, assume the maximum LUN is 0. Start working with LUN 0 in either case.
  2. Keep trying the sequence of “TEST UNIT READY” followed by “INQUIRY” until they both return success back-to-back. At this point you can look at the returned inquiry data to get more information about the name of the drive, if you care. For the inquiry, request 36 bytes. That’s what pretty much every OS does, so it’s best not to deviate from that.
  3. If the “INQUIRY” response data indicates that the peripheral device type is not 0 (meaning “direct-access device”), and there is more than one LUN, repeat step #2 with additional LUNs until you find one that is a direct-access device. Some promotional flash drives use LUN 0 as an emulated CD-ROM and the flash drive is on LUN 1, so you’d want to use LUN 1 instead of LUN 0 in that case. After this process is complete, use the LUN you discovered for all of the rest of your commands going forward. If you don’t find anything matching, just stick with LUN 0 in case the inquiry data is wrong.
  4. Attempt a “PREVENT ALLOW MEDIUM REMOVAL” command. A lot of operating systems do this, and most drives don’t support that command. It’s no big deal if the command fails. Just continue on. Interestingly I didn’t observe Windows XP sending this command on the drive I tested, but Windows 10, Mac OS X, and Linux did. I don’t know whether to include this command or not. It works for me.
  5. Keep attempting a “READ CAPACITY (10)” command until it succeeds. This will tell you the size of the drive in blocks (minus 1, because it returns the address of the last block), as well as the block size in bytes.
  6. Try a “MODE SENSE (6)” command, requesting 192 bytes of data on mode page 0x3F. The 192 matches what other operating systems request, so it’s best to match that. In the response data, if bit 7 of byte 2 is set, the drive is read-only. If the mode sense command fails, just move on. I haven’t found a drive that fails this command though.
  7. Just to be safe, do “TEST UNIT READY” again, repeating until it returns success. Now you are ready to send all the “READ (10)” and “WRITE (10)” commands you want to send.

In all of the places where I said to keep attempting something, I have a timeout of 5 seconds. If I don’t succeed and 5 seconds have elapsed in that step, I bail with an error. No drive I’ve tested so far has caused the 5 second timer to elapse, but if you’re extra worried you could try increasing the timeout.

Things to watch out for

As I tested various drives, I noted strange behaviors in certain cases. Here is a list of things you should probably watch out for.

Mass storage reset

The sample code that came with the USB library I use performed a “Bulk-Only Mass Storage Reset” command as the first step. None of the operating systems I tested did this, so I removed it. I think you should only use this command as a last resort if you have lost communication with the drive and it has stopped responding to your CBWs. (Make sure the drive isn’t simply waiting for you to read back a CSW after a stall or something too…)

Drives that are both a CD and flash drive

As I mentioned above, some promotional drives are both a CD-ROM and a flash drive. Check for that type of drive with the “Get Max LUN” command, and use the INQUIRY data on each LUN to find the one that’s actually the flash drive.

MODE SENSE (6) or MODE SENSE (10)?

While I was checking out various operating systems, I noted that sometimes Windows and Mac OS X use “MODE SENSE (6)” and sometimes they use “MODE SENSE (10)”. Linux seems to always do “MODE SENSE (6)”. I couldn’t figure out how Windows and OS X were making that determination.

I originally tried just always using “MODE SENSE (10)”, since I also always use “READ (10)” and “WRITE (10)”, so I figured why not the same with mode sense? However, that was a mistake. Some drives don’t support that command, and others return incorrect results in it. One drive I tested was particularly frustrating. Its “MODE SENSE (10)” response indicated that it was locked, even though it wasn’t. Its “MODE SENSE (6)” response correctly said it was not locked.

The moral of this story? Just stick with “MODE SENSE (6)”. Every drive I’ve tested supports it and returns correct-ish data. One drive I tested returns an incorrect data length as the first byte of the SCSI response data (the mode parameter header), so if the drive only returns 4 bytes but claims there are 70 in the response, you might want to limit your parser to only check the first 4.

As I said earlier, you should request 192 bytes of data in this command to match what other operating systems do. I’d recommend requesting mode page 0x3F, which means “all pages”. I’ve read online that some misbehaving drives may get confused if you send a mode sense request for any other page or data length.

First TEST UNIT READY command fails

On a lot of drives, the first “TEST UNIT READY” command returns failure. The sense data (obtained with “REQUEST SENSE”; see below) indicates it’s a temporary condition and to try again. On most of these drives, the next attempt succeeds. On one drive I tested, it failed the first 14 attempts.

This is why my initialization sequence says to keep trying “TEST UNIT READY” until it succeeds. I added “INQUIRY” in there as well because it seemed other OSes would intermix “INQUIRY” with it too. If after 5 seconds (or whatever time limit you’re comfortable with) it still hasn’t responded with success, then maybe something really is wrong.

Repeat failed commands

Maybe I should have just generalized the above section, but I’ll repeat it here. If a command fails that you really care about, just try again. I have it set up so if a “READ (10)” or “WRITE (10)” fails, I try again a few times before immediately bailing with an error.

In general, if an error occurs because the CSW indicates failure (and this rule of thumb also applies during the initialization sequence I described above), you should follow up with a “REQUEST SENSE” command to read information back about the failure before sending any other commands. Why? Because all the other operating systems do it too, so it’s a good idea. You are guaranteed that the drive has been tested under that behavior.

Theoretically the drive will tell you in the returned sense data whether the command failed due to a temporary condition or if the command is not supported. In practice, I do the “REQUEST SENSE” command and read the response from the device, but I ignore the content of the response. I simply repeat commands that I know are important, and I live with failure and move on if they’re not important (e.g. “PREVENT ALLOW MEDIUM REMOVAL”).

Write delays

This is probably obvious, but I’m pointing it out anyway. Sometimes “WRITE (10)” operations take a while to complete. When this happens, the drive will respond with NAKs until it’s finished. The NAKs could occur at any point — maybe while trying to read back the CSW, or while sending the next CBW, or in the middle of the data transfer process. If you’re designing a communication protocol that receives data and writes it to disk, make sure it has the ability to pause if the disk is too slow to keep up.

Handling short responses

In some cases, you will request data from the flash drive, but it will respond with less data than you requested. A perfect example of this situation is the “MODE SENSE (6)” command when requesting 192 bytes of data. I haven’t found a flash drive yet that has 192 bytes of mode pages to respond with.

According to the bulk-only transport specification, if the host requests more data than the device can provide in this situation, it’s allowed to pad the response with extra data to match the requested length. If it doesn’t do this, it must stall the BULK IN endpoint after transmitting as much data as it can. I was able to observe different drives that implemented each of these behaviors.

It turns out that there are some flash drives that ignore the above requirement and do it a different way. They don’t pad the response with extra data, and they don’t stall the endpoint. They simply send as much data as they can, without stalling the endpoint afterward. Although these devices aren’t following the bulk-only transport specification correctly, it’s not too hard to handle this situation. If you receive a USB data packet shorter than the endpoint’s maximum packet size (a “short packet”) when reading a response, but you haven’t received all the data you expected, you know the response has been terminated early by the drive, and the next read you attempt will give you the CSW. The USB library I use didn’t handle this case properly and would hang when trying to read a “MODE SENSE (6)” response from a misbehaving drive. It kept reading after the short packet. The next packet was the CSW, which it thought contained more mode sense data, and then it hung waiting for the rest of the mode sense data to arrive. I fixed the library to look for short packets and terminate the transfer early.

Because of this situation above, you might not realize a well-behaved drive has correctly stalled the endpoint until you try reading the CSW. So if you notice a stall condition after attempting to read back a CSW, clear the stall and try again. Note that the specification specifically mentions that retrying a CSW read after a stall is allowed. I suspect they allow it because of situations like the one I just described.

Safely ejecting

Some drives I tested didn’t necessarily finish saving changes before they were unplugged. For example, if I wrote data to a temporary file, and then renamed the file as my last write operation, plugging the drive into the computer showed that the rename operation hadn’t completed successfully, even though I had definitely asked the filesystem library to unmount the filesystem.

This was caused because the drive in question (a Samsung flash drive) implements caching, and I hadn’t told the drive to flush its cache to disk.

There is probably a complicated way to set up the cache properly. I believe one of the mode pages optionally returned by the “MODE SENSE (6)” command contains cache information which you might be able to configure. I came up with a simpler solution that seems to work. I send a “SYNCHRONIZE CACHE (10)” command after I’m done and have told the filesystem library to unmount the filesystem. This fixed the issue with the Samsung drive. Some drives don’t support this command and return an error, but it doesn’t seem to hurt anything.

Unsupported commands

I have read online that some poorly-designed flash drives will stop responding if you send them a command they don’t support. I haven’t observed any such drives in action. If you are concerned about this, you might want to consider removing the “PREVENT ALLOW MEDIUM REMOVAL” command from the initialization sequence, because I’ve seen many drives that don’t support it. You might also want to find a safer way of flushing the write cache than what I chose. In my use case, the very last command I send prior to the drive being ejected is the “SYNCHRONIZE CACHE” command. If that command is unsupported and causes the drive firmware to crash, the drive probably doesn’t support caching anyway, so I can assume the data is already safely written to the disk and the user is about to unplug it anyway.

Final thoughts

If at all possible, get a hardware USB analyzer. They’re typically expensive, but they give you so much detail about everything that’s going on. I was lucky enough to find one on eBay for a reasonable price. I can’t imagine that I would have been able to do this level of troubleshooting without one.

Even if you don’t have a hardware analyzer, if you follow some of my suggestions above, your device will be much more likely to be compatible with all of the random flash drives your end users happen to try out.

For 100% compatibility, it would probably be best to try to replicate exactly what Windows does when a drive is plugged in. However, doing that is difficult. It’s sometimes hard to understand why Windows sends the commands it does.

I recently wanted to play around with Android development, but I didn’t have any Android devices. So I picked up a cheap Android tablet from Walmart. It’s an RCA Viking Pro 10.1″ running Android 6.0. The model number is RCT6303W87M, although in software it identifies itself as RCT6303W87M7. But…Walmart’s website says it’s an RCT6303W87 DKF. I have no idea what is really correct, but I figured I would write out all of the model numbers so that people from Google can find this post.

Anyway, I realized after I bought it that the micro-USB port is strictly for charging. Oops, my bad. It turns out that this tablet wasn’t really designed with USB connectivity as a device in mind. It does have a USB type A port, but that’s for connecting other devices to the tablet, not the other way around. I tried turning on developer mode and any options on the tablet I could find, but nothing allowed connectivity with the computer.

I did some Googling, which seemed to indicate that other people had been in this predicament. There was talk of a mysterious “special cable” that RCA provides as an option to buy. I also found people discussing using a USB A-to-A cable with varying levels of success. I decided the best thing to do would be to contact RCA support, which led me down a bit of a rabbit hole.

The friendly RCA support person told me I needed to buy a special cable, and gave me a link on RCA’s store to order it, along with instructions for using the cable — in particular you have to connect the cable while the tablet is off, and the blue end needs to be plugged into the tablet. The cable had a price tag of $5 on their store, but it looked just like a standard USB A-to-micro cable that everyone has laying around. I went ahead and ordered it anyway, but sure enough, it wasn’t actually a special cable. It was just a run-of-the-mill micro USB cable, which I had already tried myself. There wasn’t a blue end — the entire cable was black. To make matters worse, the cable came from Canada, so I had to overpay for shipping, not to mention the foreign transaction fee on my credit card.

I wrote back to RCA support. The same person who helped me first time apologized and indicated that I hadn’t actually ordered the special cable. It appears that the special cable is available from RCA, but it’s not publicly available on their site so you have to do a special order to get it. So this time RCA sent the correct cable my way for no additional charge.

Today the cable arrived, and it is indeed special. It’s a USB A-to-A cable (well…since it came from Canada, maybe we should call it an eh-to-eh cable?). The ends are clearly marked so you know which end goes to the tablet and which end goes to the computer, and the tablet’s end is blue (although you can’t see it in the picture, because the part that goes into the computer is the part that’s blue, like a USB 3.0 cable).

I don’t know if there’s anything special about the cable over other A-to-A cables. The blue end that goes to the tablet appears to be a USB 3.0 connector, which makes sense because USB 3.0 cables are typically blue. So there are extra pins for USB 3.0–but the tablet itself doesn’t actually have connections for any of those pins. I dunno. It’s a mystery. I think they just used a 3.0 connector so they could get one that is colored blue. I think there must be something special about the cable other than just being an A-to-A cable; why else would they mark which end is which? I don’t have an easy way to do any further tests on the cable to try to figure out which pins are connected to which pins.

I guess you could say I made out like a bandit, because the special cable would cost $15 according to the label on the package. The label indicates the product is a “special cable” and it’s for the RCT6513W87, so I assume that tablet has the same problem. For reference for readers, here are the instructions RCA provided me for using the cable:

  1. Tablet has to be completely off
  2. Connect the special cable from tablet to computer, please note that the blue end goes to the tablet
  3. Plug the AC adapter into the tablet
  4. Turn on the tablet
  5. Open My Computer to see if PC will recognize the device, if not, please proceed to the next step
  6. Open Device Manager on your PC
  7. Choose Portable Devices and select Upgrade Driver Software
  8. Click on browse my computer for driver software
  9. Select “Let me pick from a list of a device drivers on my computer”
  10. Go to Portable Device and choose MTP USB Device

As soon as you do this, your PC should recognize the tablet. [In] some instances, if [your] PC will not recognize the device again, you may have to through the instruction[s] above.

I can confirm that if you start with the tablet turned off and then plug in the cable, it does seem to work properly and enumerate as a USB device on the computer as soon as you turn the tablet on. It worked out of the box with Android SDK on Linux. If you unplug the USB cable, you do end up having to power the tablet off in order to reconnect the USB, so if you do Android debugging, it would be smart to set up Wi-Fi debugging using the steps on this StackOverflow answer.

Hope this helps someone out there!

If you can believe it, Mac OS X 10.4 “Tiger” is over 12 years old as of this writing. It was first released in April of 2005. It was also the version that Apple first used on its Intel Macs in 2006. Because the Intel version came out in 2006 after the PowerPC version had already been in stores, it’s kind of a weird release. There wasn’t a retail copy of the Intel version of Tiger. It was only bundled with the first Intel Macs before 10.5 “Leopard” came out in 2007.

Because of the way it was weirdly released, it’s not super common to virtualize OS X 10.4 for Intel. Nobody’s really using it anymore because it’s so old. It’s probably full of security holes. And technically, it’s against OS X’s license agreement to virtualize it (same with the non-server versions of 10.5 and 10.6). With that said, I really doubt Apple cares about such an old version of OS X these days, and I think creating a VM of it is a really cool thing to do for educational purposes. Who knows — maybe it’s still useful for certain developers who still need to test how things work on 10.4 without keeping an old power-hungry machine around that is capable of running it.

Read the rest of this entry

As soon as you add a USB host port to your microcontroller project, a lot of possibilities suddenly open up. You can add support for plugging in a flash drive for firmware updates, diagnostics, and all kinds of miscellaneous data transfer. One task I’ve needed to complete in the past is the ability to save an Excel .xls spreadsheet. After doing some research, I found that this was actually a fairly difficult task on a microcontroller with limited memory. Most of the C/C++ Excel libraries I’ve found aren’t prepared to work in a microcontroller environment, and they generally do dynamic memory allocation because, well, Excel files are dynamically sized.

I’m going to assume that you already have USB mass storage support figured out for your particular project. This will usually involve using a USB library that provides the USB functionality. Many USB libraries also provide support for accessing mass storage devices. On top of this, you will also need a filesystem library for accessing a FAT32 filesystem, which is arguably the most common filesystem in use on flash drives today. One library I would recommend for working with FAT32 filesystems is FatFS. Note that FatFS doesn’t provide any of the USB functionality — you will have to hook it up to your USB library in diskio.c.

Now, back to the actual file generation. One thing you can do is simply generate a .csv file instead. That strategy works pretty well, and it may end up being all that you need for your particular project. One downside is that in certain cases, it will bring up a dialog box that forces the user to specify options for importing the file. LibreOffice is a particular offender in this regard.

I wanted a solution that generated a real .xls file that Excel and LibreOffice could open without any prompting and didn’t require the use of malloc(). I ended up writing my own library called MicroXLSWriter. MicroXLSWriter is a simple library that should fit on any embedded system. It generates files in a very old .xls format (BIFF2, from Excel 2.0). Modern versions of Excel (tested through Office 2007) can still open BIFF2 files without any problems. My code doesn’t completely follow the BIFF2 format perfectly, but it’s good enough that Excel and LibreOffice don’t seem to complain.

MicroXLSWriter is very limited. It doesn’t support any cell formatting or styles. You can’t customize fonts, colors, borders, or anything like that. The only thing it lets you do is set the width of each column and put text or a number into each cell. For what I needed, this is completely fine. BIFF2 files aren’t typically supported by .xls manipulation libraries, so if you’re generating something that won’t simply be opened by a user with Excel or LibreOffice, you should probably look elsewhere — if you can find a better alternative that still fits in a microcontroller.

If you’re interested, try it out. The source code is on GitHub and it has a very permissive 2-clause BSD license that allows you to use it in whatever commercial or open-source project you want, as long as you follow the simple requirements about preserving the copyright notice in materials distributed with your project (e.g. documentation). If you get a chance, let me know if you use it! I’m curious to hear about various applications where it ends up being used.

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