COM port...
От: Kosia1  
Дата: 25.02.10 16:43
Оценка:
Сегодня столкнулся с очередной проблемой...
Пробороздив просторы интернета, проронил слезу, но не принял поражение!
дело в следующем:
мне нужно нечто "ping" для com порта...
т.е. у нас большая фабрика и расстояние от компьютера до устройство большое... точнее кабель проходит по коробам на потолок и оттуда уже спускается к устройству.
Так вот, нужно написать программулинку, которая бы простукивала кабель как тестер, есть устройство "на том конце провода" или нет. а в идеале, что бы ещё и говорила, что на том конце такое-то устройство.
вот...
Сам себе мало представляю как это реализовать, по этому и обращаюсь к Вам, дорогие форумчане...
ТО что нужно юзать "System.IO.Ports;" это я уже узнал
а вот что дальше...
Прочел методы, но никак не могу представить себе логику событий.
Вот...
Подскажите, кто знает...

Заранее спасибо!
Re: COM port...
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 25.02.10 16:52
Оценка:
Здравствуйте, Kosia1, Вы писали:

K>Сегодня столкнулся с очередной проблемой...

K>Пробороздив просторы интернета, проронил слезу, но не принял поражение!
K>дело в следующем:
K>мне нужно нечто "ping" для com порта...
K>т.е. у нас большая фабрика и расстояние от компьютера до устройство большое... точнее кабель проходит по коробам на потолок и оттуда уже спускается к устройству.
K>Так вот, нужно написать программулинку, которая бы простукивала кабель как тестер, есть устройство "на том конце провода" или нет. а в идеале, что бы ещё и говорила, что на том конце такое-то устройство.
K>вот...
K>Сам себе мало представляю как это реализовать, по этому и обращаюсь к Вам, дорогие форумчане...
K>ТО что нужно юзать "System.IO.Ports;" это я уже узнал
K>а вот что дальше...
K>Прочел методы, но никак не могу представить себе логику событий.
K>Вот...
K>Подскажите, кто знает...

Я правильно понимаю, что имеется ввиду возможность написание софта как для ПК, так и для тех устройств, которые торчат с другой стороны СОМ-порта?
Потому, что если нет, то задача не решаемая.
Если да, то готов помочь
Re[2]: COM port...
От: Kosia1  
Дата: 25.02.10 16:58
Оценка:
Здравствуйте, SergeyT., Вы писали:

ST>Я правильно понимаю, что имеется ввиду возможность написание софта как для ПК, так и для тех устройств, которые торчат с другой стороны СОМ-порта?

ST>Потому, что если нет, то задача не решаемая.
ST>Если да, то готов помочь

А если я правильно понимаю Вас, то да!
Ну суть в том, что бы не тестером кабель тестировать, на повреждения, а запускаешь программу, и она в окошке тебе показывает, что этот ком порт свободен, а вот этот, занят вот таким устройство.
Спасибо что откликнулись
Re[3]: COM port...
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 25.02.10 19:28
Оценка:
Здравствуйте, Kosia1, Вы писали:

<skiped/>

Итак, мы имеем:
— несколько устройств, собственной разработки, с которыми можно как-то общаться по RS232 (хотя скорее всего по RS485, т.к. он более дальнобойный, в любом случае есть переходники RS485-RS232, поэтому можно считать, что общение с устройствами идет по RS232);
— ПК с программным обеспечением для диагностики и определения оборудования.

Теперь можно подумать о протоколе взаимодействия между устройствами и ПК.
Первое, что нужно сделать, это определить формат пакетов для этого взаимодействия.
Вот несколько набросков:
|---------------------------|
|Begin|DataLength| Data |End|
| 1b | 1 b |1..255| 1b|
где
Begin: идентификатор начала пакета (например, 0x7D)
DataLength: длина блока данных (если максимальная длина блока данных в 255 байт достаточна (судя по задаче, вполне), то 1 байта для длины блока данных также будет достаточно. Если же предполагается передача бОльших объемов данных, то стоит использовать 2 байта для длины блока данных).
Data: поле данных (обсудим ниже).
End: идентификатор конца пакета (например, 0x7E)
В случае применения однобайтовых идентификаторов начала и конца пакета необходимо обеспечить отсутствие этих байт в середине пакета, например, можно заменять все 0x7D внутри пакета на два байта: 0x7F 0x01, 0x7E на 0x7F 0x02, а 0x7F на 0x03, для подробностей стоит почитать что-либо о Escape-последовательностях).

Другой альтернативой пакетного приема (помимо применения идентификаторов начала и конца пакета) может служить тайм-аут. Например, при скорости 115200 время между приемами двух отдельных байт будет составлять примерно 0.1 мс, поэтому, если время после приема последнего принятого байта будет превышать 20мс, можно считать, что мы приняли пакет целиком.

Дополнение:
Кроме этих полей, можно добавить версию протокола (для возможности последующих расширений), контрольную сумму (CRC8 или CRC16, в зависимости от мощности процессоров на оборудовании)), идентификатор пакета (для упрощения процесса подтверждений), кроме того, можно посмотреть на множество существующих сетевых протоколов и что-либо почерпнуть у них.

Не зависимо от формата пакета, можно считать, что мы умеем доставлять между оборудованием и ПК блок данных в целости и сохранности, поэтому можно перейти к формату этого блока данных.

Итак, если все, что нам нужно — это определить наличие оборудования и определить его тип, то можно придумать нечто подобное.

Пакет Ping (ПК -> Оборудование)
Формат блока данных
|----|
|PING|
|2-4b|
В качестве формата этой команды можно взять и положить ASCII-представление строки PING в бинарном виде, либо придумать коды команд, например, передавать пару байт 0x01 0x02 (в целом не важно, какая будет последовательность, главное, чтобы все знали о ней).

Пакет Pong (Оборудование -> ПК)
(отправляется оборудованием только в ответ на команду Ping)
|---------|
|PONG|Type|
|2-4b| 1b |
Здесь, опять же, в качестве поля Pong может применяться, что угодно — тоже самое ASCII-шное представление строки PONG или заданное сочетание байт, таких как 0x01 0x02.
Поле Type может содержать перечисление с типами оборудования
0x01: оборудование 1
0x02: оборудование 2
и т.д.

Теперь по логике работы.
В программе на C# задается перечень СОМ-портов, затем программа открывает каждый из них на предопределенной скорости (и с предопределенными другими параметрами). Затем, с ПК в каждый из СОМ-портов через определенные интервалы времени начинают посылаться пакеты PING и ожидаться ответы (PONG). Если за определенное время (и количество посылок PING), оборудование не отвечает — говорим, там нет такого оборудования. Если отвечает — пишем, какое оборудование там расположено.

В дальнейшем не составляет труда добавить туда не только определение типов оборудования, но и другую функциональность, включая передачу перечня неисправностей от оборудования, удаленное конфигурирование оборудования (передача с ПК нужных данных). В общем, дальше все определяется вашими потребностями и вашей фантазией.
Re[4]: COM port...
От: Kosia1  
Дата: 26.02.10 11:00
Оценка:
Здравствуйте, SergeyT., Вы писали:
ST>Итак, мы имеем:
ST>В дальнейшем не составляет труда добавить туда не только определение типов оборудования, но и другую функциональность, включая передачу перечня неисправностей от оборудования, удаленное конфигурирование оборудования (передача с ПК нужных данных). В общем, дальше все определяется вашими потребностями и вашей фантазией.

Это очень полезная информация! Спасибо большое.
Посылать информацию по порту я сумел, а вот получить, пока никак...
Re[2]: COM port...
От: Uzzy Россия  
Дата: 26.02.10 11:08
Оценка:
Здравствуйте, SergeyT., Вы писали:

ST>Я правильно понимаю, что имеется ввиду возможность написание софта как для ПК, так и для тех устройств, которые торчат с другой стороны СОМ-порта?

ST>Потому, что если нет, то задача не решаемая.
ST>Если да, то готов помочь

Если число типов возможных удаленных устройств не так велико, и известны их протоколы, то задача очень даже решаема. (тем более что, протокол MODBUS стараются все поддерживать)
Re[5]: COM port...
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 26.02.10 11:36
Оценка:
Здравствуйте, Kosia1, Вы писали:

K>Это очень полезная информация! Спасибо большое.

K>Посылать информацию по порту я сумел, а вот получить, пока никак...

Для тестирования можно использовать нуль-модемный кабель (если есть два СОМ-порта, если второго СОМ-порта нет, то можно взять переходник USB 2 COM). Затем с одной стороны запустить какую-то программу типа COM Port Toolkit и передавать с ее помощью данные, а с другой стороны — вашу программу, которая бы просто выводила полученные данные на экран.
Вначале для тестовых целей проще всего передавать и принимать данные с помощью COM Port Toolkit, чтобы удостовериться, что кабель нормальный и параметры на обоих компьютерах настроены правильно.

Вот готовая оболочка, которую я когда-то использовал для работы с СОМ-портами (если нужно, то есть классы, выкусывающие пакеты по признаку начала и конца, а также по заданному тайм-ауту):

    /// <summary>
    /// Класс работы с последовательным портом
    /// </summary>
    public class SerialPort : IDisposable
    {
        //--------------------------------------------------------------------------
        //Construction, Destruction
        //--------------------------------------------------------------------------
        #region Construction, Destruction
        /// <summary>
        /// Оболочка для работы с СОМ-портом
        /// </summary>
        /// <param name="comNum">Номер СОМ-порта</param>
        /// <param name="baudRate">Скорость</param>
        public SerialPort(byte comNum, int baudRate)
        {
            this.comNum = comNum;
            serialPort = new System.IO.Ports.SerialPort("COM" + comNum.ToString(), baudRate);
            serialPort.Open();
            thread = new System.Threading.Thread(ThreadFn);
            thread.Start();
        }
        
        /// <summary>
        /// Очистка ресурсов
        /// </summary>
        public void Dispose()
        {
            DisposeImpl(true);
        }
        
        /// <summary>
        /// Finalizer
        /// </summary>
        ~SerialPort()
        {
            DisposeImpl(false);
        }

        private void DisposeImpl(bool manualDispose)
        {
            if (manualDispose)
            {
                if (thread != null)
                    thread.Abort();
                if (serialPort != null)
                    serialPort.Dispose();
            }
        }
        #endregion Construction, Destruction

        //--------------------------------------------------------------------------
        //Public Interface
        //--------------------------------------------------------------------------
        #region Public Interface
        /// <summary>
        /// Отправить данные
        /// </summary>
        /// <param name="data">Массив данных</param>
        /// <exception cref="Exception">Генерируется, если при работе с последовательным портом
        /// возникнет исключение</exception>
        public void SendData(Byte[] data)
        {
            serialPort.Write(data, 0, data.Length);
        }
        
        /// <summary>
        /// Текущий номер СОМ-порта
        /// </summary>
        public Byte ComNum
        {
            get { return comNum; }
            set
            {
                if (comNum != value)
                {
                    comNum = value;
                    serialPort.Close();
                    serialPort.PortName = "COM" + value.ToString();
                }
            }
        }

        /// <summary>
        /// Скорость передачи данных
        /// </summary>
        public int BaudRate
        {
            get { return serialPort.BaudRate; }
            set { serialPort.BaudRate = value; }
        }
        /// <summary>
        /// Состояние линии Dtr
        /// </summary>
        public bool DtrEnable
        {
            get { return serialPort.DtrEnable; }
            set { serialPort.DtrEnable = value; }
        }
        /// <summary>
        /// Состояние линии Rts
        /// </summary>
        public bool RtsEnable
        {
            get { return serialPort.RtsEnable; }
            set { serialPort.RtsEnable = value; }
        }

        /// <summary>
        /// Делегат приема байта
        /// </summary>
        /// <param name="data">Принятый байт данных</param>
        public delegate void OnByteReceived(Byte data);

        /// <summary>
        /// Событие приема байт
        /// </summary>
        public event OnByteReceived ByteReceived;
        #endregion Public Interface

        //--------------------------------------------------------------------------
        //Private Member Functions
        //--------------------------------------------------------------------------
        #region Private Member Functions
        //Обработка принятого байта
        private void OnReceiveByte(Byte data)
        {
            //Если на событие приема байт кто-то подписан, то отправляю ему байт
            if (ByteReceived != null)
                ByteReceived(data);
        }
        //Функция чтения данных в новом потоке
        private void ThreadFn(object obj)
        {
            //создаю входной буффер. Сюда будут писаться данные из последовательного порта
            Byte[] inputBuffer = new Byte[inputBufferSize];
            while (true)
            {

                try
                {
                    //получаю количество доступных байт
                    int availibleBytes = serialPort.BytesToRead;
                    if (availibleBytes > 0)
                    {
                        int bytesToRead = availibleBytes < inputBufferSize ? availibleBytes : inputBufferSize;
                        int readedBytes = serialPort.Read(inputBuffer, 0, bytesToRead);
                        for (int i = 0; i < readedBytes; i++)
                            OnReceiveByte(inputBuffer[i]);
                    }
                    System.Threading.Thread.Sleep(1);
                }
                catch (System.Threading.ThreadAbortException)
                {
                    break;
                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.Assert(false, e.Message);
                }
            }
        }
        #endregion Private Member Functions

        //--------------------------------------------------------------------------
        //Private Data Members
        //--------------------------------------------------------------------------
        #region Private Data Members
        /// <summary>
        /// Номер СОМ-порта
        /// </summary>
        private Byte comNum;
        /// <summary>
        /// Последовательный порт
        /// </summary>
        private System.IO.Ports.SerialPort serialPort;
        /// <summary>
        /// Поток. Нужен, т.к. данные читаются в новом потоке
        /// </summary>
        private System.Threading.Thread thread;
        /// <summary>
        /// Максимальный размер входного буффер
        /// </summary>
        private const int inputBufferSize = 1024;

        #endregion Private Data Members
    }//class RS232
Re[6]: COM port...
От: Kosia1  
Дата: 26.02.10 12:56
Оценка:
Здравствуйте, SergeyT., Вы писали:
ST>Для тестирования можно использовать нуль-модемный кабель (если есть два СОМ-порта, если второго СОМ-порта нет, то можно взять переходник USB 2 COM). Затем с одной стороны запустить какую-то программу типа COM Port Toolkit и передавать с ее помощью данные, а с другой стороны — вашу программу, которая бы просто выводила полученные данные на экран.


Спасибо а я так и сделал, про нуль-модем.
Соеденил, папа-папа. и программку свою запустил на двух компах и посылал и ловил данные.
Только вот пока не разобрался как сделать так, что бы он не по кнопочке (так сделал я)данные слушал, а пока запущенна программа.
Т.е. как гипер-терминал.
Он ждет, ждет, а когда данные пошли их выводит на экране.

Вам огромное спасибо!
Сейчас буду читать Ваш код!
Re[3]: COM port...
От: Аноним  
Дата: 27.02.10 09:04
Оценка:
Здравствуйте, Uzzy, Вы писали:


U>Если число типов возможных удаленных устройств не так велико, и известны их протоколы, то задача очень даже решаема. (тем более что, протокол MODBUS стараются все поддерживать)


Всё известно! и устройства и протоколы.
Но мне ведь нужно узнать в принципе, есть подключение к этому устройству или нет, и если есть, то какое это устройство!
Если есть варианты, пожалуйста помогите!
Буду ждать!
Re[4]: COM port...
От: Uzzy Россия  
Дата: 28.02.10 03:19
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Всё известно! и устройства и протоколы.

А>Но мне ведь нужно узнать в принципе, есть подключение к этому устройству или нет, и если есть, то какое это устройство!
А>Если есть варианты, пожалуйста помогите!
А>Буду ждать!

Ну тут все просто, используйте SerialPort класс для обмена байтами (можно использовать оболочку, что предложил Sergey.T). Если устройство может общаться по своему уникальному протоколу — посылайте сообщения по такому протоколу — получите ответ — значит вы уже знаете, что за устройство вам ответило. Если в ответ на посылку вываливается исключение, то вариантов несколько. Наиболее распространенные на моем веку были:
    неверно сформированая команда, в том числе и CRC,
    устройство не поддерживает протокол
    адрес устройства отличный от опрашиваемого.
Первый случай в целом исключается. Предполагается, что поиск устройства проходит на рабочей реализации протокола.
Поэтому придется перебрать все адреса. от 0 до 255 (это если один байт под адрес зарезервирован).
Если же устройство не ответило, то скорее всего надо пробовать другой протокол. И так с каждым протоколом. Учтите, что на одном проводе может висеть сеть устройств, работающих как на одном протоколе, так и на разных.
Также стоит понимать, что такой автоматический поиск займет достаточно много времени.

З.Ы. Есть риск зафлудить канал. Так что по мне, так лучше проверять, есть ли заданное устройство на том конце, "контакты" которого предварительно заданы. То есть искать не какое-то устройство на СОМ1, а, например, устройство_1 c сетевым адресом 23, работающим по протоколу MODBUS. Тогда проще ответить, есть оно там или нет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1270>>
Re[5]: COM port...
От: Mihas  
Дата: 01.03.10 10:55
Оценка:
U>З.Ы. Есть риск зафлудить канал. Так что по мне, так лучше проверять, есть ли заданное устройство на том конце, "контакты" которого предварительно заданы. То есть искать не какое-то устройство на СОМ1, а, например, устройство_1 c сетевым адресом 23, работающим по протоколу MODBUS. Тогда проще ответить, есть оно там или нет.
ИМХО, это единственное адекватное решение.
Re: COM port...
От: Mihas  
Дата: 01.03.10 11:02
Оценка:
K>мне нужно нечто "ping" для com порта...

А ты точно понимаешь о чем говоришь.

Во-первых, если прозвучало слово СОМ-порт, это еще не значит что до устройства протянут интерфейс RS-232.
Во-вторых, не известен протокол.
Во-третьих, не оговорена топография сети. Сколько в ней устройств? Является ли твой комп ведущим?

Короче, "на деревню дедушке"
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.