7

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.

Cracker
  • 912
  • 2
  • 14
  • 26
  • 2
    Provide an example of the data you recieve and what you actually expect. You should also clarify this statement "It works perfectly, but my code for some reason does not." because it seems your trying to indicate your sample application works but your code does not which of course makes no sense. – Security Hound Aug 16 '12 at 16:19
  • 2
    Delphi version? I voted to close because nobody can guess why you don't understand this protocol or this device's behaviour. – Warren P Aug 16 '12 at 16:22
  • Why do you think so? I understand how everything works, I have no idea, why I get different response from the device, if I send same data to it, just using different programming languages. – Cracker Aug 16 '12 at 16:27
  • 2
    Voting to close as too localized - you likely will receive better support from the manufacturer. I suggest you setup a COM port monitor to dump the communications. –  Aug 16 '12 at 16:51
  • 1
    Cracker, try adding a copy of the hex dump of the COM port trace you run for identical commands sent from both the Delphi and C# program. This is so we can see what both programs are sending too. – David Aug 16 '12 at 17:02
  • 2
    You still haven't posted what delphi version you're using, or any indication of whether you're aware (if you're using a Unicode delphi version) of the difference between Unicode and non-unicode delphi versions. Also what TYPE is BComPort1 variable, and what version of that component is it? – Warren P Aug 16 '12 at 18:10
  • Why does your C# set rts enable and dtr enable? – TJD Aug 16 '12 at 19:37
  • @TJD because COM port monitor showed that the Delphi app does it too. Anyway, it did not work even when my application did not enable DTR and RTS. – Cracker Aug 16 '12 at 19:53
  • 1
    Delphi version is *critical* for questions like this. – Jerry Dodge Aug 16 '12 at 21:49
  • Looks to me like the port is open at the wrong baud rate. – mj2008 Aug 17 '12 at 09:59
  • @WarrenP I am sorry, but all I have is the exe file of the application and the *.pas file. I have no idea which Delphi version was used to compile it. – Cracker Aug 17 '12 at 12:50
  • @mj2008 However, 9600 is correct baud rate. The MDB standart says so. You can check it yourself [in this document](https://dl.dropbox.com/u/19208429/MDB_3.0.pdf) at page 22. – Cracker Aug 17 '12 at 12:51
  • 2
    If you don't even have delphi then this is not a programming question. This is a site for asking questions about code you are writing or debugging, not a site for asking questions about EXE files you have. And how can you know if the .pas file you have even works if you're running an EXE someone else gave you? – Warren P Aug 17 '12 at 12:53
  • @JerryDodge It is Borland Delphi v6.0. I have included this information into the question. – Cracker Aug 17 '12 at 13:00
  • @WarrenP Let me make it clear to you: I have the .pas file, which contains all the source code and the .exe file which represents this code compiled. The only thing I am currently missing it the .dpr-file, that is why I can not tell you the Delphi version. And the question is not about this file itself, it is about differences between the two programs which leads to different result with the same command. – Cracker Aug 17 '12 at 14:19
  • Okay that's even more insanely "localized". For example, that .pas file references a COM port class. We don't know which one, because you didn't tell us the class name, and even if we did know that, we don't know what version, which might affect your issue. So you do not have ALL the source code. You're missing not only the project, but the components. – Warren P Aug 17 '12 at 19:58
  • A helpful idea; You tagged this "multidrop bus". Is there any chance you are using a DTR-powered 2 wire RS485 adaptor? Because the DTR signal control in the Delphi code might be part of the com port component that he was using, and might be the reason why you're not seeing the responses you wanted. Because 2-wire transmit and 2-wire receive mode might be manual (DTR controlled). – Warren P Aug 17 '12 at 20:03
  • @WarrenP The component is called BComPort. I have [uploaded it to my dropbox](https://dl.dropbox.com/u/19208429/BComPort.rar), if you would like to have a look at it. And, no, I am definetly using RS232. – Cracker Aug 18 '12 at 09:38
  • BComPort is a slightly hacked version of TComPort by Dejan Crnila, which is familiar to me. Thanks for clearing that up. I still don't think we can answer your question though. The only difference between it and regular TComPort is that the error strings appear to be localized into some other language, probably Russian, and the source code is not UTF8, it's in some non-Western ANSI locale. – Warren P Aug 18 '12 at 15:55
  • @WarrenP Okay. I will write a little application in Delphi which would send the data to port and write the received bytes into output stream. I'll be controlling this application from my C# program. I hope everything will work fine. – Cracker Aug 18 '12 at 18:45
  • Hey @Cracker, I'm struggling with a similar issue. I'm also trying to communicate with an MEI Cashflow 7900 using MDB and C#. Where did you find the delphi sample application? Any chance you could share that? My vendor didn't give me any sample applications to go along with the MEI CF7900. Or if you can't do that, what is the command you are sending down to the device in your C#'s SendData(Byte command, Byte[] data) method? What are the values of those 2 params? Any help is appreciated. – cbbcloud Feb 25 '14 at 07:51

0 Answers0