Цитата Сообщение от Гарчев Евгений Посмотреть сообщение
Я надеюсь, тут опечатка... или же Вы изменяете адрес начального опрашиваемого регистра для функции WriteMultiplyRegister (0х10), предполагая что меняете номер функции. Можете полностью предоставить структуру Вашей функции?

Какая размерность массива?
Функции:
Сначала сюда
/// <summary>
/// Write a block of 1 to 123 contiguous 16 bit holding registers.
/// </summary>
/// <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 void WriteMultipleRegisters(byte slaveAddress, ushort startAddress, ushort[] data)
{
ValidateData("data", data, 123);

var request = new WriteMultipleRegistersRequest(slaveAddress, startAddress, new RegisterCollection(data));
Transport.UnicastMessage<WriteMultipleRegistersRes ponse>(request);
}

Потом сюда


internal virtual T UnicastMessage<T>(IModbusMessage message) where T : IModbusMessage, new()
{
IModbusMessage response = null;
int attempt = 1;
bool success = false;

do
{
try
{
lock (_syncLock)
{
Write(message);

bool readAgain;
do
{
readAgain = false;
response = ReadResponse<T>();

var exceptionResponse = response as SlaveExceptionResponse;
if (exceptionResponse != null)
{
// if SlaveExceptionCode == ACKNOWLEDGE we retry reading the response without resubmitting request
readAgain = exceptionResponse.SlaveExceptionCode == Modbus.Acknowledge;
if (readAgain)
{
Debug.WriteLine(
"Received ACKNOWLEDGE slave exception response, waiting {0} milliseconds and retrying to read response.",
_waitToRetryMilliseconds);
Sleep(WaitToRetryMilliseconds);
}
else
{
throw new SlaveException(exceptionResponse);
}
}
else if (ShouldRetryResponse(message, response))
{
readAgain = true;
}
} while (readAgain);
}

ValidateResponse(message, response);
success = true;
}
catch (SlaveException se)
{
if (se.SlaveExceptionCode != Modbus.SlaveDeviceBusy)
throw;

if (SlaveBusyUsesRetryCount && attempt++ > _retries)
throw;

Debug.WriteLine(
"Received SLAVE_DEVICE_BUSY exception response, waiting {0} milliseconds and resubmitting request.",
_waitToRetryMilliseconds);
Sleep(WaitToRetryMilliseconds);
}
catch (Exception e)
{
if (e is FormatException ||
e is NotImplementedException ||
e is TimeoutException ||
e is IOException)
{
Debug.WriteLine("{0}, {1} retries remaining - {2}", e.GetType().Name, _retries - attempt + 1, e);

if (attempt++ > _retries)
throw;
}
else
{
throw;
}
}
} while (!success);

return (T)response;
}

Дальше

internal override IModbusMessage ReadResponse<T>()
{
byte[] frameStart = Read(ResponseFrameStartLength);
byte[] frameEnd = Read(ResponseBytesToRead(frameStart));
byte[] frame = Enumerable.Concat(frameStart, frameEnd).ToArray();
Debug.WriteLine("RX: {0}", string.Join(", ", frame));

return CreateResponse<T>(frame);
}

Дальше

public virtual byte[] Read(int count)
{
byte[] frameBytes = new byte[count];
int numBytesRead = 0;

while (numBytesRead != count)
numBytesRead += StreamResource.Read(frameBytes, numBytesRead, count - numBytesRead);

return frameBytes;
}

дальше сюда

public int Read(byte[] buffer, int offset, int count)
{
try
{
return _serialPort.Read(buffer, offset, count);
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace, ex.Message, ex.InnerException);
}
return 0;

}

и тут вылетают Exception и застревает, потому как прошлая функция ждет ответ величиной 4


Здесь в класса Modbus насколько я понял есть коды поддерживаемых функций и видимо 10 как раз не поддерживается, или я что то не так понимаю

Modbus:
namespace Modbus
{
/// <summary>
/// Defines constants related to the Modbus protocol.
/// </summary>
internal static class Modbus
{
// supported function codes
public const byte ReadCoils = 1;
public const byte ReadInputs = 2;
public const byte ReadHoldingRegisters = 3;
public const byte ReadInputRegisters = 4;
public const byte WriteSingleCoil = 5;
public const byte WriteSingleRegister = 6;
public const byte Diagnostics = 8;
public const ushort DiagnosticsReturnQueryData = 0;
public const byte WriteMultipleCoils = 15;
public const byte WriteMultipleRegisters = 16;
public const byte ReadWriteMultipleRegisters = 23;


Вот так записываю в тестовом проекте

Запись:
SerialPort port = new SerialPort("COM3");

// configure serial port
port.BaudRate = 115200;
port.DataBits = 8;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.ReadTimeout = 30;
port.Open();

// create modbus master
IModbusSerialMaster master = ModbusSerialMaster.CreateRtu(port);

master.WriteSingleRegister(17,5,10);
master.WriteMultipleRegisters(17,5,new ushort[] {100});