private bool                    readBitSegment(byte aSlaveID, ERegisterType aRegisterType, ushort aRegister, ref bool[] aValue)
        {
            int lFrame = (int)mFrame * 16;
            int lDiv   = aValue.Length / lFrame;
            int lStart = 0;

            bool[] lArray;

            for (int i = 0; i < lDiv; i++)
            {
                try
                {
                    if (aRegisterType == ERegisterType.COIL_BIT)
                    {
                        lArray = mMaster.ReadCoils(aSlaveID, (ushort)(aRegister + lStart), (ushort)lFrame);
                    }
                    else
                    {
                        lArray = mMaster.ReadInputs(aSlaveID, (ushort)(aRegister + lStart), (ushort)lFrame);
                    }
                }
                catch (Exception lExc)
                {
                    reportError("Error reading data for one or group of Items: " + lExc.Message);
                    return(false);
                }

                Array.Copy(lArray, 0, aValue, lStart, lFrame);

                lStart = lStart + lFrame;
            }

            int lLastPart = aValue.Length - lStart;

            if (lLastPart > 0)
            {
                try
                {
                    if (aRegisterType == ERegisterType.COIL_BIT)
                    {
                        lArray = mMaster.ReadCoils(aSlaveID, (ushort)(aRegister + lStart), (ushort)lLastPart);
                    }
                    else
                    {
                        lArray = mMaster.ReadInputs(aSlaveID, (ushort)(aRegister + lStart), (ushort)lLastPart);
                    }
                }
                catch (Exception lExc)
                {
                    reportError("Error reading data for one or group of Items: " + lExc.Message);
                    return(false);
                }

                Array.Copy(lArray, 0, aValue, lStart, lLastPart);
            }

            return(true);
        }
示例#2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="duLieuTemp"></param>
        /// <param name="serialPort"></param>
        /// <param name="quantityCoils"></param>
        /// <param name="quantityInputs"></param>
        /// <param name="quantityInputRegisters"></param>
        /// <param name="quantityHoldingRegisters"></param>
        /// <returns></returns>
        public static bool[] LayDuLieuCOMCoils(SerialPort serialPort, ushort quantityCoils, ushort minAddressCoils, ThietBiModel thietBiModel)
        {
            IModbusMaster master   = ModbusSerialMaster.CreateRtu(serialPort);
            List <bool>   readCoil = new List <bool>();

            if (quantityCoils != 0)
            {
                try
                {
                    byte slaveAddress    = 1;
                    int  soNguyenSauChia = quantityCoils / DonViQuantityMoiLanDoc;
                    for (int i = 0; i <= soNguyenSauChia; i++)
                    {
                        if (i != soNguyenSauChia)
                        {
                            int startAddress = i * DonViQuantityMoiLanDoc + minAddressCoils;
                            int quantity     = DonViQuantityMoiLanDoc - minAddressCoils;
                            var temp         = master.ReadCoils(slaveAddress, (ushort)startAddress, (ushort)(quantity));
                            readCoil.AddRange(temp.ToList());
                        }
                        else if (i == soNguyenSauChia)
                        {
                            int startAddress = i * DonViQuantityMoiLanDoc + minAddressCoils;
                            int quantity     = quantityCoils % DonViQuantityMoiLanDoc - minAddressCoils;
                            if (quantity != 0)
                            {
                                var temp = master.ReadCoils(slaveAddress, (ushort)startAddress, (ushort)(quantity));
                                readCoil.AddRange(temp.ToList());
                            }
                        }
                    }
                }
                catch (TimeoutException ex)
                {
                    ExceptionTimeOut(ex, thietBiModel);
                    throw;
                }
                catch (Modbus.SlaveException ex)
                {
                    ExceptionErrorSlave(ex, thietBiModel);
                    throw;
                }
                catch (Exception ex)
                {
                    throw;
                }
            }
            return(readCoil.ToArray());
        }
示例#3
0
        public int GetArmDqValue(ushort bit)
        {
            const ushort num = 3;

            if (bit > num)
            {
                Console.WriteLine("Wrong bit!");
                return(-1);
            }

            // ADDR = 800
            bool[] b = master.ReadCoils(0, ADDR_ARM_IO_BASE, num);

            return(b[bit] ? 1 : 0);
        }
示例#4
0
        private void ReadByFunction(IModbusMaster master, bool isFirstRead)
        {
            switch (_configurationSettings.Function)
            {
            case 1:
                UpdateUI(master.ReadCoils(_configurationSettings.SlaveId,
                                          _configurationSettings.StartAddress, _configurationSettings.Count), isFirstRead);
                break;

            case 2:
                UpdateUI(master.ReadInputs(_configurationSettings.SlaveId,
                                           _configurationSettings.StartAddress, _configurationSettings.Count), isFirstRead);
                break;

            case 3:
                UpdateUI(master.ReadHoldingRegisters(_configurationSettings.SlaveId,
                                                     _configurationSettings.StartAddress, _configurationSettings.Count), isFirstRead);
                break;

            case 4:
                UpdateUI(master.ReadInputRegisters(_configurationSettings.SlaveId,
                                                   _configurationSettings.StartAddress, _configurationSettings.Count), isFirstRead);
                break;

            default:
                throw new ArgumentException();
            }
        }
        /// <summary>
        /// 读取线圈
        /// </summary>
        /// <param name="slaveAddress">从站地址</param>
        /// <param name="registerAddress">寄存器地址</param>
        /// <param name="value">数据</param>
        public void ReadCoil(byte slaveAddress, ushort registerAddress, out bool value)
        {
            value = false;
            using (SerialPort port = new SerialPort(SerialPortName))
            {
                //配置串口
                port.BaudRate = BaudRate;
                port.DataBits = 8;
                port.Parity   = Parity.Even;
                port.StopBits = StopBits.One;
                port.Open();

                //创建Modbus主机
                var adapter = new SerialPortAdapter(port);
                adapter.ReadTimeout  = ReadTimeout;
                adapter.WriteTimeout = WriteTimeout;
                var           factory = new ModbusFactory();
                IModbusMaster master  = factory.CreateRtuMaster(adapter);

                lock (_modbusLock)
                {
                    //读寄存器
                    var values = master.ReadCoils(slaveAddress, registerAddress, 1);
                    if (values?.Length >= 1)
                    {
                        value = values[0];
                    }
                }
            }
        }
示例#6
0
 //метод читает меркер из ПЛК
 internal bool ReadMerker(ushort address, out bool m)
 {
     bool[] ms;
     address += 0x800;
     ms       = PLC.ReadCoils(1, address, 1);
     m        = ms[0];
     return(true);
 }
 public bool[] GetOutput(ushort ch = 0, ushort num = 8)
 {
     try
     {
         return(master.ReadCoils(SlaveAddress, ch, num));
     }
     catch (Exception ex)
     {
         OnException?.Invoke(ex);
         return(null);
     }
 }
示例#8
0
        /// <summary>
        /// Read multiple coils/inputs
        /// </summary>
        /// <param name="slaveaddress"></param>
        /// <param name="type"></param>
        /// <param name="start"></param>
        /// <param name="amount"></param>
        /// <returns></returns>
        public override bool[] ReadInOut(byte slaveaddress, int type, ushort start, ushort amount)
        {
            switch (type)
            {
            case (0x03):
                return(Master.ReadInputs(slaveaddress, start, amount));

            case (0x04):
                return(Master.ReadCoils(slaveaddress, start, amount));

            default:
                throw new TypeAccessException("Invalid type");
            }
        }
示例#9
0
 /// <summary>
 /// IEnumerable<[address,value]>
 /// </summary>
 public static IEnumerable <KeyValuePair <ushort, bool> > ReadCoils(
     this IModbusMaster master, byte slaveAddress, IEnumerable <ushort> addresses)
 {
     foreach (var bucket in GetCoilOrInputBucketsToRead(addresses))
     {
         ushort startAddress   = bucket.Item1;
         ushort numberOfPoints = bucket.Item2;
         bool[] values         = master.ReadCoils(slaveAddress, startAddress, numberOfPoints);
         ushort i = 0;
         foreach (var value in values)
         {
             ushort address = (ushort)(startAddress + i);
             ++i;
             yield return(new KeyValuePair <ushort, bool>(address, value));
         }
     }
 }
示例#10
0
        public static object ReadSingleObject(
            this IModbusMaster master, ObjectType objectType, byte slaveId, ushort address)
        {
            switch (objectType)
            {
            case ObjectType.Coil:
                return(master.ReadCoils(slaveId, address, 1)[0]);

            case ObjectType.DiscreteInput:
                return(master.ReadInputs(slaveId, address, 1)[0]);

            case ObjectType.HoldingRegister:
                return(master.ReadHoldingRegisters(slaveId, address, 1)[0]);

            case ObjectType.InputRegister:
                return(master.ReadInputRegisters(slaveId, address, 1)[0]);

            default:
                throw new ArgumentException("objectType");
            }
        }
        void ModbusUpdate()
        {
            float  gas_v;
            float  pump;
            float  steam_v;
            float  water_lvl;
            float  pressure;
            ushort alrm;
            bool   torch;

            while (client_connected == 2)
            {
                Thread.Sleep(500);
                if (update_task_ctoken.IsCancellationRequested)
                {
                    return;
                }
                gas_v     = UshortToFloat(mbus_client.ReadHoldingRegisters(0x00, 0, 2));
                pump      = UshortToFloat(mbus_client.ReadHoldingRegisters(0x00, 2, 2));
                steam_v   = UshortToFloat(mbus_client.ReadHoldingRegisters(0x00, 4, 2));
                water_lvl = UshortToFloat(mbus_client.ReadHoldingRegisters(0x00, 6, 2));
                pressure  = UshortToFloat(mbus_client.ReadHoldingRegisters(0x00, 8, 2));
                alrm      = mbus_client.ReadHoldingRegisters(0x00, 10, 1)[0];
                torch     = mbus_client.ReadCoils(0x00, 5, 1)[0];
                Dispatcher.Invoke(() =>
                {
                    valve2_label.Content       = String.Format("КЛ2: {0:F1}%", gas_v * 100);
                    pump_label.Content         = String.Format("НАС: {0:F1}%", pump * 100);
                    valve1_label.Content       = String.Format("КЛ1: {0:F1}%", steam_v * 100);
                    waterlvl_label.Content     = String.Format("{0:F1}%", water_lvl * 100);
                    waterlvl_progressbar.Value = water_lvl;
                    pressure_label.Content     = String.Format("{0:F1}%", pressure * 100);
                    pressure_progressbar.Value = pressure;
                    if (torch)
                    {
                        heater_status_ellipse.Fill = new SolidColorBrush(Colors.Green);
                    }
                    else
                    {
                        heater_status_ellipse.Fill = new SolidColorBrush(Colors.Red);
                    }

                    if (alrm == 1)
                    {
                        alarm_presshigh.IsEnabled = true;
                    }
                    else if (alrm == 2)
                    {
                        alarm_pressdang.IsEnabled = true;
                    }
                    else if (alrm == 3)
                    {
                        alarm_watrlow.IsEnabled = true;
                    }
                    else if (alrm == 4)
                    {
                        alarm_watrhigh.IsEnabled = true;
                    }
                    else if (alrm == 0)
                    {
                        alarm_pressdang.IsEnabled = false;
                        alarm_presshigh.IsEnabled = false;
                        alarm_watrhigh.IsEnabled  = false;
                        alarm_watrlow.IsEnabled   = false;
                    }
                });
                if (auto_mode)
                {
                }
            }
        }
示例#12
0
        /*
         *
         * /// <summary>
         * /// Метод вызова для подключения к сети по TCP
         * /// </summary>
         * /// <param name="WhatReeder"> 0 - Coils (0xxxx); 1 - Discrete Inputs (1xxxx); 3 -  Input Register (3xxxx); 4 - Holding Register (4xxxx)</param>
         * /// <param name="Slave"> Адресс устройства в TCP MODBUS</param>
         * /// <param name="IpAddress"> ip адресс устройства</param>
         * /// <param name="NumOfPoints"> количество читаемых параметров </param>
         * public void Start_Connect(string IpAddress, byte Slave, ushort StartAddress, ushort NumOfPoints, byte WhatReeder)
         * {
         *  _ipAddress = IpAddress;          // ipAddress устройства для подключения
         *
         *  _startAddress = StartAddress;   // Стартовый регистр с которого надо начинанать читать значение
         *  _numOfPoints = NumOfPoints;     // Количество регистров читаемых со стартового
         *  _slave = Slave;                 // Адресс устройства
         *  _whatReed = WhatReeder;
         *
         *  NetworkIsOk = Connect();
         *
         *  TimerCallback tm = new TimerCallback(timer1_Tick);
         *  timer1 = new Timer(tm, 0, 0, 1000);
         *
         * }
         */

        #endregion

        #region Function Code Descriptions

        /*
         *  Discrete Input      Single bit      Read-Only   DI
         *  Coils               Single bit      Read-Write  DO
         *  Input Registers     16-bits word    Read-Only   AI
         *  Holding Registers   16-bits word    Read-Write  AO
         */



        /// <summary>
        /// Метод для считывания состояния дискретного выхода в модуле (DO -на модуле, сигнал от модуля)
        /// Read Coil Status ()
        /// </summary>
        /// <param name="slaveID">Address of device to read values from</param>
        /// <param name="startAddress">Address to begin reading</param>
        /// <param name="numOfPoints">Number of coils to read</param>
        /// <returns> bool[] </returns>
        public bool[] ReadCoils(byte slaveID, ushort startAddress, ushort numOfPoints) // функциональный код 01
        {
            return(master.ReadCoils(slaveID, startAddress, numOfPoints));              // TODO: ошибка при откючении стенда
        }
示例#13
0
 private ushort[] ReadCoils(ushort startAddress, ushort pointCount)
 {
     return(m_modbusConnection.ReadCoils(m_unitID, startAddress, pointCount).Select(value => (ushort)(value ? 1 : 0)).ToArray());
 }
示例#14
0
 protected override bool[] ReadCore(IModbusMaster modbusMaster, byte slaveId, ushort startAddress, ushort numberOfPoints)
 {
     return(modbusMaster.ReadCoils(slaveId, startAddress, numberOfPoints));
 }
示例#15
0
        private async void ExecuteFunction()
        {
            try
            {
                //重新实例化是为了 modbus slave更换连接时不报错
                master = modbusFactory.CreateMaster(new TcpClient("127.0.0.1", 502));
                if (functionCode != null)
                {
                    switch (functionCode)
                    {
                    case "01 Read Coils":    //读取单个线圈
                        SetReadParameters();
                        coilsBuffer = master.ReadCoils(slaveAddress, startAddress, numberOfPoints);

                        for (int i = 0; i < coilsBuffer.Length; i++)
                        {
                            SetMsg(coilsBuffer[i] + " ");
                        }
                        SetMsg("\r\n");
                        break;

                    case "02 Read DisCrete Inputs":    //读取输入线圈/离散量线圈
                        SetReadParameters();

                        coilsBuffer = master.ReadInputs(slaveAddress, startAddress, numberOfPoints);
                        for (int i = 0; i < coilsBuffer.Length; i++)
                        {
                            SetMsg(coilsBuffer[i] + " ");
                        }
                        SetMsg("\r\n");
                        break;

                    case "03 Read Holding Registers":    //读取保持寄存器
                        SetReadParameters();
                        registerBuffer = master.ReadHoldingRegisters(slaveAddress, startAddress, numberOfPoints);
                        for (int i = 0; i < registerBuffer.Length; i++)
                        {
                            SetMsg(registerBuffer[i] + " ");
                        }
                        SetMsg("\r\n");
                        break;

                    case "04 Read Input Registers":    //读取输入寄存器
                        SetReadParameters();
                        registerBuffer = master.ReadInputRegisters(slaveAddress, startAddress, numberOfPoints);
                        for (int i = 0; i < registerBuffer.Length; i++)
                        {
                            SetMsg(registerBuffer[i] + " ");
                        }
                        SetMsg("\r\n");
                        break;

                    case "05 Write Single Coil":    //写单个线圈
                        SetWriteParametes();
                        await master.WriteSingleCoilAsync(slaveAddress, startAddress, coilsBuffer[0]);

                        break;

                    case "06 Write Single Registers":    //写单个输入线圈/离散量线圈
                        SetWriteParametes();
                        await master.WriteSingleRegisterAsync(slaveAddress, startAddress, registerBuffer[0]);

                        break;

                    case "0F Write Multiple Coils":    //写一组线圈
                        SetWriteParametes();
                        await master.WriteMultipleCoilsAsync(slaveAddress, startAddress, coilsBuffer);

                        break;

                    case "10 Write Multiple Registers":    //写一组保持寄存器
                        SetWriteParametes();
                        await master.WriteMultipleRegistersAsync(slaveAddress, startAddress, registerBuffer);

                        break;

                    default:
                        break;
                    }
                }
                else
                {
                    MessageBox.Show("请选择功能码!");
                }
                master.Dispose();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
示例#16
0
        public void OnButtonMbusExecuteClicked(object sender, RoutedEventArgs e)
        {
            if (mbus_client.Connected)
            {
                ushort offset   = ushort.Parse(boxRegOffset.Text);
                ushort quantity = ushort.Parse(boxRegNumber.Text);
                byte   slave    = 0x00;
                ushort val      = ushort.Parse(boxModbusWriteValue.Text);
                switch (boxModbusOp.Text)
                {
                case "Чтение дискретных входов":
                    bool[] discrete_output;
                    try
                    {
                        discrete_output = mbus_master.ReadInputs(slave, offset, quantity);
                    }
                    catch (IOException)
                    {
                        Console.WriteLine("Ошибка соединения. Соединение сброшено");
                        mbus_client.Close();
                        discrete_output = new bool[0];
                    }
                    catch (InvalidModbusRequestException)
                    {
                        Console.WriteLine("Что-то пошло не так...");
                        discrete_output = new bool[0];
                    }
                    foreach (bool b in discrete_output)
                    {
                        if (b)
                        {
                            Console.Write("1 ");
                        }
                        else
                        {
                            Console.Write("0 ");
                        }
                    }
                    Console.Write('\n');
                    break;

                case "Чтение дискретных выходов":
                    bool[] coil_output;
                    try
                    {
                        coil_output = mbus_master.ReadCoils(slave, offset, quantity);
                    }
                    catch (IOException)
                    {
                        Console.WriteLine("Ошибка соединения. Соединение сброшено");
                        mbus_client.Close();
                        coil_output = new bool[0];
                    }
                    catch (InvalidModbusRequestException)
                    {
                        Console.WriteLine("Что-то пошло не так...");
                        coil_output = new bool[0];
                    }
                    foreach (bool b in coil_output)
                    {
                        if (b)
                        {
                            Console.Write("1 ");
                        }
                        else
                        {
                            Console.Write("0 ");
                        }
                    }
                    Console.Write('\n');
                    break;

                case "Чтение выходных регистров":
                    ushort[] holding_output;

                    try
                    {
                        holding_output = mbus_master.ReadHoldingRegisters(slave, offset, quantity);
                    }
                    catch (IOException)
                    {
                        Console.WriteLine("Ошибка соединения. Соединение сброшено");
                        mbus_client.Close();
                        holding_output = new ushort[0];
                    }
                    catch (InvalidModbusRequestException)
                    {
                        Console.WriteLine("Что-то пошло не так...");
                        holding_output = new ushort[0];
                    }
                    foreach (int i in holding_output)
                    {
                        Console.Write(i.ToString() + " ");
                    }
                    Console.WriteLine("");
                    break;

                case "Чтение входных регистров":
                    ushort[] inreg_output;

                    try
                    {
                        inreg_output = mbus_master.ReadInputRegisters(slave, offset, quantity);
                    }
                    catch (IOException)
                    {
                        Console.WriteLine("Ошибка соединения. Соединение сброшено");
                        mbus_client.Close();
                        inreg_output = new ushort[0];
                    }
                    catch (InvalidModbusRequestException)
                    {
                        Console.WriteLine("Что-то пошло не так...");
                        inreg_output = new ushort[0];
                    }
                    foreach (int i in inreg_output)
                    {
                        Console.Write(i.ToString() + " ");
                    }
                    Console.WriteLine("");
                    break;

                case "Запись в дискретный выход":

                    bool coil = val > 0 ? true : false;
                    try
                    {
                        mbus_master.WriteSingleCoil(slave, offset, coil);
                        Console.WriteLine("ЗАП OK");
                    }
                    catch (IOException)
                    {
                        Console.WriteLine("Ошибка соединения. Соединение сброшено");
                        mbus_client.Close();
                    }
                    catch (InvalidModbusRequestException)
                    {
                        Console.WriteLine("Что-то пошло не так...");
                    }
                    break;

                case "Запись в регистр":
                    try
                    {
                        mbus_master.WriteSingleRegister(slave, offset, val);
                        Console.WriteLine("ЗАП OK");
                    }
                    catch (IOException)
                    {
                        Console.WriteLine("Ошибка соединения. Соединение сброшено");
                        mbus_client.Close();
                    }
                    catch (InvalidModbusRequestException)
                    {
                        Console.WriteLine("Что-то пошло не так...");
                    }
                    break;

                case "Запись в несколько дискретных выходов":
                    bool[] coil_input = new bool[quantity];
                    for (int i = 0; i < quantity; i++)
                    {
                        coil_input[i] = val > 0 ? true : false;
                    }
                    try
                    {
                        mbus_master.WriteMultipleCoils(slave, offset, coil_input);
                        Console.WriteLine("ЗАП OK");
                    }
                    catch (IOException)
                    {
                        Console.WriteLine("Ошибка соединения. Соединение сброшено");
                        mbus_client.Close();
                    }
                    catch (InvalidModbusRequestException)
                    {
                        Console.WriteLine("Что-то пошло не так...");
                    }
                    break;

                case "Запись в несколько регистров":
                    ushort[] reg_out = new ushort[quantity];
                    for (int i = 0; i < quantity; i++)
                    {
                        reg_out[0] = val;
                    }
                    try
                    {
                        mbus_master.WriteMultipleRegisters(slave, offset, reg_out);
                        Console.WriteLine("ЗАП OK");
                    }
                    catch (IOException)
                    {
                        Console.WriteLine("Ошибка соединения. Соединение сброшено");
                        mbus_client.Close();
                    }
                    catch (InvalidModbusRequestException)
                    {
                        Console.WriteLine("Что-то пошло не так...");
                    }
                    break;

                case "Чтение/Запись в несколько регистров":
                    ushort[] reg_write = new ushort[quantity];
                    ushort[] reg_read;
                    ushort   offset_write = ushort.Parse(boxRegOffsetWr.Text);
                    for (int i = 0; i < quantity; i++)
                    {
                        reg_write[i] = val;
                    }
                    try
                    {
                        reg_read = mbus_master.ReadWriteMultipleRegisters(slave, offset, quantity, offset_write, reg_write);
                        Console.WriteLine("ЧТЕН OK");
                        foreach (int i in reg_read)
                        {
                            Console.Write(i + " ");
                        }
                        Console.WriteLine("\nЗАП OK");
                    }
                    catch (IOException)
                    {
                        Console.WriteLine("Ошибка соединения. Соединение сброшено");
                        mbus_client.Close();
                    }
                    catch (InvalidModbusRequestException ex)
                    {
                        Console.WriteLine("Что-то пошло не так...");
                    }
                    break;
                }
            }
        }
示例#17
0
 public bool[] ReadPoints(ushort startAddress, ushort numberOfPoints)
 {
     return(_master.ReadCoils(_unitId, startAddress, numberOfPoints));
 }
        protected void ReadBuffer(ModbusBaseClientStation self, IModbusMaster master, ModbusBuffer buf)
        {
            try
            {
                ushort[] registers;
                byte[]   adr;
                bool[]   inputs;

                if (buf.pauseCounter == 0)
                {
                    ushort startAddress = buf.startAddress;
                    ushort numInputs    = buf.numInputs;
                    switch (buf.ModbusDataType)
                    {
                    case ModbusDataTypeEx.InputRegister:
                    case ModbusDataTypeEx.HoldingRegister:
                        if (buf.ModbusDataType == ModbusDataTypeEx.InputRegister)
                        {
                            registers = master.ReadInputRegisters(buf.slaveId, startAddress, numInputs);
                        }
                        else
                        {
                            registers = master.ReadHoldingRegisters(buf.slaveId, startAddress, numInputs);
                        }
                        DateTime dt      = DateTime.Now;
                        int      iresult = 0;
                        uint     uresult = 0;
                        double   fresult = 0.0;
                        foreach (ModbusChannelImp ch in buf.channels)
                        {
                            switch (ch.DeviceDataType)
                            {
                            case ModbusDeviceDataType.Int:
                                adr = BitConverter.GetBytes(registers[ch.ModbusDataAddress - buf.startAddress]);
                                switch (ch.ConversionType)
                                {
                                case ModbusConversionType.SwapBytes:
                                    byte tmp = adr[0]; adr[0] = adr[1]; adr[1] = tmp;
                                    iresult = BitConverter.ToInt16(adr, 0);
                                    break;

                                default:
                                    iresult = BitConverter.ToInt16(adr, 0);
                                    break;
                                }
                                if (ch.ModbusFs2InternalType == ModbusFs2InternalType.Int32)
                                {
                                    ch.DoUpdate(iresult, dt, ChannelStatusFlags.Good);
                                }
                                else if (ch.ModbusFs2InternalType == ModbusFs2InternalType.Double)
                                {
                                    ch.DoUpdate((double)(ch.K * iresult + ch.D), dt, ChannelStatusFlags.Good);
                                }
                                else
                                if (self.LoggingLevel >= ModbusLog.logWarnings)
                                {
                                    Env.Current.Logger.LogWarning(string.Format(StringConstants.ErrConvert,
                                                                                self.Name, ch.Name, ch.DeviceDataType.ToString(), ch.ModbusFs2InternalType.ToString()));
                                }
                                break;

                            case ModbusDeviceDataType.UInt:
                                adr = BitConverter.GetBytes(registers[ch.ModbusDataAddress - buf.startAddress]);
                                switch (ch.ConversionType)
                                {
                                case ModbusConversionType.SwapBytes:
                                    byte tmp = adr[0]; adr[0] = adr[1]; adr[1] = tmp;
                                    uresult = BitConverter.ToUInt16(adr, 0);
                                    break;

                                default:
                                    uresult = BitConverter.ToUInt16(adr, 0);
                                    break;
                                }
                                if (ch.ModbusFs2InternalType == ModbusFs2InternalType.UInt32)
                                {
                                    ch.DoUpdate(uresult, dt, ChannelStatusFlags.Good);
                                }
                                else if (ch.ModbusFs2InternalType == ModbusFs2InternalType.Double)
                                {
                                    ch.DoUpdate((double)(ch.K * uresult + ch.D), dt, ChannelStatusFlags.Good);
                                }
                                else
                                if (self.LoggingLevel >= ModbusLog.logWarnings)
                                {
                                    Env.Current.Logger.LogWarning(string.Format(StringConstants.ErrConvert,
                                                                                self.Name, ch.Name, ch.DeviceDataType.ToString(), ch.ModbusFs2InternalType.ToString()));
                                }
                                break;

                            case ModbusDeviceDataType.DInt:
                                byte[] adr0 = BitConverter.GetBytes(registers[ch.ModbusDataAddress - buf.startAddress]);
                                byte[] adr1 = BitConverter.GetBytes(registers[ch.ModbusDataAddress - buf.startAddress + 1]);
                                byte[] res  = new byte[4];
                                res     = self.SwapBytesIn(adr0, adr1, ch.ConversionType);
                                iresult = BitConverter.ToInt32(res, 0);
                                if (ch.ModbusFs2InternalType == ModbusFs2InternalType.Int32)
                                {
                                    ch.DoUpdate(iresult, dt, ChannelStatusFlags.Good);
                                }
                                else if (ch.ModbusFs2InternalType == ModbusFs2InternalType.Double)
                                {
                                    ch.DoUpdate((double)(ch.K * iresult + ch.D), dt, ChannelStatusFlags.Good);
                                }
                                else
                                if (self.LoggingLevel >= ModbusLog.logWarnings)
                                {
                                    Env.Current.Logger.LogWarning(string.Format(StringConstants.ErrConvert,
                                                                                self.Name, ch.Name, ch.DeviceDataType.ToString(), ch.ModbusFs2InternalType.ToString()));
                                }
                                break;

                            case ModbusDeviceDataType.DUInt:

                                adr0    = BitConverter.GetBytes(registers[ch.ModbusDataAddress - buf.startAddress]);
                                adr1    = BitConverter.GetBytes(registers[ch.ModbusDataAddress - buf.startAddress + 1]);
                                res     = self.SwapBytesIn(adr0, adr1, ch.ConversionType);
                                uresult = BitConverter.ToUInt32(res, 0);
                                if (ch.ModbusFs2InternalType == ModbusFs2InternalType.UInt32)
                                {
                                    ch.DoUpdate(uresult, dt, ChannelStatusFlags.Good);
                                }
                                else if (ch.ModbusFs2InternalType == ModbusFs2InternalType.Double)
                                {
                                    ch.DoUpdate((double)(ch.K * uresult + ch.D), dt, ChannelStatusFlags.Good);
                                }
                                else
                                if (self.LoggingLevel >= ModbusLog.logWarnings)
                                {
                                    Env.Current.Logger.LogWarning(string.Format(StringConstants.ErrConvert,
                                                                                self.Name, ch.Name, ch.DeviceDataType.ToString(), ch.ModbusFs2InternalType.ToString()));
                                }
                                break;

                            case ModbusDeviceDataType.Float:

                                adr0    = BitConverter.GetBytes(registers[ch.ModbusDataAddress - buf.startAddress]);
                                adr1    = BitConverter.GetBytes(registers[ch.ModbusDataAddress - buf.startAddress + 1]);
                                res     = self.SwapBytesIn(adr0, adr1, ch.ConversionType);
                                fresult = BitConverter.ToSingle(res, 0);
                                if (ch.ModbusFs2InternalType == ModbusFs2InternalType.Double)
                                {
                                    ch.DoUpdate((double)(ch.K * fresult + ch.D), dt, ChannelStatusFlags.Good);
                                }
                                else
                                if (self.LoggingLevel >= ModbusLog.logWarnings)
                                {
                                    Env.Current.Logger.LogWarning(string.Format(StringConstants.ErrConvert,
                                                                                self.Name, ch.Name, ch.DeviceDataType.ToString(), ch.ModbusFs2InternalType.ToString()));
                                }
                                break;

                            case ModbusDeviceDataType.Bool:

                                bool bit = (registers[ch.ModbusDataAddress - buf.startAddress] & (0x01 << ch.BitIndex)) > 0;
                                if (ch.ModbusFs2InternalType == ModbusFs2InternalType.Boolean)
                                {
                                    ch.DoUpdate(bit, dt, ChannelStatusFlags.Good);
                                }
                                else
                                if (self.LoggingLevel >= ModbusLog.logWarnings)
                                {
                                    Env.Current.Logger.LogWarning(string.Format(StringConstants.ErrConvert,
                                                                                self.Name, ch.Name, ch.DeviceDataType.ToString(), ch.ModbusFs2InternalType.ToString()));
                                }
                                break;

                            case ModbusDeviceDataType.String:

                                byte[]  str       = new byte[2 * ch.DeviceDataLen];
                                Decoder ascii     = (new ASCIIEncoding()).GetDecoder();
                                int     bytesUsed = 0;
                                int     charsUsed = 0;
                                bool    completed = false;
                                int     j         = 0;
                                // Conversion strategy: FIRST NONPRINTABLE CHARACTER (ORD < 32) BREAKS CONVERSION, string consists of printables converted before
                                for (int i = 0; i < ch.DeviceDataLen; i++)
                                {
                                    byte[] word = BitConverter.GetBytes(registers[ch.ModbusDataAddress - buf.startAddress + i]);
                                    if (ch.ConversionType == ModbusConversionType.SwapBytes)
                                    {
                                        if (word[1] < 32)
                                        {
                                            break;          // nonprintable character
                                        }
                                        str[j++] = word[1];
                                        if (word[0] < 32)
                                        {
                                            break;          // nonprintable character
                                        }
                                        str[j++] = word[0];
                                    }
                                    else
                                    {
                                        if (word[0] < 32)
                                        {
                                            break;          // nonprintable character
                                        }
                                        str[j++] = word[0];
                                        if (word[1] < 32)
                                        {
                                            break;          // nonprintable character
                                        }
                                        str[j++] = word[1];
                                        //Array.Copy(BitConverter.GetBytes(registers[ch.ModbusDataAddress - buf.startAddress + i]), 0, str, 2 * i, 2);
                                    }
                                }
                                string sresult;
                                if (j > 0)
                                {
                                    char[] chars = new char[j];
                                    ascii.Convert(str, 0, j, chars, 0, j, true, out bytesUsed, out charsUsed, out completed);
                                    sresult = new String(chars);
                                }
                                else
                                {
                                    sresult = "";
                                }
                                if (ch.ModbusFs2InternalType == ModbusFs2InternalType.String)
                                {
                                    ch.DoUpdate(sresult, dt, ChannelStatusFlags.Good);
                                }
                                else
                                if (self.LoggingLevel >= ModbusLog.logWarnings)
                                {
                                    Env.Current.Logger.LogWarning(string.Format(StringConstants.ErrConvert,
                                                                                self.Name, ch.Name, ch.DeviceDataType.ToString(), ch.ModbusFs2InternalType.ToString()));
                                }
                                break;
                            }
                        }
                        break;

                    case ModbusDataTypeEx.Coil:
                    case ModbusDataTypeEx.Input:
                        if (buf.ModbusDataType == ModbusDataTypeEx.Coil)
                        {
                            inputs = master.ReadCoils(buf.slaveId, startAddress, numInputs);
                        }
                        else
                        {
                            inputs = master.ReadInputs(buf.slaveId, startAddress, numInputs);
                        }
                        dt = DateTime.Now;
                        foreach (ModbusChannelImp ch in buf.channels)
                        {
                            if (ch.ModbusFs2InternalType == ModbusFs2InternalType.UInt32)
                            {
                                uint val = (uint)(inputs[ch.ModbusDataAddress - buf.startAddress] ? 1 : 0);
                                ch.DoUpdate(val, dt, ChannelStatusFlags.Good);
                            }
                            else if (ch.ModbusFs2InternalType == ModbusFs2InternalType.Boolean)
                            {
                                bool val = inputs[ch.ModbusDataAddress - buf.startAddress];
                                ch.DoUpdate(val, dt, ChannelStatusFlags.Good);
                            }
                            else
                            if (self.LoggingLevel >= ModbusLog.logWarnings)
                            {
                                Env.Current.Logger.LogWarning(string.Format(StringConstants.ErrConvert,
                                                                            self.Name, ch.Name, ch.DeviceDataType.ToString(), ch.ModbusFs2InternalType.ToString()));
                            }
                        }
                        break;
                    }   // Case
                    if (self.failures.ContainsKey(buf.slaveId))
                    {
                        // failure signal defined
                        self.failures[buf.slaveId].Value = false;
                    }
                }   // If
                else
                {
                    buf.pauseCounter--;
                }
            }   // Try
            catch (Modbus.SlaveException e)
            {
                buf.pauseCounter = self.FailedCount;
                if (self.failures.ContainsKey(buf.slaveId))
                {
                    // failure signal defined
                    self.failures[buf.slaveId].Value = true;
                }
                foreach (ModbusChannelImp ch in buf.channels)
                {
                    ch.StatusFlags = ChannelStatusFlags.Bad;
                }
                if (self.LoggingLevel >= ModbusLog.logWarnings)
                {
                    Env.Current.Logger.LogWarning(string.Format(StringConstants.ErrReceive,
                                                                self.Name, buf.slaveId, buf.ModbusDataType.ToString(), buf.startAddress, buf.numInputs, e.Message));
                }
            }
            catch (TimeoutException e)
            {
                buf.pauseCounter = self.FailedCount;
                if (self.failures.ContainsKey(buf.slaveId))
                {
                    // failure signal defined
                    self.failures[buf.slaveId].Value = true;
                }
                foreach (ModbusChannelImp ch in buf.channels)
                {
                    ch.StatusFlags = ChannelStatusFlags.Bad;
                }
                if (self.LoggingLevel >= ModbusLog.logWarnings)
                {
                    Env.Current.Logger.LogWarning(string.Format(StringConstants.ErrReceive,
                                                                self.Name, buf.slaveId, buf.ModbusDataType.ToString(), buf.startAddress, buf.numInputs, e.Message));
                }
            }
        }
示例#19
0
        private async void ExecuteFunction()
        {
            try
            {
                //每次操作是要开启串口 操作完成后需要关闭串口
                //目的是为了slave更换连接是不报错
                if (port.IsOpen == false)
                {
                    port.Open();
                }
                //根据功能码写操作方法
                if (functionCode != null)
                {
                    switch (functionCode)
                    {
                    case "01 Read Coils":    //读取单个线圈
                        SetReadParameters();
                        coilsBuffer = master.ReadCoils(slaveAddress, startAddress, numberOfPoints);

                        for (int i = 0; i < coilsBuffer.Length; i++)
                        {
                            SetMsg(coilsBuffer[i] + " ");
                        }
                        SetMsg("\r\n");
                        break;

                    case "02 Read DisCrete Inputs":    //读取输入线圈/离散量线圈
                        SetReadParameters();

                        coilsBuffer = master.ReadInputs(slaveAddress, startAddress, numberOfPoints);
                        for (int i = 0; i < coilsBuffer.Length; i++)
                        {
                            SetMsg(coilsBuffer[i] + " ");
                        }
                        SetMsg("\r\n");
                        break;

                    case "03 Read Holding Registers":    //读取保持寄存器
                        SetReadParameters();
                        registerBuffer = master.ReadHoldingRegisters(slaveAddress, startAddress, numberOfPoints);
                        for (int i = 0; i < registerBuffer.Length; i++)
                        {
                            SetMsg(registerBuffer[i] + " ");
                        }
                        SetMsg("\r\n");
                        break;

                    case "04 Read Input Registers":    //读取输入寄存器
                        SetReadParameters();
                        registerBuffer = master.ReadInputRegisters(slaveAddress, startAddress, numberOfPoints);
                        for (int i = 0; i < registerBuffer.Length; i++)
                        {
                            SetMsg(registerBuffer[i] + " ");
                        }
                        SetMsg("\r\n");
                        break;

                    case "05 Write Single Coil":    //写单个线圈
                        SetWriteParametes();
                        await master.WriteSingleCoilAsync(slaveAddress, startAddress, coilsBuffer[0]);

                        break;

                    case "06 Write Single Registers":    //写单个输入线圈/离散量线圈
                        SetWriteParametes();
                        await master.WriteSingleRegisterAsync(slaveAddress, startAddress, registerBuffer[0]);

                        break;

                    case "0F Write Multiple Coils":    //写一组线圈
                        SetWriteParametes();
                        await master.WriteMultipleCoilsAsync(slaveAddress, startAddress, coilsBuffer);

                        break;

                    case "10 Write Multiple Registers":    //写一组保持寄存器
                        SetWriteParametes();
                        await master.WriteMultipleRegistersAsync(slaveAddress, startAddress, registerBuffer);

                        break;

                    default:
                        break;
                    }
                }
                else
                {
                    MessageBox.Show("请选择功能码!");
                }
                //关闭串口
                port.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }