DEV Community

Hamza Haidar
Hamza Haidar

Posted on

Modbus floating-point values converter

When Reading from Modbus floating point, it is divided into two registers with int64 type. In order to read the right value you have to convert it into float value using the following code.

class SurroundingClass
{
    public double convertValues(int v1, int v2)
    {
        double res = 0;
        string v1_hex = Strings.Right("0000" + Conversion.Hex(v1), 4);
        string v2_hex = Strings.Right("0000" + Conversion.Hex(v2), 4);

        int v1_256 = Hex2Dec(v1_hex) / 256;
        int v2_256 = Hex2Dec(v2_hex) / 256;

        int v1_remaining = Hex2Dec(v1_hex) - Conversion.Int(Hex2Dec(v1_hex) / 256) * 256;
        int v2_remaining = Hex2Dec(v2_hex) - Conversion.Int(Hex2Dec(v2_hex) / 256) * 256;

        string v1_bin = Strings.Right("0000000000" + IntToBin(v1_256), 8);
        string v1_rem_bin = Strings.Right("0000000000" + IntToBin(v1_remaining), 8);
        string v2_bin = Strings.Right("0000000000" + IntToBin(v2_256), 8);
        string v2_rem_bin = Strings.Right("0000000000" + IntToBin(v2_remaining), 8);

        int sign = v1_bin.Substring(0, 1) == "0" ? 1 : -1;

        string C = Strings.Right(v1_bin, 7) + Strings.Left(v1_rem_bin, 1);
        double c_dec = BinToDec(C);
        double c_rem = c_dec - 127;

        double f1 = BinToDec(Strings.Right(v1_rem_bin, 7)) * 256 * 256 + BinToDec(v2_bin) * 256 + BinToDec(v2_rem_bin);

        int div_v800000 = Hex2Dec(800000);
        int div_v400000 = Hex2Dec(400000);

        double res_v800000 = f1 / div_v800000 + 1;
        double res_v400000 = f1 / div_v400000;

        double res1;
        if (c_dec > 0)
            res1 = res_v800000;
        else
            res1 = res_v400000;

        res = sign * res1 * Math.Pow(2, c_rem);
        return Strings.Format(res, "0.000");
    }

    public string IntToBin(int intValue)
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        while (intValue != 0)
        {
            sb.Insert(0, (intValue % 2).ToString());
            intValue /= 2;
        }
        return sb.ToString();
    }

    public double BinToDec(string ans)
    {
        string dig;
        int p;
        double dec, B, d;
        p = 0;
        for (int x = ans.Length - 1; x >= 0; x += -1)
        {
            dig = ans.Substring(x, 1);
            if (!(dig == "0" | dig == "1"))
            {
                dec = 0;
                MessageBox.Show("Incorrect entry.  ");
                break;
            }
            double.TryParse(dig, ref B);
            d = B * (Math.Pow(2, p));
            dec = dec + d;
            p = p + 1;
        }
        return dec;
    }

    public long Hex2Dec(string n1)
    {
        return Convert.ToInt64(n1, 16);
        long nl1;
        long nGVal;
        long nSteper;
        long nCount;
        long x;
        long nVal;
        long Stepit;
        string hVal;

        nl1 = Strings.Len(n1);
        nGVal = 0;
        nSteper = 16;
        nCount = 1;
        for (x = nl1; x >= 1; x += -1)
        {
            hVal = Strings.UCase(Mid(n1, x, 1));
            switch (hVal)
            {
                case "A":
                    {
                        nVal = 10;
                        break;
                    }

                case "B":
                    {
                        nVal = 11;
                        break;
                    }

                case "C":
                    {
                        nVal = 12;
                        break;
                    }

                case "D":
                    {
                        nVal = 13;
                        break;
                    }

                case "E":
                    {
                        nVal = 14;
                        break;
                    }

                case "F":
                    {
                        nVal = 15;
                        break;
                    }

                default:
                    {
                        nVal = Conversion.Val(hVal);
                        break;
                    }
            }
            Stepit = (Math.Pow(nSteper, (nCount - 1)));
            nGVal = nGVal + nVal * Stepit;
            nCount = nCount + 1;
        }
        Hex2Dec = nGVal;
    }
}

Top comments (0)