Interacting with a coin changer using COM port [closed]
Asked Answered
K

0

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.

Koniology answered 16/8, 2012 at 16:13 Comment(21)
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.Arthropod
Delphi version? I voted to close because nobody can guess why you don't understand this protocol or this device's behaviour.Reo
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.Koniology
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.Dealfish
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.Matthiew
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?Reo
Why does your C# set rts enable and dtr enable?Decigram
@Decigram 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.Koniology
Delphi version is critical for questions like this.Thwack
Looks to me like the port is open at the wrong baud rate.Questionless
@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.Koniology
@Questionless However, 9600 is correct baud rate. The MDB standart says so. You can check it yourself in this document at page 22.Koniology
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?Reo
@JerryDodge It is Borland Delphi v6.0. I have included this information into the question.Koniology
@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.Koniology
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.Reo
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).Reo
@WarrenP The component is called BComPort. I have uploaded it to my dropbox, if you would like to have a look at it. And, no, I am definetly using RS232.Koniology
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.Reo
@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.Koniology
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.Cutcheon

© 2022 - 2024 — McMap. All rights reserved.