How to Build a PC Based Controller Systems

Parallel Port
a 25 pin parallel printer port built into an older personal computer

Mach3 CNC Controller
a Mach3 CNC controller designed to be used with a 25 pin parallel printer port built into an older personal computer

Centronics Parallel Port
a 36 pin Centronics port

USB to Parallel Port
a USB to Parallel port cable for modern personal computers with USB support but no parallel printer ports


with an older PC, through a parallel port (also known as a Centronics port or IEEE-1284 port)

or with a newer PC, through a USB port using a USB to parallel port cable

If you want to build your own control system, you can review some options at Control Systems. The option described here, to build your own controller device, is that you could leverage a PC and a parallel printer port or a USB parallel printer adapter. For that option, first lets cover some background on the approach, and then the steps to take to build this controller.

Early dot matrix printers had a print head consisting of a row of seven to nine metal pins connected to solenoids. When power was applied to the solenoids, the pin was pulled forward to strike the paper and leave a dot. The parallel port was designed to make it simple to set or clear these pins. However, instead of a printer head, a parallel port could control any number of other items like turning on an electric motor for a wheel on a robot or switching on or off a control valve for a thruster on a spacecraft.

A MACH3 CNC system is an example of a parallel printer port being used to control a CNC machine from a personal computer.

With an older personal computer with a parallel port built in, using DOS or Windows, you can copy files to pseudo files with the name PRN, LPT1, LPT2, or LPT3 by doing:
    copy {filename} PRN
This is a simplistic way to send a file byte by byte to the parallel port changing the state of the parallel port pins. More interesting would be to do this programmatically by opening the PRN or LPT# pseudo file, and writing bytes to the pseudo file as needed to change the start of the parallel port pins.

With this configuration you should be able to run commands like:
    copy {filename} LPT1
... to send files to a printer like an older EPSON FX Series dot matrix printer. However, if you want to use the parallel ports data bits to control items like an LED light or an electric motor, depending on your parallel port, you will probably need electronics that respond like an older printer. Otherwise you'll only be able to send one byte, which will cause the computer to think that the printer is busy and it won't send any more bytes of data. The parallel or centronics port handshake uses the following pattern.

First, data is presented on the parallel port pins 2 to 9 representing data bits 0 through 7. The computer then lowers the Strobe line (pin 1), waits a minimum of 1 μS, and then raises the Strobe line. The data bits would normally be read by the printer on the rising edge of the Strobe line. The printer electronics would indicate that it is busy processing the data by raising the Busy line (pin 11). The computer then checks to see if the printer electronics are indicating it is busy, and waits for the Busy line to go low. Once the printer has accepted data, it will acknowledge receiving the data by a low pulse, about 5 μS, on the Ack line (pin 10). Quite often the computer will ignore the Ack line to save time, but it won't ignore the Busy line.

Thus, depending on the parallel port hardware or cable you have, any electronics you wire up may need to respond as printer electronics would. Your electronics might not need to do anything. They might need to keep the Busy line (pin 11) low so the computer sees that it can keep sending data. Alternately they might need to raise the Busy line and then lower it to indicate the data has been accepted. In rare cases your electronics might need to both raise and lower the Busy line and also lower and raise the Ack line (pin 10). Other parallel port input pins like the Paper-Out line (pin 12), Select line (pin 13), and Error line (pin 15) should be kept low.

Parallel port pins
Pin (DB25) Pin (36 pin) Signal Name Direction
1 1 Strobe Out Control
2 2 D0 Out Data
3 3 D1 Out Data
4 4 D2 Out Data
5 5 D3 Out Data
6 6 D4 Out Data
7 7 D5 Out Data
8 8 D6 Out Data
9 9 D7 Out Data
10 10 Ack In Status
11 11 Busy In Status
12 12 Paper-Out In Status
13 13 Select In Status
14 14 Linefeed Out Control
15 32 Error In Status
16 31 Reset Out Control
17 36 Select-Printer Out Control
18-25 16,17,19-30,33 Ground Gnd

How To:

1) collect items you will need

2) build the Strobe to Busy circuit to respond as the parallel or centronics port handshake

As mentioned above, any electronics you wire up may need to respond as printer electronics would. The most common handshake you will need to produce is to raise and lower the Busy line (pin 11) after the Strobe line is lowered and raised indicating data is available. In order to do this you could just invert the Strobe line and delay it slightly. This can be done with a transistor circuit to invert the Strobe line signal, and then an RC (resistor/capacitor) circuit to delay that signal. The RC circuits output is then fed back into the Busy line. To provide the small amount of current this circuit needs, you can leverage the Linefeed, Reset, or Select-Printer lines which are outputs that should be held high (5v). Here's a diagram of the circuit you want to wire up.

Strobe to Busy Circuit Strobe to Busy Circuit

3) Build the simple Motor circuit and wire up a motor or light

You typically shouldn't wire up a digital output directly to a motor since a motor will probably draw more current than the digital output is rated for. Instead you should have a small amplifying switch circuit, and a separate power supply to drive the motor. This can be done with a transistor circuit to amplify any of the 8 digital output signals from the parallel port. A diode and capaciter in parallel to the motor prevents problems with the circuit when the motor is stopped and it momentarily acts as a little generator. This circuit can be used for driving a small motor from just about any digital output like an Arduino, smartphone parallel port, etc., not just this project. Here's a diagram of the circuit you want to wire up.

Motor Circuit Motor Circuit

4) use LPT1 to control the parallel port

With a newer personal computer with a USB port and a USB to parallel port cable the pseudo files of PRN and LPT# don't exist, or at least they don't exist by default. With a USB to parallel port cable plugged into a computer, you can configure it as an LPT# pseudo filename in Windows by following these steps:

Every time a byte is written to the data ports, the data is only present as long as the Busy line is high. However, the Strobe to Busy circuit above regularly lowers the Busy line so that you can continue to send control bytes. Thus you need to continuously send control bytes to the port in order to be able to change the state in the future.

To do this, write a program that sets the bits you want to turn on in a byte or char variable, open LPT1 for writing, and send that byte to LPT1 in a loop. The data will be held as long as the program is in the loop.

Alternatively, you could build a digital logic circuit that latches (saves) the data ports triggered by the Strobe line. You would then connect any motors or lights to the output of these latches. This might be a better solution for some, but would then require a more complex circuit and a separate power supply for the digital circuit. You could still use USB-Controller to send the data by using it's Settings to set the countdown counter to 1.

Copyright (C) 2017 - 2020 R. J. Kuhn. Please note that you are not allowed to reproduce or rehost this page without written permission.