Search code examples
arduinobit-manipulationarduino-c++

Pack array of int16_t into multiple uint64_t


I have an array of N per 6 entries

const int16_t xzyabc[][6] PROGMEM = {
    {1, 2, 3, 4, 5, 6},
    {7, 8, 9, 10, 11, 12},
};

Each value in the array is an int16_t number.

For each four int16_t, I want to pack it onto a uint64_t.

I tried the code below.

void Telemetry::loop()
{
  const size_t numArrays = sizeof(xzyabc) / sizeof(xzyabc[0]);
  const size_t elementsPerArray = sizeof(xzyabc[0]) / sizeof(xzyabc[0][0]);
  const size_t elementsPerUint64 = 4;
  const size_t numUint64 = (numArrays * elementsPerArray + elementsPerUint64 - 1) / elementsPerUint64;

  uint64_t convertedArray[numUint64];

  for (size_t i = 0; i < numUint64; i++)
  {
    uint64_t value = 0;
    for (size_t j = 0; j < elementsPerUint64; j++)
    {
      size_t index = i * elementsPerUint64 + j;
      if (index < numArrays * elementsPerArray)
      {
        int16_t element = xzyabc[index / elementsPerArray][index % elementsPerArray];
        value |= static_cast<uint64_t>(element) << (16 * j);
      }
    }

    uint32_t parteSuperior = (uint32_t)(value >> 32);
    uint32_t parteInferior = (uint32_t)(value & 0xFFFFFFFF);
    Serial.print("Number: ");
    Serial.print(parteSuperior);
    Serial.print(parteInferior);
    Serial.println();

    convertedArray[i] = value;
  }

  callback(convertedArray, numUint64);
}

The idea of the code above is to iterate over the array and for each quadrupled, put it on a unsigned integer.

Results in:

Number: 262147131073
Number: 524295393221
Number: 786443655369

And they look wrong to me, I tried to unpack it on NodeJS and it failed.

How can I fix this? Or what I'm doing wrong?


Solution

  • As sugestion of @Peter, I ended using memcpy

    uint64_t buffer[10]{0};
    
    memcpy(buffer, xzyabc, sizeof(xzyabc));