POS协议串口通信

时间:2011-11-28 17:26:05

标签: c# embedded serial-port

我有一个收银机,我试图用C#进行通信(我不是在使用POS for .NET)。 基本上我想让它从我的应用程序数据库中提取项目。

因此收银机通过串口将此字符串发送到应用程序主机:     •COMMAND:项目搜索包

Command Short Description:          "Searches PC for a PLU code" 

Data Send Example Format:           ?/1234567890123/

“/”是数据包字段分隔符。该数字是要搜索的项目的条形码。 “?”是个 数据包描述符,表示这是一个请求项目信息的数据包。

我必须以回复数据包回复

Reply Packet Format:    "1/ITEM DESCRIPTION/1200.00/0.00/1/" if the item exists in the host database

OR

"0/"  if it does not exist in which it will search its internal memory for it

协议规定了通信规则:

ECR/POS    HOST COMPUTER

Idle    
               Idle
Enquire(ENQ)    
               Acknowledge(ACK) 
Packet("?/1234567890123/")  
               Acknowledge(ACK) 
               Packet("1/ITEM DESCRIPTION/1200.00/0.00/1/")
Acknowledge(ACK)    
Idle    
               Idle

ENQ,ACK是ASCII控制代码。如果数据包没有正确制作,我会收回NAK。

现场规格如下:

==== Field 1:       Found flag
Type:           FLAG
Length:         1
Notes:          This flag must be zero when item could not be found
            in the database, else (if found) it must be set to
            one. In the 1st case, the rest of the fields must
            not be sent. 

==== Field 2:       Item description
Type:           STRING
Length:         Variable, 1-20 characters
Notes:          The PLU description for the requested code

==== Field 3:       Item unit price
Type:           AMOUNT
Length:         Default
Notes:          This is the unit price for the requested code

==== Field 4:       Item discount amount
Type:           AMOUNT
Length:         Default
Notes:          This is an auto-discount value for this PLU

==== Field 5:       Department
Type:           INTEGER
Length:         1
Notes:                  It is the department index which the PLU belongs

我希望它能从主机应用中获取价格。 问题是寄存器接受我的响应数据包是否有效(它通过串口发回ACK)但在自己的LCD屏幕上我得到“错误:不存在的项目”。好像我发了一个“0”标志。我不知道问题是什么。我很绝望。

东西是寄存器询问主机的价格,如果它找不到,它会查询它自己的内部存储器(最多可以存储4000个项目)。如果我手动将项目存储在内部存储器中,我可以从主机应用程序更改它的属性(价格,描述等)。

我甚至无法以编程方式在内部存储器中添加项目,尽管我也从串行协议通信中获得“OK”(ACK)。这样我就可以通过编程方式添加项目并将其从内部存储器中拉出来。

我可以手动存储每个项目,然后如果它存在于内部存储器中,我可以根据主机应用程序改变它(更改价格,描述等)。然后它可以在内部存储器中获得我为它设置的价格。这真的很乏味。我必须先手动存储一切,我有2个相同类型的收银机。我想要的是内部没有任何东西,但是从主机那里取出一切。

请帮忙。我没有想法。

编辑:这是我嗅出的数据包捕获

#      TIME          PORT      DATA                                            ASCII
000044 13:52:03.437  COM2   >> 05                                              .
000045 13:52:03.437  COM2   << 06                                              .
000046 13:52:03.453  COM2   >> 02 30 31 2F 30 31 2F 32 2F 30 30 2F 3F 2F 39 39 .01/01/2/00/?/99
                               39 20 20 20 20 20 20 20 20 20 20 2F 31 2F 34 38 9          /1/48
                               03 06                                           ..
000049 13:52:03.453  COM2   << 06 02 30 31 2F 30 31 2F 32 2F 30 30 2F 31 2F 54 ..01/01/2/00/1/T
                               45 53 54 20 49 54 45 4D 20 2F 30 30 30 30 2E 36 EST ITEM /0000.6
                               36 2F 30 2E 30 30 2F 31 2F 33 36 03             6/0.00/1/36.

“01/01/2/00 /”部分是在线数据包标题,包括机器索引号,职员等。每个数据包以0x02(STX)开头,以0x03(ETX)结束。最后一个字段是数据包校验和数,如果我错了,它会发回NAK。

即使我弄错了字段,它似乎也会发回ACK。它只是检查校验和。 协议在这里https://rapidshare.com/files/1772287788/DL_Protocol.doc

*的 更新: *

它似乎表现得相当奇怪。我可以写入其内部存储器(存储项目)并修改除项目条形码之外的任何现有项目的字段。我只是存储在我想要的4000个指数中的任何一个。 但是,如果我从外部(从它自己的键盘)进入寄存器菜单到项目存储子菜单,请按“存储新项目”,然后在“销售”屏幕上返回,而不是实际存储任何内容,只是一直取消,它实际上下次存储每个字段。也就是说,它还存储我给它的下一个Set_PLU()命令的条形码(完全与之前未能存储条形码的命令相同),无论它是新记录还是旧记录(基本上是我给出的索引位置)它)。

有趣的是,当我进入“存储新项目菜单”时,它会给我一个新的条形码进入。如果我键入一个,它会自动将其存储在下一个可用索引中。我只是在没有打字的情况下取消下一个Set_PLU()命令适用于我选择的任何索引,即使它不是下一个可用的索引。可以是较旧的一个,在这种情况下,它会修改所有内容或一个比下一个更大的内容。

每次我需要存储产品时都必须这样做很烦人。这是什么?

3 个答案:

答案 0 :(得分:2)

在阅读了您的规范和数据后,我认为最后有一个缺失的斜线。在您的规范中,您写道:

Reply Packet Format:    "1/ITEM DESCRIPTION/1200.00/0.00/1/" if the item exists in the host database

但是在你的裸线数据中,我会看到:

1/TEST ITEM /0000.66/0.00/1/36

所以也许最后一个斜线丢失了。最后一个参数是 PLU所属的部门索引。也许这个号码对收银机的显示也有一些影响。

更新

好的,这只是一次尝试。现在我唯一想到的就是这样一个问题:“你有一个能够正确传输东西的系统吗?”如果是,您可以将它附加到您机器的第二个串行端口并编写一个简单的程序,只需在两个COM端口之间传输数据,另外将它们写入文件。因此,您可以检查其他系统正在发送的数据,或者制造商有一个演示应用程序,您可以从中嗅探它发送的确切数据。

最后但并非最不重要的是要求制造商提供一些指导,因为他应该知道数据的确切外观(或许可以给你一个例子吗?)。

顺便说一句,你已经嗅到了一些串行数据,所以你应该有一个应用程序。我最喜欢的是Free Serial Port Monitor

答案 1 :(得分:1)

确保将串行端口的编码设置为ASCII代码页。

E.g:

        port = new SerialPort("COM" + PortNum.ToString(), 
           9600, Parity.None, 8, StopBits.Two);
        port.Encoding = Encoding.GetEncoding(28591);

如果您要发送Unicode字符,则可能会混淆设备。

答案 2 :(得分:1)

好的人我做到了。我实际上必须在主机应用程序的收银机中的“存储新项目”(手动)菜单中才能正确存储条形码。我不知道为什么会这样(它确实存储了所有其他字段),这没有任何意义。我想无论手动输入如何,都必须通过串口存储条形码才能使制造商无所不知。

至于从主机应用程序获取的商品价格,我必须发送没有在线标题的简单响应(机器编号,文员编号等),尽管在规范中它说我应该。我实际上有3个协议修订,最合适的一个错误。

这意味着我无法分割信号并让每个收银机丢弃不适合它的响应。我想我会为PC购买一个额外的串口。谢谢大家的回复。