views:

810

answers:

2

We are trying to emulate a POS keyboard in order to integrate an application with an existing Point of Sale application.

We ran across this software: Virtual Serial Port Kit

It basically creates a virtual serial port pair so that data send to COM1 can come out of COM4 and vice versa. This allows our application to send data through COM4 to appear to the POS application that it is talking to a keyboard on COM1.

Pretty ingenious, but it seems there is some kind of signalling going on that we are not able to replicate with the .Net System.IO.Ports.SerialPort class...

From what we can tell from serial port monitoring programs, this is how the startup sequence works:

  1. 8 byte Command sent to keyboard
  2. Keyboard beeps
  3. Some kind of signal is sent from the keyboard
  4. Second 8 byte command is sent to keyboard, triggered by the signal
  5. Keyboard replies with device and version information

When using our virtual serial port, we cannot figure out how to replicate the signal sent from the keyboard. We can see all data coming through properly, so we believe the settings on our SerialPort object are correct. Here is a snippet of our SerialPort settings:

_port.BaudRate= 9600;
_port.Parity = Parity.None;
_port.DataBits = 8;
_port.StopBits = StopBits.One;
_port.DtrEnable = true;
_port.RtsEnable = true;

We also noticed from using portmon we see a GET_MODEM_STATUS request that is what the POS application is waiting on before sending the second command.

Any ideas on how to diagnose this? Since we are using .NET this whole situation is a little more low level than we're used to.

UPDATE: I also want to note that we tried the SDK here: Franson Serial Tools but we could not even get data to go through when using this SDK.

UPDATE: We have thrown out using any kind of virtual serial port. We have gotten a cable to run from the POS PC to another and can see data coming across to emulate the keyboard. Now our problem is that we can't figure out how to signal that the keyboard is ready to recieve data as the top answer mentions. It appears that the POS application sends the command to beep an waits up to 3 seconds waiting for a signal. So it times out when talking to our application, but not when talking to the real keyboard

How can we do this with the SerialPort class? We already set DtrEnable and RtsEnable to true, do we need to set something else? Or do we have to use a lower level serial port p/invoke to accomplish this?

SOLUTION:

_port.RtsEnabled = false;
Thread.Sleep(1000);
_port.RtsEnabled = true;

This makes the POS application think the keyboard is plugged in, which makes sense. I'll mark the #1 answer as the answer since it greatly helped us find the solution.

A: 

I've not done serial port development for years, but when I did I always used a Crossover Cable and a second PC running Windows HyperTerminal.

Martin Brown
We'll try this and let you know our results, this would be good because we do not have to rely on a 3rd party serial program. We could just connect the cable to a different PC.
Jonathan.Peppers
Did not seem to work, the PC has a female end for this keyboard while a normal RS232 port is male. So we tried a standard RS232 cable (male one end, female on the other) to go from the POS PC to another, but no data seemed to come through. Do we need a special cable to see it work? Your link had a picture of a null modem cable that is female on both ends, which won't work for this device.
Jonathan.Peppers
Martin Brown
Another site that looks good is http://www.tronisoft.com/cat_rs232adapters.php
Martin Brown
+4  A: 

EDITED to give more perspective from the point of view of simulating the keyboard.

As it happens I have written low-level drivers for the 92R keyboard in the distant past.

You really need the documentation for the proprietary protocol to do this properly - for example commands sent to the keyboard contain a sequence number and a checksum. I'd recommend contacting Fujitsu and attempting to get hold of this documentation.

From what you've described:

  • The first 8-byte command you sent was probably a reset command (as it caused the keyboard to beep). The keyboard sends a response to acknowledge the command, then resets itself.

  • After sending a reset command, the POS app needs to wait for the keyboard to reset (I think about 3000ms) before sending other commands.

  • It looks like the second send is a command to request the firmware version.

  • The POS app will also need to subsequently send a command to enable "autoinput" before the keyboard will actually send keystrokes.

  • There are also commands available to request the keylock position, sound the tone generator, enable/disable the MSR, and write to the optional embedded 2-line display. So your simulator will need to be capable of reproducing the responses to these commands.

  • Once the POS app has enabled "autoinput" the keyboard will send unsolicited messages with the keystrokes being pressed (or keylock position changes, or MSR input). IIRC these messages also have a sequence number and checksum that you will need to reproduce in your simulator.

The only signalling I know of is that the keyboard raises CTS when it is ready to receive data. If you connect two ports on a PC, you need a special null modem cable (see below) so that when your simulator raises RTS on COM4 it will be seen as CTS on the other port.

The COM ports on a TeamPOS motherboard provide power to the keyboard. You probably don't want to connect these pins to your COM4 port, so I would suggest using a null modem cable that connects only the following pins:

2 (Tx data) - 3 (Rx data)

3 (Rx data) - 2 (Tx data)

7 (RTS) - 8 (CTS)

8 (CTS) - 7 (RTS)

Joe
Excellent answer. We have already reverse engineered the checksum and most of the commands--it's something we're used to doing. However, we haven't every had to mess with signalling on serial ports before--it must be something that happens under the hood in .Net's SerialPort class or something only older devices use. It turns out that the virtual COM port we're using doesn't support signalling over CTS or RTS, and that is probably our issue. We will research the proper cable you mentioned and let you know our results.
Jonathan.Peppers
Well, we were able to create your cable. We took a null modem cable hooked to a female to male converter and broke all the pins off that were not needed. But now we are basically at the same point where we were with the virtual port. We are not sure how to send the signal that the keyboard is sending from .Net, I will update my question.
Jonathan.Peppers
Had a quick question, every now and then the keyboard driver (FjrKbdPO.exe) stops being able to talk to our emulated keyboard, event though the communication coming through looks completely normal. Restarting the computer fixes this issue. Any ideas on what could be going on?
Jonathan.Peppers
Difficult to say without seeing the messages being exchanged. When you say "stops being able to talk..." do you mean it stops processing the unsolicited keystroke messages you are sending? Maybe it is waiting for a keylock change or an MSR message?
Joe
We switched to using a virtual serial port at one point, and this was causing the issue. Using our specialized cable with missing pins seems to be 100% reliable, we just loop it back to the same PC--which is dumb but it works.
Jonathan.Peppers
Glad you've got it working - good luck!
Joe