Computer tachometer

Most of the current automotive tachometers are electric, with four connections in the back. One connection is for 12V power, the other is for 12V lighting, another is a ground, and the last is a pulse connection. The pulse connection receives the electrical pulses from the tachometer generator (usually hooked up to the distributor shaft, cam, or some other dirty place under the hood). Oddly enough, the power supply in your computer (or in a donor system) can provide 12V power, and your serial port can provide the pulses.

Hardware stuff

They say a picture is worth 1K words (or .5K DWORDS), so here's something to look at:

Through this crudely rendered drawing, you can get a rough idea of what needs to happen to connect the hardware. One of the hard-drive power cables coming from the system's power supply is used to feed the tach power and lighting, and the ground from the same connection is used for the tach ground.  

The only thing that may be a little fuzzy is the connection between the tach's pulse feed and the serial port. The tachometer normally would receive the pulses from the tach generator, but we're going to simulate that by sending chars through the serial port. Connect the TX pin on the serial port to the pulse wire on the tach.

Software stuff

Now that the hardware is ready, we can set up the software to drive it. Start a new project in whatever compiler you have that has a version of APRO installed. Drop a TApdComPort and TAdTerminal on the form (or just an APAX control if you're doing the ActiveX thing). Make sure the hardware flow control is disabled (since we didn't hardwire the DTR/RTS pins on the physical port). Set the Baud to 1200 (that worked pretty well in our tests). Select the serial port that's connected to the tach's pulse wire, and you're ready to test. Run the project, and start typing stuff in the terminal window. If things are working well, then you should see the tach needle bounce around.

Fine tuning

What we've done so far is shown that we can make the needle bounce by sending chars out the port. Now comes the part that requires actual thought.  

Port setup

The tach needle is controlled by the circuitry in the tach itself, the timing of the pulses controls where the needle goes. When used in a car, the pulses are usually generated when each cylinder fires. Since most engines run in the 500-8000 RPM range, that would be (roughly) 9-133 pulses per second.  A baud of 300 would sound reasonable, however, in testing we found that a baud of 2200 (if your port will support it) gave the best results.

You'll also want to make sure the hardware flow control is disabled. If you are requiring RTS, then you'll never get anything out the port (unless you wire the cable so RTS is raised).

The data bits, parity, and stop bits values will modify the pulses that you're going to be sending. To keep things simple, use the default 8N1 and fine-tune it from there.

Chars to send

The unknown part about this is whether the tach will react to each bit (most likely scenario) or just the timing of the bursts. Considering that each char that you send out the port is 10 bits (1 start bit, 1 stop bit, 8 data bits), to rough-in the RPM ranges, we can ignore the start and stop bits and just use the data part.  

My original theory was to send a char based on a timer, every 1/10th of a second sending out a different char. In testing, that really made the needle bounce around. What we came up with was setting the OutSize to 128 and sitting in a loop sending chars when there was space in the output buffer. To do this for the test project, we did it this way:

procedure TForm1.CheckBox1Click(Sender: TObject);
  while CheckBox1.Checked do begin
    if ApdComPort1.OutBuffFree > 10 then
      ApdComPort1.Output := #170;

Running this gave us a steady 3100 reading on the tach at 2200 baud, and about 1800 at 1200 baud.

The actual character that you're sending changes the RPM reading on the tach. The binary representation of the char is what you need to look at. We used #170 because it is 1010 1010, so there would be a nice even bit pattern.

More research needs to be put into the correct chars to send to obtain a given reading. With the tach that we have (a "Pro Tach" from the local AutoZone), we couldn't get a good reading over 3100 RPM at 2200 baud. Here's a quick run-down of the chars that we sent (in decimal), their binary representation, and the indicated RPM:

At 2200 baud, we go this:

char binary RPM
170 1010 1010 1900
136 1000 1000 3100
146 73 36 1001 0010 0100 1001 0010 0100 3100
255 1111 1111 0
238 1110 1110 0

At 1200 baud, we got this:

char binary RPM
170 1010 1010 2150
136 1000 1000 2600
146 73 36 1001 0010 0100 1001 0010 0100 3100
255 1111 1111 0
238 1110 1110 2600

If you see a pattern here, let us know<g>. You'll have to play with the baud and characters that you send to get RPMs that are meaningful to you.

Possible uses

Now that you have a tach that you can control from the serial port, how can you use it? Since the tach is measuring rates, you can hook into the network traffic properties to indicate your connection rate (some older tachs go from 0 to 6000, which would work nicely for a 56K dialup connection). You could also use it to monitor drive space, CPU or memory usage, or practically anything else that can be numerically indicated. One thing to remember is that the dial face can usually be replaced, so you can create an indicator more indicative of whatever you're monitoring.