Tony Huang, th257
Nathaniel Smith, nrs27

Table of Contents
Introduction | High Level Design | Program/Hardware Design | Results | Conclusions | Appendix

I. Introduction

A. Sound Bite

Our project is a stationary linear barcode scanner made from an IR emitter and an IR detector

B. Project Summary

Originally, we were hoping to construct 1-d barcode scanner using a linear CCD sensor (Charge Coupled Device), which in theory would enable us to scan the whole cross-section of a barcode string at once. However, we have since learned that it was very difficult and expansive to even get a hold of a single unit of a linear CCD sensor (most vendors do not sell CCD sensors in small quantity, say, 1 unit). Even after we managed to acquire a linear CCD sensor (off Nathan’s old scanner), we were still unable to integrate it with the microcontroller since the chip is unmarked and therefore lacks documentation. The lack of proper documentation and the complexity of the CCD sensor operation finally made us realize that constructing a home-made CCD barcode scanner is simply beyond us at this point. With the project deadline only weeks away, we decided to make a linear barcode scanner with photo-detectors instead. The operation of a photo-detector is very simple. Depending on the reflectance of the scanned object, photo-detector simply outputs different level of analog voltage (generally higher voltage for larger reflectance). Using the photo-sensitive nature of a photo-detector, we were able to construct a home-made linear barcode scanner at a very cheap price.

Go to Top

II. High Level Design

A. Project Idea Source and Rationale

Our original goal was to come up with a final project that utilizes most, if not all the knowledge we have accumulated from other projects throughout the semester, and of course, it has to be doable with our current level of technical expertise. We were eventually inspired to make a barcode scanner because Nathan’s grandparents own a Quilting template store and it is a long and arduous process for them to mark price on each of their inventory items (not to mention the amount of price remarking if there is to be a price change for a particular product). After some research on the past final projects, it turned out that a barcode scanner had already been done before. However, the previous barcode group bought a commercial wand-type barcode scanner and therefore their project was mostly software-base. We naturally wanted to do something with barcode scanner hardware. Our first idea was a CCD barcode scanner but we eventually settled with a photo-detector linear barcode scanner (see “Summary” for reason). With no pre-made commercial barcode scanner, our linear barcode scanner project is half hardware and half software.

B. Project Background

There are many types of commercial barcode standard. We decided to use Code 3 of 9, or Code 39 for our project because it was one of the first barcode standards we came across; it was easy to understand and it can encode both English alphabets and numerical digits (among other special characters). Each Code 39 character consists of 5 black stripes sandwiching 4 white spaces. Black stripes, as well as white spaces can be both thin and thick. Code 39’s encoding scheme is therefore binary, with thick stripes/spaces representing 1’s and thin stripes/spaces representing 0’s (shades of the stripes/spaces do not matter since black and white simply allows us to differentiate the thickness of stripes/spaces). The following table shows all the available encodings in Code 39.

[Image taken from Barcodeman]

For example, the English alphabet, “K” would correspond to the binary code of length 9: 100000011 (scanning from left to right according to thickness).

A typical Code 39 barcode consists of a string of character, delimiting by a thin white space. Therefore, starting from the first black stripe (since there could be infinite white space before the actual barcode, the barcode always starts with the first black stripe), a scanner would have to disregard every 10th binary encoding (thin white spaces). Furthermore, since one could conceivably scan a barcode string upside down, a typical Code 39 barcode string also starts and ends with a “*” character. Therefore the software knows to flip bit fields for each character encoding when it detects an upside down “*” at the beginning of a barcode string (but we will ignore this error checking functionality in our project and assume our barcode will always be scanned at the correct orientation).

Another feature of Code 39 is the inclusion of an error checking character at the end of each barcode string (not including the starting and ending “*”). As shown in the following table, each character in Code 39 has an assigned error checking value (except “*”).

Char Value Char Value Char Value Char Value
0 0 B 11 M 22 X 33
1 1 C 12 N 23 Y 34
2 2 D 13 O 24 Z 35
3 3 E 14 P 25 - 36
4 4 F 15 Q 26 . 37
5 5 G 16 R 27 SPACE 38
6 6 H 17 S 28 $ 39
7 7 I 18 T 29 / 39
8 8 J 19 U 30 + 41
9 9 K 20 V 31 % 42
A 10 L 21 W 32
[Data taken from Barcodeman]

A correctly scanned and decoded barcode string must satisfy the following conditions: the error value sum modulo 43 of all the characters (not including starting, ending “*” or the error checking character) must equal to the error value of the error checking character. For example, if we want to use 1234 as our barcode string, we need to encode it as “*1234A” (not including the quotation marks). The error checking calculation is show as follow:

C. Logical Structure

Essentially, the majority of this project focused on the conversion from the actual barcode strings to a series of binary data representing the thick/thin stripes/spaces of each particular barcode character (See “Project Background” for more detail on barcode encodings). Once we have attained a reliable method of conversion between the actual barcodes and the barcode binary width data, the rest of the project became simple matters of parsing and decoding barcode binary width data, comparison of scanned code with pre-defined inventory barcodes and outputting the scanned result onto the LCD screen.

D. Hardware/Software Tradeoffs

One of the sacrifices we had to make in order to meet the final project deadline was our decision to abandon our initial idea of making a CCD barcode scanner. It was not an easy choice for us, since we must have devoted at least 2 weeks before the final project month to try to acquire a linear CCD sensor and 2 weeks more into the final project month to try to figure out how to work a linear CCD sensor. In the end, we had to give up on the idea since the inner working of a CCD sensor was too complicated for us to integrate it with our scanner project in the allotted 4 weeks of final project. By sticking with simpler components such as an IR emitter and an IR detector, we were finally able to make some real progress to construct a functional barcode scanner. Another tradeoff we decided to make was our choice of not integrating Code 39’s backward scanning error checking feature into our scanner project. In retrospect, it was not so much of a tradeoff than a designing decision. We felt that the most important feature and mission of our project is to make a functional linear barcode scanner using an IR emitter and an IR detector that can perform the analog to digital conversion between an actual barcode string and the barcode width binary data. Furthermore, we were also pressed on time to finish the main feature of our scanner project. Therefore, we decided not to implement backward scanning error checking and assume that we will always scan our barcode string in the correct orientation.

E. Relationship of your design to available IEEE, ISO, ANSI, DIN, and other standards

Our barcode scanner project utilizes the barcode standard of Code 39 as the basis of our decoding process.

F. Relevant Patents/Copyrights

Our final project is a stationary barcode scanner using an IR emitter and an IR detector. We derived our scanning technique from the commercial wand-type barcode scanners, in which a light detecting photo-detector inside the scanner wand would detect the amount of reflection given off from the barcode strings (usually source by a light emitting LED that is also similarly built inside the scanner wand). Relevant patents: United States Patent 4210802, 4408120.

Go to Top

III. Program/Hardware Design

A. Program Details

When we got our first batch of ADC data from the MCU after our first barcode scan pass, we had some idea as to how we should go about interpreting these ADC data points (several thousands of them from one scan pass). However, we were still unsure about the exact approach we should take to implement our data interpretation algorithm. Therefore, we attempted to analyze our scanned result by first passing the ADC data points onto the hyper terminal, capturing them as a text file and then importing them onto MATLAB for graphical analysis. Even before we took a look at the data points, we knew that black stripe on the barcode string would yield a low ADC values and white space on the barcode string would yield a high ADC value since black surface absorbs more and reflect less IR than does the white surface.

While the data points we took confirmed our presumption of low ADC for black surface and high ADC for white surface, the resulting ADC graph was not what we were hoping for. Instead of an even amplitude oscillation between the a nearly constant high ADC value and a nearly constant low ADC value, we got a graph that has peaks and valleys at several different ADC values, a most undesirable outcome that threw us off of our initial plan using a threshold based binary assignment (With a clean threshold, we can covert any ADC value above the threshold as 1 and anything under as 0, where 0 and 1 represent black and white). It turned out that our IR detector’s active scan area is much bigger than the thin stripe/space of our sample barcode and it was therefore taking the average of the neighboring black and white stripe/space’s reflectance at any one time as its output (therefore, if we are at a thin black stripe neighboring by thick white space, the ADC graphical conversion would yield a shallower valley than if we were scanning a thick black stripe neighboring by thin white space).

Without any of the specialize lens/optics available to a commercial wand-type barcode scanner, the only way we could increase our scanning resolution is to physically limit our IR detector’s active scanning area by exposing only small portion of its active scanning area during barcode scanning. The first side effect of covering up our detector’s active scanning area is a much smaller ADC difference between the black and white conversions, of which we remedied by passing the voltage output of our IR detector through an OpAmp before feeding it to A/D conversion pin (PORTA.0). The second side effect is the shifting of the overall ADC conversion range depending on the shade of the cover-up (higher overall range if we cover it up with white paper, and lower if we cover it up with black paper). Since we were getting a lot of 255 with a white cover (which meant we are missing a lot of peaks), we decided to use the black cover instead, which offered a much more responsive ADC conversion with no clipping.

Even with a finer scanning resolution, we were still unable to achieve a clear threshold between white and black peaks/valleys. Other problems such as the storing capacity of the MCU made us reconsider our attempt to interpret our barcodes by defining a threshold, or by finding graphical maximum and minimum. A major problem with all these methods is that they all require us to store ADC values in time into an array for post scanning analysis, and therefore we have a time limit for each scan pass (ie: we have to finish scanning before our ADC data array on the MCU is filled up each scan pass).

Fortunately, using a matlab peak detection script we have scrounged from the web, Nathan was able to implement the following barcode width interpretation algorithm.

The peak detection algorithm keeps track of whether we are looking for a minimum or maximum. In our analog data, there is some noise and so the extrema is updated whenever the current value is beyond the current extrema. Also, if the current value deviates away from the current extrema by a certain amount, then a transition from high to low or vice versa has taken place. Our algorithm now looks for the opposite extrema values. We simply record when the transitions take place (this is executed by timer0 clear on match ISR, where it polls for ADC value at 250 us interval). After we have gotten the indices of all max transitions (two arrays, white to black and black to white) and merged them into one array (this merged array represents the whole of our barcode string in stripe/space width), we simply look for the difference between each index and use it to interpret our barcode stripe/space width (if the index difference is big, we got a think stripe/space, and if the index difference is small, we got a thin stripe/space, where our white to black transition array records all the white space and our black to white transition array records all the black stripes). Of course, since each barcode scan pass is performed at a different speed (we scan our barcodes by hand) and scan speed also varies during each scan pass, we needed a interpretation algorithm that could dynamically recognized difference index difference as thick or thin (ie: Scan pass no.1 might have an average width of 200+ as thick and <120 as thin while scan pass no.2 might have an average width of 150+ as thick and <50 as thin). We accomplished this by setting the first width as a variable called “minreference”, and the second width as a variable called “maxreference”. Another variable, called “threshold”, which holds the average of “minreference” and “maxreference”, would determine if the current width is a thick or a thin (if the width value is above threshold, it’s a thick, and vice versa for thin). What makes this algorithm dynamical is that “minreference” and “maxreference” are updated individually whenever a new thin or thick is detected. Therefore, “threshold” is also updated every width interpretation cycle, making our width interpretation algorithm more tolerant to variable speed between each scan and within each scan (of course, our interpretation algorithm still works better if we scan at a relatively even speed).

The max transition algorithm has the advantage of looking at only one ADC value at any one time. Therefore with this new algorithm we were able to shed ourselves the need to record our entire ADC data stream for each scan pass.

Once our program had a reliable way to convert the entire barcode string into a single thick/thin binary array, our job became a lot simpler. To finish the rest of our barcode scanner software, we only had to perform the following:
  1. Define an array of bit map for the 44 barcode characters, each character is represented by 9 bit of 0 and 1, where 0 represents thin and 1 represents thick (each character is stored as an integer, since an integer is the smallest variable type that will hold 9 bits)
  2. Extract the single barcode width binary array into 7 integers, each representing one barcode character (for our barcode scanner project, we decided to standardize all our sample barcode to be 7 characters, with 2 “*” at the beginning and end, 1 error checking character and 4 actual ID characters).
  3. Compare the extracted 7 integers with the pre-defined barcode character bit map and find the corresponding characters.
  4. Compare the resulting barcode with the pre-defined inventory barcodes and find the matching code.
  5. If there is match, print out the product’s barcode (4 characters), name and price onto the LCD.

B. Hardware Details

Our linear barcode scanner consists of the following components:
  1. QEC122, IR emitting LED
  2. L14F2, IR Detecting Photodarlington
  3. LMC7111, Operational amplifier
  4. Resistors: 1k x 1, 330 x 4, 300x1, 10k1, 20k x 1, 10k tri-Pot
  5. Wooden block
  6. MDL(S)-16264, 2x16 LCD screen (to display the results)
  7. AtmelMega 32 MCU

The wiring of the overall circuit is shown in the following diagram: (the output of the Photo-detector is passed through an OpAmp before going into the ADC pin for reasons mentioned in “Program Details”)

Click on the picture to see the diagram in full size (This will open up a new window, so please disable any pop-up blocker first if you cant seem to access the full sized picture).

To minimize our photo-detector’s active scanning area (in another word, increasing its resolution), we first drilled two tunnels inside a wooden block that converge at roughly the right angle (the wooden block as a whole will serve as the chassis of our stationary barcode scanner) and position our IR emitter and IR detector in the following manner:

[Image taken from]

Wooden Scanning Apparatus top, the center small slit is the scanning aperture

Wooden Scanning Apparatus bottom. Hole on the right side holds the IR Emitting Diode while the left holds the IR Detecting Photodarlington

C. Hardware/software design reference

For our barcode scanner’s hardware, we modeled our scanning apparatus after the diagram taken from

For our barcode scanner software, we derived our own max transition detection algorithm from the peak/valley detection matlab script written by Eli Billauer on his website

D. Things we have tried but didn’t work

Our original goal was to construct a functional barcode scanner that can scan any commercial barcode (in Code 39) available. However, without precision optics and focusing lens, our scanner’s resolution is simply too large to scan a regular size Code 39 commercial barcode. Therefore, we prepared our own blown-up (roughly x1.5) barcode sample for scanning purpose (the ratio of barcode width to height stills follows the Code 39 standard, both are simply enlarged).

A comparison between a real barcode(top) and our barcode sample(bottom) [The top code is of a different barcode standard, but it has the same heigh and width as a commercial Code 39 barcode]

Go to Top

IV. Results

A. Execution

The basic operation of our barcode scanner involves the following steps:

1. Setting up the scanning software by pressing button 1 (we defined it to be PORTB.2).
2. The barcode scanner is now ready, press and hold button 2 (we defined it to be PORTB.0) to begin scanning (let go of button 2 will stop the scanning process).
3. Press button 1 and review the result on the LCD screen.
4. The scanned result will remain static for a few second, then we return to step 2 again

Overall, the operation of our barcode scanner is very simple, however, it does require some practice before a first time operator can perform successful scans consistently.

B. Accuracy

While our barcode scanner cannot scan a regular size Code 39 commercial at all, we do get very good results (5 successful scans out of 7 scans in one of our earlier trial, but the accuracy is much higher now) on our specialized barcode sample.

C. Safety in our design

Our barcode scanner’s user interface involves only 2 buttons and the wooden scanning apparatus. If setup correctly, our barcode scanner does not expose its user to any electrical connection at any time and therefore is very safe to operate.

D. Interference with other people's designs

Our barcode scanner setup does not produce RF noise or any sort of harmful radiation (IR radiation from the IR emitting diode is pretty much negligible even before it was contained inside the wooden chassis and therefore should not interfere with other people’s project).

E. Usability

While a first timer user may not be able to achieve successful scans right away on our machine. Anyone with rudimentary hand-eye coordination and some scanning practice should be able to scan any of our specialized barcode samples correctly on our barcode scanner. As for scanning a typical commercial Code 39 barcode using our scanner, it is impossible to do so at the moment. However, with the right focusing lens and some more time, we are confident we can modify our current scanner setup to scan an actual commercial Code 39 barcode.

Go to Top

V. Conclusions

A. Expectation vs. Results

Initially, we were hoping to achieve what the last barcode group could not, to create a barcode scanner using a linear CCD sensor. However, it soon became apparent to us why the last group gave up on the idea. Not only was it extremely difficult to acquire an actual linear CCD sensor, it was nigh impossible to figure out how to operate the sensor due to lack of instructional literature on the web. Therefore, we had to settle with our backup plan, to make a linear barcode sensor using a photo-detector and a photo-emitter. While it was no joy ride either to get our backup plan to work, we were finally able to make some headway on our final project. With our current barcode scanner working accurately (relatively), we felt that we could have added much more feature to our current linear barcode scanner if we had started out in the photo-detector direction. If there were a next time, we would definitely try to do our research better before starting out our project in an unrealistic direction.

B. Applicable Standards

Our design uses the barcode standard, Code 39, also know as Code 3 of 9.

C. Intellectual property considerations

Our barcode scanning apparatus is modeled after the diagram on the web page and our barcode interpretation software’s max transition algorithm is a modified version of Eli Billauer’s peak/valley detection matlab script on his website Furthermore, our sample barcode fonts are downloaded from the free demo section of IDAutomation

D. Borrowed/reused code

Our barcode interpretation software’s max transition algorithm is a modified version of Eli Billauer’s peak/valley detection matlab script on his website

E. Code in the public domain

Our barcode interpretation software’s max transition algorithm is a modified version of Eli Billauer’s peak/valley detection matlab script on his website As part of his publicized code, Eli Billauer states, “This function is released to the public domain; Any use is allowed.”

F. Trademark/Patent Issues

Our stationary barcode scanner uses the basic scanning principle found on any commercial wand-type barcode scanner. Since we do not plan to make profit off our home-made barcode scanner and acknowledge the patent sources (see “Project Background”), we do not have to worry about patent/trademark issues.

G. Signing of Non-disclosure agreement for Our parts

No, none of our barcode scanner components require us to sign an non-disclosure agreement during their acquisition.

H. Patent Opportunities

No, since our stationary barcode scanner is model after existing commercial barcode scanner, we cannot file a patent for our project.

I. Ethical considerations (IEEE Code of Ethics)

1. To accept responsibility in making decisions consistent with the safety, health and welfare of the public, and to disclose promptly factors that might endanger the public or the environment;

As harmless as our barcode scanner is, we made sure that our hardware wirings are isolated electrically from the operator while limiting the amount of wires a user has to make contact with during an regular scanning session.

2. To avoid real or perceived conflicts of interest whenever possible, and to disclose them to affected parties when they do exist;

The construction of our barcode scanner project is a purely academic pursuit and we have no intent to make profit off our project commercially.

3. To be honest and realistic in stating claims or estimates based on available data;

After many scanning trials, we can confirm that our barcode scanner does work with our specialized barcode sample.

4. To reject bribery in all its forms;

No partisan supports/protests our barcode scanner project and we have accepted no bribe from anyone.

5. To improve the understanding of technology, its appropriate application, and potential consequences;

During the construction of our barcode scanner, we learned a lot about the linear barcode scanning technique and how/why it is being used by retailers throughout the commercial industry.

6. To maintain and improve our technical competence and to undertake technological tasks for others only if qualified by training or experience, or after full disclosure of pertinent limitations;

We do not claim we that can produce a fully functional commercial quality linear barcode scanner with the knowledge we gained from designing our barcode scanner.

7. To seek, accept, and offer honest criticism of technical work, to acknowledge and correct errors, and to credit properly the contributions of others;

We welcome and hope to receive comments and suggestions from the TA’s, Professor Land during the demonstration of our project.

8. To treat fairly all persons regardless of such factors as race, religion, gender, disability, age, or national origin;

Our barcode scanner can be operated by any individual regardless of his/her race, religion, disability, or national origin.

9. To avoid injuring others, their property, reputation, or employment by false or malicious action;

The operation of our barcode scanner is purely passive and it does not commit any harmful effect to anyone near it, be it physical or abstract.

10. To assist colleagues and co-workers in their professional development and to support them in following this code of ethics.

We remind each other of ethical consideration during the design/construction of our barcode scanner.

I. Legal considerations

Our barcode scanner produces no illegal radiation nor does it output undesirable interference to radio traffics.

Go to Top

VI. Appendix

A. Commented program listing


B. Schematics

Click on the picture to see the diagram in full size (This will open up a new window, so please disable any pop-up blocker first if you cant seem to access the full sized picture).

C. Cost details

Part Name Price Source
AtmelMega 32 MCU $8 ECE 476 Lab
Custom PC Board $5 ECE 476 Lab
RS232 Connector $1 ECE 476 Lab
2x16 LCD Screen $8 ECE 476 Lab
Wires, Resisors, Tri-Pots $0 ECE 476 Lab
5V Power Supply $5 ECE 476 Lab
LMC7111 CMOS OPAMP $1.69 ECE 476 Lab
QEC122 IR Emitting Diode $0.54 Digikey
L14F2 IR Detecting Photodarlington $1.68 Digikey
RS232 CPP $0 Sampled from Maxim
Wooden Block $0 Scrap from Lowes Home Improvement
Total $30.91

D. Task Distribution

E. References

i. Data sheets

QEC122-IR Emitting Diode
L14F2-IR Detection Photodarlington

ii. Vendor sites

Maxim Integrated Circuit

iii. Code/designs borrowed from others

Wooden scanning apparatus/chassis idea taken from

Max transition algorithm adapted from Eli Billauer’s peak/valley detection matlab script on his website

iv. Background sites/papers

Barcode Primer
Scanning Technologies
Fairchild Imaging
Integrated Publishing
Code 39 Specification

F. Thanks

Big Thanks goes to Professor Bruce Land, our section TA (Jason Chiang) and section Consultant (Richard West) for the wonderful semester.

Go to Top