Linux Reads Bar Codes

A hardware and device driver project for Linux.
Wand Data Sheet Description

Hewlett-Packard's description of the wand's electrical operation says basically the same thing, in techno-speak:

The HBCS-A000 series digital bar code wands consist of a precision optical sensor and an electronic circuit that creates a digital output of the bar code pattern. The open collector transistor requires only a pull-up resistor to provide a TTL-compatible output.

A nonreflecting black bar results in a logic high (1) level output, while a reflecting white space will cause a logic low (0) level output. The initial state will be indeterminate. However, if no bar code is scanned, after a short period, (typically less than one second) the wand will assume a logic low state.

Hewlett-Packard's PDF file for the HBCC-0500 data sheet--a portion of that data sheet is visible in Figure 3--can be found in the archive file, barcode.tgz, at

Figure 3. HBCC-0500 Data Sheet

The HBCS-A000 Series of HP wands have a data sheet of their own. A link to the PDF file for the wand data sheet is available at

Signal Processing

It turns out that the initial state of the wand circuit is, in practice, quite predictable for the very reason that the circuit does indeed revert to a known state whenever the wand is idle. We do make use of this property in the code that processes the video signal from the wand. When we start a scanning operation we always begin by waiting for a black bar. This method of initiating processing of the video signal has proven in practice to be quite reliable.

Measure the Bar Widths

When we see the beginning of the first black bar, we reset our clock to zero. We then cycle in a loop while advancing the clock and waiting for the signal to toggle to the white level. When the video signal toggles to the white level we read the clock and write down the reading as the measured width of the first black bar. We reset the clock to zero and again cycle while advancing the clock and waiting for the next video signal transition. When we get the white-to-black transition we read the clock and write down that reading as the width of the first white bar. We continue to time the width of the bars in this way until we either fill our data buffer or our clock counts all the way up to a preset value called ``white timeout''. Either event terminates data collection. In keeping with Jens Axboe's general rules for kernel modules, all of this timing and busy waiting, by the way, is handled in user-side code rather than in our device driver.

Doing the hard part in user-side code will be fault or feature depending on how you look at it. Although Linux is not designed for real-time work, the user-side experimental code works fine, as long as it is the only process Linux is running. On a more heavily loaded system, however, it may not work at all because the count accumulated by our software timer will, of course, be meaningless if the software loop is interrupted. For use on a heavily loaded Linux system, most of the processing now done in user-side code would be located in a dedicated microcomputer built into the wand interface, such as found, for example, in the :CueCatTM wand [Linux Journal, November 2000, page 138]. When the goal is to learn how to process the video signal, however, development is expedited by working on the user side where we have the full power of Linux at our disposal.

The Interface Circuit

The interface circuit shown in Figure 2 can be used to connect a Hewlett-Packard HBCS-A300 Bar Code reader wand to a PC serial port. A printed circuit board for the interface circuit, designed around the Digi-Key PCB-mount DIN socket, is shown in Figure 4. The wand operates from a 5-volt DC supply and consumes less than 5 milliamps, so we obtain sufficient power for the wand from the PC's RS-232 control line called Data Terminal Ready (DTR). The DTR line will be at -12 Vdc after the computer has been reset and remains there until a program asserts the DTR signal at that serial port, at which time it switches to +12 Vdc. To isolate our interface circuit from the negative voltage, we have a diode in front of the 78L05 voltage regulator. When we assert DTR to power up the wand, the voltage on the DTR line goes to about +12 Vdc. The diode that serves to isolate our interface circuit from the initial negative voltage, now serves to drop the +12 voltage down toward +11 volts. This off-loads the regulator slightly and still leaves it with some 6 volts of ``head room'', which is still excessive. We get away with it in this case because 5 milliamps of current through a 6-volt drop dissipates only about 30 milliwatts in the regulator, and so it barely warms up.

Figure 4. Serial Port Interface Circuit for the Digi-Key PCB-Mount DIN Socket

The 3.3K resistor provides the pull-up for the open-collector output from the wand, giving us a TTL-compatible signal. Like the diode, the LED serves two functions: it shows when DTR is high, telling us that the circuit is powered up, and it flickers reassuringly while the wand is transmitting video data on the Data Carrier Detect (DCD) line.