Modbus TCP client not detecting arduino but can still write to registers.


I am working on a project that interfaces a client PC with a environmental chamber over Modbus TCP. I am using KEPServerEX as the OPC server to communicate over TCP with the ardunio.

I am using 2 holding registers, one is being used to hold a setpoint value set by the PC and the other is holding the chamber temperature set by the chamber.

The problem I am getting is that the OPC server can’t seem to get the data from the arduino it says that the value is “Unknown” and the quality of the data is “Bad”. Also when I try and send it some data using the OPC Quick Client it says unable to write to address on device but when I look at the output the arduino gives me the value what was sent. So the write did work but the OPC server thinks it didn’t work.

I am not sure what the problem could be weather it might be something with the ArduinoModbus library or the OPC server or my code.

I am looking for any incite on how to make my project work.

For some other information the OPC Quick Client error when I try and write from it is "Failed on item ‘W.Mid_Chamber.TSW’ for asynchronous 2.0 write transaction 6C6D0CCF (HR=0x80004005) "

Here is my code:

#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoModbus.h>

EthernetServer server(502);
ModbusTCPServer modbusTCPServer;

EthernetClient client;
float temp_send=25;
bool start = true;
float setpoint=0;
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
long interval1=500;
long interval2 =500;
uint16_t setpoint_modbus[2]={16840,0};
void setup() {
  byte mac[] = { 0xA8, 0x61, 0x0A, 0xAE, 0x5C, 0x88 };
  IPAddress ip (192,168,0,223);
  IPAddress myDns(192, 168, 1, 1);
  IPAddress gateway(192, 168, 0, 1);
  byte subnet(255, 255, 255, 0);
  // put your setup code here, to run once:

   while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only

  Ethernet.begin(mac, ip, myDns, gateway, subnet);
  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    //Serial.println(F("Ethernet shield was not found.  Sorry, can't run without hardware."));
    while (true) {
      ; // do nothing, no point running without Ethernet hardware
  if (Ethernet.linkStatus() == LinkOFF) {
    //Serial.println(F("Ethernet cable is not connected."));
  modbusTCPServer.configureHoldingRegisters(0, 4);
  Serial.println("step up done");

float readascii(){//read serial data can covert to float
  String value;
  bool isneg=false;
  char input;
  uint8_t len = 0;
  float ans = 200;
    input =;
    if(((input-'0')>=0 &&(input-'0')<=9)||(input=='.')&&(len<8)||(input == '-')){
      value += (char)input;
      //Serial.println(F("made it here"));
      return ans;
  char valuechararray[len];
  ans = value.toFloat();
  return ans;
unsigned int f_2uint_int1(float float_number) {             // split the float and return first unsigned integer

  union f_2uint {
    float f;
    uint16_t i[2];

  union f_2uint f_number;
  f_number.f = float_number;

  return f_number.i[0];

unsigned int f_2uint_int2(float float_number) {            // split the float and return first unsigned integer

  union f_2uint {
    float f;
    uint16_t i[2];

  union f_2uint f_number;
  f_number.f = float_number;

  return f_number.i[1];


void loop() {
  // waits for client to be available
  EthernetClient client = server.available();
        // poll for Modbus TCP requests, while client connected
        if(start){ //init of chamber
          Serial.println("start system"); 
          Serial.println("set circulators = on");
          start = false;
        unsigned long currentMillis = millis();
        if(currentMillis - previousMillis1 >= interval1){
          Serial.print("set setpoint 1 = ");
          Serial.println(setpoint); //set setpoint for chamber 
          previousMillis1 = currentMillis;  
        if(currentMillis - previousMillis1 >= interval2){
          Serial.println("read pv 1");//ask chamber for temp
          temp_send=readascii(); //read chamber temp
          if(temp_send!=200){//if different send to client
            uint16_t low_order =f_2uint_int1(temp_send);
            uint16_t big_order =f_2uint_int2(temp_send);
            modbusTCPServer.holdingRegisterWrite(0x02,low_order);//send bits 0-15
            modbusTCPServer.holdingRegisterWrite(0x03,big_order);//send bits 16-31
          previousMillis1 = currentMillis;