Combing specific output of Char array and/or strings

Hi all,

Need some help from you gurus. I'm generally fairly handy around arduino coding but this project is stretching me a bit. I've spent all day getting some serial input in a format I can work with and I'm almost there, but I'm missing something probably obvious when I try to manipulate the output.

Context:

I'm building an OBD reader for a specific use case with vehicles and have it up and running via ELM AT Commands. This involves serial requests and then handling the response.

At the moment I'm just working on the sample code that was provided with the OBD adaptor (the rest of the code is done, just need to get the response handler working), but as that works with standard commands and I'm using extended AT commands I've had to go off path a bit.

Problem:

I've managed to get the correct response via serial, take that response and find the two characters in the Buffer response I need to pull (char 39 and 40).

Combined they form a hexadecimal number that when converted to decimal format (and some basic math applied) give me transmission temperatures.

The hexadecimal conversion is working fine when I input dummy numbers, but I'm having issues pulling the two characters, combining them into a single string, then passing them to strtol.

My code for the function is below, I've commented it as much as possible. I'm sure I'm missing something obvious or there is a better way to get to the outcome - but I'm at a loss - help!!

void testATcommands()
{
  //Setup AT Commands to sent
  //ATZ - soft reset
  //ATH1 - Show headers
  //ATS1 - Show Spaces between bytes
  //0100 - test PID code
  //ATSH7E - Switch header to Trans Module
  //2102 - Call Trans Temp PID
  static const char cmds[][9] = {"ATZ\r", "ATH1\r", "ATS1\r", "0100\r", "ATSH7E1\r", "2102\r"};
  char buf[128];

  for (byte i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++) {
    const char *cmd = cmds[i];
    mySerial.print("Sending ");
    mySerial.println(cmd);
    
    //Send Serial command
    if (obd.sendCommand(cmd, buf, sizeof(buf))) {
      char *p = strstr(buf, cmd);
      if (p)
        p += strlen(cmd);
      else
        p = buf;
        
      //Take buffer and pull characters 39 and 40 - combined gives AT Temp (If statement is check digit to make sure we pull correct PID response from multiple lines)

      if (buf[4] == '1') {
        //Debug - print full Buffer
        mySerial.println(buf);

        //Debug - print Char 39 and 40 seperately
        mySerial.print(buf[39]);
        mySerial.println(buf[40]);

        //Combine char 39 and 40 to create Hex number for conversion (This is broken/not correct)
        char output1 = buf[39];
        char output2 = buf[40];
        char output3 = strcat(buf[39], buf[40]);

        //Debug - test combined output
        mySerial.println("HEX Number");
        mySerial.println(output3);

        //Take output of char 39 and 40 and convert from Hex to Dec, putting in a string like "63" in place of Output3 gives expected output
        long output4 = strtol(output3, NULL, 16);

        //Temp equation to correct output
        output4 = output4 - 50;

        //Print Trans Temp to serial
        mySerial.println("Corrected DEC number");
        mySerial.println(output4);

      }

      while (*p == '\r') p++;
      while (*p) {
        mySerial.write(*p);
        if (*p == '\r' && *(p + 1) != '\r')
          mySerial.write('\n');
        p++;
      }
      mySerial.println();

    } else {
      mySerial.println("Timeout");
    }
    delay(1000);
  }
  mySerial.println();
}
char output3 = strcat(buf[39], buf[40]);

This tries to concatenate buf[40] with buf[39] and puts the result in buf[39]. Is that what you meant to do ?

As suggestion

Declare a 3 element array of chars
Copy buf[39] into element 0
Copy buf[40] into element 1
Put a zero in element 2 to terminate the string
Use strtol() on the result

thanks for the quick reply Bob. Sounds like I'm mis-understanding the use of strcat - I had assume it would concatenate them together with the output being 'output3' - obviously not the case.

Your recommendation makes sense.

Something like this?

char output3[3] = {buf[39], buf[40]};

Or do I need to declare the array of chars then use something like strcpy to do each one?

This worked perfectly! Thanks Bob - I thought it was something simple, glad it was!

char output3[3] = {buf[39], buf[40]};

Don't forget to add the zero terminator to make it a string. A local variable may be initialised to any value, so it is better to explicitly add the termination

char output3[] = {buf[39], buf[40], 0};

noted - thanks Bob I had just taken the example on the help page. Cheers!

My SafeString library (available via the library manager) has an OBD parser example.
Also see the SafeString tutorial OBD data processor example section for more details

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.