HEX output to DEC conversion & equation

Hi folks, I successfully connected Arduino via Bluetooth module HC-05 to my car’s ELM327 OBD2 bluetooth adapter.

Currently I’m able to send PID requests and read their responded values on Arduino’s LCD display and also in serial port monitor.

Harder part for me is to understand how to obtain correct values for equation after converting HEX response to DEC value.

If someone experienced can help me resolve this I will be very grateful.

Here’s part of Arduino code:

BuildINString = "";  

Serial.println("213E1");    //PID request 21 3E 1
delay(1000);    //wait 1 sec.

ReadData();
   
WorkingString = BuildINString.substring(1,9);    //Obtain data for equation    here I'm not sure if (1,9) is OK
A = strtol(WorkingString.c_str(),NULL,16);    //Converts HEX to DEC; A is defined as Long 
WorkingString = BuildINString.substring(9,17);    //Obtain data for equation     here I'm not sure if (9,17) is OK
B = strtol(WorkingString.c_str(),NULL,16);    //Converts HEX to DEC; B is defined as Int

DisplayValue = (((A*256)+B)*0.02)-40;    //Equation
DisplayString = String(DisplayValue) + "°C";    //Result of equation with °C
Serial.println(DisplayString);   //Shows result of equation in serial port monitor
lcd.setCursor(0, 1); 
lcd.print(DisplayString);   //Shows result of equation on Arduino's LCD display

Responded value from serial port monitor of PID 213E1 were 61 3E 0C 13.

In this case I need to convert 0C to decimal and use it as A in equation; and also convert 13 to decimal and use it as B in equation.

HEX 0C to DEC = 12 HEX 13 to DEC = 19

Steps of equation should then looks like: (((A*256)+B)*0.02)-40 (((12*256)+19)*0.02)-40 (3091*0.02)-40 21.82 °C

Responded value from serial port monitor of PID 213E1 were 61 3E 0C 13.

are you saying you received the string "61 3E 0C 13"?

if so, one approach is to use sscanf()

    int a, b, c, d;
    const char *s = "61 3E 0C 13";

    sscanf (s, " %x %x %x %x", &a, &b, &c, &d);

    printf (" %s -- %d, %d, %d, %d\n", s, a, b, c, d);

use sprintf() and Serial.print in place of printf

You can obtain the expected result without doing any intermediate conversion:

1. This is what you have got through intermediate conversion (0x0C ---> 12 decimal, 0x13---> 13 decimal).

(((A*256)+B)*0.02)-40
(((12*256)+19)*0.02)-40
(3091*0.02)-40
21.82 °C

2. You can compute like this:

float x = (((0x0C * 256) + 0x13) * 0.02) - 40;
  Serial.print(x, 2);  //shows: 21.82

A & B values from HEX are changing. I'm wondering if strtol command is right/needed. Here I'm messing around with start, end position (1, 9).

you have an ASCII answer where numbers are represented in a human readable way on multiple characters (two if there is always the leading 0).

If you want to do any math, you need to first transform your ASCII string into numbers ==> that's what @gcjr answer #1 was doing for you.

Then a number is a number, base representation is just a matter of preference on what you display, for math equation, your arduino does not care.

Thank you for explanation. I will give it a try.

I understand that you are receiving natural binary bytes and storing them into an array like:

byte myData[] = {0x61, 0x3E, 0x0C, 0x13};

Then, the expected result is:

float x = (((myData[2] * 256) + myData[3]) * 0.02) - 40; //myData[2], myData[3] may change
Serial.print(x, 2);  //shows: 21.82

Hi guys,
It’s finally working after few attempts.

The main reason of getting wrong values were in format of received data.
It doesn’t gave me response 61 3E 0C 13 but 2131E[61 3E 0C 13] instead.

So I just move start positions of HEX reading like this:

WorkingString = BuildINString.substring(12,14);   //Read HEX value "0C" from position 12 to 13
A = strtol(WorkingString.c_str(),NULL,16);  
WorkingString = BuildINString.substring(15,17);   //Read HEX value "13" from position 15 to 16
B = strtol(WorkingString.c_str(),NULL,16);

Equation itself is working like a charm with this code:

DisplayValue = (((A*256)+B)*0.02)-40;   
DisplayString = String(DisplayValue) + " C";

Is there a possibility to output “DisplayString” on 2 decimal places?

Is there a possibility to output "DisplayString" on 2 decimal places?

That depends on the type of DisplayValue, which your snippet doesn't reveal.

Is your sensor really accurate to two decimal places?

I'm not using any sensor, Arduino reads values form car's ECU.

I got a number with 2 decimal places from equation on computer but it shows me value without decimal places on Arduino's LCD.

are you using float or int for the data you want to print ?

I'm not using any sensor, Arduino reads values form car's ECU.

The engine control unit is not making up data to send you. The data comes from pressure and temperature sensors. So, I'll ask again. Is the sensor accurate to two decimal places?

I'm blind as hell...

It's written in reply #6.