Modbus TCP Slave

Hello
I am setting up an Arduino micro with a ENC28J60 Ethernet module to control a solenoid valve using Modbus. I want the valve to close when the value on a sensor I have setup that is outputting its values using Modbus TCP . My question is using this hardware and this Modbus Library, how do I read in the value coming off my other Modbus device?

Is your other ModBus device a client or a server? Post a link to the manual of that device.

https://www.honeywellanalytics.com/~/media/honeywell-analytics/products/midas/documents/midasa001-technical-manual-eng-rev22.pdf?la=en

Its a Honeywell Midas Gas Detector

That sensor is a ModBus TCP server, so to get the values you need a ModBus TCP client on your Arduino. The linked library has only support for the server part (in ModBus RTU that part is called a slave).

Are there any other TCP based Arduino Modbus libraries that would work? I am mainly trying to keep things on the network so I can remotely trigger things.

Would this library be suitable? GitHub - luizcantoni/mudbus: Automatically exported from code.google.com/p/mudbus

hairem:
Would this library be suitable? GitHub - luizcantoni/mudbus: Automatically exported from code.google.com/p/mudbus

No, same problem, only implements (part) of a ModBus TCP server.

Are there any other TCP based Arduino Modbus libraries that would work?

I'm only using ModBus RTU (serial variant) myself, so I'm not up-to-date with libraries for the networked version of the protocol.

/*
 * return
 *   - 0 is success
 *   - negative is comm error
 *   - positive value is modbus protocol exception code
 */
int modbusRequest(byte uid, unsigned int addr, byte len, short *regs) {

  const byte CODE_IX = 7;
  const byte ERR_CODE_IX = 8;
  const byte LENGTH_IX = 8;
  const byte DATA_IX = 9;

  int err = modbusConnection();
  if (err != 0)
    return err;

  byte request[] = {0, 1, 0, 0, 0, 6, uid, FNC_READ_REGS, (byte) (addr / 256), (byte) (addr % 256), 0, len};
  modbus.write(request, sizeof(request));

  int respDataLen = len * 2;
  byte response[max((int) DATA_IX, respDataLen)];
  int readLen = modbus.readBytes(response, DATA_IX);
  if (readLen < DATA_IX) {
    modbus.stop();
    return MODBUS_NO_RESPONSE;
  }
  switch (response[CODE_IX]) {
    case FNC_READ_REGS:
      break;
    case (FNC_ERR_FLAG | FNC_READ_REGS):
      return response[ERR_CODE_IX]; // 0x01, 0x02, 0x03 or 0x11
    default:
      return -3;
  }
  if (response[LENGTH_IX] != respDataLen)
    return -2;
  readLen = modbus.readBytes(response, respDataLen);
  if (readLen < respDataLen)
    return -4;
  for (int i = 0, j = 0; i < len; i++, j += 2) {
    regs[i] = response[j] * 256 + response[j + 1];
  }
  return 0;
}

int modbusWriteSingle(unsigned int address, int val) {

  const byte CODE_IX = 7;
  const byte ERR_CODE_IX = 8;
  const byte RESPONSE_LENGTH = 9;

  int err = modbusConnection();
  if (err != 0)
    return err;

  byte req[] = { 0, 1, 0, 0, 0, 6, 1, FNC_WRITE_SINGLE, // header
        (byte) (address / 256), (byte) (address % 256),
        (byte) (val / 256), (byte) (val % 256)};

  modbus.write(req, sizeof(req));

  byte response[RESPONSE_LENGTH];
  int readLen = modbus.readBytes(response, RESPONSE_LENGTH);
  if (readLen < RESPONSE_LENGTH) {
    modbus.stop();
    return MODBUS_NO_RESPONSE;
  }
  switch (response[CODE_IX]) {
    case FNC_WRITE_SINGLE:
      break;
    case (FNC_ERR_FLAG | FNC_WRITE_SINGLE):
      return response[ERR_CODE_IX]; // 0x01, 0x02, 0x03, 0x04 or 0x11
    default:
      return -3;
  }
  while (modbus.read() != -1); // 4 more bytes address and reg value
  return 0;
}

int modbusConnection() {
  if (!modbus.connected()) {
    modbus.stop();
    if (!modbus.connect(symoAddress, 502))
      return MODBUS_CONNECT_ERROR;
    modbus.setTimeout(2000);
    msg.print(F(" modbus reconnect"));
  }
  return 0;
}

global variable modbus is EthernetClient or WiFiClient