Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 22.10.2018
Сообщений: 2

Ошибка чтения / записи данных с COM порта

18.08.2024, 19:28. Показов 827. Ответов 2

Студворк — интернет-сервис помощи студентам
Добрый вечер! По ощущениям, прогуглил уже всё что только мог, но не смог решить проблему. Впервые вообще взаимодействую с железом, до этого занимался только высокоуровневыми штуками. Задача такая: есть плата, есть стенд для тестирования этой платы, стенд подключается через COM порт. Программа должна реализовывать некоторый алгоритм тестирования этой платы. Сейчас попробовал добавить во view кнопку, которая переключает состояние части стенда 0/1 и наоборот (вкл-выкл, проще говоря, при этом стенд щелкает и я получаю хотя бы какой-то фидбек по тому, что я делаю). Столкнулся со следующей ошибкой - failed to connect: Access to Port COM3 is denied. При этом компорт не занят вообще никакими другими ресурсами, все запускается от имени администратора и все остальные методы решения, которые я нашёл мне не помогают. Предварительно написал консольную прогу, которая не могла читать состояние, но могла его изменять. При этом выдавала либо таймаут эксшепшен, либо Access to the path 63 is denied, пофиксить так же не смог, но стенд хотя бы щелкал при вводе 0/1. Помогите мне пожалуйста. Я буду очень рад если вы объясните что я делаю не так и поможете понять как это все вообще должно работать.

консоль:

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
83
using System;
using System.IO.Ports;
using Modbus.Device;
 
namespace ModbusConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // Подключаемся к устройству
            var serialPort = new SerialPort("COM3")
            {
                BaudRate = 4800,
                Parity = Parity.Even,
                DataBits = 8,
                StopBits = StopBits.One,
                ReadTimeout = 1000
            };
 
            try
            {
                serialPort.Open();
                Console.WriteLine("Device connected");
 
                // Создаем Modbus RTU мастер
                var modbusMaster = ModbusSerialMaster.CreateRtu(serialPort);
                modbusMaster.Transport.Retries = 3;
 
                // чтение из slave 1 
                ReadSlave(modbusMaster, 2, 1300);
 
                // запись в регистр slave 1
                Console.Write("Введите значение для записи в slave 1 (регистр 1000): ");
                if (int.TryParse(Console.ReadLine(), out int valueToWrite))
                {
                    WriteToSlave(modbusMaster, 2, 1300, valueToWrite);
                    serialPort.Close();
                }
                else
                {
                    Console.WriteLine("Неверное значение для записи.");
                }
 
                // Закрываем порт
                serialPort.Close();
                Console.WriteLine("Соединение закрыто.");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Ошибка: {ex.Message}");
            }
        }
 
        static void ReadSlave(IModbusSerialMaster master, byte slaveId, ushort startAddress)
        {
            try
            {
                ushort numOfPoints = 1;
                ushort[] result = master.ReadHoldingRegisters(slaveId, startAddress, numOfPoints);
                Console.WriteLine($"Slave {slaveId} register value at address {startAddress}: {result[0]}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Read error from slave {slaveId}: {ex.Message}");
            }
        }
 
        static void WriteToSlave(IModbusSerialMaster master, byte slaveId, ushort startAddress, int valueToWrite)
        {
            try
            {
                ushort[] values = { (ushort)valueToWrite };
                master.WriteMultipleRegisters(slaveId, startAddress, values);
                Console.WriteLine("Write successful");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Write error to slave {slaveId}: {ex.Message}");
            }
        }
    }
}
вьюмодель

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
using System;
using System.IO.Ports;
using System.Windows.Input;
using Modbus.Device;
using System.ComponentModel;
 
namespace RPStesting
{
    public class MainViewModel : INotifyPropertyChanged
    {
 
        private IModbusSerialMaster _modbusMaster;
        private SerialPort _serialPort;
        private bool _isConnected; // текущее состояние подключен или нет
        private ushort _currentRegisterValue; 
 
        // Команда для переключения значения регистра
        public ICommand ToggleRegisterCommand { get; }
 
        // Сообщение о состоянии
        public string StatusMessage { get; private set; }
 
        // Конструктор ViewModel, где инициализируется команда и соединение с устройством
        public MainViewModel()
        {
            ToggleRegisterCommand = new RelayCommand(ToggleRegister, CanToggleRegister);
            _isConnected = false; // По умолчанию соединение закрыто
            InitializeModbusConnection(); // Инициализация соединения Modbus
        }
 
        //соединения с устройством
        public void InitializeModbusConnection()
        {
            _serialPort = new SerialPort("COM3")
            {
                BaudRate = 4800,
                Parity = Parity.Even,
                DataBits = 8,
                StopBits = StopBits.One,
                ReadTimeout = 1000
            };
 
            try
            {
                // Открываем COM-порт
                _serialPort.Open();
                StatusMessage = "Device connected";
                // Создаем ModbusRTU мастер
                _modbusMaster = ModbusSerialMaster.CreateRtu(_serialPort);
                _modbusMaster.Transport.Retries = 3; // Устанавливаем количество попыток на 3
 
                _isConnected = true; // Обновляем состояние подключения
                StatusMessage = "Device connected"; // Устанавливаем сообщение о состоянии
            }
            catch (Exception ex)
            {
                // Если возникает ошибка, выводим сообщение об ошибке
                StatusMessage = $"Failed to connect: {ex.Message}";
            }
 
            // Уведомляем UI об изменении StatusMessage
            OnPropertyChanged(nameof(StatusMessage));
        }
 
        // Метод для проверки возможности переключения значения регистра
        private bool CanToggleRegister(object parameter)
        {
            return _isConnected; // Можно переключать, только если соединение установлено
        }
 
        // Метод для переключения значения регистра
        private void ToggleRegister(object parameter)
        {
            if (_modbusMaster == null || !_isConnected) return; // Если соединение не установлено, выходим
 
            try
            {
                // Переключаем значение регистра (если 0, то ставим 1 и наоборот)
                _currentRegisterValue = _currentRegisterValue == 0 ? (ushort)1 : (ushort)0;
 
                // Записываем значение в Modbus-устройство
                WriteToSlave(2, 1300, _currentRegisterValue);
 
                // Обновляем статусное сообщение
                StatusMessage = $"Register value toggled to {_currentRegisterValue}";
            }
            catch (Exception ex)
            {
                // Если возникает ошибка, выводим сообщение об ошибке
                StatusMessage = $"Error toggling register: {ex.Message}";
            }
 
            // Уведомляем UI об изменении StatusMessage
            OnPropertyChanged(nameof(StatusMessage));
        }
 
        // Метод для записи значения в Modbus-устройство
        private void WriteToSlave(byte slaveId, ushort startAddress, ushort valueToWrite)
        {
            try
            {
                // Создаем массив значений и записываем в устройство
                ushort[] values = { valueToWrite };
                _modbusMaster.WriteMultipleRegisters(slaveId, startAddress, values);
            }
            catch (Exception ex)
            {
                // Если возникает ошибка, выбрасываем исключение с описанием ошибки
                throw new Exception($"Write error: {ex.Message}");
            }
        }
 
        // Реализация интерфейса INotifyPropertyChanged для уведомления UI об изменениях
        public event PropertyChangedEventHandler PropertyChanged;
 
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
 
        // Деструктор для закрытия и освобождения ресурсов SerialPort
        ~MainViewModel()
        {
            _serialPort?.Close();
            _serialPort?.Dispose();
        }
    }
 
    // Реализация RelayCommand для команд
    public class RelayCommand : ICommand
    {
        private readonly Action<object> _execute; // для выполнения команды
        private readonly Predicate<object> _canExecute; // для проверки возможности выполнения команды
 
        public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
        {
            _execute = execute ?? throw new ArgumentNullException(nameof(execute));
            _canExecute = canExecute;
        }
 
        public bool CanExecute(object parameter)
        {
            return _canExecute == null || _canExecute(parameter);
        }
 
        public void Execute(object parameter)
        {
            _execute(parameter);
        }
 
        // Событие для уведомления об изменении состояния возможности выполнения команды
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
    }
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
18.08.2024, 19:28
Ответы с готовыми решениями:

ошибка при записи данных с COM порта
Здравствуйте, отправляю запрос в COM порт каждые две секунды (использую Matlab). полученные цифры (цифры с контроллера и время) записываю в...

реализация записи/чтения COM порта
доброго времени суток всем. Народ, нид хелп!! Пишу прогу для работы с модемом. Проблема заключается в следующем: когда запускаю прогу в...

Помогите с макросом чтения-записи порта
Всем здрасти! Прошу помощи. Сам не могу разобраться :( Нужно организовать программу чтения и записи в порт, где в качестве...

2
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3384 / 2704 / 573
Регистрация: 04.09.2018
Сообщений: 8,514
Записей в блоге: 3
18.08.2024, 19:49
баранкин, по коду вроде все правильно. Сам ком-порт не отваливается периодически? Не пропадает из системы?
0
0 / 0 / 0
Регистрация: 22.10.2018
Сообщений: 2
18.08.2024, 20:51  [ТС]
wizard41, есть аналог программы на плюсах (но там все супер криво сделано, не масштабируется и вообще очень сложно и неприятно всё), там плата тестируется нормально и всё идет ок, на любом ком порте. Отсюда делаю вывод, что компорт не отваливается
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.08.2024, 20:51
Помогаю со студенческими работами здесь

Два потока, чтения и записи с ком порта
с++, старый,не нэтовский, вроде 2000, может старее два потока, чтения и записи с ком порта, чтение всегда запущен,читает, записи же...

Ошибка чтения порта
Нужно считать байт с порта, я использую операцию in, и записываю в регистр AL (восьмиразрядный), при указании порта &lt;0FFh (255)...

Ошибка чтения с порта usb
Добрый день, коллеги! К Raspberry 3 на usb порт через pl2303hx подключена матричная клавиатура. Матричная клавиатура опрашивается...

Программа чтения Com-порта и визуализации данных
Друзья, прошу помощи. Требуется написать прогу для слушания Com-порта и визуализации данных в окне. Имеется спортивное табло и пульт...

Драйвер чтения данных из СОМ-порта(Ассемблер)
Доброго времени суток,может завалялся у кого драйвер DOS на ассемблере под COM-порт(без разницы на какой,очень нужна простейшая основа...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru