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); }
/// <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()); }
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); }
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]; } } } }
//метод читает меркер из ПЛК 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); } }
/// <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"); } }
/// <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)); } } }
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) { } } }
/* * * /// <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: ошибка при откючении стенда }
private ushort[] ReadCoils(ushort startAddress, ushort pointCount) { return(m_modbusConnection.ReadCoils(m_unitID, startAddress, pointCount).Select(value => (ushort)(value ? 1 : 0)).ToArray()); }
protected override bool[] ReadCore(IModbusMaster modbusMaster, byte slaveId, ushort startAddress, ushort numberOfPoints) { return(modbusMaster.ReadCoils(slaveId, startAddress, numberOfPoints)); }
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); } }
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; } } }
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)); } } }
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); } }