0

I have a web app (javascript) that needs to send a arduino(ESP32) a 12bit value (0x7DF). I have a websocket connection that only accepts a Uint8_t payload, so I split the value into 4 bytes (Uint8_t). I can send the array to the arduino, but how do i reconstruct it back into a 32bit value?

This is the code i am using to turn it into bytes:

const uInt32ToBytes = (input) => {
  const buffer = Buffer.alloc(4)
  buffer.writeUInt32BE(input, 0)
  return [
    buffer[0],
    buffer[1],
    buffer[2],
    buffer[3]
  ]
}

//With an input of 0x7DF i get an output of [0, 0, 7, 223]

I have tried a lot of options given in other questions but none work. This is what they suggested:

uint32_t convertTo32(uint8_t * id) {
  uint32_t bigvar = (id[0] << 24) + (id[1] << 16) + (id[2] << 8) + (id[3]);
  return bigvar;
}
//This returns an output of 0. 

Any help is appreciated EDIT: My convert function has a test variant and not the original solution. fixed that.

hamza765
  • 106
  • 14
  • You write to the buffer as big-endian, but use a little-endian algorithm to recompose the integer. – Passerby Dec 08 '21 at 22:54
  • @Passerby That should produce an incorrect result, but not `0`. – Barmar Dec 08 '21 at 22:54
  • @passerby it returns 0 either way. I was thinking maybe I had it wrong so i tried to go LE, but same response. I'll change it back in the OP – hamza765 Dec 08 '21 at 22:55
  • I'm guessing he's getting `0` when he later extracts the low-order 12 bits, since that's what he wants to send to Arduino. So you're probably right. And the solution is just to reverse the indexes in either the JS or C++ code. – Barmar Dec 08 '21 at 22:59
  • Marginally related: See if you have [`htonl` and `ntohl`](https://stackoverflow.com/questions/36924598/understanding-htonl-and-ntohl) on your system. – user4581301 Dec 08 '21 at 23:04
  • @Passerby I'm sorry, i don't know how better to explain the 0. I was expecting a x7DF but got 0. I've also fixed the order in the OP. I get 0 either way for some reason. I have checked and made sure the function is receiving the correct data, and it is. – hamza765 Dec 08 '21 at 23:04
  • Fortunately Artyer has a pretty likely explanation. Please try it out and get back to us. – user4581301 Dec 08 '21 at 23:31
  • 1
    His answer worked so i have marked it as the best answer – hamza765 Dec 08 '21 at 23:35

1 Answers1

2

On Arduino, ints are 16 bit, so id[0] << 24 (which promotes id[0] from uint8_t to int) is undefined (and wouldn't be able to hold the value anyways, making it always 0).

You need some casts beforehand:

return (static_cast<uint32_t>(id[0]) << 24)
     | (static_cast<uint32_t>(id[1]) << 16)
     | (static_cast<uint32_t>(id[2]) << 8)
     | (static_cast<uint32_t>(id[3]));

Artyer
  • 31,034
  • 3
  • 47
  • 75
  • You have a point but I don't think it matters what the int size in that architecture is since `id[0]` is still a uint8_t and the shift operator will be applied to it, without a cast to int. –  Dec 08 '21 at 23:32
  • This worked perfectly. You are a god. Thank you. – hamza765 Dec 08 '21 at 23:34
  • 1
    @Jellyboy `<<` promotes both of its arguments beforehand (which is why this would have "worked" on systems with 32 bit ints) – Artyer Dec 09 '21 at 00:11
  • You are correct, Just tested on Godbolt. https://gcc.godbolt.org/z/5s391bEsf –  Dec 09 '21 at 00:24