Страница 5 из 5 ПерваяПервая ... 345
Показано с 41 по 44 из 44

Тема: СПК110: подключение ProfiNet-устройства

  1. #41

    По умолчанию

    Цитата Сообщение от melky Посмотреть сообщение
    Ну вот в nuget есть Modbus.Net Siemens Profinet Implementation, не знаю что такое. И еще там парочка непонятных
    Не помню, он или нет
    Исходник в пнд скину, всё там, на работе лежит...

  2. #42

    По умолчанию

    Если кому-то срочно надо, то саму библиотеку я вспомнил: S7netplus
    https://www.nuget.org/packages/S7netplus
    https://github.com/S7NetPlus/s7netplus
    https://github.com/S7NetPlus/s7netplus/wiki

    Ну, модбас я вспомню из тысячи: NModbus. Мы с ним много лет рука-об-руку идём
    https://www.nuget.org/packages/NModbus

    Но исходники всё равно в пнд

    UPD
    ChatGPT. Примерно так я и делал в итоге:
    Миниатюры Миниатюры Нажмите на изображение для увеличения. 

Название:	Снимок экрана_20240831_161024.png 
Просмотров:	35 
Размер:	134.6 Кб 
ID:	78378  
    Последний раз редактировалось aaaSashaMGGU; 31.08.2024 в 16:23.

  3. #43

    По умолчанию

    Вот это пригодится. А то наши программеры думают как с сименсом подружиться.

  4. #44

    По умолчанию

    Как обещал, исходники
    У меня нет такого проекта, где я одновременно читаю Профинет, а потом создаю Modbus-сервер. Это были всегда разные задачи

    1) Чтение S7-1200. Запись мне была не нужна, но, судя по Wiki, просто вместо Plc.Read нужно будет сделать Plc.Write
    Код:
    Imports System.Threading 'Для Mutex-ов
    Imports S7.Net 'Для Siemens
    
    'Класс опроса паллетайзера
    Public Class ОпросПаллетайзера
    
        'Блокировка доступа к переменным
        Public Mutex As Mutex = New Mutex()
    
        'Признак связи c АСУ
        Public PrConnectASU As Boolean = True
    
        'Создание потока
        Public Поток As New System.Threading.Thread(AddressOf ГлавныйПоток)
    
        'Параметры класса
        Public ВсегоПаллетов As New Var
    
        'Разное
        Dim TimeBadWork As Integer = 0         'Счётчик неудачных попыток коннекта
        Dim PrEndWork As Boolean = False       'Признак конца работы
    
        'Функция, запускаемая один раз, при создании класса
        Public Sub New()
            'Запуск потока
            Поток.Start()
        End Sub
    
        'Главный поток
        Private Sub ГлавныйПоток()
    
            'Бесконечный цикл
            While PrEndWork = False
                Try
                    'Подключаемся
                    Dim Plc As New Plc(CpuType.S71200, "192.168.231.10", 0, 1) 'Создаем объект подключения к контроллеру Siemens S7-1200 по TCP/IP
                    Plc.Open() ' открываем соединение
    
                    'Читаем
                    Dim Data1 As Long = Plc.Read("DB1006.DBD44") 'Wrapped_pallet 'Counter for wrapped pallet 'Счётчик паллетов, находящийся в блоке DB1006 и имеющий смещение DBD44 с типом DInt (8 байтов ~ Long в VB)
    
                    'Закрываем
                    Plc.Close()
    
                    'Закрываем доступ к защищённым ресурсам потока
                    Mutex.WaitOne()
    
                    'Достоверность
                    ВсегоПаллетов.Valid = True
    
                    'Значение
                    ВсегоПаллетов.Value = Data1
    
                    'Открываем доступ к защищённым ресурсам потока
                    Mutex.ReleaseMutex()
    
                    'Счётчик неудачных попыток коннекта
                    TimeBadWork = 0
    
                Catch Ex As Exception
    
                    'Закрываем доступ к защищённым ресурсам потока
                    Mutex.WaitOne()
    
                    'Достоверность
                    ВсегоПаллетов.Valid = False
    
                    'Открываем доступ к защищённым ресурсам потока
                    Mutex.ReleaseMutex()
    
                    'Ошибка
                    Dim Err = Ex.ToString           'Только для отладки
                    TimeBadWork = TimeBadWork + 1   'Счётчик неудачных попыток коннекта
                End Try
    
                'Признак связи c АСУ
                PrConnectASU = (TimeBadWork < 10)
    
                'Пауза в потоке
                System.Threading.Thread.Sleep(5000)
            End While
        End Sub
    
        'Штатное завершение работы
        Public Sub EndWork()
            PrEndWork = True 'Признак конца работы
        End Sub
    End Class
    2) ModbusTCP сервер:
    Код:
    using System.Threading;    //Потоки
    using System.Net;          //Работа в сети
    using System.Net.Sockets;  //Работа в сети
    
    using NModbus;             //Modbus
    using NModbus.Data;        //Modbus
    using System;
    
    //Модбас-Сервер
    public class Modbus_TCP_Server
    {
        //Создание потоков
        private Thread ЗапускСервера;
        private Thread Поток1;
    
        //Сеть
        private IModbusSlaveNetwork Network;
    
        //Данные
        private ISlaveDataStore dataStore1 = new SlaveDataStore();
        private ISlaveDataStore dataStore2 = new SlaveDataStore();
    
        //Разное
        private bool PrEndWork = false; //Признак конца работы
    
        //Собственно, вес
        public float Ves = 0;
    
        public Modbus_TCP_Server()
        {
            //Запуск потоков
            ЗапускСервера = new Thread(ГлавныйЗапускСервера);
            Поток1 = new Thread(ГлавныйПоток1);
            ЗапускСервера.Start();
            Поток1.Start();
        }
    
        //Запуск сервера
        public void ГлавныйЗапускСервера()
        {
            //Порт и IP
            int Port = 50300;
            IPAddress IP = ((IPAddress[])Dns.GetHostAddresses(Dns.GetHostName()))[1];
    
            //Создаём сервер
            TcpListener slaveTcpListener = new TcpListener(IP, Port);
            slaveTcpListener.Start();
    
            //Создаём данные
            IModbusFactory factory = new ModbusFactory();
            Network = factory.CreateSlaveNetwork(slaveTcpListener);
    
            //Создаём Slave-адреса на Modbus-Сервере
            IModbusSlave slave1 = factory.CreateSlave(1, dataStore1);
            IModbusSlave slave2 = factory.CreateSlave(2, dataStore2);
            Network.AddSlave(slave1);
            Network.AddSlave(slave2);
    
            //Бесконечный цикл
            try
            {
                Network.ListenAsync().GetAwaiter().GetResult();
                Thread.Sleep(Timeout.Infinite);
            }
            catch (Exception ex)
            {
                string Test = ex.ToString();
            }
        }
    
        //Главный поток, где, собственно, происходит обновление данных
        public void ГлавныйПоток1()
        {
            //Бесконечный цикл
            while (PrEndWork == false)
            {
                //Массив для записи на ModbusTCP
                ushort[] MassivToModbusTCP = new ushort[11];
    
                //Значения
                int Num = 0; //Номер параметра
                Num = Num + 1; GetToModbusParamsFromVar(ref MassivToModbusTCP, Num, Ves, true); //Вес
    
                //Запись на Modbus
                dataStore1.HoldingRegisters.WritePoints(0, MassivToModbusTCP);
                //dataStore2.HoldingRegisters.WritePoints(0, MassivToModbusTCP);
    
                //Пауза в потоке
                System.Threading.Thread.Sleep(1000);
            }
        }
    
        //Функция записи на модбас параметров вара
        public void GetToModbusParamsFromVar(ref ushort[] MassivToModbusTCP, int Num, float Var, bool Valid) //Массив Модбаса, номер параметра, Вар для записи на Модбас, Достоверность для записи на Модбас
        {
            //Массив байтов из значения вара
            byte[] TempMas = BitConverter.GetBytes(Var);
    
            //Пишем массив для Modbus-а
            MassivToModbusTCP[(Num - 1) * 3 + 0] = (ushort)(TempMas[1] * 256 + TempMas[0]); //0 и 1 байт
            MassivToModbusTCP[(Num - 1) * 3 + 1] = (ushort)(TempMas[3] * 256 + TempMas[2]); //2 и 3 байт
            MassivToModbusTCP[(Num - 1) * 3 + 2] = (ushort)(Valid ? 1 : 0);                 //Достоверность
        }
    
        //Штатное завершение работы
        public void EndWork()
        {
            PrEndWork = true;
            Network.Dispose(); //Прибиваем сеть, из-за чего завершаются все циклы
        }
    }
    3) ModbusTCP клиент
    Код:
    Imports NModbus            'Modbus
    Imports NModbus.Data       'Modbus
    Imports System.Threading
    
    Public Class Водоподготовка
    
        'Создание потока
        Dim Поток1 As New System.Threading.Thread(AddressOf ГлавныйПоток1)
    
        'Блокировка доступа к переменным
        Public Mutex As Mutex = New Mutex()
    
        'Признак связи c АСУ
        Public PrConnectASU As Boolean
    
        'Главные глобальные внешние параметры нашей АСУТП
        Public ПараметрАналог(100) As Double 'Аналоговые датчики
        Public ПризнакАварии As Boolean      'Дискретный признак аварии
    
        'Разное
        Dim TimeBadWork As Integer                              'Счётчик неудачных попыток коннекта
        Dim PrEndWork                                           'Признак конца работы
    
        'Функция, запускаемая один раз, при создании класса
        Public Sub New()
            'Запуск потоков
            Поток1.Start()
        End Sub
    
        'Главный поток
        Private Sub ГлавныйПоток1()
            'Бесконечный цикл
            While PrEndWork = False
    
                'Закрываем доступ к защищённым ресурсам потока
                Mutex.WaitOne()
    
                Try
                    'Подключаемся
                    Dim Factory = New ModbusFactory
                    Dim TcpClient As New TcpClient("192.168.0.110", 8000)
                    TcpClient.SendTimeout = 5000    'Таймауты
                    TcpClient.ReceiveTimeout = 5000 'Таймауты
                    Dim Master As IModbusMaster = Factory.CreateMaster(TcpClient)
                    Master.Transport.ReadTimeout = 5000  'Таймауты
                    Master.Transport.WriteTimeout = 5000 'Таймауты
                    Dim HoldingRegisterIn1 = Master.ReadHoldingRegisters(0, 0, 100)               'Читаем 100 регистров, первый параметр - адрес ModBus-устройства, второй - адрес регистра, третий - количество читаемых регистров (битов)
                    Dim HoldingRegisterIn2 = Master.ReadHoldingRegisters(0, 100, 106)             'Читаем 106 регистров, первый параметр - адрес ModBus-устройства, второй - адрес регистра, третий - количество читаемых регистров (битов)
                    Dim HoldingRegisterIn = HoldingRegisterIn1.Concat(HoldingRegisterIn2).ToArray 'Объединим 2 массива
    
                    'Параметры
                    ПараметрАналог(1) = GetSingle(HoldingRegisterIn(6), HoldingRegisterIn(7))      '[Давление В-1 (Из города)]
                    ПараметрАналог(2) = GetSingle(HoldingRegisterIn(10), HoldingRegisterIn(11))    '[Давление В-1 (В корпуса 1, 2, 3)]
                    ПараметрАналог(3) = GetSingle(HoldingRegisterIn(14), HoldingRegisterIn(15))    '[Давление В-3 (После перекачного насоса)]
                    ПараметрАналог(4) = GetSingle(HoldingRegisterIn(184), HoldingRegisterIn(185))  '[Давление В-3 (После насосов УЗВ)]
                    ПараметрАналог(5) = GetSingle(HoldingRegisterIn(16), HoldingRegisterIn(17))    '[Уровень ёмкости водоподготовка]
                    ПараметрАналог(6) = GetSingle(HoldingRegisterIn(176), HoldingRegisterIn(177))  '[Уровень ёмкости УЗВ]
                    ПараметрАналог(7) = GetSingle(HoldingRegisterIn(0), HoldingRegisterIn(1))      '[Температура в помещении]
                    ПараметрАналог(8) = GetSingle(HoldingRegisterIn(162), HoldingRegisterIn(163))  '[Расход В1. Датчик 10л]
                    ПараметрАналог(9) = GetSingle(HoldingRegisterIn(164), HoldingRegisterIn(165)) '[Расход В1. Датчик 100л]
                    ПараметрАналог(10) = GetSingle(HoldingRegisterIn(160), HoldingRegisterIn(161)) '[Расход В1. Суммарный]
                    ПараметрАналог(11) = GetSingle(HoldingRegisterIn(166), HoldingRegisterIn(167)) '[Расход В3. Датчик 100л]
                    ПараметрАналог(12) = GetSingle(HoldingRegisterIn(72), HoldingRegisterIn(73))   '[Расход В3. Суммарный]
                    ПараметрАналог(13) = GetSingle(HoldingRegisterIn(74), HoldingRegisterIn(75))   '[Расход УЗВ. Датчик 10л]
                    ПараметрАналог(14) = GetSingle(HoldingRegisterIn(76), HoldingRegisterIn(77))   '[Расход УЗВ. Датчик 100л]
                    ПараметрАналог(15) = GetSingle(HoldingRegisterIn(78), HoldingRegisterIn(79))   '[Расход УЗВ. Суммарный]
    
                    'Совокупная авария
                    ПризнакАварии = Val(Strings.Mid(DecToBin(HoldingRegisterIn(150)), 8, 1)) 'Адрес 150.08. Совокупная авария
    
                    'Счётчик неудачных попыток коннекта
                    TimeBadWork = 0
    
                Catch Ex As Exception
                    Dim Err = Ex.ToString           'Только для отладки
                    TimeBadWork = TimeBadWork + 1   'Счётчик неудачных попыток коннекта
                End Try
    
                'Признак связи c АСУ
                PrConnectASU = (TimeBadWork < 10)
    
                'Открываем доступ к защищённым ресурсам потока
                Mutex.ReleaseMutex()
    
                'Пауза в потоке
                System.Threading.Thread.Sleep(2000)
            End While
        End Sub
    
        'Штатное завершение работы
        Public Sub EndWork()
            PrEndWork = True
        End Sub
    End Class
    4) ModbusCom клиент (Здесь я кучу всего удалил для примера, так как в классе было много ещё чего лишнего, к модбасу не относящееся)
    Код:
    using System.Collections.Generic;
    using System.Text;
    using System.Diagnostics;
    using System.Threading;
    using System.IO.Ports;
    using System.Windows.Forms;
    using System.Collections;
    using System.IO;
    using System;
    
    //Работа с ModBus
    using NModbus;        //Modbus
    using NModbus.Data;   //Modbus
    using NModbus.Serial; //Modbus
    
    namespace AkvaTex
    {
        public class SignalPro
        {
            //Отдельный поток на опрос модбаса (ОВЕНовский модуль)
            public void ThreadNewModBus()
            {
                while (!m_stop) //Действия циклически продолжаются до остановки потока
                {
                    //Проверяем признак имитации, чтобы не трогать модбасы, если включена имитация
                    if (fImitator)
                    {
                        //Тут ничего нет. Пока что...
                    }
                    else
                    {
                        //Пишем выходы на ОВЕНовский модуль
                        try
                        {
                            if (!sPortModBus.IsOpen)
                            {
                                sPortModBus.PortName = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\\Akvatex_05_2012\\").GetValue("comPortTemperature").ToString();
                                sPortModBus.BaudRate = 9600;
                                sPortModBus.DataBits = 8;
                                sPortModBus.Parity = System.IO.Ports.Parity.None;
                                sPortModBus.StopBits = System.IO.Ports.StopBits.One;
                                sPortModBus.ReadTimeout = 500;
                                sPortModBus.Open();
                            }
    
                            var Factory = new ModbusFactory();
                            IModbusMaster ModbusMaster = Factory.CreateRtuMaster(new SerialPortAdapter(sPortModBus)); //Создаём Модбас-Мастера
                            ModbusMaster.Transport.ReadTimeout = 500;  //Таймауты
                            ModbusMaster.Transport.WriteTimeout = 500; //Таймауты
    
                            ushort[] RegistersToModbus = { 0 };                                                       //Массив регистров для записи на Мобдас. Именно массив, а не отдельный регистр, т.к., модуль, отчего-то не хочет работать по команде 6 (WriteSingleRegister), а хочет работать только по команде 16 (WriteMultipleRegisters)
                            RegistersToModbus[0] = (ushort)(RegistersToModbus[0] + 001 * komPK_240_1);                //ПК-240/1
                            RegistersToModbus[0] = (ushort)(RegistersToModbus[0] + 002 * komPZ_222_2);                //ПЗ-222/2
                            RegistersToModbus[0] = (ushort)(RegistersToModbus[0] + 004 * komPK_203);                  //ПК-203
                            RegistersToModbus[0] = (ushort)(RegistersToModbus[0] + 008 * 0);                          //Свободный
                            RegistersToModbus[0] = (ushort)(RegistersToModbus[0] + 016 * 0);                          //Свободный
                            RegistersToModbus[0] = (ushort)(RegistersToModbus[0] + 032 * 0);                          //Свободный
                            RegistersToModbus[0] = (ushort)(RegistersToModbus[0] + 064 * 0);                          //Свободный
                            RegistersToModbus[0] = (ushort)(RegistersToModbus[0] + 128 * 0);                          //Свободный
                            ModbusMaster.WriteMultipleRegisters(2, 50, RegistersToModbus);                            //Пишем на модбас: адрес, регистр, значение 
    
                            ModbusMaster.Dispose();
                            sPortModBus.Close();
                        }
                        catch
                        {
                        }
                    }
    
                    //Пауза потока
                    Thread.Sleep(100);
                }
            }
        }
    }

Страница 5 из 5 ПерваяПервая ... 345

Похожие темы

  1. СПК110 + устройства других производителей
    от GoodLuck в разделе СПК1xx (архив)
    Ответов: 20
    Последнее сообщение: 15.04.2021, 15:30
  2. Ответов: 5
    Последнее сообщение: 03.02.2017, 11:46
  3. Ответов: 1
    Последнее сообщение: 02.07.2015, 09:09
  4. Modbus и периферийные устройства для СПК110
    от in37usd в разделе СПК1xx (архив)
    Ответов: 11
    Последнее сообщение: 20.04.2015, 07:46
  5. Ответов: 2
    Последнее сообщение: 06.10.2009, 07:54

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •