I’ve always considered barcodes to be one of those invisible innovations that profoundly changed the world. What we might recognize as modern barcodes were originally designed as a labor-saving device in the rail and retail industries, but were quickly adopted by factories for automation, hospitals to help prevent medication errors, and a wide variety of other industries to track the movements of goods.
The technology is accessible, since all you really need is a printer to make barcodes. If you’re already printing packaging for a product, it only costs you ink, or perhaps a small sticker. Barcodes are so ubiquitous that we’ve ceased noticing them; as an experiment I took a moment to count all of them on my (cluttered) desk – I found 43 and probably didn’t find them all.
Despite that, I’ve only used them in exactly one project: a consultant and friend of mine asked me to build a reference database out of his fairly extensive library. I had a tablet with a camera in 2011, and used it to scan the ISBN barcodes to a list. That list was used to get the information needed to automatically enter the reference to a simple database, all I had to do was quickly verify that it was correct.
While this saved me a lot of time, I learned that using tablet or smartphone cameras to scan barcodes was actually very cumbersome when you have a lot of them to process. And so I looked into what it takes to hack together a robust barcode system without breaking the bank.
A Barcode Reader to Make a Hacker Proud
Dedicated barcode scanners cost around $20 USD from banggood or DX and are an obvious solution, but that would be boring. I also wanted a more powerful device: a barcode scanner that could directly connect to the Internet so I could track things centrally online without any further hardware. While the idea was hardly unique, it still stuck with me. Recently, I saw a tiny barcode scanner module (Youku E1005) for sale for $17 USD with no datasheet, and I knew the game was on.
The scanner module itself was very compact, which lent itself well to making a convenient device. It had a generic unlabeled MCU, and a 12-pin ribbon cable connector. The vendor told me it supported Code 39 barcodes (true – but it actually supports many more!), and had USB and TTL output. It was time to puzzle the module out!
Dissecting Barcode Hardware
Logically, some of the 12 pins were going to be power, ground, USB data lines, and TTL serial output. Typically these modules are used to build hand-held barcode scanners, so also require a trigger to be pressed to activate the scanner. The first step was to desolder the connector so I could get access to the pads underneath.
The next step was to identify power and ground. Ground was pretty easy since several components were connected to what was clearly a ground plane. The power pin was harder, but there was an IC that looked like a voltage regulator in a SOT-753 package. Given common pinouts, both the enable and the voltage input pins were connected to a single pad.
Having probable inputs for power and ground, I connected 3.3v to the circuit. Nothing happened, which is expected as I’ve yet to find the trigger pin that activates the device. The easiest thing to do was to quickly connect each remaining pad to ground and see if the trigger was of the ‘active-low’ variety. It turned out it was, and the LED of the device turned on to indicate it was ready to scan.
Making Sense of It All
The final step was to find the TTL output. That turned out to be pretty easy now that I could force the device to scan barcodes. I took an arbitrary barcode and scanned it while looking at different pins on my oscilloscope. When I found output, I captured it so I could determine the baud rate later on. The final pinout I found is to the right. The flat cable connector pads were fairly dense, so I soldered wires to components connected to the relevant pads rather than the pads themselves where possible.
After scanning a barcode and capturing the output on my oscilloscope, I saw that the duration of the shortest peak was just over 100μs. That translates to a frequency of a little under 10000 bits per second. The closest common baudrate is 9600 baud, so that is likely our TTL baudrate. Now, we have all the information we need to connect the barcode scanner module to a microcontroller, in our case an ESP8266 running NodeMCU.
Our code will be very simple: Change the UART speed to 9600 baud, and when any data is received concatenate what comes in for the next 150 milliseconds and print it out. Remember to set the baud rate of your development tool (e.g. ESPlorer) to 9600 as well.
-- Setup UART and print something so we know it's working uart.setup(0, 9600, 8, uart.PARITY_NONE, uart.STOPBITS_1, 0) print("Scanning") -- Set up a couple of variables so they're not nil data = "" datac = "" -- This function prints out the barcode data and clears all variables so the scanner can read a new barcode. If you wanted to send the data over MQTT, your code would replace the print statement here. function finish() print(datac) data = "" datac = "" end -- This function concatenates all data received over 150 milliseconds into the variable datac. The scanner sends the data in multiple parts to the ESP8266, which needs to be assembled into a single variable. uart.on("data", 0, function(data) tmr.alarm(0,150,0,finish) datac = datac .. data end, 0)
This worked quite nicely and was able to read various types of barcode without issue. It would be very easy to connect this to a server on the Internet, either directly via MQTT, or using an Internet of Things dashboard. It would even be possible to implement encryption and authentication if you needed.
Custom Tricks Now Open Up To Us
An interesting fact is that the NodeMCU is capable of executing serial input, so make sure that feature is turned off (the 0 at the end of the uart.setup line). Otherwise someone will promptly drop by with the barcode to the right. The usual precautions apply to the backend as well. You could even filter out problematic characters at the hardware level, which would be nice. Of course if you’re clever this could be a feature and not a vulnerability.
I didn’t have a particular use case for this barcode scanner in mind, but it would be nice to see someone implement it in a cloud Point-of-Sale system for small merchants in Asia to track inventory in a primarily cash-based economy. In effect that would be very similar to the original use of barcode scanners – minus the expensive POS system.
Finally, while at a local convenience store, I saw the perfect project case for this sitting on a shelf. I bought it, and it was filled with candy! Sometimes we live in the best of all possible worlds: