public virtual void WriteMultipleRegisters() { ushort testAddress = 120; ushort[] testValues = new ushort[] { 10, 20, 30, 40, 50 }; ushort[] originalValues = Master.ReadHoldingRegisters(SlaveAddress, testAddress, (ushort)testValues.Length); Master.WriteMultipleRegisters(SlaveAddress, testAddress, testValues); ushort[] newValues = Master.ReadHoldingRegisters(SlaveAddress, testAddress, (ushort)testValues.Length); Assert.AreEqual(testValues, newValues); Master.WriteMultipleRegisters(SlaveAddress, testAddress, originalValues); }
/// <summary> /// Запись желаемых параметров в устройство. /// </summary> protected virtual void SettingsWrite() { if (settings != null && !init) { ushort[] values = new ushort[aSettingsLength - aSettingsStart]; bool changes = false; values[aSettingsFlagsOffset] = FlagsWriteableWanted; changes |= (_flagsWriteable ^ FlagsWriteableWanted) != 0; // parameters foreach (var p in settings) // table { if (p != null) { values[aSettingsParametersOffset + GetId(p)] = p.WantedValue; //values[aSettingsParametersOffset + p.ID] = p.WantedValue; changes |= p.RawValue != p.WantedValue; // несовпадение желаемого с действительным } } if (changes) // весь пакет настроек { ioDelay(); master.WriteMultipleRegisters(DeviceID, aSettingsStart, values); return; } } // default //ioDelay(); //master.WriteSingleRegister(DeviceID, aSettingsStart, wzoom); }
public void WriteMultipleRegisters(ushort start, ushort[] values) { if (RTUConnected || TCPConnected) { lock (_Locker) _Master.WriteMultipleRegisters(1, start, values); } }
private void MainWork() { var res = Master.ReadHoldingRegisters(1, 4008, 3); for (int i = 0; i < res.Length; i++) { res[i]++; } var id = (ushort)Thread.CurrentThread.ManagedThreadId; Master.WriteMultipleRegisters(1, 4008, new ushort[] { id, id, id, id }); }
public int writeMultiRegisters(ModbusRegisters regs) { if (master == null) { commsts = COMMSTS_UNKONOWN; return(RET_INITFAILURE); } if (tcpClient == null) { commsts = COMMSTS_PORTNOTOPEN; return(RET_INITFAILURE); } lock (locker) { try { for (int i = 0; i < regs.numRegisters; i++) { regs.values[i] = regs.stReg[i].value; } master.WriteMultipleRegisters(regs.slaveid, regs.startAddress, regs.values); } catch (TimeoutException ex) { //LogClass.GetInstance().WriteLogFile("WriteMultipleRegisters Timeout:" + port.WriteTimeout.ToString()); //MessageBox.Show("Serial Port Write Timeout:" + port.WriteTimeout.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); if (rtycnt++ < MAX_RETYR_COUNT) { return(RET_TIMEOUT); } else { commsts = COMMSTS_FAILURE; return(RET_COMMERROR); } } catch (Exception ex) { LogClass.GetInstance().WriteExceptionLog(ex); //MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); commsts = COMMSTS_FAILURE; return(RET_FAILURE); } } rtycnt = 0; commsts = COMMSTS_NORMAL; return(RET_OK); }
/// <summary> /// Write a block of contiguous 32 bit holding registers. /// </summary> /// <param name="master">The Modbus master.</param> /// <param name="slaveAddress">Address of the device to write to.</param> /// <param name="startAddress">Address to begin writing values.</param> /// <param name="data">Values to write.</param> public static void WriteMultipleRegisters32(this ModbusMaster master, byte slaveAddress, ushort startAddress, uint[] data) { if (master == null) { throw new ArgumentNullException("master"); } if (data == null) { throw new ArgumentNullException("data"); } if (data.Length == 0 || data.Length > 61) { throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The length of argument data must be between 1 and 61 inclusive.")); } master.WriteMultipleRegisters(slaveAddress, startAddress, Convert(data).ToArray()); }
/// <summary> /// Write a block of contiguous 32 bit holding registers. /// </summary> /// <param name="master">The Modbus master.</param> /// <param name="slaveAddress">Address of the device to write to.</param> /// <param name="startAddress">Address to begin writing values.</param> /// <param name="data">Values to write.</param> public static void WriteMultipleRegisters32( this ModbusMaster master, byte slaveAddress, ushort startAddress, uint[] data) { if (master == null) { throw new ArgumentNullException(nameof(master)); } if (data == null) { throw new ArgumentNullException(nameof(data)); } if (data.Length is 0 or > 61) { throw new ArgumentException("The length of argument data must be between 1 and 61 inclusive."); } master.WriteMultipleRegisters(slaveAddress, startAddress, Convert(data).ToArray()); }
private Dictionary <int, string> SendRequests(ModbusMaster master, MasterSettings masterSettings) { if (master == null) { return(null); } var results = new Dictionary <int, string>(); foreach (var slave in masterSettings.SlaveSettings) { string hexResults = ""; PackagesCounter.RequestedPackagesCount += 1; try { if (masterSettings.IsLoggerEnabled) { Logger.WriteDebug($"Sent request to a slave: DeviceId = {slave.DeviceId}; SlaveAddress={slave.StartAddress}; NumberOfRegisters={slave.NumberOfRegisters}."); } switch (slave.ActionType) { case ActionTypes.Read: var registers = master.ReadHoldingRegisters(slave.DeviceId, slave.StartAddress, slave.NumberOfRegisters); if (registers == null || registers.Length == 0) { throw new EmptyResultException( $"Slave with address {slave.DeviceId} returned an empty result when reading {slave.NumberOfRegisters} registers starting with register number {slave.StartAddress}."); } PackagesCounter.RecievedPackagesCount += 1; isConnectionLost = false; var inputs = registers.ConvertToBitArray(); hexResults = inputs.ConvertToHex(); var startAddress = slave.StartAddress; foreach (var type in slave.Types) { switch (type.Item2) { case ModbusDataType.SInt16: // Берём из массива битов первые 16, чтобы сконвертировать их в знаковое 16-битное целое число. var sInt16Part = inputs.Take(8 * type.Item1).ToArray(); // Обрезаем у массива эти первые 16 бит (16 бит = 2 байта). inputs = inputs.Skip(8 * type.Item1).ToArray(); // Преобразуем массив битов в строку, состоящую из единиц и нулей. var sInt16BinaryString = string.Join("", sInt16Part.Select(x => x ? 1 : 0)); // Конвертируем полученное двоичное число в знаковое 16-битное целое число. var sInt16 = Convert.ToInt16(sInt16BinaryString, 2); // Добавляем полученное число в список значений. results.Add(startAddress, sInt16.ToString()); // Перемещаем указатель на следующий регистр (16 бит = 2 байта = 1 регистр) startAddress += (ushort)(type.Item1 / 2); break; case ModbusDataType.UInt16: // Берём из массива битов первые 16, чтобы сконвертировать их в беззнаковое 16-битное целое число. var uInt16Part = inputs.Take(8 * type.Item1).ToArray(); // Обрезаем у массива эти первые 16 бит (16 бит = 2 байта). inputs = inputs.Skip(8 * type.Item1).ToArray(); // Преобразуем массив битов в строку, состоящую из единиц и нулей. var binaryString = uInt16Part.Select(x => x ? 1 : 0); // Конвертируем полученное двоичное число в беззнаковое 16-битное целое число. var uShort = Convert.ToUInt16(string.Join("", binaryString), 2); // Добавляем полученное число в список значений. results.Add(startAddress, uShort.ToString()); // Перемещаем указатель на следующий регистр (16 бит = 2 байта = 1 регистр) startAddress += (ushort)(type.Item1 / 2); break; case ModbusDataType.SInt32: // Берём из массива битов первые 32, чтобы сконвертировать их в знаковое 32-битное целое число. var sInt32Part = inputs.Take(8 * type.Item1).ToArray(); // Обрезаем у массива эти первые 32 бит (32 бит = 4 байта). inputs = inputs.Skip(8 * type.Item1).ToArray(); // Преобразуем массив битов в строку, состоящую из единиц и нулей. var sInt32BinaryString = sInt32Part.Select(x => x ? 1 : 0); // Конвертируем полученное двоичное число в знаковое 32-битное целое число. var sInt32 = Convert.ToInt32(string.Join("", sInt32BinaryString), 2); // Добавляем полученное число в список значений. results.Add(startAddress, sInt32.ToString()); // Перемещаем указатель на следующий регистр (32 бита = 4 байта = 2 регистра) startAddress += (ushort)(type.Item1 / 2); break; case ModbusDataType.UInt32: // Берём из массива битов первые 32, чтобы сконвертировать их в беззнаковое 32-битное целое число. var uInt32Part = inputs.Take(8 * type.Item1).ToArray(); // Обрезаем у массива эти первые 32 бит (32 бит = 4 байта). inputs = inputs.Skip(8 * type.Item1).ToArray(); // Преобразуем массив битов в строку, состоящую из единиц и нулей. var binaryUInt32String = uInt32Part.Select(x => x ? 1 : 0); // Конвертируем полученное двоичное число в беззнаковое 32-битное целое число. var uInt32 = Convert.ToUInt32(string.Join("", binaryUInt32String), 2); // Добавляем полученное число в список значений. results.Add(startAddress, uInt32.ToString()); // Перемещаем указатель на следующий регистр (32 бита = 4 байта = 2 регистра) startAddress += (ushort)(type.Item1 / 2); break; case ModbusDataType.Hex: // Берём из массива битов первые 32, чтобы сконвертировать их в беззнаковое 32-битное целое число. var hexPart = inputs.Take(8 * type.Item1).ToArray(); // Обрезаем у массива эти первые 32 бит (32 бит = 4 байта). inputs = inputs.Skip(8 * type.Item1).ToArray(); // Преобразуем массив битов в строку, состоящую из единиц и нулей. var binaryHexString = hexPart.Select(x => x ? 1 : 0); // Конвертируем полученное десятичное число в знаковое 32-битное целое число, после этого конвертируем число в 16-ричную систему счисления. var hex = Convert.ToUInt32(string.Join("", binaryHexString), 2).ToString("X"); // Добавляем полученное число в список значений. results.Add(startAddress, $"0x{hex}"); // Перемещаем указатель на следующий регистр (32 бита = 4 байта = 2 регистра) startAddress += (ushort)(type.Item1 / 2); break; case ModbusDataType.UtcTimestamp: // В данном случае мы должны считать целое число (тоже беззнаковое 32-битное) и преобразовать к дате. // Берём из массива битов первые 32, чтобы сконвертировать их в знаковое 32-битное целое число. var utcTimestampPart = inputs.Take(8 * type.Item1).ToArray(); inputs = inputs.Skip(8 * type.Item1).ToArray(); // Преобразуем массив битов в строку, состоящую из единиц и нулей. var binaryUtcTimestampString = utcTimestampPart.Select(x => x ? 1 : 0); // Конвертируем полученное двоичное число в беззнаковое 32-битное целое число. var utcTimestamp = Convert.ToUInt32(string.Join("", binaryUtcTimestampString), 2); // Добавляем полученное число в список значений. results.Add(startAddress, new DateTime(1970, 1, 1).AddSeconds(utcTimestamp) .ToLocalTime() .ToString("yyyy.MM.dd HH:mm:ss")); // Перемещаем указатель на следующий регистр (32 бита = 4 байта = 2 регистра) startAddress += (ushort)(type.Item1 / 2); break; case ModbusDataType.String: bool[] stringPart; if (inputs.Length > 8 * type.Item1) { stringPart = inputs.Take(8 * type.Item1).ToArray(); inputs = inputs.Skip(8 * type.Item1).ToArray(); results.Add(startAddress, stringPart.ConvertToString()); startAddress += (ushort)(type.Item1 / 2); } else { stringPart = inputs; inputs = new bool[0]; results.Add(startAddress, stringPart.ConvertToString()); startAddress += (ushort)(stringPart.Length / 16); } break; default: throw new ArgumentOutOfRangeException(); } } if (masterSettings.IsLoggerEnabled) { Logger.WriteDebug($"Recieved data from slave: DeviceId = {slave.DeviceId}; SlaveAddress={slave.StartAddress}; NumberOfRegisters={slave.NumberOfRegisters}; {hexResults}"); } break; case ActionTypes.Write: var data = new ushort[] { Convert.ToUInt16(slave.Formula) }; master.WriteMultipleRegisters(slave.DeviceId, slave.StartAddress, data); if (masterSettings.IsLoggerEnabled) { Logger.WriteDebug($"Sent data to slave: DeviceId = {slave.DeviceId}; SlaveAddress={slave.StartAddress}; {data}"); } break; } } catch (SlaveException slaveException) { switch (slaveException.SlaveExceptionCode) { case 130: if (!isConnectionLost) { Logger.Write(slaveException.Message); } isConnectionLost = true; break; default: if (loggerEnabled) { Logger.Write(slaveException.Message); } else { throw slaveException; } break; } } catch (Exception exception) { if (loggerEnabled) { Logger.Write(exception.Message); } else { throw exception; } } } return(results); }