title: serial port communication with POS from .NET
body: <p>I am trying to communicate with a cash register through the serial port from a C# app I am building and I have a small  utility provided from the manufacturer which gives me some info about the device like firmware version etc.</p>
  
  <p>In the protocol specification it states that communication begins with the "ENQ" ASCII control (0x05h) code on the sender end, to which the receiver must respond "ACK"(0x06h). Then a request packet can be sent that contains a command etc. </p>
  
  <p>Connection settings:</p>
  
  <pre><code>   - Baud rate:     9600 baud
     - Parity:        none
     - Data:          8
     - Stop:          1
     - Flow control:  none
  </code></pre>
  
  <p>Transmission:</p>
  
  <pre><code>Sender  Receiver
  
  Idle    
      Idle
  Enquire 
      Acknowledge
  Packet  
      Acknowledge 
  </code></pre>
  
  <p>The packet structure is the following (STX = 0x02h , ETX = 0x03h):</p>
  
  <pre><code>                  +-----+--------- - - -+-----+
                    | STX |      Data     | ETX |  
                    +-----+--------- - - -+-----+
  </code></pre>
  
  <p>Fields in data section are separated with '/':</p>
  
  <pre><code>+--------++---------+---------+---------+- - - +---------++----------+
    | Header || Field 1 / Field 2 / .... / Field N || Checksum |
    +--------++---------+---------+---------+- - - +---------++-
  </code></pre>
  
  <p>Sender/Receiver states:</p>
  
  <pre><code>      Sender                        Receiver
  ---------------------------------------------------
         IDLE                        IDLE
      ENQUIRE ---------------------&gt; 
          &lt;--------------------- ACKNOWLEDGE
       PACKET ---------------------&gt; (verify error)
              &lt;--------------------- NOT ACKNOWLEDGE
       PACKET ---------------------&gt; (verify error)
              &lt;--------------------- NOT ACKNOWLEDGE
       PACKET ---------------------&gt; (verify success)
              &lt;--------------------- ACKNOWLEDGE
       .
       .
       (Rest of packet exchange)
      ---------------------------------------------------
  </code></pre>
  
  <p>So I try to communicate and I get nothing back. I downloaded a serial port sniffer, run the manufacturers utility and pressed the "get device version" button. I got:</p>
  
  <pre><code>#   Time            Port        Data                     ASCII
  000001  20:03:06.484    COM2    &lt;&lt;  18 18 18 05          ....
  000002  20:03:06.500    COM2    &gt;&gt;  06 06                  ..
  000003  20:03:06.500    COM2    &lt;&lt;  02 76 2F 36 35 03    .v/65.
  000004  20:03:06.515    COM2    &gt;&gt;  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    &lt;&lt;  06  .
  000009  20:03:07.015    COM2    &gt;&gt;  06  .
  000010  20:03:07.015    COM2    &lt;&lt;  18 18 18 05 02 61 2F 34 34 03                .....a/44.
  000011  20:03:07.015    COM2    &gt;&gt;  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    &lt;&lt;  06  .
  000015  20:03:07.515    COM2    &gt;&gt;  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    &lt;&lt;  18 18 18 05 02 74 2F 36 33 03             .....t/63.
  000018  20:03:07.531    COM2    &gt;&gt;  2F 31 39 32 30 30 39 2F 31 31 03      /192009/11.
  000019  20:03:07.531    COM2    &lt;&lt;  06                                    .
  </code></pre>
  
  <p><em><strong></em>**<em>*</em>**<em>*</em>****</strong>(ENQ = 05, ACK = 06, STX = 02 , ETX = 03, CAN = 18, '/' = 2F)</p>
  
  <p>The code:</p>
  
  <pre><code>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);
      }
  }
  </code></pre>
  
  <p>I managed to send the commands from my app and logged the communication (18 18 18 05 is being sent) but I get no response at all from the register.
  Everything I send seems correct. Any ideas? Am I missing something stupid?</p>