Я пытаюсь связаться с кассовым аппаратом через последовательный порт из приложения C #, которое я создаю, и у меня есть небольшая утилита от производителя, которая дает мне некоторую информацию об устройстве, например, версию прошивки и т. Д.
В спецификации протокола говорится, что обмен данными начинается с управляющего кода ASCII "ENQ" (0x05h) на стороне отправителя, на который получатель должен ответить "ACK" (0x06h).Затем может быть отправлен пакет запроса, содержащий команду и т. Д.
Настройки соединения:
- Baud rate: 9600 baud
- Parity: none
- Data: 8
- Stop: 1
- Flow control: none
Передача:
Sender Receiver
Idle
Idle
Enquire
Acknowledge
Packet
Acknowledge
Структура пакета следующая (STX= 0x02h, ETX = 0x03h):
+-----+--------- - - -+-----+
| STX | Data | ETX |
+-----+--------- - - -+-----+
Поля в разделе данных разделяются с помощью '/':
+--------++---------+---------+---------+- - - +---------++----------+
| Header || Field 1 / Field 2 / .... / Field N || Checksum |
+--------++---------+---------+---------+- - - +---------++-
Состояния отправителя / получателя:
Sender Receiver
---------------------------------------------------
IDLE IDLE
ENQUIRE --------------------->
<--------------------- ACKNOWLEDGE
PACKET ---------------------> (verify error)
<--------------------- NOT ACKNOWLEDGE
PACKET ---------------------> (verify error)
<--------------------- NOT ACKNOWLEDGE
PACKET ---------------------> (verify success)
<--------------------- ACKNOWLEDGE
.
.
(Rest of packet exchange)
---------------------------------------------------
Я пытаюсь общаться и ничего не получаю.Я скачал сниффер последовательного порта, запустил утилиту производителей и нажал кнопку «получить версию устройства».Я получил:
# Time Port Data ASCII
000001 20:03:06.484 COM2 << 18 18 18 05 ....
000002 20:03:06.500 COM2 >> 06 06 ..
000003 20:03:06.500 COM2 << 02 76 2F 36 35 03 .v/65.
000004 20:03:06.515 COM2 >> 02 30 30 2F 30 30 2F 30 32 2F 31 2E 30 31 2F 31 .00/00/02/1.01/1
000005 2E 30 31 2F 20 35 38 2F 35 30 30 30 2F 31 34 30 .01/ 58/5000/140
000006 2F 32 30 2F 31 30 2F 31 30 2F 20 36 2F 20 35 2F /20/10/10/ 6/ 5/
000007 33 30 2F 37 37 03 30/77.
000008 20:03:06.515 COM2 << 06 .
000009 20:03:07.015 COM2 >> 06 .
000010 20:03:07.015 COM2 << 18 18 18 05 02 61 2F 34 34 03 .....a/44.
000011 20:03:07.015 COM2 >> 06 02 30 30 2F 30 30 2F 30 32 2F 30 37 30 30 33 ..00/00/02/07003
000012 36 34 35 2F 31 2F CD D0 20 2F 44 4C 38 30 4C 49 645/1/ΞΞ /DL80LI
000013 56 31 52 31 35 20 20 20 20 20 2F 39 34 03 V1R15 /94.
000014 20:03:07.015 COM2 << 06 .
000015 20:03:07.515 COM2 >> 06 06 02 30 30 2F 30 30 2F 30 32 2F 31 38 31 31 ...00/00/02/1811
000016 31 31 11
000017 20:03:07.515 COM2 << 18 18 18 05 02 74 2F 36 33 03 .....t/63.
000018 20:03:07.531 COM2 >> 2F 31 39 32 30 30 39 2F 31 31 03 /192009/11.
000019 20:03:07.531 COM2 << 06 .
********** (ENQ = 05, ACK = 06, STX = 02, ETX = 03, CAN = 18, '/' = 2F)
Код:
public partial class Form1 : Form
{
// Add this variable
string RxString;
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
serialPort1.PortName = "COM2";
serialPort1.BaudRate = 9600;
serialPort1.DataBits = 8;
serialPort1.Parity = System.IO.Ports.Parity.None;
serialPort1.StopBits = System.IO.Ports.StopBits.One;
serialPort1.DtrEnable = true;
serialPort1.RtsEnable = true;
try
{
serialPort1.Open();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
if (serialPort1.IsOpen)
{
buttonStart.Enabled = false;
buttonStop.Enabled = true;
textBox1.ReadOnly = false;
}
}
private void buttonStop_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
buttonStart.Enabled = true;
buttonStop.Enabled = false;
textBox1.ReadOnly = true;
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (serialPort1.IsOpen) serialPort1.Close();
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
// If the port is closed, don't try to send a character.
if (!serialPort1.IsOpen) return;
// If the port is Open, declare a char[] array with one element.
char[] buff = new char[1];
// Load element 0 with the key character.
buff[0] = e.KeyChar;
// Send the one character buffer.
serialPort1.Write(buff, 0, 1);
// Set the KeyPress event as handled so the character won't
// display locally. If you want it to display, omit the next line.
e.Handled = true;
}
private void DisplayText(object sender, EventArgs e)
{
textBox1.AppendText(RxString);
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
RxString = serialPort1.ReadExisting();
this.Invoke(new EventHandler(DisplayText));
}
private void buttonENQ_Click(object sender, EventArgs e)
{
// If the port is closed, don't try to send a character.
if (!serialPort1.IsOpen) return;
byte[] Buff = new byte[4];
Buff[0] = 0x18;
Buff[1] = 0x18;
Buff[2] = 0x18;
Buff[3] = 0x05;
serialPort1.Write(Buff, 0, 4);
}
}
Мне удалось отправить команды из моего приложенияи зарегистрировал сообщение (18 18 18 05 отправляется), но я не получаю никакого ответа из реестра.Все, что я посылаю, кажется правильным.Есть идеи?Я что-то упустил глупо?