Barcode scanning solution for OS X

Are you using USB Bar Code scanners to input data into a Xojo application?

Then you are probably struggling with the fact that the scanner simulates typing on the keyboard, and you have to figure out how to tell the scanner input data apart from actual typing.

But there may be a better solution. At least with the GoDEX GS550 (admittedly not the cheapest scanner but I am sure most other scanners support this mode as well because it’s a USB standard for scanners), it is possible to configure it so that it doesn’t send keyboard strokes but transmits the data over a separate “HID” USB channel. To receive such data, you can install a USB HID handler for the device while your OSX app runs, and then you can receive the data from the scanner cleanly and distinctly, no matter in which state you app is, even if it’s in the background.

To make this work you will need some of the MBS plugins, though. Though you may be able to do this all with declares, it’s just not worth the effort for me.

I’ve uploaded a demo project here: http://files.tempel.org/RB/HID_Bar_Code_Scanner_Demo.rbp.zip

See the instructions in the “About” Note inside the module.

Thanks so much for this post!

This is an issue that I’ve been struggling with for a quite some time.

Users of the barcode scanning application that I wrote would occasionally rename files and folders on their machines due to the application not being focused while scanning barcodes.

The scanner that I’m using (Symbol LS2208) cannot be set up as a Generic HID device, but it can be set up to use “Simple COM Port Emulation” which enables communication through their custom Windows USB driver. Your code, modified slightly (the scanner buffers all of the packets and delivers the data as a complete string), allows me to read data from the scanner in OSX while the application runs in the background.

Thanks again!

Jared

Awesome!

@Jared Feder, how do you receive the data from the scanner now in your case? Since it’s not a HID device, most of my code isn’t working for you, right? Are you using Xojo’s Serial device interface instead?

Ah, never mind. Yes, you probably used the Serial port. I’ve updated my demo project to do the same, alternatively. Will post that soon.

A few question, though: Your scanner uses 9600 Baud, right? And It delivers the data without any prefixes (so, no telling which type of code it has read), and with a CR as suffix, right?

Like you, I initially thought that “Simple COM Port Emulation” would be Serial over USB (similar to interfacing with an Arduino), but it turns out that the configuration is just poorly named.

I took that at face value when I said in my first post that it couldn’t be set up as a Generic HID device.

In reality, it connects as a HID device with your code, but rather then sending each raw packet as it’s read, it buffers them until scanning is complete and then sends the scanned data as a full string to the ReceivedData event of the BarCodeScanner class. Barcode type identification and packet processing is all done internally by the scanner, so that is the portion of code that I removed for my purposes.

Jared, the code that puts together the fragments is necessary on HID devices because a HID device packet is limited to somewhere around 64 bytes. So, if your codes are longer than about 60 chars, you will need that special code I put in there.

Oddly, the rather expensive Gryphon GD4400, which I just tested as well, does not seem to have such a HID mode. I’ve therefore programmed it to use the serial interface, i.e. it appears like a serial-to-USB adapter on the Mac. With that, it sends only the bare characters of the barcode, just the same as a it would when using the default keyboard interface.

I tested your original code again only changing wantThisDevice to:

Private Function wantThisDevice(productName as String) As Boolean return productName.Left(6)="Symbol" End Function

Scanning a Code128 barcode containing “913N2057461” results in hitting the following breakpoint:

break // huh? all packets should start with $02

This is the data packet (padded with 00 out to 64 bytes):

0D3931334E323035373436310D0A

So it’s a CR followed by the barcode string, followed by CR and LF

I hope that helps identify what is going on with this scanner.
I might not have a deep enough understanding to explain it clearly.

Ah, so it uses the HID channel but does not use the scanner protocol. Instead, you get just the plain barcode data.

Curious.

Oh well. Simply skip all the code that does the checking up to and including the type identification. Instead, just assign d to payload and then check if the collected data (including previous fragments) ends with a CR. if yes, remove the CR and deliver it. Otherwise postpone to wait for the rest (which is important if you get more than 63 chars).

It looks like that method will work great.

Sorry for the runaround with this strange scanner.
Your post still provided a much better solution than what I was previously using.

Thanks again!

I like to add that I’ve also found a solution to support scanners of the IBM/Toshiba/… alliance, which includes the popular scanners from DataLogic. They have their own USB protocol, which I’ve managed to crack for this purpose.

great!