Strtol - Selecting what part I want to use

Hey everyone. I just became familiar with the strtol function. I am using it to parse out some hex numbers that are sent from a server to the client (the arduino) which will then switch relays using the MCP 23017 port expander IC.

My question is when the string is sent in ("0x00; 0xFF; 0x55 "), how can I use the second hex value ("0xFF"), and so on similar to how an array would work. If that is possible. If not what would be the best way to go about it?

Here's the code:

  String serverMsg;
  char parsedMsg[50];
  char delimiters[] = " ;";

void update_MCP23017(uint8_t value) {
  Wire.beginTransmission(0x20);
  Wire.write(0x12);      // address bank
  Wire.write(value);  // value to send
  Wire.endTransmission();
}

  void update_MCP23017_1(uint8_t value) {
  Wire.beginTransmission(0x20);
  Wire.write(0x13);      // address bank
  Wire.write(value);  // value to send
  Wire.endTransmission();
}


serverMsg = "0x00; 0xFF; 0x55 ";
  serverMsg.toCharArray(parsedMsg, 50);
  char * pch;
  int i = 0;
  pch = strtok (parsedMsg, delimiters);
  while (pch != NULL)
  {

    Serial.println (pch);
    if (i == 1) update_MCP23017((int) strtol(pch, 0, 16)); 
    if (i == 2) update_MCP23017_1((int) strtol(pch, 0, 16));
    pch = strtok (NULL, delimiters);
    ++i;

Take a look at the strtok() and/or the sscanf() functions

Which server is this? The format is strange, a hex… in a string… with delimiters!

if you depend on a String (capital S) you could use something like this

String serverMsg = "0x00; 0xFF; 0x55";

void setup() {
  Serial.begin(115200); Serial.println();

  Serial.print("extracting value of second item of : "); Serial.println(serverMsg);
  int indexOfSeparator = serverMsg.indexOf(';');
  if (indexOfSeparator != -1) {
    const char * semiColonPtr = serverMsg.c_str() + indexOfSeparator;
    char *ptr;
    long result = strtol(semiColonPtr + 1, &ptr, 16);
    if (ptr != semiColonPtr + 1) {  // if we managed to parse something
      Serial.print(F("Value = 0x")); Serial.println(result, HEX);
      if (*ptr != '\0') { // if we are not at the end of the cString after the number
        Serial.print(F("There was more data after the number -> "));
        Serial.println(ptr);
      }
    }
  } else Serial.println("could not find ';'");
}

void loop() {}

if you want to parse and extract all the data, you could do something like this

String serverMsg = "0x00; 0xFF; 0x55";

void setup() {
  Serial.begin(115200); Serial.println();

  Serial.print("Listing values in : "); Serial.println(serverMsg);
  const char * startPtr = serverMsg.c_str();
  while (startPtr != nullptr) {
    char *ptr;
    long result = strtol(startPtr, &ptr, 16);
    if (ptr != startPtr) {  // if we managed to parse something
      Serial.print(F("Value = 0x")); Serial.println(result, HEX);
    } else {
      Serial.println("Parsing error");
      break;
    }
    startPtr = strchr(ptr, ';');
    if (startPtr != nullptr) startPtr++;
    if (*startPtr == '\0') startPtr = nullptr;
  }
}

void loop() {}

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