05-14-2010 03:45 AM
Background:
I'm using a Symbol DS6707 barcode reader to input a text string from a 2D barcode into LabVIEW.
http://www.motorola.com/Business/DS6707
[The barcode reader is programmed to add a carriage return character to the end of the string on barcode read completion.]
The ASCII text data is passed to the PC via the USB HID (Human Interface Device) protocol.
http://en.wikipedia.org/wiki/Human_interface_device
The barcode reader uses keyboard emulation to implement USB HID . This means that the barcode text is inputted into the PC as though someone was typing it in on a keyboard. This allows the barcode reader to be universally used in any Windows application to enter text.
Problem:
I wish to aquire the above text data into LabVIEW without having focus on any LabVIEW window. You could think of it like wanting the ASCII data to enter the LabVIEW app as though it was arriving via a serial COM port, i.e. no focus on text string input controls required.
My starting point was to use the Express 'Prompt User for Input' and then progressed to a recommendation on this forum
http://forums.ni.com/ni/board/message?board.id=170&message.id=198863
which worked really well but now I need the input without focus as axplained above.
Various forums have mentioned the Windows HID.DLL. This route was not an elegent one considering what seems a reasonable and relativly simple thing to want to do - read a keyboard buffer!
I then found Keyboard monitor.vi (attached) which contains Initialize Keyboard.vi and Aquire Input Data.vi. These vi's read my HID USB Keyboard and my HID USB barcode scanner but the output isn't in ASCII and has a strange output system. They do read the keyboard buffer without having focus on any LabVIEW window - which is my main requirement.
My goal now is to enter the following string (this has been scanned into this page using the scanner and barcode reader):
212122-2508-01964-51007/350-K1-******-0000
Unfortunatly the vi above returns '-' as 'MINUS' etc.
Goal:
Is it possible to have a vi to pass out the above string (terminated on <CR>) from the PC keyboard buffer in LabVIEW (without having focus on any LabVIEW window) ???
Any help much appreciated in anticipation.
Andy
05-14-2010 04:07 AM - edited 05-14-2010 04:08 AM
Well the VIs return an enum that indicates the key that was pressed. It would be a very simple exercise to create a lookup table to translate each individual enum value into its corresponding string character and therefore I'm not going to do that for you.
You'll want to use an array constant with up to 105 elements (or less if you are not interested in the upper keypresses at all) and then using an index array and for loop, "lookup" the corresponding character for each returned element.
05-14-2010 04:23 AM
Hi Rolfk,
Thanks for the reply. I did try to write some LabVIEW code similar to what you suggest but got stuck on zero and few other things.
My vi was outputting zero when no key is pressed, so on pressing zero nothing changed. The change that does occur on pressing zero is that the numeric array changes between greyed out and active. I don't know how to interpret this. Also how to synchronize the key values returned within a poled loop, i.e if two character follow each other that are the same there is no sync?
My none elegant attempt is attached.
05-14-2010 08:36 AM
Hi Andy
You can read keyboard clicks without using a string control, but it won't be as simple as a serial read.
First, you can use the VIs in the Advanced>>Input Device palette, which will tell you which button is clicked at any moment. This means you will have to continuously poll and that you could, theoritically, miss some keys.
Second, if you want to capture keystrokes inside the VI, you can use an event structure with the Key Down event. This will gurantee that you get all the clicks and you don't need to poll.
Third, you can probably call some windows API functions to intercept the windows event which is fired when you press a key. Try searching the Microsoft Developer Network (MSDN), which has documentation of the windows API.
If your VI is the active window (it will be if you use the string control), then the second method (key down event for the VI) is all that you need, and it will work perfectly.
The third option is probably more complex, but may be possible. You can try doing some reading here to see if you can come up with something. You can try searching for something called "LV toolbox", which I believe shows examples of working with windows message queues, Although I'm not sure whether you can intercept messages from other processes.
05-14-2010 04:39 PM
AndyVessey wrote:
I wish to aquire the above text data into LabVIEW without having focus on any LabVIEW window. You could think of it like wanting the ASCII data to enter the LabVIEW app as though it was arriving via a serial COM port, i.e. no focus on text string input controls required.
Many barcode scanners can be set to emulate a serial device instead of a keyboard device. Does your scanner support this (I'd be surprised if it doesn't), and if so, will that solve your problem?
05-17-2010 05:59 AM - edited 05-17-2010 06:01 AM
David,
Thanks for the reply. Just wondering what is wrong with continuing along the Acquire Input Data.vi route. Behind this vi someone (probably NI?) has written a DLL to read Windows input streams on behalf of LabVIEW. I just need to know how to extract raw values from the DLL really, as it works without focus and reads the HID USB bar-code reader.
Looking into your other suggestions I can't find "First, you can use the VIs in the Advanced>>Input Device palette". So I did a Google search on this and still can't find it but found this from 2005! lol ...
http://www.mofeel.net/394-comp-lang-labview/24157.aspx
I'm quite disappointed really that LabVIEW 8.6 can't do such a basic computing task as read the keyboard buffer - as it can and has done for years - read the coms buffer.
Does anyone have a vi for this? It must have been done before? Much appreciated if anyone can post me a vi for this - it's much lower level than I expected with the powerful & advanced LabVIEW 8.6!
Nathand,
Thanks for the suggestion but we have this bar-code reader as standard here and USB is by far the preferred interface. It is possible to go serial to get round the LabVIEW deficiency but I want a 'plug-in and go' solution on any PC. I know I could use a USB to Serial converter but on assigning it the COM number is never standard COM3 or COM6 etc, etc, Going serial would mean going back in technology and at additional cost and additional un-standardization.
05-17-2010 09:00 AM
Andy,
I've dealt with barcode scanners as an input device to LabVIEW many times over the years. I've set them up as HID (virtual wedge) devices and as serial devices.
First, let me give you something to think about. For a scanner set up as HID, if some other application has focus, the scan goes to the other app - LV never sees it. If you set it up as serial, you can guarantee that the scan gets seen by LV, as long as LV has the com port open. This may be why the other poster offered serial as a consideration.
If you choose to set up the scanner as HID, your best option would probably be an event structure with an event registered for ThisVI->Key Down? filter event. One of the items in the event's data is the 'Char' value, which is the ASCII value of the keystroke, unless it's an actual keyboard press of something non-ASCII, like a Fn key. The 'Vkey' event data will tell you if the event is ASCII or not.
This event registration will ensure that ALL keystroke data (while your VI has focus!) will be processed, regardless of whether a specific LV FP control has focus. You're still left with the problem of, how do you know if someone's typing into a text box, or using the scanner? If the scanner can prepend something which no one will ever type, you can probably come up with some sort of flagging logic to determine whether to discard the event from further LV processing, and handle it yourself. This is not a trivial task.
Which leads back to why I've come full circle, and my barcode devices are setup as serial devices now 🙂
Good luck whatever you do!
Dave
05-17-2010 10:30 AM
Hi David,
Thanks for the reply. A few points...
"For a scanner set up as HID, if some other application has focus, the scan goes to the other app - LV never sees it." This is incorrect, I've just tried running my 'Keyboard monitor av.vi' while typing into Word and both apps see the data simultaneously, so LabVIEW does see it. I would build-up the string to the specific length of expected input and then disregard it if's over length or missing <CR> etc. For my specific application none of the other Windows open and running take text entry anyway.
I have used serial and wedge bar-code readers in the past, by the way and a recommendation, the one I prefer and use nowadays in the factory here is the Cognex Insight 5110 LAN reader and we have those working very nicely over our LAN with LabVIEW.
Unfortunately the factory wide application in this instant requires the Symbol reader. I wanted to set this application up so that which ever window the operator accidently clicks on and diverts focus to the Symbol app keeps working. The other apps they have don't take text input fortunately. We get a lot of moans, frustrations and call-outs to the text entry window loosing focus. I know you can programatically set it to have focus but they still manage to loose it and get the text entry window to the back.
"This event registration will ensure that ALL keystroke data (while your VI has focus!) will be processed" this goes against my main initial requirement unfortunately.
Just wondering why the 'Keyboard monitor.vi' route hasn't been mentioned? Is there anyone at NI UK that has experience of this vi/DLL combo?
Andy
05-17-2010 11:43 AM
AndyVessey wrote:Nathand,
Thanks for the suggestion but we have this bar-code reader as standard here and USB is by far the preferred interface. It is possible to go serial to get round the LabVIEW deficiency but I want a 'plug-in and go' solution on any PC. I know I could use a USB to Serial converter but on assigning it the COM number is never standard COM3 or COM6 etc, etc, Going serial would mean going back in technology and at additional cost and additional un-standardization.
In case it wasn't clear, I wasn't suggesting that you actually connect the scanner to a serial port. The scanner should emulate a serial port over USB. For the readers I've seen it's as simple as scanning a particular symbol that tells the scanner to pretend it's a serial device connected to a USB port, and possibly installing a driver.
I understand the COM port problem, but it's not too hard to send an ID command on each installed serial port until you find the one to which the scanner is connected.
05-17-2010 02:57 PM
Andy,
First, sorry, you are absolutely correct. The VIs used in your attached example do indeed see keyboard data without regard to which app has focus. My experience was with an earlier incarnation of direct-keyboard VIs supplied by NI several LabVIEW versions back which DID NOT return key data unless LV had focus (any window, but not necessarily on one of its controls). So my reply was irrelevant and wrong. I hadn't tried the 'new' direct keyboard VIs.
The VIs your example uses are the same ones referenced by the NIUK AE - they can be found in the palettes under Connectivity->Input Device Control.
Unfortunately, now that I've taken them for a bit of a test drive, I see some behavior that troubles me. Depending upon how frequently the keyboardAcquire VI is called, I get multiple reports for the same key, even struck briefly, long before I would expect auto-repeat to kick in. I'm concerned that maybe these VIs are a little TOO low-level, and are just reporting the instantaneous key-down state, and in no particular order, which might be OK for something like a gaming/pointing app but doesn't work to give you ordered, buffered key data. Unless somebody else can show me how they should be called to prevent this behavior, I'd hardly recommend them for your purposes.
Nathan's suggestion, to try to convert your USB-attached scanner to appear as a virtual COM port, has worked well for me on a USB-connected corded scanner from Intermec, and also for Intermec's Bluetooth scanners. Of course, if your scanner does not offer this as an option, it's not applicable. I'm not sure about the "probing" for a scanner - in my case, the COM number is fixed at the time it's instantiated, and I use MAX to assign it a VISA alias, so my code always uses the alias, and MAX insulates my code from hardware changes.
Not what you wanted to hear, but still perhaps a viable alternative.
Dave