5890 Remote Panel – Control an HP 5890 over RS-232

My latest project is setting up an HP 5890 Series II Plus gas chromatograph. One challenge with operating older lab equipment is always accessing and storing the data they produce. Commercial options sometimes exist, but are often cost prohibitive for individuals. Introduced in 1984, the HP 5890 set the standard for gas chromatographs. According to Agilent, the instrument-centric spin-off of HP, the 5890 is the best-selling GC in history (https://www.chem.agilent.com/cag/aboutapg/abouthistory.html). Many of them are still in use in laboratories around the world, including at my current place of employ. And yet, there has been little software support from the open-source community. In setting-up my 5890, I intend to write software along the way and offer it to the world freely, under an unrestrictive open-source license, the GPL. 5890 Remote Panel is the first piece of software I’ve produced. Hopefully in time there will be more.

So what is 5890 Remote Panel? It is the product of my initial experimentation learning to communicate with the 5890 of an RS-232 interface. One of the simplest and most powerful commands the 5890 understands is the RK (Remote Keystrokes) command. This simple command simulates key presses from any of the keys on the 5890 keyboard. 5890 Remote Panel is written entirely around this one command. It allows remote operation of the 5890 GC through a virtual keyboard, just as though the user were standing at the physical instrument. This could be extremely useful for people who have a 5890 with a non-functioning keyboard, for example. Or perhaps one might need to start/stop a run, monitor run time, or change temperature settings from another room or, with a remote desktop connection, from anywhere in the world. This initial version does not record or process any chromatograms from the GC. If you need that kind of capability, take a look at UniChrom (http://www.unichrom.com) which provides support for 5890’s.

5890 Remote Panel is written entirely in Python3 and depends on the serial, tkinter, ttk, time, and re libraries, all of which are standard Python libraries. It should operate on any platform that supports Python3 (OSX, Windows, Linux, etc) but has been tested only on Debian GNU/Linux (kernel 4.2.6-1). It is released under GPLv3 and can be downloaded as a zip file using this link:

Download 5890 Remote Panel

Here is a screenshot and below one can find the technical details of operation.



The HP 5890 can have one of two different serial interface cards that I know of, the 19242-60030 and the 19257-60010. Both cards understand similar commands but the syntax used is different. 5890 Remote Panel is written to communicate with the 19257 card only. Communication works as a conversation initiated by the PC. A command is sent to which the GC will issue a reply. The link below lists the available commands with short descriptions.

HP 5890 19257A Serial Interface Command List

Many commands need parameters and this simple document gives no details. The best source I’ve found so far is the HP 5890 Serial Interface Manual, part 19242-90120, for the 19242 series card (special thanks to Gerard Spain at the Mace Head Atmospheric Research Station of the National University of Ireland, Galway). Other DIY-er’s may email me if they are interested in the contents of that manual.

The baud rate for the 19257 card is set by a small, 8-position switch block labeled S1. For RS-232 communication (rather than GPIB), positions 7 (SRQ_EN) and 8 (GPIB) must be set to off (0, toward the outer edge of the board). Positions 1, 2, and 3 then determine the baud rate. All switches on gives the lowest possible rate of 150 bps. All switches off gives the highest rate of 19200 bps. The other available rates are 300, 600, 1200, 2400, 4800, and 9600. The details of the switch configuration can be found in the Installation Guide for the Agilent GPIB/RS-232 Interface Kit, Accessory 19257A (manual part number is 19257-90107). The baud rate can be verified by holding down the CLEAR button on the GC keyboard while the GC turns runs through its self tests after turning it on. This will take you to a communications test menu and the display will read “User Tests Sel 0..7”. Test 4 will display the current RS-232 baud rate.

When 5890 Remote Panel loads, it first tries to open serial port “/dev/ttyS0” using the pySerial library. That port is the default because that was the one I needed on my own PC. There is a configuration dialog that allows the user to change the port, though any setting changes will be forgotten when the program is closed. Of course, since the program is distributed as Python source code, any defaults can be freely modified. The HP 5890 Series II Plus uses the settings below by default.

  • data bits = 8
  • stop bits = 1
  • parity = none
  • hardware handshaking = none
  • end-of-line character = CR+LF

Once the port is successfully opened, the program sends out the test command “ID” and listens for a reply which should be “IDEN HP19257A Rev C” or similar. As long as some reply is returned, the program will assume it is correctly connected. It next issues an OT (output) command “OTRemote Panel OK” which, if successful, will change the LED display on the 5890 to read “Remote Panel OK”. The 5890 should respond with “OTEN” which stands for “output end”.

At this point the programs waits for user interaction. Each time the user clicks one of the buttons on the virtual keyboard, the program issues a remote keypress (RK) command to the GC with the keycode of the button clicked. For example, to simulate the pressing of the “OVEN” key, the command “RKG” is sent. The GC will response, e.g. “RKENOVEN TEMP 40 40” contains the contents of the GC’s LED display after the “RKEN” prefix. The virtual display is updated to match the GC display based on this reply.

How to align the red-green-blue (RGB) LCD panels (adjust convergence) of a Sharp XG-P10XU Projector

Projectors based on 3LCD technology work by splitting the white light from the lamp into 3 beams colored red, green, and blue, passing each beam through one of three LCD panels, combining the 3 beams back into one through a prism, and finally focusing the combined beam onto a wall or screen. In this process, the positions of the three individual LCD panels must be carefully controlled to ensure proper convergence. If a panel becomes misaligned, the corresponding color will be offset from the other colors in the image a condition known as misconvergence.

Small misalignments by a pixel or less are usually tolerable when displaying videos and motion pictures. When text is displayed however, even a misalignment of only one pixel can lead to blurry text that is hard to read. The problem is worst for small fonts whose characters may only be one to two pixels wide.

To fix the problem the convergence must be adjusted by realigning the LCD panels. Advanced projectors offer this option through the projector’s software interface but cheaper models lack any control over convergence. The Sharp NoteVision XG-P10XU is one such projector. The convergence is set at the factory and the unit sealed so that the user is forced to accept any misalignment in the purchased unit or that may develop over time. This post shows how to adjust the convergence of the Sharp NoteVision XG-P10XU 3 LCD projector by opening the case and accessing the optical bench inside. The process should be analogous for any 3LCD based projector.

The first step is to remove the external screws and top cover.  There are 15 screws total to remove and all can be removed with a philips screw driver. The screw positions are:

  • 2 screws on the left side of the unit
  • 2 screws on the right side of the unit
  • 1 screw on the front below the lens (secures the lens collar)
  • 6 large screws around the perimeter of the back side
  • 4 small screws on the back among all of the ports and connectors

projector left view projector lens collar screw projector rear view projector right view


The back cover should come off easily now. The blue lens collar on the front should be pulled off. It has small plastic tabs holding it in place. A knife can be used to pry the collar off.

projector rear cover off projector removing lens collar

Only after the back panel and lens collar are removed can the top cover by taken off. Once again, small plastic tabs make this slightly challenging but a knife inserted in the crevice between the top and bottom covers and bent up and down works well to separate the two. At the front two corners are small plastic pieces that will fall away. Be careful not to lose them down inside the projector. The top cover can only be pulled a few inches up from the unit because there are wires running to the speakers mounted on the cover as well as a ribbon cable running to the control panel. It is only necessary to unplug the speaker wires from the projector. Set the top cover off to the side a bit with the ribbon cable still attached. Later you will operate the projector in this state and it will be necessary to use the control panel.

projector opening case front projector opening case rear  projector under lid

That completes disassembly. You should now have access to the optical bench in the center of projector just behind the lens. You will see three ribbon cables that lead to each of the three LCD panels. The panels are mounted vertically and are hard to see clearly buried beneath all of the circuit boards. The square area between them holds the prism that recombines the beams and reflects them into the lens.

projector open not running

When standing at the rear of the projector so that it is pointed away from you, the left most panel is for the blue component, the center panel is green, and the right panel is red. If you look closely on the circuit boards near the ribbon cables that run to the panels will be the codes BP, GP, and RP for blue panel, green panel, and red panel, respectively. If you are attempting to adjust the panels on a different model and aren’t sure which is which, do not fret. Once the projector is turned on it will be obvious which panel is which.

WARNING! There are serious risks to operating the projector with the cover off. You are exposing yourself to dangerous voltages. DO NOT TOUCH ANY OF THE EXPOSED CIRCUITS OR WIRES. For maximum safety, wear latex or nitrile gloves. Be extremely careful not to short any of the circuits on the exposed PCB’s. Do not drop screws or metal tools onto the boards or into the unit. Try to have only one tool in your hand at a time and grasp it securely. Watch out for the cooling fans. Don’t stick anything in them, especially not your fingers. If you proceed to any of the following steps you do so at your own risk. I am not liable if you hurt yourself, the projector, or your surroundings.

To adjust the panels it will be necessary to operate the projector with the cover off. Plug in a video source and the unit’s power cable. Turn the projector on and focus it onto a white wall or screen in a dimly lit or dark room. It’s best. to connect a computer and have open a graphics-editing application. To gauge the alignment, I recommend long horizontal and vertical bars drawn in white on a black background. Make sure the bars are not anti-aliased. The pencil tools in MS Paint and GIMP work well for this. You may find that inverting the colors helps as well, especially to gauge the alignment of the blue panel. Test patterns can also be found online and displayed.

projector open and running

Inspect the displayed image and try to determine which colors are misaligned. The green panel in this projector is fixed as in most 3LCD projectors. You will be adjusting the red and blue. In the case of red and for the white line drawn on black, along the outer edge of the white line look for red pixels. If the panel is too far to the right, the outer right edge will be lined with red pixels and consequently the inner left edge will be lined with bluish-green pixels. For blue you’re looking for extra light blue pixels on the outer edge and yellow pixels on the inner edge.

Choose a panel to adjust first. You must loosen the retaining (locking) screws of the panel so that it can be adjusted. In this model, these are the two small black hex screws that run horizontally. Do not remove them, just loosen them a bit. You will need a hex wrench here. Now the panel can be adjusted by turning the hex bolts near the top of the panel. There is a bolt for vertical and a bolt for horizontal position. Some units will have screws instead of hex bolts and some may have a tilt adjustment as well. A pair of pliers may be needed to turn the adjustment bolts.

projector adjustment knobs locations

Adjustments should be in small increments. If you make a large adjustment, the beams will become severely misaligned. This might be a good way to determine which adjustment bolt moves what direction. Keep adjusting the bolts until you can no longer see extra colored pixels offset from the white bars (or black if on a white background). Go slowly and be patient. Sometimes, the best you can do is about +/- 1/2 pixel. When you feel satisfied with the adjustment, re-tighten the retaining screws (hex screws). Make sure they’re tight enough that bumps and heat won’t displace the panels again.

projector adjusting convergence

Repeat for the other panel and you’re finished. Turn off and unplug the projector. Then reverse the disassembly steps to replace the top cover, back cover, and lens collar. Don’t forget to plug the speakers back in. I recommend to tape the front plastic corner pieces in place until the unit is fully reassembled. Here’s hoping all went well.

 projector replacing cover taping corners

Update apt public keys in Debian to fix package authentication errors

The apt program for Debian uses public and private keys to validate packages downloaded from the repositories. You can learn all about it at https://wiki.debian.org/SecureApt. Public keys are stored in /etc/apt/trusted.gpg. If keys are missing, outdated, corrupted, etc. apt will complain when trying to install packages with an error like “The following signatures couldn’t be verified because the public key is not available”. You can choose to ignore the error. If so, when it reoccurs in the future you will see warnings like “WARNING: The following packages cannot be authenticated!”.

The solution to this problem is to update your public keys for the Debian repositories. These keys are installed via the package debian-archive-keyring. A simple “apt-get install debian-archive-keyring” is probably enough to update the keys are remove the errors/warnings during package installs.

auth.log errors: pam_winbind.so missing

I had an authorization log (/var/lib/auth.log) was filling up with errors related to a missing pam_winbind.so library:

May  1 01:25:01 servername CRON[1906]: pam_unix(cron:session): session opened for user root by (uid=0)
May  1 01:25:01 servername CRON[1906]: pam_unix(cron:session): session closed for user root
May  1 01:25:16 servername auth: PAM unable to dlopen(/lib/security/pam_winbind.so): /lib/security/pam_winbind.so: cannot open shared object file: No such file or directory
May  1 01:25:16 servername auth: PAM adding faulty module: /lib/security/pam_winbind.so

…over and over. I tried upgrading winbind to the latest version in the Debian stable repositories. I installed libpam-winbind (2:3.6.6-6+deb7u3 for both). Neither of those actions fixed the problem. The library, pam_winbind.so, was not present in /lib/security.

After reading this thread:


I found that the library was simply in the wrong location. It was the only file under /lib/powerpc-linux-gnu/security/. This machine is a powerpc. Other architectures will have a different architecture name in the /lib directory.

The simple solution was to make a symlink under at /lib/security/pam_winbind.so that points to the existing library at /lib/powerpc-linux-gnu/security/pam_winbind.so:

sudo ln -s /lib/powerpc-linux-gnu/security/pam_winbind.so /lib/security/pam_winbind.so

No more errors in the auth.log.

How to change “about:home” to anything in Firefox (Icecat, Iceweasel)

Before reading, please note that I’ve written this post with respect to Icecat 17.0.1 which is a rebranded version of Firefox. I can’t guarantee that things will work the same with Firefox or Iceweasel (another rebrand) or other versions of any of these Mozilla browsers.

The concept of a home page is not well defined in Firefox. In Edit->Preferences there is a Home Page setting. When Firefox starts, this is the url that will be displayed. But it’s not the url displayed when a new tab is created or when visiting about:home. Those are two other, independent settings. The first is set from the about:config screen by changing the preference browser.newtab.url. It’s also necessary to set browser.newtabpage.enabled to false. The latter is not easily changed. There is no preference to change it.

The about:home page is a static page included in the Firefox distribution. In can be found in the file omni.jar (or omni.ja in my distribution). The exact location of this file will depend on the distribution, the operating system, and probably the Firefox version. It’s probably easiest to find it by doing a search of your file system. One my try entering “chrome://browser/content/findme” in the address bar of a Firefox tab. The resulting error message might indicate where omni.jar is to be found.

Once located, the omni.jar file can be opened and it’s contents browsed and edited. I use fileroller on my Debian based pc to browse the contents of the archive. Inside the archive, you need to find the aboutHome.xhtml file. In my version of Icecat (17.0.1) it is located within the archive at /chrome/browser/content/branding/. If you don’t have a rebranded version of Firefox, you might find it at /chrome/browser/content/browser/abouthome/.

Open this file for editing. Within the <head> element of the xhtml page, simply add the following script tag:

window.location.href = "https://www.startpage.com";

Whenever about:home is accessed, the page will be automatically redirected to whatever url is set in the quotation marks. You can test this by typing “about:home” in the address bar of a Firefox tag. This shouldn’t require that you restart Firefox in order to work.

Playing around with the omni.jar file turns out to be a lot of fun. With my current configuration, I am able to browse the contents of the jar file using Firefox itself by typing in the following in the address bar of a tab: “jar:file:///home/Files/Programs/icecat-17.0.1/omni.ja!/”.

It also seems possible to access some components directly. For example, entering “chrome://browser/content/browser.xul” in the address bar of a tab, appears to load another instance of Firefox within that Firefox tab. It’s like a new Firefox window all contained within a tab. Very cool.

Screenshot - 03202014 - 03:35:10 PM

Dome light triggered RGB LED footwell lighting in a 2010 Honda Fit


I recently installed LED footwell lighting in a 2010 Honda Fit. The LED’s are driven with a PWM dimmer/controller that uses potentiometers to manually adjust the brightness of each of the RGB channels. Any combination of red, green, and blue is possible. The LED’s match the operation of the dome light switch and come on for the same events, e.g. when the door is opened. They also come on when the dome light switch is set to ON. In order to allow the LED’s to fade with the dome light, it was necessary to make a small modification to the dimmer/controller.

During installation I remembered to take lots of photos. I made an instructable with complete details that can be found at the following link:


Batch Table Operations – A QtiPlot plug-in/script

I’ve been taking lots of data at work. Each data file collected has to be imported to QtiPlot as a table and then several columns are added to the table and calculated from the imported data. Some days I have over 100 data sets, which means > 100 tables to manipulate. It was becoming impractical to perform all of the necessary table operations by hand. This script was written to automate the table operations I needed.

Batch Table Operations

To use one simply selects the tables to be affected from the list of existing tables. Then one selects and configures the operation to perform. Finally, clicking the “apply” button will perform the operation on the chosen tables.

As of today (1/30/14) the script allows adding and removing columns based on name, changing column types (x, y, z, etc.), and applying formulas to columns. Obviously, alot more could be done, but at the moment, this fits my needs. As I require more features I will add them. If you would like to request a feature add a comment or send me an email and I’ll see what I can do.



Edit 8/5/14:

I just tried to install this in version of QtiPlot running on Windows 7 but was unable to get the script interface to load. The particular version of QtiPlot installed on the target machine came from an unofficial Windows binary (https://www.cells.es/old/Members/cpascual/docs/unofficial-qtiplot-packages-for-windows) that I’ve used before. That QtiPlot package comes with parts of PyQt4 but not the entire library. As such it is necessary to install both python 2.7 and PyQt4 as well. Then, the …/PyQt4/uic module folder has to be copied into the PyQt4 directory of the the QtiPlot installation.

At least, that was the solution in the past. Now this no longer works. The uic module is found but fails to load. I expect it’s because the version of Qt against which QtiPlot was complied and the version for which the uic module were written are now too different. Or it may be that the version of Python is too new (2.7.8). I got this to work in the past with Python 2.7.5. Anyway, under Windows at least, I no longer expect for the batchTable plugin to be usable because it draws its interface using the uic module I can’t get working. Things should still work on Linux installations. The long term solution would be to rewrite the plugin to use a Tkinter interface instead of Qt thereby removing the dependency problem.

How to fix slow DNS look-up’s in Firefox running under Linux

I’ve had this problem for some time now and chose today to do some research. Luckily, I found a workaround pretty quickly.

I use the Mozilla based browser GNU IceCat which is functionally equivalent to Mozilla Firefox. When a page is requested, the browser displays a small spinning icon in the left corner of the tab. Loading a page involves three basic steps: converting the URL into an IP address, contacting the web server at the IP address, receiving the web page (and other resources). During the first two steps, the icon will be grey and spinning counter-clockwise. The status bar will show messages like “Looking up google.com” and “Waiting for google.com”. Typically, DNS queries (the first step) take on the order of 100 ms to complete. Therefore if you see the first message, you may have the same problem.

The symptom was that IceCat (Firefox) was taking about 3 to 5 seconds to make DNS queries every time I tried to navigate to a new address. The cause of the problem seems to be that my system is making IPv6 DNS queries first by default but these types of requests are being ignored by the DNS resolver which doesn’t support IPv6. My system sends a query and then waits a certain amount of time before giving up and trying an IPv4 query. That time waiting was the delay I was experiencing.

The ideal fix would be to change the way the DNS resolver responds to IPv6 DNS queries. That’s obviously out of my control. A system-wide fix involves setting up your own DNS resolver – a bit more work than I’m interested in. The easy fix was to address the issue for IceCat (Firefox) only which is good enough for me as web-browsing is my primary internet activity.

The fix is to change the value for the key “network.dns.disableIPv6” from “false” to “true” in IceCat’s (Firefox’s) “about:config” page.

For more information, the issue has been discussed extensively here:


How to make a hole in a light bulb without shattering it

In order to use a light bulb to illuminate the inside of a vacuum chamber, I needed to release the gas contained within the bulb else it would likely have exploded the bulb when the external pressure was reduced. However, I wanted to keep the glass intact in order to protect the fragile filament from my clumsy hands and to provide that soft white glow.

I first tried scoring and breaking only a small piece of the bulb, but that always resulted in an uncontrolled cracking/shattering of the entire bulb. The best suggestion I found on the internet involved using a CO2 laser to make the hole. That would probably work, but I’ll save building a CO2 laser from scratch for another day. Other suggestions typically involved drilling under running water at very low speeds with a very sharp drill bit. Since both patience and drills were in short supply, I tried another method.

I found that by using a metal file at a tangent to the glass, one can very slowly thin the glass in a relatively small area. In my experience, eventually the thinned glass breaks away leaving a small hole. The hole isn’t round and doesn’t form in an absolutely controllable way. Perhaps it may be possible to “punch” a smaller hole after thinning the glass but before it breaks.

light bulb

Rebuilding a Raid 1 array: Using mdadm to add the new drive back to the array

Because of frequent disk failures that occur in my Mobile Desktop for reasons I’ve yet to conclusively identify, I decided early on to run two drives in a Raid 1 array. In this way, a single drive failure was easily overcome. A week or so ago one of my current drives started producing read errors and it was removed from the array by mdadm (linux’s multi-disk administrator). Today I’m adding the failed drive back to the array (currently only 1 active drive) and decided to post the commands I use so I can find them easily in the future. For more information on creating, administering, and repairing Raid arrays in linux, I suggest an article on howtoforge.com by Falco Timme.

As of right now, my Raid 1 array (md0) has one connected drive (really partition), /dev/sda1. The drive (partition) that I want to add back to the array is /dev/sdb1. Both drives are from Western Digital but sda is a 250 GB disk while sdb is a 320 GB disk. Because sdb was previously in the array, there’s nothing special that I’ll need to do to use it, but I will be limited to using only 250 GB of the space on that drive. Here is the output from some mdadm commands to clarify the picture:

ecellingsworth@MD1-LMDE ~ $ cat /proc/mdstat
 Personalities : [raid1]
 md0 : active raid1 sda1[3]
 244194841 blocks super 1.2 [2/1] [_U]
 ecellingsworth@MD1-LMDE ~ $ sudo mdadm --detail /dev/md0
 [sudo] password for ecellingsworth:
 Version : 1.2
 Creation Time : Thu Sep 15 10:36:29 2011
 Raid Level : raid1
 Array Size : 244194841 (232.88 GiB 250.06 GB)
 Used Dev Size : 244194841 (232.88 GiB 250.06 GB)
 Raid Devices : 2
 Total Devices : 1
 Persistence : Superblock is persistent
Update Time : Fri May 31 11:41:27 2013
 State : active, degraded
 Active Devices : 1
 Working Devices : 1
 Failed Devices : 0
 Spare Devices : 0
Name : MD1-Ubuntu:0
 UUID : 7d0d271d:04fdd2c1:de65ca3f:4c375489
 Events : 1279820
Number   Major   Minor   RaidDevice State
 0       0        0        0      removed
 3       8        1        1      active sync   /dev/sda1

First I copy the partition table from the good drive to the failed drive. If you use any of these commands yourself, be sure you use the right drive identifier. If you switch sda and sdb, you will destroy the good drive.

ecellingsworth@MD1-LMDE ~ $ sudo sfdisk -d /dev/sda | sudo sfdisk --force /dev/sdb
 Checking that no-one is using this disk right now ...
Disk /dev/sdb: 38913 cylinders, 255 heads, 63 sectors/track
 Old situation:
 Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0
Device Boot Start     End   #cyls    #blocks   Id  System
 /dev/sdb1   *      0+  30400   30401- 244196001   fd  Linux raid autodetect
 /dev/sdb2          0       -       0          0    0  Empty
 /dev/sdb3          0       -       0          0    0  Empty
 /dev/sdb4          0       -       0          0    0  Empty
 New situation:
 Units = sectors of 512 bytes, counting from 0
Device Boot    Start       End   #sectors  Id  System
 /dev/sdb1   *        63 488392064  488392002  fd  Linux raid autodetect
 /dev/sdb2             0         -          0   0  Empty
 /dev/sdb3             0         -          0   0  Empty
 /dev/sdb4             0         -          0   0  Empty
 Successfully wrote the new partition table
Re-reading the partition table ...
If you created or changed a DOS partition, /dev/foo7, say, then use dd(1)
 to zero the first 512 bytes:  dd if=/dev/zero of=/dev/foo7 bs=512 count=1
 (See fdisk(8).)

Now I remove any traces of the previous Raid information from the failed drive (partition).

ecellingsworth@MD1-LMDE ~ $ sudo mdadm --zero-superblock /dev/sdb1

All that’s left to do is put /dev/sdb1 back into the array.

ecellingsworth@MD1-LMDE ~ $ sudo mdadm -a /dev/md0 /dev/sdb1
 mdadm: added /dev/sdb1

Mdadm will then resync the two drives by copying everything from /dev/sda1 to /dev/sdb1. This process takes three to four hours for my 250 GB drives and will be longer for larger drives. You can monitor the rebuilding process using the following ‘cat /proc/mdstat’. I like to run this command with ‘watch’ every few seconds to see the rebuilding progress in real time.

ecellingsworth@MD1-LMDE ~ $ watch -n 5 'cat /proc/mdstat'
Every 5.0s: cat /proc/mdstat                            Fri May 31 11:51:17 2013
Personalities : [raid1]
 md0 : active raid1 sdb1[2] sda1[3]
 244194841 blocks super 1.2 [2/1] [_U]
 [>....................]  recovery =  2.6% (6465024/244194841) finish=124.7
 min speed=31746K/sec
unused devices: <none>

Don’t trust the estimated time. The rebuilding process will run in the background, but if you are using the PC at the time, the rebuilding has to pause every time you need access to the file system. And, for some reason, rebuilding tends to slow way down near the end.

Edit 12/17/14:

I’ve used the above process to add back to the array a failing drive several times now. However, in my case, since I’m adding back the same drive that was previously in the array, it’s not necessary to copy the the partition table from the good drive nor is it necessary to zero the superblock on the failed drive. Instead, I use one command “mdadm -a” to add the drive back to the array and it rebuilds fine. This has the advantage that it’s much less risky. There’s no chance of destroying the good drive by wiping it’s partition table or superblock. And, I doubt anything would happen if you told mdadm to add a drive that’s already in the array, though I’m not going to test this theory myself.