Отправка и чтение данных по COM-порту

273
23 ноября 2017, 00:25

Здравствуйте, уважаемые программисты!

Обращаюсь к вам за помощью, подскажите пожалуйста по следующему вопросу: К ПК подключено устройство по последовательному СOM-порту, используется протокол RS-232. Задача состоит в том, чтобы отправлять команды устройству и получать ответ.

Пример кода №1:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Threading;
    namespace PortDataReceived
{
    class Program
    {
        static void Main(string[] args)
        {
            SerialPort mySerialPort = new SerialPort("COM1");
            string KeyWord = "exit";
            string EnterWord = "";
            mySerialPort.BaudRate = 9600;
            mySerialPort.Parity = Parity.None;
            mySerialPort.StopBits = StopBits.One;
            mySerialPort.DataBits = 8;
            mySerialPort.Handshake = Handshake.None;
            mySerialPort.RtsEnable = true;
            mySerialPort.DataReceived += new SerialDataReceivedEventHandler 
            (DataReceivedHandler);
            mySerialPort.Open();
            while(true)
                {
                Console.Write(">>");
                EnterWord = Console.ReadLine();
                if (EnterWord == KeyWord)
                {
                    Console.WriteLine("Вы вышли из программы");
                    break;
                }
                else
                {
                    Console.WriteLine("Отправили комманду на COM-порт");
                    mySerialPort.WriteLine(EnterWord);
                }
            }
            Console.ReadKey();
            mySerialPort.Close();
        }
        private static void DataReceivedHandler(
                        object sender,
                        SerialDataReceivedEventArgs e)                                          
        {
            SerialPort sp = (SerialPort)sender;
            string indata = sp.ReadExisting();
            //string indata = sp.ReadLine();
            if (indata == null)
            {
                Console.WriteLine("Нет данных");
            }
            else
            {
                Thread.Sleep(2000);
                Console.WriteLine("Data Received:");
                Thread.Sleep(2000);
                Console.WriteLine(indata);
            }
        }
    }
}

Вывод №1: Комментарий :

1) Нужно, чтобы выводилась одна строка целиком - "Service connection opened (COM0)" 2) Нужно, чтобы выводилась одна строка целиком - "10 значений в одной строке"

В цикле программного кода добавлен ввод команды (на скрине выглядит как ">>". Как сделать так, чтобы ввод команды был доступен только тогда, когда будет полностью получет ответ на запрос?

Пример кода №2( отличие - вместо строки string indata = sp.ReadExisting(); используется строка string indata = sp.ReadLine(); ) :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Threading;
    namespace PortDataReceived
{
    class Program
    {
        static void Main(string[] args)
        {
            SerialPort mySerialPort = new SerialPort("COM1");
            string KeyWord = "exit";
            string EnterWord = "";
            mySerialPort.BaudRate = 9600;
            mySerialPort.Parity = Parity.None;
            mySerialPort.StopBits = StopBits.One;
            mySerialPort.DataBits = 8;
            mySerialPort.Handshake = Handshake.None;
            mySerialPort.RtsEnable = true;
            mySerialPort.DataReceived += new SerialDataReceivedEventHandler 
           (DataReceivedHandler);
            mySerialPort.Open();
            while(true)
                {
                Console.Write(">>");
                EnterWord = Console.ReadLine();
                if (EnterWord == KeyWord)
                {
                    Console.WriteLine("Вы вышли из программы");
                    break;
                }
                else
                {
                    Console.WriteLine("Отправили комманду на COM-порт");
                    mySerialPort.WriteLine(EnterWord);
                }
            }
            Console.ReadKey();
            mySerialPort.Close();
        }
        private static void DataReceivedHandler(
                        object sender,
                        SerialDataReceivedEventArgs e)                                          
        {
            SerialPort sp = (SerialPort)sender;
            //string indata = sp.ReadExisting();
            string indata = sp.ReadLine();
            if (indata == null)
            {
                Console.WriteLine("Нет данных");
            }
            else
            {
                Thread.Sleep(2000);
                Console.WriteLine("Data Received:");
                Thread.Sleep(2000);
                Console.WriteLine(indata);
            }
        }
    }
}

Вывод №2: Комментарий:

1) После сообщения - "Data Received", выводится пустая строка. После ввода команды - "open" на скрине из проги("Advanced Serial Port Monitor") видно, что на месте пропускa написано - " [len=1]". Видимо это сообщение не отображается. Как сделать так, чтобы оно отображалось? Либо , чтобы это сообщение вообще не выводилось? 2) Ответ на запрос - "paramset" каждый параметр выводится отдельно. Вывод ответа принял такой вид, потому что метод чтения данных изменился с "ReadExisting" на "ReadLine". Пример №2 мне нравится больше, потому что ответы на запросы - "open" и "rep test" выводятся должным образом. Только символ ввода запроса - ">>" портит вид вывода. Тут нужно сделать также, чтобы ввод нового запроса был доступен только после конца ответа. И сделать ответ на запрос - "paramset" как в выводе №1(чтобы все поля выводились сразу, а не по очереди отделенными друга от друга сообщением - "Data Received".

Вывод программы "Advanced Serial Port Monitor": Комментарий:

В идеале, в своем коде, я хочу сделать вывод как в этой проге,

только без сообщений типа -"[len=1]". Только значения параметров.

Как быстрее изменить код и не делать его сложным? Что лучше добавить:

1) свой буфер в виде массива и сделать вывод побитово,используя методы "BytesToRead","ReadByte" ?

2) проверка начала и конца сообщения ?

Постарался описать задачу как можно подробнее, чтобы вы поняли, что мне нужно в точности. Заранее благодарю всех, кто постарается помочь.

READ ALSO
Проверка IAP подписки в Юнити

Проверка IAP подписки в Юнити

Как проверить если юзер купил подписку и дать доступ к игре, игра на iOS, как получить информацию о статусе юзера (подписан или нет) или срок...

275
Приложение требует разрешения Unity3d

Приложение требует разрешения Unity3d

Игра созданная на Unity3d при запуске требует 2 разрешения:

260
Coded UI клик по координатам wpf c#

Coded UI клик по координатам wpf c#

В соседнем топике мне подсказали, что через Coded UI можно спокойно кликать по координатам в диспетчере задач и тпЕсли я правильно понял, Coded UI - этж...

300
gulp-postcss: набор опций (плагинов) в зависимости от условия

gulp-postcss: набор опций (плагинов) в зависимости от условия

Я ознакомился со списоком так называемых оптимизаций cssnano (list of cssnano optimizations): он включает в себя autoprefixer (не по умолчанию), cssnano-util-raw-cache и другие...

323