【问题标题】:How to send Data command to IT_100 Serial Port?如何发送数据命令到 IT_100 串口?
【发布时间】:2014-03-05 08:27:44
【问题描述】:

我有一台 DSC IT_100 。我想发送数据命令来调用警报。但是我无法处理它。

        SerialPort myPort = new SerialPort("COM6");

        myPort.BaudRate = 9600;
        myPort.Parity = Parity.None;
        myPort.StopBits = StopBits.One;
        myPort.DataBits = 8;
        myPort.Handshake = Handshake.None;

        myPort.Open();

我以 HEX 格式发送数据。这是我的程序

var sendData = GetBytes("6541D2CRLF");
myPort.WriteLine(sendData);

private static string GetBytes(string input)
        {
            string result = "";

            char[] values = input.ToCharArray();
            foreach (char letter in values)
            {
                int value = Convert.ToInt32(letter);
                result += String.Format("{0:X}", value);

            }
            return result;
        }

在编程表中它说:

能否请您帮我如何将这些数据发送到 COM..

【问题讨论】:

  • 不要转换为十六进制,这只是在文档中完成以了解要发送的字节。

标签: c# serial-port ascii


【解决方案1】:

我相信你需要遵循方法:

public static byte[] BuildPacket(string Command, string DataBytes)
{
    List<byte> output = new List<byte>();

    // Add command text
    output.AddRange(Encoding.ASCII.GetBytes(Command));

    // Add data bytes
    output.AddRange(Encoding.ASCII.GetBytes(DataBytes));

    // Add checksum
    byte chkSum = 0;
    foreach(byte b in output )
    {
        chkSum += b;
    }
    output.AddRange(Encoding.ASCII.GetBytes(chkSum.ToString("X")));

    output.AddRange(Encoding.ASCII.GetBytes(Environment.NewLine));

    return output.ToArray();
}

要获取需要发送到端口的字节,请使用如下方法:

var sendData = BuildPacket("654","3");
myPort.WriteLine(sendData);

查看了您的编程表,似乎有一个错误:

  1. 显示的数据字节不正确 字符 1 不是 33 十六进制,而是 31。我相信在您的情况下数据字节应该是 3。您可以尝试一下,但是当我将值 3 用于数据字节时,我会得到他们在使用 1 时计算的校验和。

请注意,我没有 COM 端口或您的设备来对此进行测试,因此您的结果可能会有所不同。

我阅读了设备的手册here。

【讨论】:

  • 其实行不通。代表只是为了您的利益
  • @goGud 知道为什么它不起作用吗?发生了什么?
  • 我想从应用程序设置警报。当然没有错误,但似乎我发送了错误的数据或buildPacket返回了错误的数据..我不确定。
  • 啊,我想我知道出了什么问题,让我更新我的答案。
  • @goGud 嘿,你能试试我在这里放的新 BuildPacket。
【解决方案2】:

我有这个工作。经过一夜的挠头。

关键是校验和计算。下面的代码连接到我的 IT-100(在 IP/串行适配器上运行),并向其发送“轮询”命令和“状态”命令。

困难的部分(我花了几个小时反复试验)是奇怪的校验和计算。手册中的算法真的很奇怪:

  1. 将所有 ASCII 码加在一起
  2. 截断为 8 位
  3. 创建高半字节和低半字节
  4. 将半字节 (0x01 -> 0x0F) 的值转换为字符的 ASCII 码。

例如,在上面的第 4 步中:0x01 = '1' = 0x31 = Beyond Stupid

我的完整代码如下。

using System;
using System.Net.Sockets;
using System.Text;

namespace IT100TestDriver
{
    class Program
    {
        static void Main(string[] args)
        {
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            var address = System.Net.IPAddress.Parse("192.168.1.250");
            System.Net.EndPoint ep = new System.Net.IPEndPoint(address, 1024);
            s.Connect(ep);
            byte[] buffer = new byte[1024];

            NetworkStream ns = new NetworkStream(s);

            AsyncCallback callback = null;
            callback = ar =>
            {
                int bytesRead = ns.EndRead(ar);
                string fromIT100 = Encoding.ASCII.GetString(buffer, 0, bytesRead);
                Console.Write(fromIT100);
                ns.BeginRead(buffer, 0, 1024, callback, null);
            };

            Console.WriteLine("Connected to: {0}", ep.ToString());
            ns.BeginRead(buffer, 0, 1024, callback, null);

            while (true)
            {
                var ki = Console.ReadKey(true);
                byte[] command = null;                
                switch (ki.KeyChar)
                {
                    case 'p':
                        {
                            Console.WriteLine("Sending Ping");
                            command = Encoding.ASCII.GetBytes("000"); // ping
                        }
                        break;
                    case 's':
                        {
                            Console.WriteLine("Sending Status Request");
                            command = Encoding.ASCII.GetBytes("001"); // status request
                        }
                        break;
                }

                if (command != null)
                {
                    byte[] crlf = { 0x0D, 0x0A };
                    ns.Write(command, 0, command.Length);
                    byte[] checksum = calculateChecksum(command);
                    ns.Write(checksum, 0, checksum.Length);
                    ns.Write(crlf, 0, crlf.Length);
                }
            }
        }
        private static byte[] calculateChecksum(byte[] dataToSend)
        {
            int sum = 0;
            foreach(byte b in dataToSend)
            {
                sum += b;
            }

            int truncatedto8Bits = sum & 0x000000FF;
            byte upperNibble = (byte)(((byte)(truncatedto8Bits & 0x000000F0)) >> 4);
            byte lowerNibble = (byte) (truncatedto8Bits & 0x0000000F);

            // value is 0x09, need to treat it as '9' and convert to ASCII (0x39)

            byte upperNibbleAsAscii = (byte)nibbleToAscii(upperNibble);
            byte lowerNibbleAsAscii = (byte)nibbleToAscii(lowerNibble);
            return new byte[] { upperNibbleAsAscii, lowerNibbleAsAscii };
        }

        private static char nibbleToAscii(byte b)
        {            
            switch (b)
            {
                case 0x00: return '0';
                case 0x01: return '1';
                case 0x02: return '2';
                case 0x03: return '3';
                case 0x04: return '4';
                case 0x05: return '5';
                case 0x06: return '6';
                case 0x07: return '7';
                case 0x08: return '8';
                case 0x09: return '9';
                case 0x0A: return 'A';
                case 0x0B: return 'B';
                case 0x0C: return 'C';
                case 0x0D: return 'D';
                case 0x0E: return 'E';
                case 0x0F: return 'F';
                default:
                    throw new ArgumentOutOfRangeException("Unknown Nibble");
            }
        }
    }   
}

【讨论】:

  • 我应该添加来自设置为 Telnet 或 TCP 服务器模式的 Planet ICS-100 的 IP/端口组合。这使得 IT-100 在我的网络上可用,非常方便。如果您使用的是实际的串行端口,您的代码会略有不同。
猜你喜欢
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-30
  • 1970-01-01
相关资源
最近更新 更多