Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
5 / 5 / 3
Регистрация: 18.10.2011
Сообщений: 156

Как автоматически определить 3 различных устройства, подключаемых к трём раздичным COM портам

30.06.2015, 17:06. Показов 1376. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Как автоматически определить 3 различных устройства, подключаемых к трём разным COM портам, работающим на разной скорости.
На форме создал три SerialPort.
У каждого своя скорость: 115200 (подключаю плату с ПЛИС), 9600 (мультиметр) и 2400 (DC источник).

Вот пример как делаю для одного из COM портов (для остальных аналогично):
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
private void port2_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            port2.Read(InputData2, 0, 1);     // считываем в массив
            SetText2(InputData2);
        }
 
        private void SetText2(byte[] bt_in)
        {
 
            if (this.txtIn.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText2);
                this.Invoke(d, new object[] { bt_in });
            }
            else this.txtIn.Text += Convert.ToString(bt_in[0]) + "\t";
            strdata2 = this.txtIn.Text;
        }
//-----------------------------------------------------------------------------------------------------------------------------//
//----------------------------------------------------- Нажатие на checkBox1 --------------------------------------------------//
//-----------------------------------------------------------------------------------------------------------------------------//
        private void checkBox1_CheckedChanged(object sender, EventArgs e)   // подключение port1 - плата MUX
        {
            string[] ports = SerialPort.GetPortNames();
            if (checkBox1.Checked == true)
            {
                checkBox1.Text = "Disconnect plate";
                for (int i = 0; i < ports.Length; i++)
                {
                    Array.Clear(InputData1, 0, 1);    // очищаем масив
                    if (i >= ports.Length)
                    {
                        break;
                    }
                    if (port1.IsOpen)
                    {
                        port1.Close();
                    }
                    if ((ports[i] != port2.PortName) && (ports[i] != port3.PortName))
                    {
                        port1.PortName = ports[i];
                        try
                        {
                            port1.Open();
                            if (port1.IsOpen)
                            {
                                bt[0] = 51;                         // "00110011"
                                port1.Write(bt, 0, 1);
                                Thread.Sleep(50);                   // ожидание
                                if (port1.IsOpen)
                                    if ((InputData1[0] == Convert.ToInt32("00110011", 2)) || (InputData1[0] == Convert.ToInt32("01101010", 2)))
                                    {
                                        label1.Text = port1.PortName; // +": 115200,8N1";
                                        label1.Visible = true;
                                        tabControl1.Enabled = true;
                                        break;
                                    }
                            }
                        }
                        catch (Exception X)
                        {
                        }
                    }
                }
                if ((label1.Visible == false) || (label1.Text == "Not found"))
                {
                    checkBox1.Checked = false;
                    checkBox1.Text = "Connect to plate";
                    label1.Text = "Not found";
                    label1.Visible = true;
                }
            }
            else
            {
                if (port1.IsOpen)
                    port1.Close();
                port1.PortName = "COM";
                label1.Text = "COM";
                label1.Visible = false;
                checkBox1.Text = "Connect to plate";
                tabControl1.Enabled = false;
            }
        }
Периодически происходит зависание программы, в случае, если port для источника с BaudRate 2400 видит плату с ПЛИС 115200.
Помогите. плииз, а то в отпук не отпустят вовремя
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.06.2015, 17:06
Ответы с готовыми решениями:

Реализация автоматически подключаемых расширений spring
Добрый день. Мне нужно как-то реализовать расширения, которые автоматически искались и подключались бы к моему приложению (то есть...

Как заставить автоматически запускаться устройства в диспетчере устройств?
как заставить автоматически запускаться устройства в диспетчере устройств в Windows 10? Вроде как есть такая утилиты devcon.exe, но я не...

Автоматически открываются ссылки на сайт различных казино
Всем доброго вечера. Ничего необычного не делал. Сидел в интернете и внезапно стали открываться различные сайты с казино. Преимущественно...

9
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
30.06.2015, 17:11
Цитата Сообщение от Shakesbeer Посмотреть сообщение
3 различных устройства, подключаемых к трём разным COM портам
По каким параметрам определяется каждое из устройств? По формату ответа?
Цитата Сообщение от Shakesbeer Посмотреть сообщение
Периодически происходит зависание программы
Используйте многопоточность.
0
5 / 5 / 3
Регистрация: 18.10.2011
Сообщений: 156
30.06.2015, 17:17  [ТС]
По каким параметрам определяется каждое из устройств? По формату ответа?
Да, в зависимости от ответа.
Используйте многопоточность.
Как бы в потоках не запутаться. Если можете какой-нибудь пример показать с максимальным количеством пояснений
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
30.06.2015, 18:23
Лучший ответ Сообщение было отмечено Shakesbeer как решение

Решение

Цитата Сообщение от Shakesbeer Посмотреть сообщение
можете какой-нибудь пример показать
Пример-могу, в процессе вечера. На счет много комментариев - не могу обещать))

Добавлено через 15 минут
Shakesbeer, и приведите пример ответа для каждого из устройств.

Добавлено через 42 минуты
Shakesbeer, вот приблизительный вариант, поскольку я не знаю точно вашу задачу.
В данном виде создается один слушатель порта, который десять раз передает в порт данные и ожидает получения массива байт определенного размера. Если такой размер в буфере есть - он еого читает, и потом сравнивает с заданным шаблоном.
Естественно, таких объектов-слушателей можно создать и два, и три.
Класс-слушатель.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO.Ports;
using System.ComponentModel;
 
namespace PortListner_Demo {
    class PortListner : BackgroundWorker {
        private SerialPort port = null;
        private byte[] answerPattern = null;
        private byte[] askToDevice = null;
 
        public PortListner(string name, int baud, byte[] answer, byte[] ask ) {
            this.WorkerReportsProgress = true;
            this.WorkerSupportsCancellation = true;
 
            port = new SerialPort(name, baud);
            answerPattern = answer;
            askToDevice = ask;
        }
        protected override void OnDoWork(DoWorkEventArgs e) {
            List<byte> temp = new List<byte>();
            using (port) {
                port.Open();
                ReadBlock(askToDevice, temp, answerPattern.Length);
                if (string.Join("", answerPattern.Select(b => b.ToString())).CompareTo(
                    string.Join("", temp.Select(b => b.ToString()))) == 0) {
                    e.Result = "Device answerd correct!";
                }
                else {
                    e.Result = "Wrong answer from device!";
                }                              
            }
        }
        void ReadBlock(byte[] dataToWrite, List<byte> dataForRead, int readSize) {
            for (int i = 0; i < 10; i++) {
                port.DiscardInBuffer();
                port.Write(dataToWrite, 0, dataToWrite.Length);
                for (int j = 0; j < 10; j++) {
                    if (port.BytesToRead == readSize) {
                        byte[] data = new byte[readSize];
                        port.Read(data, 0, readSize);
                        dataForRead.AddRange(data);
                        return;
                    }
                    Thread.Sleep(100);
                }
            }
            throw new TimeoutException("Device not answers!");
        }
    }
}
Пример использования.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
using System.ComponentModel;
 
namespace PortListner_Demo {
    class Program {
        static void Main(string[] args) {
            PortListner type1Listner = new PortListner("COM1",11520, new byte[]{ 0x10, 0x01, 0xad }, new byte[]{ 0x10, 0xad, 0xad});
            type1Listner.RunWorkerCompleted += new RunWorkerCompletedEventHandler(type1Listner_RunWorkerCompleted);
            type1Listner.RunWorkerAsync();
            Console.ReadLine();
        }
 
        static void type1Listner_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) {
            if (e.Error != null) {
                Console.WriteLine(e.Error.Message);
                return;
            }
            Console.WriteLine(e.Result.ToString());
        }
    }
}
1
5 / 5 / 3
Регистрация: 18.10.2011
Сообщений: 156
01.07.2015, 13:03  [ТС]
Я так понимаю, создавая type1Listner, мы создаем новый BackgroundWorker поток обработки данных с COM порта. И можем добавлять таких сколько угодно.
Можете приписать объяснения к функциям. Потому что не все здесь понятно.
Функция type1Listner_RunWorkerCompleted возвращает результат.
И вызов осуществляется написанием в любом месте тела программы:
C#
1
2
3
PortListner type1Listner = new PortListner("COM1",11520, new byte[]{ 0x10, 0x01, 0xad }, new byte[]{ 0x10, 0xad, 0xad});
            type1Listner.RunWorkerCompleted += new RunWorkerCompletedEventHandler(type1Listner_RunWorkerCompleted);
            type1Listner.RunWorkerAsync();
Добавлено через 25 минут
И как можно связать этот класс с формой? Как к нему обращаться?

Добавлено через 40 минут
Как вместо e можно возвращать принятые данные?
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
01.07.2015, 13:07
Цитата Сообщение от Shakesbeer Посмотреть сообщение
создавая type1Listner, мы создаем новый BackgroundWorker
Создаем наследника от него, имея все преимущества данного класса.
Цитата Сообщение от Shakesbeer Посмотреть сообщение
И можем добавлять таких сколько угодно.
Именно так.
Цитата Сообщение от Shakesbeer Посмотреть сообщение
Функция type1Listner_RunWorkerCompleted возвращает результат.
Это обработчик завершения асинхронной операции.
Цитата Сообщение от Shakesbeer Посмотреть сообщение
как можно связать этот класс с формой? Как к нему обращаться?
Точно так же как и в консоли. Создали объект, подписались на его события и запустили поток.
Цитата Сообщение от Shakesbeer Посмотреть сообщение
Как вместо e можно возвращать принятые данные?
У аргумента события RunWorkerCompletedEevntArgs e есть свойство - e.Result. Вот туда и ставьте что необходимо.
Только имейте ввиду, это свойство типа System.Object, то есть, передать можно все что угодно, но на стороне вызывающего кода необходимо явное приведение типов.
0
5 / 5 / 3
Регистрация: 18.10.2011
Сообщений: 156
01.07.2015, 15:41  [ТС]
Но это использование только одного потока.
Получается для использования трёх COM портов с многопоточностью нужно добавлять ещё пару классов:
C#
1
2
3
4
class PortListner : BackgroundWorker {
        private SerialPort port = null;
        private byte[] answerPattern = null;
        private byte[] askToDevice = null;
Добавлено через 17 минут
И на сколько я понял после получения e.Result поток завершается и можно спокойно создавать новый, не боясь пересения со старым портом.
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
01.07.2015, 15:57
Цитата Сообщение от Shakesbeer Посмотреть сообщение
для использования трёх COM портов с многопоточностью нужно добавлять ещё пару классов
Естественно.
Цитата Сообщение от Shakesbeer Посмотреть сообщение
после получения e.Result поток завершается
Ну если просто - то да, он (то есть ваше использование этого потока) завершается.
А по сути, BGW использует ThreadPool (пул потоков), и поэтому этот поток будет использован CLR и далее.
0
5 / 5 / 3
Регистрация: 18.10.2011
Сообщений: 156
01.07.2015, 16:27  [ТС]
Ну если просто - то да, он (то есть ваше использование этого потока) завершается.
А по сути, BGW использует ThreadPool (пул потоков), и поэтому этот поток будет использован CLR и далее.
Вот тут интересно не будет ли излишнего накопления рабочих потоков, если буду постоянно создавать их после вывода e.Result?
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
01.07.2015, 17:53
Цитата Сообщение от Shakesbeer Посмотреть сообщение
не будет ли излишнего накопления рабочих потоков
Не будет. Как я сказал выше, BGW использует пул имеющихся потоков CLR.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.07.2015, 17:53
Помогаю со студенческими работами здесь

Сколькими способами можно распределить по трем пакетам (пакеты не различать) 8 различных книг?
Сколькими способами можно распределить по трем пакетам (пакеты не различать) 8 различных книг? Сколькими способами можно послать 8...

Как определить тип устройства
Возможно ли определить устройство на стороне сервера? То есть через php.

Задание: Определить сколько различных сигналов могло быть подано m флажками различных цветов
Задание: Определить сколько различных сигналов могло быть подано m флажками различных цветов. Отличие сигналов заколючается в порядке...

[COBOL] Как автоматически определить отступ до начального уровня?
Здравствуйте. Использую парсер CB2XML (CopyBook to XML) для конвертации COBOL CopyBook в XML. Импортирую список файлов за раз. ...

Как определить модель мобильного устройства на сайте?
Сидел в интернете и наткнулся на вирусный сайт вроде &quot;Ваш телефон ZTE Blade GF3&lt;угадал мою модель&gt; заражен вирусом, это приведет к...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru