Цитата Сообщение от polubencev Посмотреть сообщение
Вот смотрите, через modscan64 пытаешься ТРМ считать, не получается. Там адреса с 4хххх. Например через Овен ОРС, указываешь 4105 все идет
modscan64 платная программа и даже воспроизвести эксперимент не каждый сможет.

Для изучения работы с Modbus читал уставку в ТРМ212 самописным тестовым кодом на FreePascal с использованием библиотеки работы с COM-портом Synaser

Обратите внимание, что после приёма значения из порта, для адекватного вывода на печать приходилось выполнять обмен байт в принятом 16 или 32 разрядном числе.

Кроме того, число типа Float занимает 2 регистра и не может быть типом MW, скорее уж MD - DWORD.
Код:
      MB_ReadUInt16(ser, ModBusSetting_Addr, trm212SP, uiR);
      Writeln(uiR);
      Sleep(100);
      MB_ReadSignedInt16(ser, ModBusSetting_Addr, trm212SP, siR);
      Writeln(siR);
      Sleep(100);
      MB_ReadFloat32(ser, ModBusSetting_Addr, trm212SP_, fR);
      Writeln(fR: 0: 1);
      Sleep(100);
      MB_ReadChar8(ser, ModBusSetting_Addr, trm212DEV, cR);
      Writeln(cR);
      Sleep(100);
      MB_ReadChar8(ser, ModBusSetting_Addr, trm212VER, cR);
      Writeln(cR);
Сама функция чтения была обёрткой над вызовом функции 03
Код:
function MB_ReadUInt16(var SerialPort: TBlockSerial; DevAddr, RegNo: word;
  var R: UInt16): integer;
begin
  Result := MB_ReadRegesters(SerialPort, DevAddr, RegNo, 1, R);
  R := Swap(R);
end;

function MB_ReadFloat32(var SerialPort: TBlockSerial; DevAddr, RegNo: word;
  var R: Float32): integer;
var
  t: TDWordConvert;
begin
  Result := MB_ReadRegesters(SerialPort, DevAddr, RegNo, 2, t);
  t.dw := Swap(t.dw);
  t.w0 := Swap(t.w0);
  t.w1 := Swap(t.w1);
  R := t.f32;
end;
Вызов функции 03
Код:
function MB_ReadRegesters(var SerialPort: TBlockSerial;
  DevAddr, RegNo, RegCount: word; var ResBuffer): integer;
var
  Buffer: TBuffer;
  crc16: word;
  i: integer;
  ReadLen: word;
begin
  if not SerialPort.InstanceActive then
  begin
    //ComException('can not read from a closed port.');
    exit;
  end;

  if (DevAddr > 247) then
  begin
    if DevAddr > 40000 then
      DevAddr := DevAddr - 40001
    else
      exit;
  end;
{
Запрос
00 - адрес устройства
01 - функция
02 - адрес первого из группы считываемых регистров hi
03 - то же, lo
04 - количество считываемых регистров hi
05 - то же, lo
06 - crc16 lo
07 - то же hi
}
  Buffer[0] := lo(DevAddr);
  Buffer[1] := $03;
  Buffer[2] := hi(RegNo);
  Buffer[3] := lo(RegNo);
  Buffer[4] := hi(RegCount);
  Buffer[5] := lo(RegCount);
  crc16 := Crc16InitValue;
  for i := 0 to 5 do
    Crc16 := UpdateCrc16(Buffer[i], crc16);
  Buffer[6] := lo(crc16);
  Buffer[7] := hi(crc16);

  SerialPort.SendBuffer(@Buffer, 8);
  SerialPort.RecvBufferEx(@Buffer, RegCount * 2 + 5, Timeout_1s div 10);

{
Ответ в корректном случае
00 - адрес устройства
01 - функция
02 - количество байт в ответных данных
03 - данные lo
04 - данные hi
05 - CRC16 lo
06 - CRC16 hi

В случае ошибки
или таймаут
или устройство пришлёт
00 - адрес устройства
01 - (=$83) код функции с установленным старшим битом
02 - код ошибки (exception code)
03 - lo crc16
04 - hi crc16
}

  if Buffer[01] = $83 then
  begin
    ReadLen := 5;
  end
  else
  begin
    ReadLen := Buffer[2] + 3;
  end;
  Crc16 := Crc16InitValue;
  for i := 0 to ReadLen - 1 do
    Crc16 := UpdateCrc16(Buffer[i], crc16);
  if Crc16 <> Buffer[ReadLen] + 256 * Buffer[succ(ReadLen)] then
  begin
    //ошибка приёма пакета - не правильный crc16
  end
  else
  begin
    //writeln('CRC16 Ok');
  end;
  if RegCount * 2 = Buffer[02] then
  begin
    move(Buffer[3], TBuffer(ResBuffer), RegCount * 2);
  end
  else
  begin
    //ошибка приёма пакета - не правильное количество принятых байт
  end;
  Result := SerialPort.LastError;
end;
При этом, адреса регистров задавались в 16-ричной системе счисления
Код:
  {LvoP. Оперативные параметры (только чтение: Modbus-функция 0x03)}
  trm212STAT   = $0000; {binary}
  trm212PV1    = $0001; {Signed Int16}
  trm212PV2    = $0002; {Signed Int16}
  trm212LUPV   = $0003; {Signed Int16}
  trm212SP     = $0004; {Signed Int16} {запись: Modbus-функция 0x10}
  trm212SET_P  = $0005; {Signed Int16}
  trm212O      = $0006; {Int16}
  {LvoP. Рабочие параметры прибора (чтение: Modbus-функция 0x03), запись: Modbus-функция 0x10}
  trm212r_L    = $0007; {Int16}
  trm212r_out  = $0008; {Signed Int16}
  trm212R_S    = $0009; {Int16}
  trm212AT     = $000A; {Int16}
  {LvoP. Оперативные параметры прибора только чтение: Modbus-функция 0x03)}
  trm212DEV    = $1000; {Char[8]}
  trm212VER    = $1004; {Char[8]}
  trm212STAT_  = $1008; {binary}
  trm212PV1_   = $1009; {Float32}
  trm212PV2_   = $100B; {Float32}
  trm212LUPV_  = $100D; {Float32}
  trm212SP_    = $100F; {Float32}
  trm212SET_P_ = $1011; {Float32}
  trm212O_     = $1013; {Float32}