Reading and identifying multiple USB keyboards - delphi

I'm in charge of technology at my local camera club, a not-for-profit charity in Malvern UK. We have a database-centric competition management system which is home-brewed by me in Delphi 6 and now we wish to add a scoring system to it. This entails attaching 5 x cheap-and-standard USB numeric keypads to a PC (using a USB hub) and being able to programmatically read the keystrokes from each keyboard as they are entered by the 5 judges. Of course, they will hit their keys in a completely parallel and asynchronous way, so I need to identify which key has been struck by which judge, so as to assemble the scores (i.e. possible multiple keystrokes each) they have entered individually.
From what I can gather, Windows grabs the attention of keyboard devices and looks after the characer strings they produce, simply squirting the chars into the normal keyboard queue (and I have confirmed that by experiment!). This won't do for my needs, as I really must collect the 5 sets of (possibly multiple) key-presses and allocate the received characters as 5 separate variables for the scoring system to manipulate thereafter.
Can anyone (a) suggest a method for doing this in Delphi and (b) offer some guide to the code that might be needed? Whilst I am pretty Delphi-aware, I have no experience of accessing USB devices, or capturing their data.
Any help or guidance would be most gratefully received!

Windows provides a Raw Input API, which can be used for this purpose. In the reference at the link provided, one of the advantages is listed as:
An application can distinguish the source of the input even if it is
from the same type of device. For example, two mouse devices.
While this is more work than regular Windows input messages, it is a lot easier than writing USB device drivers.
One example of its use (while not written in Delphi) demonstrates what it can do, and provides some information on using it:
Using Raw Input from C# to handle multiple keyboards.

Related

How to enumerate MTP and PTP devices

This answer explains how to use WMI to find attached USB mass storage devices by drive letter but I am trying to find the names of (or UNC paths to) attached MTP or PTP devices, such as attached cameras or mobile devices which are mounted without a drive letter, so that I can crawl their directories to search for images. How can I do this?
First of all, you need to understand that having MTP device name will not allow you to crawl it directories or search for images with methods you use for simple PC filesystems. It's only simplified view from Windows Explorer, not really state of things.
I don't know how exeactly do it with Delphi, but there is a Windows Portable Devices API and it all uses COM, so I beleave there is a way to get it works even on Delphi.
Another way you may try, is using libmtp it's a plain C library, you definetely can call it's dll methods from Delphi with some helper code.
If you want just names, you can find names of attached WPD devices (Windows Portable Devices, they are using MTP and PTP protocols) using SetupDiGetDeviceRegistryProperty WinApi function.
First you need to call SetupDiGetClassDevs with GUID_DEVINTERFACE_WPD (it is defined in PortableDevice.h but you can find it easy in google
{6AC27878-A6FA-4155-BA85-F98F491D4F33} )
Then iterate on devices using SetupDiEnumDeviceInfo, get id of each device from WPD cathegory with CM_Get_Device_ID function call and pass it to SetupDiGetDeviceRegistryProperty with SPDRP_FRIENDLYNAME (or SPDRP_DEVICEDESC, maybe you should try different parameters)
There are a lot of samples of using this functions, for example this one:
SetupDiGetDeviceProperty usage example

Microcontroller Programming in Delphi

I've been searching for some information regarding microcontroller programming but the info I find is either way over my head or doesn't appear to exist. I'm looking for something easier to digest! I'm relatively new to programming and come from an SQL DBA background and decided that it would be quicker for me to learn some programming fundamentals and then teach myself Delphi than it would to get some changes implemented through my company's insane design change note system!
After a couple of years of Delphi programming I can cope with writing database applications without too much bother and I want to be able to move on a level.
We use PIC microcontrollers on our PCBs; mainly the PIC18F family. The software on the PICS is written in C but there are parameters values that are written to by a Delphi application that interface with the PIC using an ActiveX control.
Basically, SQL Database holds parameter info, Delphi client app retrieves those values, passes them to the ActiveX controll which does all the low level stuff on the PIC. For example the internal EEPROM will have a map and within any particular address a value will be stored to switch something on or off or hold an integer value etc.
I've gotten hold of an MPLAB kit which has an ICD2 device that can read and write values to the internal EEPROM and I understand how to change these hexadecimal values using MPLAB software.
My hope isn't to learn embedded microcontroller programming; rather that I can write a Delphi app that will do something similar to MPLAB software. E.g read and write values to certain memory addresses within the EEPROM.
I'd be very gratefull if anyone can point me in the right direction of any libraries or components that may already exist for bridging this gap between simple Delphi form application and writing low level PIC EEPROM. I doubt such any easy interface exists but I thought I'd ask. To summarise I want to be able to have a simple form app, with some edit boxes that the user types in or selects from dropdown boxes, parameter values, to click on a button and to assign those parameter values to specific EEPROM memory addresses. Thank you for reading and any comments would be gratefully received.
Regards
KD
I'm a big fan of MikroElectronika and have used their Pascal tools for pic16 series MCU with great success (touch screen interfaces, ZigBee, ...).
http://www.mikroe.com/
Updated 2015 Answer:
Why not a Raspberry Pi with FreePascal and Lazarus? The boards cost from $5 to $25 US, as of this date, and the development tools are free.
Original 2012 Answer:
If you like to use Pascal, you might find Free Pascal useful on small embedded systems, but the minimum I believe you will find it can compile on is a Linux-based ARM embedded system. The fact that you use pascal on both sides is very unlikely to help you accomplish anything major.
If you want to go all the way down the the smallest PIC microcontrollers, you'll find that it's almost always a variant of C that you'll be using. Frankly, at that level, the differences aren't that much. If you can write Pascal, you can learn enough C in a day, to use with microcontrollers.
Don't be scared to use the native language that most microcontrollers support. My personal favorites are the Rabbit microcontrollers, formerly from Z-World, now from digi -- I think I paid about $100 US for the first board and development toolkit.
Interfacing such an application with delphi is pretty easy, usually these days, I would interface using TCP/IP over either wired Ethernet, or wireless (Wifi). But if you really want to you could use RS-232 or RS-485 serial links. (RS-485 has the advantage that you can wire it up to 5 miles long.) If I was using a serial link, I'd probably implement something like Modbus on both sides, if I just wanted to send some numeric data back and forth, and if I was doing something text-oriented, I think I'd write a mini HTTP web server on the embedded controller, and most boards these days come with enough HTTP server demos to make that drop-dead easy.
Delphi outputs Win32 and Win64 native applications you can write software that can interact with certain devices if the PCB has serial comunication or I2C you can write software that in Delphi that it will interact with the physical device.
But if you want to programm the devices yourself , write software that will run on this devices you can't do it in Delphi. I suggest you buy an Arduino it's an excellent envoirment for beginners in microcontroller programming.
If you have the source code of your pic microcontroller then you can implement the code in C to read from Serial, USB or some other interface available in your hardware and write it to the eeprom. This way its easy to write the app in any high level language like delphi, c++, etc.
Or you can write your PIC application using the mikropascal compiler from mikroeletronika that its very good and I've been using for a long time, but as you can see you will have to implement some mecanism to read from the interface and write to your eeprom as I've mentioned before.
This compiler comes with a lote of librarys to work with many devices. You should take a look on it, its not free but the price is low and in their site you can find samples and sample boards to test it.
One option, if you want a simple interface to write to the PIC EEPROM, is to use the ICD command line utility. Unfortunately it is not available for the ICD2, but the PICkit 2 and 3 (which are cheap), ICD3, and RealICE have command line utilities that give you the ability to write to the EEPROM (google pk2cmd). In Delphi, you could just wrap a very simple set of command line calls to pk2cmd.

How to read from a cheap generic USB device?

I bough a cheap RFID reader from eBay, just to play about with. There is no API, it just writes to stdin - that it to say, if you have Notepad open and tap an RFID tag to the reader its Id number appears in the Notepad window.
I am looking around for a reasonably priced reader/writer with an actual API (any recommendations?).
Until then I need to knock together a quick demo using what I have, just to prove the concept.
How can I best intercept the input from the USB connection? (and is there a free VCL control to do this?)
I guess if I just have a modal form with a control which is active then I can hook its on change event. But modal forms seem a bit rude. Maybe I can hook keyboard input, as it seems to be injecting like types chars?
Any idea? Please tell me if I cam not explaining this clearly enough.
Thanks in advance for your help.
In the end, I just hooked the keyboard, rather than trying to intercept the USB. It works if I check that my application is active and pass on the keystrokes otherwise. My app doesn't have any keyboard input, just mouse clicks (and what I read from RFID is digits only, so I can still handle things like Alt+F4. Maybe not the perfect solution for everyone, but all that I could get to work)
Based on your description, it sounds like the RFID reader is providing a USB HID keyboard interface.
I don't know if there is anything similar in delphi, but in libusb there is a libusb_claim_interface, which requests that the OS hand control over to your program.
A Delphi library for doing HID devices:
http://www.soft-gems.net/index.php?option=com_content&task=view&id=14&Itemid=33

How to generate unique serial number of machine in Delphi?

I have question how to generate unique serial number of machine in Delphi? I tried to do this using the ID the motherboard or processor, but unfortunately it's unfortunately supported. Partition serial numbers, etc. fall off, because it is changing after the formatted. I'm looking for something that doesn't change after the formatted. Has anyone any idea?
Inside JCL library, there are several functions very usefull for this topic:
function CPUID: TCpuInfo;
function GetMacAddresses(const Machine: string; const Addresses: TStrings): Integer;
function GetVolumeSerialNumber(const Drive: string): string;
function GetBIOSName: string;
What you're after is actually some sort of "hardware fingerprint", not an "serial number". The problem with this approach is that it's not 100% reliable. Proof: Microsoft didn't manage to find a way to properly limit OEM software to any single computer, you can actually re-install a OEM license on a new computer after a while! Once you agree there can't be a perfect solution you may look at your options and try getting something that's good enough.
For my applications I'm creating a fingerprint based on info returned by GetSystemInfo, GetVolumeInformation and (for the 'C:' partition) and a selection of registry keys from HKLM\HARDWARE (lots of registry keys actually, everything but usb, keyboard and mouse stuff). I'm reading hardware information from the registry because a Windows application can't really access hardware directly (DOS-style approaches can't work), and because I don't have time to figure out ways to determine hardware-related information for many different devices.
My approach has the following disadvantages:
Uses the partition serial number, as set up by Format. An format would clearly change the fingerprint.
Uses information about the installed drivers. Updating an driver might actually change the fingerprint! Moving a card from one PCI port to an other might change the fingerprint.
None the less, even with all of this changing information taken into account, I get collisions: Something like 1/1000 computers! There are several factors at work here:
Big OEM build many computers using the same hardware. They also clone HDD's in order to speed up software installation so different PC's might get the same partition serial number.
I'm building a very short hash from all that information, short enough so people can read it to me on the phone without too many mistakes.
This system works for me, but it will not work for you if you expect to re-identify computers once they're reinstalled.
You can test GLibWMI that extract information of several components on Windows.
It's free and source included. You can find it on my Web or in Sourceforge.
alt text http://img175.imageshack.us/img175/1250/imagen344.png
Include components for BIOSInfo, DiskInfo, ProcessorInfo,...
With this three components you can obtain information like this:
alt text http://img690.imageshack.us/img690/6006/imagen349.png
You can find the BIN/EXE of GenericDemo (all components) here; You can test all information that you can retrive with this components.
I had a similar problem back in the good old DOS days. I found out that the ROM of the installed hardware ie. video card, disk controllers seriel ports etc. was accessible directly, since they are memory-mapped. This means that I was able to create a list of installed hardware, and use it to generate a "serial number", that uniquely identified each computer (until the hardware setup was changed). I'm sure something similar is possible today as well.
Check out http://duartes.org/gustavo/blog/post/motherboard-chipsets-memory-map, if you want to use this approach.
Regards
Frank
Often the MAC address of the (a) network card is used, there are several ways to query the mac address (in Delphi) but the easiest/cleanest way is probably to use the GetAdaptersInfo API.
Here is a simple solution
Generate a GUID
Save the Guid value in the registry
Use the value of the guid as the serial number
If you a worried about security use a
hash over the ( Guid + some secret data)
I tend to agree with the "it can't be done" camp. At least not 100%, but it can probably be done "good enough" to keep the average user in line.
And if it can be done then it probably has been done. Did you check Torry's Delpi300, etc (maybe even sourceforge, although you might have to translate into Delphi).
http://www.google.com.sg/search?hl=en&source=hp&q=How+to+generate+unique+serial+number+of+machine+in+Delphi actually looks promising

Emulate GPS or a serial device

Is it possible to get location data out of Google Gears, Google Gelocation API or any other web location API (such as Fire Eagle) in such a format that it appears to other software as a GPS device?
It occured to me reading these answers to my question regarding WiFi location finding, on Super User, that if I could emulate a GPS unit, many of these web services could act as a 'poor-mans' GPS to otherwise less useful software that requires it.
Is GPSD an option?
Preferably OSX & Python, but I would be interested in any implementation.
There is a very similar thread on a Python mailinglist that mentions Windows virtual COM ports and discusses Unix's pseudo-tty capabilities. If the app(s) you want to use let you type in a specific tty device file, this may be the easiest route. (Short of asking the authors to provide a plugin API for what you're trying to do, or buying yourself a $20 bluetooth GPS mouse.)
Are you using OS X?
There is a project macosxvirtualserialport on Google code that provides a graphical wrapper around some of the features of a utility called socat. I'd recommend taking a look at socat if you see potential in the pseudo-tty route. I believe you could use socat to link a pipe from a Python program to a pseudo-tty.
Most native Mac apps will be querying IOServiceMatching for a device with kIOSerialBSDRS232Type, and I doubt that a pseudo-tty will show up as an IOKit service.
In this case, unless you can find a project that has already implemented such a thing, you will need to implement a driver as described in this How to create virtual COM port thread. If you're going to the trouble of create a device driver, you would want to base it on IOKit because of that likely IOServiceMatching query. You can find the Apple16X50Serial project mentioned in that post at the top of Apple's open source code list (go to the main page and pick an older OS release if you want to target something pre-10.6).
If your app is most useful with realtime data (e.g. the RouteBuddy app mentioned in the Python mailinglist thread can log current positions) then you will want to fetch updates from your web sources (hopefully they support long-polling) and convert them to basic NMEA RMC sentences. You do not want to do this from inside your driver code. Instead, divide your work up into kernel-land and user-land pieces that can communicate, and put as little of the code as possible into the kernel part.
If you want to let apps both read and write to these web services, your best bet would probably be to simulate a Garmin device. Garmin has more-or-less documented their protocol in the IntfSpec.pdf file included with their Device Interface SDK. Again, you'd want to split as much as you could into user-space code.
I was unable to find a project or utility that implements the kernel side of an IOKit-based virtual serial interface, but I'd be surprised if there wasn't one hiding somewhere out there. Unfortunately, most of the answers I found to that question were like this, with the developer being told to get busy writing a kext.
I'm not exactly sure how to accomplish what you're asking, but I may be able to lend some insight as to how you might begin to get it done. So here goes:
A GPS device shows up to most systems as nothing more than a serial device -- a.k.a. a COM port if you're dealing with Windows, /dev/ttySx if you're in *nix. By definition, a serial port's specific duty is to stream data across a bus, one block at a time. So, it would then follow logically that if you want to emulate the presence of a GPS device, you should gather the data you're consuming and put it into a stream that somehow acts like an active serial port.
There are, however, some complications you might want to consider:
Most GPS devices don't just send out location data; there's also information on satellite locations, fix quality, bearing, and so on. Then again, nobody's made any rules saying you have to make all that data available. There's probably more to this, but I'll admit that I need to do more research in this area myself.
I'm not sure how fast you can receive data when dealing with Google Latitude, etc., but any delays in receiving would definitely result in visible pauses in your "serial port"'s data stream. Again, this may not be as big a complication as it seems, because GPS devices are known to "burst" data across the bus anyway, but I'd definitely keep an eye on that. You want to make sure there's always a surplus of data coming across, not a shortage.
Along the way you'll also have to transform the coordinates you receive into valid GPS sentences, as well. You can find specifications for those, but I would definitely make friends with the NMEA standard -- even though it is a flawed standard, it's the one everyone seems to agree on anyway.
Hope this helped you, at least a little bit. Are there anymore details specific to your problem that you think could be useful in answering this question?
Take a look to Franson GPS Gate which allows you to connect to Google Earth among other things (like simulating GPS and so on). Is windows only though but I think you could get some useful ideas from it.
I haven't looked into it very much, but have you considered using Skyhook's SDK? It might provide you with some of what you are looking for. It's available for every major desktop and mobile OS.

Resources