Erratic Hex to decimal conversion

Erratic Hex to decimal conversion

I have this code that almost works, the issue I have is that every now and then the Hex converted decimals are incorrect for the CO, NO, NO2 some others and can't determine why? As in the output you can see at 14:10:16.643 and 14:10:19.724 the conversion of 00CB should be 203 and not 3253.

I am using CO = strtol(COdata, NULL, 16); for the conversion.

The conversion is erratic and no pattern.

This is the typical response output from the analyzer with ;03xxxx as O2, ;04xxx as CO, ;05xxx as NO and so on. //$8C82;01C5;0200000000;0300D2;040001;050000;060000;078000;088000;09FFFE;0A02DC;0B02D1;0C0304;0D8000;0E8000;0F8000;10017B;1113;1213;2E8000;83

This code is written for an emission analyzer pulled in through an USB host shield and output through an ethernet shield minicking a PLC modbus register. I am only concerned with the hex conversion currently and the code is planned to be further optimized.

#include <stdlib.h>
#include <CP210x.h>
#include <usbhub.h>
#include "pgmstrings.h"
#include <SPI.h>

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

byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(169, 254, 0, 4); //ECOM Arduino address

EthernetClient ethClient;
ModbusTCPClient modbusTCPClient(ethClient);

IPAddress server(169, 254, 0, 2); //Server_PLC address

bool validateCheckSum(char *data, uint16_t dataLength, uint16_t checksum);
int hexchartoint(char hex);

//If need to change chip select pin CS/SS open library UsbCore.h find "typedef MAX3421e<P10, P9> MAX3421E"
//and change <SS, Int> to the corresponding pin#'s.
//Not used
//If using legacy library open Max3421e_constants.h find "define MAX_SS 10 and change "10"

String readString;

class CP210xAsync : public CP210xAsyncOper
{
  public:
    uint8_t OnInit(CP210x *pftdi);
};

uint8_t CP210xAsync::OnInit(CP210x *cp210x)
{
  uint8_t rcode = 0;
  rcode = cp210x->IFCEnable();
  if (rcode)
  {
    return rcode;
  }
  rcode = cp210x->SetBaudRate(9600); //changed from 115200
  if (rcode)
  {
    return rcode;
  }
  rcode = cp210x->SetDataBits(8);
  if (rcode)
  {
    return rcode;
  }
  rcode = cp210x->SetStopBits(CP210X_STOP_BITS_1);
  if (rcode)
  {
    return rcode;
  }
  rcode = cp210x->SetParity(CP210X_PARITY_NONE);
  if (rcode)
  {
    return rcode;
  }
  rcode = cp210x->SetFlowControl(CP210X_FLOW_CONTROL_OFF);
  if (rcode)
  {
    return rcode;
  }
  return rcode;
}

USB     Usb;
//USBHub Hub(&Usb);
CP210xAsync cp210xAsync;
CP210x cp210x(&Usb, &cp210xAsync);
uint8_t rcode;
int RCVDtotal = 0, RCVD = 0;
char data[140];
int j = 0;
int Sentcmd = 0;
int RCVDcmpt = 0;

//Start Test Variables
uint16_t O2 = 0;
char O2data[4];
uint16_t NO = 0;
char NOdata[4];
uint16_t NO2 = 0;
char NO2data[4];
uint16_t CO = 0;
char COdata[4];
uint16_t NOX = 0;
uint16_t Flow = 0;
char Flowdata[3];

uint16_t SO2 = 0;
char SO2data[4];
uint16_t airTemp = 0;
char airTempdata[4];
uint16_t gasTemp = 0;
char gasTempdata[4];
uint16_t sensorTemp = 0;
char sensorTempdata[4];

uint16_t SN = 0;
char SNdata[4];

int command = 0;
int index = 0;
String datas, dataf, datasn;
//End Test Variables

void setup()
{
  Serial.begin( 9600 );//115200

  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }
  else if (!Ethernet.linkStatus() == LinkOFF) {
    Serial.print("connected ");
  }

  Serial.println(F("Start"));
  if (Usb.Init() == -1)
    Serial.println(F("OSC did not start."));
  delay( 200 );
  Serial.println(F("Waiting for command"));
}

void loop()
{

  if (!modbusTCPClient.connected()) {
    // client not connected, start the Modbus TCP client
    Serial.println("Attempting to connect to Modbus TCP server");
    Ethernet.begin(mac, ip);

    if (!modbusTCPClient.begin(server, 502)) {
      Serial.println("Modbus TCP Client failed to connect!");
    }
    else {
      Serial.println("Modbus TCP Client connected");
    }
  }


  if (command == 1) {
    Usb.Task();
    if ( Usb.getUsbTaskState() == USB_STATE_RUNNING )  {
      if (Sentcmd == 0)   {
        char strbuf[] = "$0802EE\r"; //command 2 (0x02) read all sensors
        Serial.print(F("Command Sent: ")); Serial.println((char*)strbuf);
        rcode = cp210x.SndData(strlen(strbuf), (uint8_t*)strbuf); //send to analyzer
        Sentcmd = 1;
        delay(100);
      }
      uint8_t  buf[64]; //buf is an array of upto 64 integers
      uint16_t rcvd = 64;
      if (Sentcmd == 1) {
        rcode = cp210x.RcvData(&rcvd, buf);
        Serial.print(F("RCVD: ")); Serial.print(rcvd); Serial.print(F(" "));
        RCVD = rcvd;
        RCVDtotal += RCVD;
        if ( rcvd >= 1 && RCVDtotal <= 140) {
          Serial.print(F(" Total RCVD: ")); Serial.print(RCVDtotal); Serial.print(F(" "));
          for (uint16_t i = 0; i < rcvd ; j++, i++) {
            Serial.print((char)buf[i]);
            data[j] = buf[i];
          }
          Serial.println();
        }
        else if (RCVDtotal == 140) {
          RCVDcmpt = 1;
        }
      }
      if (RCVDcmpt == 1) {
        datas = "";
        for (uint16_t k = 0; k < 140 ; k++) {
          Serial.print(data[k]);
          datas = datas + data[k];
        }
        Serial.println();

        bool startRecord = false;
        if (data[0] == '$') {
          startRecord = true;
          //     Serial.println("Passed Start Record Check.");
        }

        bool correctLength = false;
        char lengthByteString[1];
        lengthByteString[0] = data[1];
        lengthByteString[1] = data[2];
        uint16_t lengthByte = strtol(lengthByteString, NULL, 16);
        if (lengthByte == 140) {
          correctLength = true;
          //    Serial.println("Passed Length Check.");
        }

        /*
                int CheckSum = hexchartoint(data[139]);
                 CheckSum = CheckSum + (hexchartoint(data[139]) * 16);

                Serial.println(CheckSum);

                bool goodCheckSum = validateCheckSum(data, lengthByte, CheckSum);

                if (goodCheckSum)
                  Serial.println("Passed CheckSum.");

        */


        //  if (correctLength && startRecord)
        {
          //0123456789111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999
          //          012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
          //$8C82;01C5;0200000000;0300D2;040001;050000;060000;078000;088000;09FFFE;0A02DC;0B02D1;0C0304;0D8000;0E8000;0F8000;10017B;1113;1213;2E8000;83
          //                      o2     co     no     no2    so2                  AT     GT     ST

          int indexo2 = datas.indexOf(";03") + 3; //o2 starts at 24
          int indexco = datas.indexOf(";04") + 3; //co starts at 31
          int indexno = datas.indexOf(";05") + 3; //38
          int indexno2 = datas.indexOf(";06") + 3; //45
          int indexso2 = datas.indexOf(";07") + 3; //52
          int indexat = datas.indexOf(";0A") + 3; //73
          int indexgt = datas.indexOf(";0B") + 3; //80
          int indexst = datas.indexOf(";0C") + 3; //87

          int rangeo2 = indexco - 3 - indexo2;
          int rangeco = indexno - 3 - indexco;
          int rangeno = indexno2 - 3 - indexno;
          int rangeno2 = indexso2 - 3 - indexno2;
          int rangeso2 = (datas.indexOf(";08")) - ((datas.indexOf(";07")) + 3);
          int rangeat = indexgt - 3 - indexat;
          int rangegt = indexst - 3 - indexgt;
          int rangest = (datas.indexOf(";0D")) - ((datas.indexOf(";0C")) + 3);

          Serial.print("O2 Index24: "); Serial.print(indexo2);  Serial.print(" Range: "); Serial.print(rangeo2); Serial.print(" Values: ");
          for (index = 0; index < rangeo2; index++) {
            O2data[index] = data[ indexo2 + index ];
            Serial.print(O2data[index]);
          }
          O2 = strtol(O2data, NULL, 16); //hex to string conversion
          Serial.print(" "); Serial.println( O2 / 10.0);

          Serial.print("CO Index31: "); Serial.print(indexco); Serial.print(" Range: "); Serial.print(rangeco); Serial.print(" Values: ");
          for (index = 0; index < rangeco; index++) {
            COdata[index] = datas[indexco + index];
            Serial.print(COdata[index]);
          }

          CO = strtol(COdata, NULL, 16);
          Serial.print(" "); Serial.println(CO);

          Serial.print("NO Index38: "); Serial.print(indexno); Serial.print(" Range: "); Serial.print(rangeno); Serial.print(" Values: ");
          for (index = 0; index < rangeno; index++) {
            NOdata[index] = datas[indexno + index];
            Serial.print(NOdata[index]);
          }

          NO = strtol(NOdata, NULL, 16);
          Serial.print(" "); Serial.println(NO);

          Serial.print("NO2 Index45: "); Serial.print(indexno2); Serial.print(" Range: "); Serial.print(rangeno2); Serial.print(" Values: ");
          for (index = 0; index < rangeno2; index++) {
            NO2data[index] = data[indexno2 + index];
            Serial.print(NO2data[index]);
          }
          NO2 = strtol(NO2data, NULL, 16);
          Serial.print(" "); Serial.println(NO2);

          Serial.print("SO2 Index52: "); Serial.print(indexso2); Serial.print(" Range: "); Serial.print(rangeso2); Serial.print(" Values: ");
          for (index = 0; index < rangeso2; index++) {
            SO2data[index] = data[indexso2 + index];
            Serial.print(SO2data[index]);
          }
          SO2 = strtol(SO2data, NULL, 16);
          Serial.print(" "); Serial.println(SO2);

          Serial.print("AT Index73: "); Serial.print(indexat); Serial.print(" Range: "); Serial.print(rangeat); Serial.print(" Values: ");
          for (index = 0; index < rangeat; index++) {
            airTempdata[index] = data[indexat + index];
            Serial.print(airTempdata[index]);
          }
          airTemp = strtol(airTempdata, NULL, 16);
          Serial.print(" "); Serial.println(airTemp / 10.0);

          Serial.print("GT Index80: "); Serial.print(indexgt); Serial.print(" Range: "); Serial.print(rangegt); Serial.print(" Values: ");
          for (index = 0; index < rangegt; index++) {
            gasTempdata[index] = data[indexgt + index];
            Serial.print(gasTempdata[index]);
          }
          gasTemp = strtol(gasTempdata, NULL, 16);
          Serial.print(" "); Serial.println(gasTemp / 10.0);

          Serial.print("ST Index87: "); Serial.print(indexst); Serial.print(" Range: "); Serial.print(rangest); Serial.print(" Values: ");
          for (index = 0; index < rangest; index++) {
            sensorTempdata[index] = data[indexst + index];
            Serial.print(sensorTempdata[index]);
          }
          sensorTemp = strtol(sensorTempdata, NULL, 16);
          Serial.print(" "); Serial.println(sensorTemp / 10.0);

          NOX = NO + NO2;
          Serial.print("NOX: "); Serial.println(NOX);

          if (!modbusTCPClient.holdingRegisterWrite(0x001D, O2)) {
            Serial.print("Failed to write MHR30! ");
            Serial.println(modbusTCPClient.lastError());
          }

          if (!modbusTCPClient.holdingRegisterWrite(0x001E, CO)) {
            Serial.print("Failed to write MHR31! ");
            Serial.println(modbusTCPClient.lastError());
          }

          if (!modbusTCPClient.holdingRegisterWrite(0x001F, NO)) {
            Serial.print("Failed to write MHR32! ");
            Serial.println(modbusTCPClient.lastError());
          }

          if (!modbusTCPClient.holdingRegisterWrite(0x0020, NOX)) {
            Serial.print("Failed to write MHR33! ");
            Serial.println(modbusTCPClient.lastError());
          }

          if (!modbusTCPClient.holdingRegisterWrite(0x0021, SO2)) {
            Serial.print("Failed to write MHR34! ");
            Serial.println(modbusTCPClient.lastError());
          }

          if (!modbusTCPClient.holdingRegisterWrite(0x0022, airTemp)) {
            Serial.print("Failed to write MHR35! ");
            Serial.println(modbusTCPClient.lastError());
          }

          if (!modbusTCPClient.holdingRegisterWrite(0x0023, gasTemp)) {
            Serial.print("Failed to write MHR36! ");
            Serial.println(modbusTCPClient.lastError());
          }

          if (!modbusTCPClient.holdingRegisterWrite(0x0024, sensorTemp)) {
            Serial.print("Failed to write MHR37! ");
            Serial.println(modbusTCPClient.lastError());
          }

          if (!modbusTCPClient.holdingRegisterWrite(0x0026, 1)) {
            Serial.print("Failed to write MHR39! ");
            Serial.println(modbusTCPClient.lastError());
          }

          Serial.println();
        }


        Sentcmd = 0;
        j = 0;
        RCVDtotal = 0;
        RCVDcmpt = 0;
        command = 2;
        delay(1000);
      }

    }
    else {
      if (!modbusTCPClient.holdingRegisterWrite(0x001D, 1)) {
        Serial.print("Failed to write MHR30! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x001E, 1)) {
        Serial.print("Failed to write MHR31! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x001F, 1)) {
        Serial.print("Failed to write MHR32! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0020, 1)) {
        Serial.print("Failed to write MHR33! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0021, 1)) {
        Serial.print("Failed to write MHR34! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0022, 1)) {
        Serial.print("Failed to write MHR35! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0023, 1)) {
        Serial.print("Failed to write MHR36! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0024, 1)) {
        Serial.print("Failed to write MHR37! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0025, 1)) {
        Serial.print("Failed to write MHR38! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0026, 0)) {
        Serial.print("Failed to write MHR39! ");
        Serial.println(modbusTCPClient.lastError());
      }

    }

  }

  if (command == 2) {

    Usb.Task();
    if ( Usb.getUsbTaskState() == USB_STATE_RUNNING )  {
      if (Sentcmd == 0)   {
        //char strbuf[] = "$0800EC\r"; //command 0 (0x00) read eeprom
        // char strbuf[] = "$0802EE\r"; //command 2 (0x02) read all sensors
        //  char strbuf[] = "$0A05005A\r"; //command 5 (0x05) read single Answer J2KN
        //  char strbuf[] = "$0A05015B\r"; //command 5 (0x05) read Status 1 Analyzer
        //  char strbuf[] = "$0A05025C\r"; //command 5 (0x05) read Error Status
        // char strbuf[] = "$0A05145F\r"; //command 5 (0x05) read single sn
        // char strbuf[] = "$0A05035D\r"; //command 5 (0x05) read single sensor O2 0.0
        // char strbuf[] = "$0A054866\r"; //command 5 (0x05) read single sensor O2 0.00
        char strbuf[] = "$0A05315E\r"; //command 5 (0x05) read single flow
        //  char strbuf[] = "$0A050A6B\r"; //command 5 (0x05) read single Air Temp
        // char strbuf[] = "$0806F2\r"; //command 6 (0x06) read status values
        Serial.print(F("Command Sent: ")); Serial.println((char*)strbuf);
        rcode = cp210x.SndData(strlen(strbuf), (uint8_t*)strbuf); //send to analyzer
        Sentcmd = 1;
        delay(100);
      }
      uint8_t  buf[64]; //buf is an array of upto 64 integers
      uint16_t rcvd = 64;
      if (Sentcmd == 1) {
        rcode = cp210x.RcvData(&rcvd, buf);
        Serial.print(F("RCVD: ")); Serial.print(rcvd); Serial.print(F(" "));
        RCVD = rcvd;
        RCVDtotal += RCVD;
        if ( rcvd >= 1 && RCVDtotal <= 16) {
          Serial.print(F(" Total RCVD: ")); Serial.print(RCVDtotal); Serial.print(F(" "));
          for (uint16_t i = 0; i < rcvd ; j++, i++) {
            Serial.print((char)buf[i]);
            data[j] = buf[i];
          }
          Serial.println();
        }
        else if (RCVDtotal == 16) {
          RCVDcmpt = 1;
        }
      }
      if (RCVDcmpt == 1) {
        for (uint16_t k = 0; k < 16 ; k++) {
          Serial.print(data[k]);
          dataf = dataf + data[k];
        }
        Serial.println();


        bool startRecord = false;
        if (data[0] == '$') {
          startRecord = true;
          //   Serial.println("Passed Start Record Check.");
        }

        bool correctLength = false;
        char lengthByteString[1];
        lengthByteString[0] = data[1];
        lengthByteString[1] = data[2];
        uint16_t lengthByte = strtol(lengthByteString, NULL, 16);
        if (lengthByte == 16) {
          correctLength = true;
          //   Serial.println("Passed Length Check.");
        }

        //  if (startRecord && correctLength)
        {
          //0123456789
          //$1085;310104;91 typical output

          int indexflow = ((dataf.indexOf(";31")) + 3); //flow starts at 8
          int rangeflow = ((dataf.indexOf(";", (dataf.indexOf(";") + 1)))) - ((dataf.indexOf(";31")) + 3);
          Serial.print("Flow Index8: "); Serial.print(indexflow);  Serial.print(" Range: "); Serial.print(rangeflow); Serial.print(" Values: ");
          // for (index = 0; index < rangeflow; index++) {
          for (index = 0; index < 4; index++) {
            Flowdata[index] = data[ 8 + index ];
            Serial.print(Flowdata[index]);
          }
          Flow = strtol(Flowdata, NULL, 16); //hex to string conversion
          Serial.print(" "); Serial.println( Flow / 100.0);

          if (!modbusTCPClient.holdingRegisterWrite(0x0025, Flow)) {
            Serial.print("Failed to write MHR38! ");
            Serial.println(modbusTCPClient.lastError());
          }
          else {
            //     Serial.print("Flow Written");
          }
        }

        Serial.println();

        Sentcmd = 0;
        j = 0;
        RCVDtotal = 0;
        RCVDcmpt = 0;
        command = 1;
        delay(1000);
      }

    }
    else {
      if (!modbusTCPClient.holdingRegisterWrite(0x001D, 1)) {
        Serial.print("Failed to write MHR30! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x001E, 1)) {
        Serial.print("Failed to write MHR31! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x001F, 1)) {
        Serial.print("Failed to write MHR32! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0020, 1)) {
        Serial.print("Failed to write MHR33! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0021, 1)) {
        Serial.print("Failed to write MHR34! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0022, 1)) {
        Serial.print("Failed to write MHR35! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0023, 1)) {
        Serial.print("Failed to write MHR36! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0024, 1)) {
        Serial.print("Failed to write MHR37! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0025, 1)) {
        Serial.print("Failed to write MHR38! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0026, 0)) {
        Serial.print("Failed to write MHR39! ");
        Serial.println(modbusTCPClient.lastError());
      }

    }
  }
  if (command == 0) {

    Usb.Task();
    if ( Usb.getUsbTaskState() == USB_STATE_RUNNING )  {
      if (Sentcmd == 0)   {
        //char strbuf[] = "$0800EC\r"; //command 0 (0x00) read eeprom
        // char strbuf[] = "$0802EE\r"; //command 2 (0x02) read all sensors
        //  char strbuf[] = "$0A05005A\r"; //command 5 (0x05) read single Answer J2KN
        //  char strbuf[] = "$0A05015B\r"; //command 5 (0x05) read Status 1 Analyzer
        //  char strbuf[] = "$0A05025C\r"; //command 5 (0x05) read Error Status
        char strbuf[] = "$0A05145F\r"; //command 5 (0x05) read single sn
        // char strbuf[] = "$0A05035D\r"; //command 5 (0x05) read single sensor O2 0.0
        // char strbuf[] = "$0A054866\r"; //command 5 (0x05) read single sensor O2 0.00
        //char strbuf[] = "$0A05315E\r"; //command 5 (0x05) read single flow
        //  char strbuf[] = "$0A050A6B\r"; //command 5 (0x05) read single Air Temp
        // char strbuf[] = "$0806F2\r"; //command 6 (0x06) read status values
        Serial.print(F("Command Sent: ")); Serial.println((char*)strbuf);
        rcode = cp210x.SndData(strlen(strbuf), (uint8_t*)strbuf); //send to analyzer
        Sentcmd = 1;
        delay(100);
      }
      uint8_t  buf[64]; //buf is an array of upto 64 integers
      uint16_t rcvd = 64;
      if (Sentcmd == 1) {
        rcode = cp210x.RcvData(&rcvd, buf);
        Serial.print(F("RCVD: ")); Serial.print(rcvd); Serial.print(F(" "));
        RCVD = rcvd;
        RCVDtotal += RCVD;
        if ( rcvd >= 1 && RCVDtotal <= 16) {
          Serial.print(F(" Total RCVD: ")); Serial.print(RCVDtotal); Serial.print(F(" "));
          for (uint16_t i = 0; i < rcvd ; j++, i++) {
            Serial.print((char)buf[i]);
            data[j] = buf[i];
          }
          Serial.println();
        }
        else if (RCVDtotal == 16) {
          RCVDcmpt = 1;
        }
      }
      if (RCVDcmpt == 1) {
        for (uint16_t k = 0; k < 16 ; k++) {
          Serial.print(data[k]);
          datasn = datasn + data[k];

        }
        Serial.println();
        //0123456789
        //$1085;141E9B;BE

        int indexsn = datasn.indexOf(";14") + 3; //starts at 8
        int rangesn = ((datasn.indexOf(";", (datasn.indexOf(";") + 1)))) - ((datasn.indexOf(";14")) + 3);
        Serial.print("SN Index8: "); Serial.print(indexsn);  Serial.print(" Range: "); Serial.print(rangesn); Serial.print(" Values: ");
        for (index = 0; index < rangesn; index++) {
          SNdata[index] = data[ indexsn + index ];
          Serial.print(SNdata[index]);
        }
        SN = strtol(SNdata, NULL, 16); //hex to string conversion
        Serial.print(" "); Serial.println( SN );



        if (!modbusTCPClient.holdingRegisterWrite(0x0027, SN)) {
          Serial.print("Failed to write MHR40! ");
          Serial.println(modbusTCPClient.lastError());
        }

        Serial.println();

        Sentcmd = 0;
        j = 0;
        RCVDtotal = 0;
        RCVDcmpt = 0;
        command = 1;
        delay(1000);
      }

    }
    else {
      if (!modbusTCPClient.holdingRegisterWrite(0x001D, 1)) {
        Serial.print("Failed to write MHR30! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x001E, 1)) {
        Serial.print("Failed to write MHR31! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x001F, 1)) {
        Serial.print("Failed to write MHR32! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0020, 1)) {
        Serial.print("Failed to write MHR33! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0021, 1)) {
        Serial.print("Failed to write MHR34! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0022, 1)) {
        Serial.print("Failed to write MHR35! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0023, 1)) {
        Serial.print("Failed to write MHR36! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0024, 1)) {
        Serial.print("Failed to write MHR37! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0025, 1)) {
        Serial.print("Failed to write MHR38! ");
        Serial.println(modbusTCPClient.lastError());
      }

      if (!modbusTCPClient.holdingRegisterWrite(0x0026, 0)) {
        Serial.print("Failed to write MHR39! ");
        Serial.println(modbusTCPClient.lastError());
      }

    }
  }

}


bool validateCheckSum(char *data, uint16_t dataLength, uint16_t checksum) {



  int dataSum = 0;

  for (int index = 0; index < (dataLength - 2); index++) {
    dataSum = dataSum + (hexchartoint(data[index]));
  }


  Serial.println(dataSum);

  if (dataSum == checksum) {
    return true;
  }
  else {
    return false;
  }

}

int hexchartoint(char hex) {
  if (hex >= '0' && hex <= '9')
    return hex - '0';

  if (hex >= 'A' && hex <= 'F')
    return hex - 'A';

  if (hex >= 'a' && hex <= 'f')
    return hex - 'a';

  if (hex == ';')
    return 59;

  return 0;
}

Output

type or14:10:16.042 -> Command Sent: $0802EE

14:10:16.123 -> RCVD: 1  Total RCVD: 1 $
14:10:16.162 -> RCVD: 64  Total RCVD: 65 8C82;01C5;0200000000;030025;040035;0500CB;060000;078000;080000;0
14:10:16.242 -> RCVD: 22  Total RCVD: 87 9FFED;0A0439;0B0430;0C
14:10:16.323 -> RCVD: 52  Total RCVD: 139 046F;0D0079;0E8000;0F0099;100192;1114;1214;2E8000;8C
14:10:16.403 -> RCVD: 1  Total RCVD: 140 

14:10:16.403 -> RCVD: 0 $8C82;01C5;0200000000;030025;040035;0500CB;060000;078000;080000;09FFED;0A0439;0B0430;0C046F;0D0079;0E8000;0F0099;100192;1114;1214;2E8000;8C

14:10:16.563 -> O2 Index24: 24 Range: 4 Values: 0025 3.70
14:10:16.603 -> CO Index31: 31 Range: 4 Values: 0035 53
14:10:16.643 -> NO Index38: 38 Range: 4 Values: 00CB 3253
14:10:16.723 -> NO2 Index45: 45 Range: 4 Values: 0000 0
14:10:16.763 -> SO2 Index52: 52 Range: 4 Values: 8000 32768
14:10:16.803 -> AT Index73: 73 Range: 4 Values: 0439 108.10
14:10:16.843 -> GT Index80: 80 Range: 4 Values: 0430 1716.10
14:10:16.883 -> ST Index87: 87 Range: 4 Values: 046F 113.50
14:10:16.923 -> NOX: 3253
14:10:16.963 -> 
14:10:17.923 -> Command Sent: $0A05315E

14:10:18.003 -> RCVD: 1  Total RCVD: 1 $
14:10:18.043 -> RCVD: 0 RCVD: 0 RCVD: 15  Total RCVD: 16 1085;310104;91

14:10:18.123 -> RCVD: 0 $1085;310104;91

14:10:18.123 -> Flow Index8: 8 Range: 4 Values: 0104 2.60
14:10:18.163 -> 
14:10:19.123 -> Command Sent: $0802EE

14:10:19.203 -> RCVD: 1  Total RCVD: 1 $
14:10:19.243 -> RCVD: 0 RCVD: 64  Total RCVD: 65 8C82;01C5;0200000000;030026;04002F;0500CB;060000;078000;080000;0
14:10:19.363 -> RCVD: 22  Total RCVD: 87 9FFED;0A0439;0B0430;0C
14:10:19.403 -> RCVD: 53  Total RCVD: 140 046F;0D007A;0E8000;0F0098;100192;1114;1214;2E8000;A4

14:10:19.483 -> RCVD: 0 $8C82;01C5;0200000000;030026;04002F;0500CB;060000;078000;080000;09FFED;0A0439;0B0430;0C046F;0D007A;0E8000;0F0098;100192;1114;1214;2E8000;A4

14:10:19.644 -> O2 Index24: 24 Range: 4 Values: 0026 3.80
14:10:19.684 -> CO Index31: 31 Range: 4 Values: 002F 47
14:10:19.724 -> NO Index38: 38 Range: 4 Values: 00CB 203
14:10:19.764 -> NO2 Index45: 45 Range: 4 Values: 0000 0
14:10:19.803 -> SO2 Index52: 52 Range: 4 Values: 8000 32768
14:10:19.844 -> AT Index73: 73 Range: 4 Values: 0439 108.10
14:10:19.884 -> GT Index80: 80 Range: 4 Values: 0430 1716.10
14:10:19.963 -> ST Index87: 87 Range: 4 Values: 046F 113.50
14:10:20.003 -> NOX: 203
 paste code here

All your arrays like char NOdata[4]; can store only 4 characters, but strtol expect a C string (a null terminated char array), so you must change the size to 5, and, even if global variables are initialized with 0s and you are sure NOdata (and others values) will always contain 4 characters, it's good practice to make sure to add a 0 after writing the characters in the arrays.

char NOdata[5];
...
for (index = 0; index < rangeno; index++) {
    NOdata[index] = datas[indexno + index];
    Serial.print(NOdata[index]);
}
NOdata[index] = '\0'; // now it's a valid C string

guix Thanks for the info!!!

I am not able to implement the change until Monday but after reading and exploring what you advised it sounds like the issue. As from reading the string reference just by increasing the array to 5, arduino/compiler will add the required null character or is it better to just add the null character?

NOdata[5] = '\0';

Also the for index loop will over write the NOdata index but would it be recommended to clear the index after each loop?

The compiler will not add a 0 at the end, but as I said, when you create a global variable char array[5]; it's automatically initialized with 5 zeros (unlike a local variable which is not automatically initialized so it would contain garbage), so if you always change only the first 4 characters of this global array, then the last character would always stay a 0, but in my opinion it's better to add it anyway, it shows what you intended to do (making a valid C string)

To be honest, you code is bad.. You have other problems, like this:

char lengthByteString[1];
lengthByteString[0] = data[1];
lengthByteString[1] = data[2];

You try to store 2 characters in an "array" that can only store one character :slight_smile:

Try something simpler, like this example using strtok and sscanf : https://ideone.com/8xsxD4

You could even do it with sscanf only (using the %n specifier)