Отправка и получение из .NET на последовательное устройство, такое как VT 100

У меня есть последовательное устройство, которое предназначено для приема и ответа на команды от терминала типа VT100. Я могу использовать любое количество «эмуляторов терминала» для работы с этим устройством. Но то, что я ХОЧУ сделать, это отправить серию команд из приложения .NET Windows и получить ответы обратно в том же приложении, чтобы я мог управлять графическим интерфейсом, который будет «простым от грязи» для операторов. Чего я не хочу, так это еще одного эмулятора терминала. Похоже, что с помощью «System.IO.Serial.SerialPort» я могу открыть соединение, отправить сообщение, назначить делегата для получения сообщения, фактически получить сообщение... но сообщение, которое я отправляю (команда), не является интерпретируется так, как я ожидаю (когда я проверяю состояние устройства с помощью эмулятора терминала, состояние не соответствует команде, отправленной через .Net), и сообщение, которое я получаю в ответ, не в формате, который я могу расшифровать.

Я считаю, что мне нужно правильно закодировать команду и правильно декодировать ответ... но я не могу найти документацию, которая четко объясняет, как это сделать.

(Я работаю на С#, но буду признателен за любой пример .Net)

Код, с которым я работаю для создания прототипа:

using System;
using System.IO.Ports;
using System.Text;

namespace busmanager
{
    public class buslink
    {
        SerialPort _serialPort;
        Boolean _echo;
        Delegate _receiver;

        //Defaut Ctor:
        public buslink(Delegate Receiver)
        {
            String[] SerialPorts = System.IO.Ports.SerialPort.GetPortNames();
            if (SerialPort.GetPortNames().Length > 0)
            {
                SetChannel(PortDefinitions.GetDefaults(SerialPort.GetPortNames()[0]), Receiver);
            }
            else
            {
                throw new Exception("Unable to connect to serial port");
            }
        }

        //Custom Ctor: for externally defined PortDefinitions
        public buslink(PortDefinitions PortDefinitions, Delegate Receiver)
        {
            SetChannel(PortDefinitions, Receiver);
        }

        private void SetChannel(PortDefinitions PortDefinitions, Delegate Receiver)
        {
            _serialPort = new SerialPort()
            {
                PortName = PortDefinitions.PortName,
                //BaudRate = PortDefinitions.BaudRate,
                Parity = PortDefinitions.Parity,
                StopBits = PortDefinitions.StopBits,
                DataBits = PortDefinitions.DataBits,
                Handshake = PortDefinitions.Handshake,
                ReadTimeout = PortDefinitions.ReadTimeout,
                WriteTimeout = PortDefinitions.WriteTimeout,
                NewLine = "\n",
                Encoding = System.Text.Encoding.ASCII,
                DtrEnable = true,


            };
            _echo = PortDefinitions.Echo;
            _serialPort.DataReceived += new SerialDataReceivedEventHandler(_serialPort_DataReceived);
            _serialPort.Open();
            _receiver = Receiver;

        }

        void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] c = new byte[1000];
           int x = _serialPort.Read(c,0,1000);
            string d = c.ToString();

            _receiver.DynamicInvoke(_serialPort.ReadExisting());
        }

        public string Send(string Cmd)
        {
            Cmd = Cmd.ToUpper();
            byte[] sendBytes = Encoding.ASCII.GetBytes(Cmd);
            try
            {
                if (ValidateCmd(Cmd))
                {
                    _serialPort.WriteLine(Cmd);
                    if (_echo)
                    {
                        return "ECHO: " + Cmd;
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return string.Empty;

        }

        private bool ValidateCmd(string Cmd)
        {
            return true;
        }



        public void Dispose()
        {
            _serialPort.Close();
            _serialPort.Dispose();
        }
    }

    public struct PortDefinitions
    {
        public string PortName { get; set; }
        public int BaudRate { get; set; }
        public Parity Parity { get; set; }
        public StopBits StopBits { get; set; }
        public int DataBits { get; set; }
        public Handshake Handshake { get; set; }
        public int ReadTimeout { get; set; }
        public int WriteTimeout { get; set; }
        public bool Echo { get; set; }

        public static PortDefinitions GetDefaults(string PortName)
        {
            return new PortDefinitions()
                                        {
                                            PortName = PortName.ToUpper(),
                                            BaudRate = 9600,
                                            Parity = Parity.None,
                                            StopBits = StopBits.One,
                                            DataBits = 8,
                                            Handshake = Handshake.None,
                                            ReadTimeout = 1000,
                                            WriteTimeout = 1000,
                                            Echo = true
                                        };
        }


    }


}

Устройство является проприетарным, но оно принимает следующие команды: InX OutY (где X и Y — порты на устройстве, и создается соединение между входным и выходным портами) Status All (показывает состояние всех входов


person Cos Callis    schedule 25.03.2014    source источник
comment
Какой код вы используете для этого? Пожалуйста, опубликуйте его, а также любую имеющуюся у вас информацию об устройстве, к которому вы подключаетесь. То есть скорости передачи, биты данных, стоповые биты и т. д.   -  person Chris Ballard    schedule 25.03.2014
comment
Звучит так, как будто вы разговариваете с устройством, которое ожидает общения с VT100, поэтому вы пишете код, который, по сути, притворяется VT100, верно? Вы должны показать нам код, который у вас есть, вместе с фактическими байтами, которые отправлены/получены, и что, по вашему мнению, они должны означать.   -  person Gabe    schedule 25.03.2014
comment
@Gabe, правильно, я пытаюсь создать приложение, которое будет «эмулировать» VT 100 на сервере (с ограниченным набором допустимых команд) и простым пользовательским интерфейсом для пользователей ...   -  person Cos Callis    schedule 26.03.2014
comment
+1 за упоминание VT100   -  person John Saunders    schedule 26.03.2014
comment
Вам нужно опубликовать, какие байты вы отправляете и что получаете.   -  person Gabe    schedule 26.03.2014
comment
@Gabe, на данный момент ничего не работает. Я пробовал разные значения X/Y из приведенного выше примера, я пробовал разные варианты, но _serial.WriteLine(Cmd), где Cmd — это строка «допустимых команд», таких как In 1 Out1 (допустимые значения 0- F для каждого X и Y), а также Статус Все. Они работают из эмулятора терминала, но не в коде .Net, поэтому я подозреваю, что мне нужно отформатировать их по-другому, возможно, с какой-то оболочкой, чтобы сообщить устройству, что это команда, которую я пытался добавить /n и /r /n, так как вы поправили меня на EOL, но все равно команда не влияет на устройство.   -  person Cos Callis    schedule 26.03.2014
comment
Измените его, чтобы использовать Write вместо WriteLine, и вручную добавьте \r\n для новых строк, а затем опубликуйте фактические байты (в десятичном или шестнадцатеричном формате), отправленные и полученные.   -  person Gabe    schedule 26.03.2014


Ответы (1)


У вас неправильно установлено определение новой строки. У вас есть NewLine = "/N", но вам почти наверняка нужно, чтобы он был "\r\n" или "\n".

person Gabe    schedule 25.03.2014
comment
Спасибо ... Я ценю исправление в этом вопросе, но, похоже, оно не решает мою проблему. - person Cos Callis; 26.03.2014
comment
@CosCallis: Какие значения не сработали? Я знаю /N, но что еще? - person Gabe; 26.03.2014
comment
Спасибо за вашу попытку помочь в этом. Обнаружено, что проблема заключалась не в наборе команд, а в скорости отправки команд. Устройство не могло справиться с потоком. - person Cos Callis; 03.04.2014