I have a coin changer MEI Cashflow E7900
and an MDB adapter to connect the device to a serial port. The shop which sold me the adapter also provided a test application, which is written in Delphi, compiled with Borland Delphi v6.0. It works perfectly, but my code for some reason does not.
When you use MDB you have to send POLL
command every 200ms. If everything is OK, the Coin changer sends ACK
. When I send it using Delphi application the session looks like this:
=> 0x0B* 0x0B (The star character means parity set to Mark. By default parity is Space)
<= 0x00
So everything is OK, that is what I am expecting. When I send POLL
with the C# application it is like:
=> 0x0B* 0x0B
<= 0x3F 0x00
Sometimes the coin changer sends me 0x3F 0x11
after POLL
which makes no sense, there is no any valid response like this. When I get such a response I run the Delphi application, and it gets a valid ACK
response. I was using a COM port sniffer to make sure that there's no any difference in the data sent, including the port configuration itself and I keep getting different response.
Here goes the source code for the test application (Delphi):
<...>
//The component used it called BComPort
form1.BComPort1.BaudRate:=br9600;
form1.BComPort1.Parity:=paSpace;
form1.BComPort1.Port:="%port name goes here%";
form1.BComPort1.Open;
<...>
procedure SetModeBit(modebit:boolean);
begin
if modebit then begin
form1.BComPort1.BeginUpdate;
form1.BComPort1.Parity:=paMark;
form1.BComPort1.EndUpdate;
end else begin
form1.BComPort1.BeginUpdate;
form1.BComPort1.Parity:=paSpace;
form1.BComPort1.EndUpdate;
end;
procedure TForm1.PollTimer(Sender: TObject);
var
s,buf,buf2:string;
i,len:integer;
x,adr,dat1,ack,chk:byte;
crc:integer;
<...>
adr:=$08 or $0B;
SetModeBit(true);
form1.BComPort1.Write(adr,1);
dat1:=0;
crc:=adr + dat1;
try
s:=inttohex(crc,10);
s:=s[length(s)-1]+s[length(s)];
chk:=strtoint('$'+s);
except
end;
SetModeBit(false);
form1.BComPort1.Write(chk,1);
Full code listing available here, but the code provided here should be enough.
My code (C#):
private const byte P_ADDRESS = 0x8;
static void Main(string[] args)
{
<...>
port = new SerialPort(ports[index]);
port.BaudRate = 9600;
port.StopBits = StopBits.One;
port.DataBits = 8;
port.DtrEnable = true;
port.RtsEnable = true;
port.Parity = Parity.Space;
<...>
}
private static void onDataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] dataReceived = new byte[port.BytesToRead];
SetModeBit(false);
port.Read(dataReceived, 0, dataReceived.Length);
Console.WriteLine("Data received:");
foreach (Byte b in dataReceived)
{
Console.Write(b.ToString("X") + " ");
}
Console.WriteLine();
}
private static void SetModeBit(Boolean mode)
{
port.Parity = mode ? Parity.Mark : Parity.Space;
}
private static void SendData(Byte cmd, Byte[] data)
{
byte adr = (byte)(P_ADDRESS | cmd);
byte crc = adr;
foreach (var b in data)
crc += b;
SetModeBit(true);
port.Write(new byte[] { adr }, 0, 1);
SetModeBit(false);
if (data.Length > 0)
port.Write(data, 0, data.Length);
port.Write(new byte[] { crc }, 0, 1);
}
Poll command with the Delphi application:
17.08.2012 18:05:18 COM8 Capture Started
17.08.2012 18:05:38 COM8 Opened By Process ID=2872
17.08.2012 18:05:38 Baud Rate =9600
17.08.2012 18:05:38 RTS Signal = True
17.08.2012 18:05:38 DTR Signal = True
17.08.2012 18:05:38 Line Control Change: SPACE-8-1
17.08.2012 18:05:38 Baud Rate =9600
17.08.2012 18:05:38 RTS Signal = True
17.08.2012 18:05:38 DTR Signal = True
17.08.2012 18:05:38 Line Control Change: MARK-8-1
17.08.2012 18:05:38 Write 1 Bytes:
0B ; .
17.08.2012 18:05:38 Baud Rate =9600
17.08.2012 18:05:38 RTS Signal = True
17.08.2012 18:05:38 DTR Signal = True
17.08.2012 18:05:38 Line Control Change: SPACE-8-1
17.08.2012 18:05:38 Write 1 Bytes:
0B ; .
17.08.2012 18:05:38 GetCommStatus Result:16
17.08.2012 18:05:38 Parity Error = True
17.08.2012 18:05:38 Baud Rate =9600
17.08.2012 18:05:38 RTS Signal = True
17.08.2012 18:05:38 DTR Signal = True
17.08.2012 18:05:38 Line Control Change: SPACE-8-1
17.08.2012 18:05:38 Read 1 Bytes:
00 ; .
Poll command with my application:
17.08.2012 18:12:08 COM8 Capture Started
17.08.2012 18:12:11 COM8 Opened By Process ID=3164
17.08.2012 18:12:11 Baud Rate =9600
17.08.2012 18:12:11 RTS Signal = True
17.08.2012 18:12:11 DTR Signal = False
17.08.2012 18:12:11 Line Control Change: SPACE-8-1
17.08.2012 18:12:11 Baud Rate =9600
17.08.2012 18:12:11 RTS Signal = True
17.08.2012 18:12:11 DTR Signal = True
17.08.2012 18:12:11 Line Control Change: SPACE-8-1
17.08.2012 18:12:11 DTR Signal = True
17.08.2012 18:12:11 Baud Rate =9600
17.08.2012 18:12:11 RTS Signal = True
17.08.2012 18:12:11 DTR Signal = True
17.08.2012 18:12:11 Line Control Change: MARK-8-1
17.08.2012 18:12:11 Write 1 Bytes:
0B ; .
17.08.2012 18:12:11 Baud Rate =9600
17.08.2012 18:12:11 RTS Signal = True
17.08.2012 18:12:11 DTR Signal = True
17.08.2012 18:12:11 Line Control Change: SPACE-8-1
17.08.2012 18:12:11 Write 1 Bytes:
0B ; .
17.08.2012 18:12:11 GetCommStatus Result:16
17.08.2012 18:12:11 Parity Error = True
17.08.2012 18:12:11 Read 1 Bytes:
3F ; ?
17.08.2012 18:12:11 Read 1 Bytes:
00 ; .
The data received seems to be almost the same, except 0x3F
in the beginning. But the device behaviour is different too, it does not seem to be connected to the PC, it says "Disabled by machine", when I use C# application, and "Status OK" when I use Delphi application. May this be happening because of the .NET Framework? Any names of libraries for COM port interaction are appretiated.
I have idea, why I get different response. May be I hope someone here would help me. Thanks in advance. Also thanks for reading this huge question.