0

I'm getting a bit tripped up on const char pointers lately.

I'm getting a message from a server that comes through as either a c style string, a standard library string, or a WString:

return types

underlying types

I'm sending down a buffer of 32bit values from my server that aren't ascii or utf text, they're just bit values I want to parse and read on the esp32 side:

example data from the server

I thought "oh, I'll just mask the bit values 32 bits at a time and right shift the data to get the message (in reverse order, but still I can work with that). The problem that I'm running into is that I can shift numbers but not strings or byte arrays.

I wrote out a function to allow me to grab a piece of the string 32 bits at a time and convert that into a number while using an offset:

uint_fast32_t get32BitInt(const char *data, int offset = 0)
{

  uint32_t payload = 0;
  for (uint8_t i = 0; i < 8; i++)
  {
    payload <<= 0;
    payload += data[i + offset];
  }
  return payload;
}

But when I try to grab the first couple of 32 bit chunks the data isn't what I expected:

void handleGameFrame(const char *data, uint32_t length)
{

  uint8_t phaseAndColission = get32BitInt(data, 32);
  uint8_t player = getByte(data, 32 * 2);

  Serial.print("data: ");
  Serial.println(data);
  Serial.print("phaseAndColission: ");
  Serial.println(phaseAndColission, DEC);
  Serial.print("player: ");
  Serial.println(player, DEC);

}

yields:

enter image description here

I know the Serial.println(data); isn't going to output anything b/c it's a c-string of non-printable values, but the other chunk grabbing isn't giving me the same output from my server. It's hard to verify everything without being able to see all of the bits in the overall data pointer and I think I tied myself in (another) knot.

Is there a good way to parse 32 bit values out of a const c-string?

7
  • "they're just bit values". You mean, they're just uint32_t that are being pointed at with a const char * ?
    – timemage
    Feb 22, 2021 at 15:47
  • Oh, I just mean data (the const char *) holds bits in it that can't be Serial.println-ed because because even in 8 bit form they're not ascii/utf valid characters so nothing goes to the monitor. Feb 22, 2021 at 16:15
  • but yeah, data is a c-string of bytes and I know that I want to interpret it as 32 bit integers, I just can't figure out how to do it. Feb 22, 2021 at 16:16
  • Well, "c-string" basically means zero or more non-'\0' followed by '\0'. If any of your numbers happen to have a zero byte in them, that will terminate the "string" before the end of your actual data. E.g. 0xAA00BB. It's really just not a string at all. In terms of how you get the data out of it, if it's properly aligned for uint32_t, you can just const uint32_t *ui32p = reinterpret_cast<const uint32_t *>(mycharptr); If it's not aligned, you would do something like memcpy it into an array or individual elements into a single uint32_t variable. There's nothing really "Arduino" here.
    – timemage
    Feb 22, 2021 at 16:23
  • might have to hex encode the values to transmit them.
    – dandavis
    Feb 22, 2021 at 17:03

1 Answer 1

1

You wrote:

I wrote out a function to allow me to grab a piece of the string 32 bits at a time and convert that into a number while using an offset

This function is almost correct. Try this:

uint_fast32_t get32BitInt(const char *data, int offset = 0)
{

  uint32_t payload = 0;
  for (uint8_t i = 0; i < 4; i++)
  {
    payload <<= 8;
    payload |= data[i + offset];
  }
  return payload;
}

Compared to your version, the differences are:

  • It reads 4 bytes instead of 8, as 32 bits are four bytes.

  • For each byte being read, it shifts the payload by 8 bits (i.e. one byte) instead of zero. Shifting by zero has no effect.

  • It uses |= instead of +=: just a micro-optimization for the sake of 8-bit MCUs. It shouldn't make much if a difference on a 32-bit micro.

1
  • Oh my god. I can't believe I missed that bit shift by zero :facepalm: I know the for loops conditional check is also wrong, but I can't believe I missed the shift error. Thanks for pointing those out and also the bitwise or optimization. I appreciate you taking the time to correct the function :bows: Feb 23, 2021 at 2:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.