user50862: I am reading data from a meter over dlms protocol and I am getting hex values from there. I want to convert that hex string to signed decimal value. For example - ff9d denotes a value of -99 [reference].
My hex to decimal code is:
unsigned int hexToDec(String hexString)
{
  unsigned int decValue = 0;
  int nextInt;

  for (int i = 0; i < hexString.length(); i++)
  {
    nextInt = int(hexString.charAt(i));
    if (nextInt >= 48 && nextInt <= 57) nextInt = map(nextInt, 48, 57, 0, 9);
    if (nextInt >= 65 && nextInt <= 70) nextInt = map(nextInt, 65, 70, 10, 15);
    if (nextInt >= 97 && nextInt <= 102) nextInt = map(nextInt, 97, 102, 10, 15);
    nextInt = constrain(nextInt, 0, 15);
    decValue = (decValue * 16) + nextInt;
  }
  return decValue;
}

Can anyone please help me how to do it in Arduino IDE?

user68310: Which mode of DLMS you are you using?

IEC 61107 or currently IEC 62056-21, was an international standard for a computer protocol to read utility meters. It is designed to operate over any media, including the Internet. A meter sends ASCII (in modes A..D) or HDLC (mode E) data to a nearby hand-held unit (HHU) using a serial port. IEC 62056

In your question you mentioned:

hex string

which means a string of hex characters using ASCII (modes A to D).
However, in the comments you mentioned:

void ReactivePower(unsigned char data[], int dataSize)
String reacP = String(data[dataSize - 5], HEX) + String(data[dataSize - 4], HEX);

which means an array of bytes obtained from a stream of bytes using HDLC (mode E).
ASCII (Modes A to D)
For ASCII (modes A to D), there is a simple transformation to get the digit value from the hex character.
              ASCII
 Hex   --------------------                            Digit
 char  Decimal  Hexadecimal    Op1    Low nibble  Op2  Base 10
-----  -------  -----------  -------  ----------  ---  -------
 '0'      48        30        & 0x0F       0              0
 '1'      49        31        & 0x0F       1              1
 '2'      50        32        & 0x0F       2              2
 '3'      51        33        & 0x0F       3              3
 '4'      52        34        & 0x0F       4              4
 '5'      53        35        & 0x0F       5              5
 '6'      54        36        & 0x0F       6              6
 '7'      55        37        & 0x0F       7              7
 '8'      56        38        & 0x0F       8              8
 '9'      57        39        & 0x0F       9              9
 'A'      65        41        & 0x0F       1       +9    10
 'B'      66        42        & 0x0F       2       +9    11
 'C'      67        43        & 0x0F       3       +9    12
 'D'      68        44        & 0x0F       4       +9    13
 'E'      69        45        & 0x0F       5       +9    14
 'F'      70        46        & 0x0F       6       +9    15
 'a'      97        61        & 0x0F       1       +9    10
 'b'      98        62        & 0x0F       2       +9    11
 'c'      99        63        & 0x0F       3       +9    12
 'd'     100        64        & 0x0F       4       +9    13
 'e'     101        65        & 0x0F       5       +9    14
 'f'     102        66        & 0x0F       6       +9    15


For characters '0' to '9', simply AND with 0x0F.
For characters 'A' to 'F' and 'a' to 'f', AND with 0x0F and add 9.

char ch = '1';
byte b = 0;
if (ch >= '0' && ch <= '9')
{
  b = ch & 0x0F;
}
else if ((ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'))
{
  b = (ch & 0x0F) + 9;
}

It's also important to know whether the transformation was successful, e.g. the first character could be bad (either a null terminator or non hex character), so this needs to be tested for during the transformation. Also, there are four nibbles in an int16 so the transformation needs to quit when a maximum of four hex characters have been processed:
void setup()
{
  pinMode(13, OUTPUT);
  Serial.begin(115200);
}

void loop()
{
  char string[] = "A";
  //char string[] = "Waffle";
  //char string[] = "ff9d";
  int16_t the_int = 0;
  int count = AsciiToInt16(string, the_int);

  Serial.print(string);
  Serial.print(",  ");
  if (count)
  {
    Serial.print("Ok,  ");
    Serial.print(count);
    Serial.print(",  ");
    Serial.println(the_int);
  }
  else
  {
    Serial.println("Bad");
  }
}

int AsciiToInt16(const char* ch, int16_t& value)
{
  int count = 0;
  byte nibble = 0;

  // Stop after 4th nibble or null terminator.
  for(int i = 0; i < 4 && ch[i] != 0; i++)
  {
    if (AsciiToNibble(ch[i], nibble))
    {
      value <<= 4;
      value |= nibble;
      count++;
    }
    else
    {
      break;  // Stop after non hex digit.
    }
  }
  return count;
}

bool AsciiToNibble(const char ch, byte& b)
{
  if (ch >= '0' && ch <= '9')
  {
    b = ch & 0x0F;
    return true;
  }
  else if ((ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'))
  {
    b = (ch & 0x0F) + 9;
    return true;
  }
  return false;
}

Output
A,  Ok,  1,  10
Waffle,  Bad
ff9d,  Ok,  4,  -99

HDLC (Mode E)
For HDLC (mode E), simply do:
void ReactivePower(byte data[], int dataSize)
{
  uint16_t reacP = (data[dataSize - 5] << 8) | data[dataSize - 4];
  Serial.println(dataSize);
  Serial.println(reacP);
}
. . .
  byte data[] = { 1, 3, 5, 2, 4, 8 };
  ReactivePower(data, sizeof(data));

Output
6
773


user7508: 
For example – ff9d denotes a value of -99

The function you wrote returns an unsigned integer which, being
unsigned, cannot be negative. The simple fix is to declare it as
int hexToDec(String hexString)

That should be enough to get it working as expected. Note that the local
variable decValue still has to be unsigned, otherwise you would get a
signed overflow, which is undefined behavoir (i.e. “forbidden”) in
C++. Returning an unsigned number from a function that is supposed to
return a signed number is perfectly fine: you get an implicit conversion
which is guaranteed to do the right thing.
Now, if I may provide some more feedback about this function:

Use, if you can, plain C strings (char *) instead of String
objects, as the latter are not very friendly to your Arduino's memory.
Use fixed-length integers (uint16_t if your protocol dictates 16-bit
integers) instead of the generic int, otherwise your code will fail
if you move to a 32-bit platform, such as an ARM-powered Arduino.
Use character literals ('0' instead of 48) instead of hard-coding
ASCII code points, as that makes the code more readable.
Use a simple subtraction (nextInt - '0') instead of the quite
expensive map() function.

Here is my take at it. Note that it has a “classic C” accent you do not
need to replicate. You may prefer using indices to crawl the string.
int16_t hex2int(const char *hex)
{
    uint16_t value;  // unsigned to avoid signed overflow
    for (value = 0; *hex; hex++) {
        value <<= 4;
        if (*hex >= '0' && *hex <= '9')
            value |= *hex - '0';
        else if (*hex >= 'A' && *hex <= 'F')
            value |= *hex - 'A' + 10;
        else if (*hex >= 'a' && *hex <= 'f')
            value |= *hex - 'a' + 10;
        else
            break;  // stop at first non-hex digit
    }
    return value;
}

Example usage:
Serial.println(hex2int("ff9d"));  // prints "-99"


Edit: As revealed by the comments, the whole question is an XY
problem. You are asking help about your misguided solution rather
than your actual problem. The data you have is not hex: it's binary.
You have a 16-bit signed integer stored in a byte array, most
significant byte first. You figured out you can convert that to an
integer by converting it first to a string representation as
hexadecimal, then converting that representation back to a binary
number. Of course you can do that, but it's an overly complicated and
expensive way of doing something trivial.
The canonical way to recover an integer from a byte array is by
assembling the bytes together using bitwise logic and bit shifts. In
this case:
int16_t reactive_power = (uint16_t) data[dataSize - 5] << 8
                       | data[dataSize - 4];


50862: <p>I am reading data from a meter over dlms protocol and I am getting hex values from there. I want to convert that hex string to signed decimal value. For example - ff9d denotes a value of -99 <a href="https://www.rapidtables.com/convert/number/hex-to-decimal.html" rel="nofollow noreferrer">[reference]</a>.</p>
<p>My hex to decimal code is:</p>
<pre><code>unsigned int hexToDec(String hexString)
{
  unsigned int decValue = 0;
  int nextInt;

  for (int i = 0; i &lt; hexString.length(); i++)
  {
    nextInt = int(hexString.charAt(i));
    if (nextInt &gt;= 48 &amp;&amp; nextInt &lt;= 57) nextInt = map(nextInt, 48, 57, 0, 9);
    if (nextInt &gt;= 65 &amp;&amp; nextInt &lt;= 70) nextInt = map(nextInt, 65, 70, 10, 15);
    if (nextInt &gt;= 97 &amp;&amp; nextInt &lt;= 102) nextInt = map(nextInt, 97, 102, 10, 15);
    nextInt = constrain(nextInt, 0, 15);
    decValue = (decValue * 16) + nextInt;
  }
  return decValue;
}
</code></pre>
<p>Can anyone please help me how to do it in Arduino IDE?</p>
 68310: <p>Which mode of DLMS you are you using?</p>
<blockquote>
<p>IEC 61107 or currently IEC 62056-21, was an international standard for a computer protocol to read utility meters. It is designed to operate over any media, including the Internet. A meter sends ASCII (in modes A..D) or HDLC (mode E) data to a nearby hand-held unit (HHU) using a serial port. <a href="https://en.wikipedia.org/wiki/IEC_62056" rel="nofollow noreferrer">IEC 62056</a></p>
</blockquote>
<p>In your question you mentioned:</p>
<blockquote>
<p>hex string</p>
</blockquote>
<p>which means a string of hex characters using ASCII (modes A to D).</p>
<p>However, in the comments you mentioned:</p>
<blockquote>
<p><code>void ReactivePower(unsigned char data[], int dataSize)</code>
<code>String reacP = String(data[dataSize - 5], HEX) + String(data[dataSize - 4], HEX);</code></p>
</blockquote>
<p>which means an array of bytes obtained from a stream of bytes using HDLC (mode E).</p>
<h1>ASCII (Modes A to D)</h1>
<p>For ASCII (modes A to D), there is a simple transformation to get the digit value from the hex character.</p>
<pre class="lang-none prettyprint-override"><code>              ASCII
 Hex   --------------------                            Digit
 char  Decimal  Hexadecimal    Op1    Low nibble  Op2  Base 10
-----  -------  -----------  -------  ----------  ---  -------
 '0'      48        30        &amp; 0x0F       0              0
 '1'      49        31        &amp; 0x0F       1              1
 '2'      50        32        &amp; 0x0F       2              2
 '3'      51        33        &amp; 0x0F       3              3
 '4'      52        34        &amp; 0x0F       4              4
 '5'      53        35        &amp; 0x0F       5              5
 '6'      54        36        &amp; 0x0F       6              6
 '7'      55        37        &amp; 0x0F       7              7
 '8'      56        38        &amp; 0x0F       8              8
 '9'      57        39        &amp; 0x0F       9              9
 'A'      65        41        &amp; 0x0F       1       +9    10
 'B'      66        42        &amp; 0x0F       2       +9    11
 'C'      67        43        &amp; 0x0F       3       +9    12
 'D'      68        44        &amp; 0x0F       4       +9    13
 'E'      69        45        &amp; 0x0F       5       +9    14
 'F'      70        46        &amp; 0x0F       6       +9    15
 'a'      97        61        &amp; 0x0F       1       +9    10
 'b'      98        62        &amp; 0x0F       2       +9    11
 'c'      99        63        &amp; 0x0F       3       +9    12
 'd'     100        64        &amp; 0x0F       4       +9    13
 'e'     101        65        &amp; 0x0F       5       +9    14
 'f'     102        66        &amp; 0x0F       6       +9    15
</code></pre>
<ul>
<li>For characters '0' to '9', simply <code>AND</code> with 0x0F.</li>
<li>For characters 'A' to 'F' and 'a' to 'f', <code>AND</code> with 0x0F and <code>add</code> 9.</li>
</ul>
<pre class="lang-cpp prettyprint-override"><code>char ch = '1';
byte b = 0;
if (ch &gt;= '0' &amp;&amp; ch &lt;= '9')
{
  b = ch &amp; 0x0F;
}
else if ((ch &gt;= 'A' &amp;&amp; ch &lt;= 'F') || (ch &gt;= 'a' &amp;&amp; ch &lt;= 'f'))
{
  b = (ch &amp; 0x0F) + 9;
}
</code></pre>
<p>It's also important to know whether the transformation was successful, e.g. the first character could be bad (either a null terminator or non hex character), so this needs to be tested for during the transformation. Also, there are four nibbles in an <code>int16</code> so the transformation needs to quit when a maximum of four hex characters have been processed:</p>
<pre class="lang-cpp prettyprint-override"><code>void setup()
{
  pinMode(13, OUTPUT);
  Serial.begin(115200);
}

void loop()
{
  char string[] = &quot;A&quot;;
  //char string[] = &quot;Waffle&quot;;
  //char string[] = &quot;ff9d&quot;;
  int16_t the_int = 0;
  int count = AsciiToInt16(string, the_int);

  Serial.print(string);
  Serial.print(&quot;,  &quot;);
  if (count)
  {
    Serial.print(&quot;Ok,  &quot;);
    Serial.print(count);
    Serial.print(&quot;,  &quot;);
    Serial.println(the_int);
  }
  else
  {
    Serial.println(&quot;Bad&quot;);
  }
}

int AsciiToInt16(const char* ch, int16_t&amp; value)
{
  int count = 0;
  byte nibble = 0;

  // Stop after 4th nibble or null terminator.
  for(int i = 0; i &lt; 4 &amp;&amp; ch[i] != 0; i++)
  {
    if (AsciiToNibble(ch[i], nibble))
    {
      value &lt;&lt;= 4;
      value |= nibble;
      count++;
    }
    else
    {
      break;  // Stop after non hex digit.
    }
  }
  return count;
}

bool AsciiToNibble(const char ch, byte&amp; b)
{
  if (ch &gt;= '0' &amp;&amp; ch &lt;= '9')
  {
    b = ch &amp; 0x0F;
    return true;
  }
  else if ((ch &gt;= 'A' &amp;&amp; ch &lt;= 'F') || (ch &gt;= 'a' &amp;&amp; ch &lt;= 'f'))
  {
    b = (ch &amp; 0x0F) + 9;
    return true;
  }
  return false;
}
</code></pre>
<p><strong>Output</strong></p>
<pre class="lang-none prettyprint-override"><code>A,  Ok,  1,  10
Waffle,  Bad
ff9d,  Ok,  4,  -99
</code></pre>
<h1>HDLC (Mode E)</h1>
<p>For HDLC (mode E), simply do:</p>
<pre class="lang-cpp prettyprint-override"><code>void ReactivePower(byte data[], int dataSize)
{
  uint16_t reacP = (data[dataSize - 5] &lt;&lt; 8) | data[dataSize - 4];
  Serial.println(dataSize);
  Serial.println(reacP);
}
. . .
  byte data[] = { 1, 3, 5, 2, 4, 8 };
  ReactivePower(data, sizeof(data));
</code></pre>
<p><strong>Output</strong></p>
<pre class="lang-none prettyprint-override"><code>6
773
</code></pre>
 7508: <blockquote>
<p>For example – ff9d denotes a value of -99</p>
</blockquote>
<p>The function you wrote returns an <em>unsigned</em> integer which, being
unsigned, cannot be negative. The simple fix is to declare it as</p>
<pre class="lang-cpp prettyprint-override"><code>int hexToDec(String hexString)
</code></pre>
<p>That should be enough to get it working as expected. Note that the local
variable <code>decValue</code> still has to be unsigned, otherwise you would get a
signed overflow, which is <em>undefined behavoir</em> (i.e. “forbidden”) in
C++. Returning an unsigned number from a function that is supposed to
return a signed number is perfectly fine: you get an implicit conversion
which is guaranteed to do the right thing.</p>
<p>Now, if I may provide some more feedback about this function:</p>
<ul>
<li>Use, if you can, plain C strings (<code>char *</code>) instead of <code>String</code>
objects, as the latter are not very friendly to your Arduino's memory.</li>
<li>Use fixed-length integers (<code>uint16_t</code> if your protocol dictates 16-bit
integers) instead of the generic <code>int</code>, otherwise your code will fail
if you move to a 32-bit platform, such as an ARM-powered Arduino.</li>
<li>Use character literals (<code>'0'</code> instead of <code>48</code>) instead of hard-coding
ASCII code points, as that makes the code more readable.</li>
<li>Use a simple subtraction (<code>nextInt - '0'</code>) instead of the quite
expensive <code>map()</code> function.</li>
</ul>
<p>Here is my take at it. Note that it has a “classic C” accent you do not
need to replicate. You may prefer using indices to crawl the string.</p>
<pre class="lang-cpp prettyprint-override"><code>int16_t hex2int(const char *hex)
{
    uint16_t value;  // unsigned to avoid signed overflow
    for (value = 0; *hex; hex++) {
        value &lt;&lt;= 4;
        if (*hex &gt;= '0' &amp;&amp; *hex &lt;= '9')
            value |= *hex - '0';
        else if (*hex &gt;= 'A' &amp;&amp; *hex &lt;= 'F')
            value |= *hex - 'A' + 10;
        else if (*hex &gt;= 'a' &amp;&amp; *hex &lt;= 'f')
            value |= *hex - 'a' + 10;
        else
            break;  // stop at first non-hex digit
    }
    return value;
}
</code></pre>
<p>Example usage:</p>
<pre class="lang-cpp prettyprint-override"><code>Serial.println(hex2int(&quot;ff9d&quot;));  // prints &quot;-99&quot;
</code></pre>
<hr />
<p><strong>Edit</strong>: As revealed by the comments, the whole question is an <a href="http://xyproblem.info/" rel="nofollow noreferrer">XY
problem</a>. You are asking help about your misguided <em>solution</em> rather
than your actual <em>problem</em>. The data you have is not hex: it's binary.
You have a 16-bit signed integer stored in a byte array, most
significant byte first. You figured out you can convert that to an
integer by converting it first to a string representation as
hexadecimal, then converting that representation back to a binary
number. Of course you can do that, but it's an overly complicated and
expensive way of doing something trivial.</p>
<p>The canonical way to recover an integer from a byte array is by
assembling the bytes together using bitwise logic and bit shifts. In
this case:</p>
<pre class="lang-cpp prettyprint-override"><code>int16_t reactive_power = (uint16_t) data[dataSize - 5] &lt;&lt; 8
                       | data[dataSize - 4];
</code></pre>
