0

I'm trying to solve some problems for a contest, and I have a problem with it. I have to implement a function that has 3 arguments like this:

void foo(unsigned char* A, unsigned char* B, unsigned char* C);

And what comes in, is 6 bytes of data. I have to convert these 6 bytes of data to integer data (maybe long long). The problem is, I don't know how to map the bytes in the right order.

I'm using an Arduino Uno board.

Please help me with it.

  • 1
    What is the right order of the six bytes? And how are they contained in the char arrays from the functions parameters? – chrisl Jul 10 '18 at 7:06
  • @chrisl 0x123412341234 to {0x12,0x34,0x12,0x34,0x12,0x34} – qqq1ppp Jul 10 '18 at 9:05
  • I'm not quite sure, what exactly you want to do. As I understand you get 3 char arrays with each 2 bytes in the correct order as parameters into your function, and then you want to declare a long long and fill the bytes from the arrays into this variable. Is this correct? – chrisl Jul 10 '18 at 10:10
  • @chrisl nope. each of the parameters inputs 6 byte of data. and I want to convert it like what I said/ – qqq1ppp Jul 11 '18 at 8:14
3

The trick is to use a union data type and get full control of the mapping. The issue of data representation and endian is now under your control:

uint64_t foo(uint8_t* A, uint8_t* B, uint8_t* C)
{
  union {
    uint64_t X;
    struct {
      uint8_t A[2];
      uint8_t B[2];
      uint8_t C[2];
      uint8_t D[2];
    };
  } map;
#if defined(MSB_ORDER)
  for (int i = 0, j = 1; i < 2; i++, j--) {
    map.A[i] = 0;
    map.B[i] = C[j];
    map.C[i] = B[j];
    map.D[i] = A[j];
  }
#else
  for (int i = 0; i < 2; i++) {
    map.A[i] = A[i];
    map.B[i] = B[i];
    map.C[i] = C[i];
    map.D[i] = 0;
  }
#endif
  return map.X;
}

void setup()
{
  Serial.begin(9600);
  while (!Serial);
  uint8_t a[] = { 0x12, 0x34 };
  uint8_t b[] = { 0x56, 0x78 };
  uint8_t c[] = { 0x9a, 0xbc };
  uint64_t res = foo(a, b, c);
  Serial.print((uint32_t) (res >> 32), HEX);
  Serial.print((uint32_t) res, HEX);
}

void loop()
{
}

Cheers!

1
uint64_t foo(uint8_t* A, uint8_t* B, uint8_t* C)
{
    uint64_t aux = 0;
    aux = A[0];
    aux <<= 8;
    aux |= A[1];
    aux <<= 8;
    aux |= B[0];
    aux <<= 8;
    aux |= B[1];
    aux <<= 8;
    aux |= C[0];
    aux <<= 8;
    aux |= C[1];
    return aux;
}

following sample code:

  uint8_t a[] = { 0x12, 0x34 };
  uint8_t b[] = { 0x56, 0x78 };
  uint8_t c[] = { 0x9a, 0xbc };

  uint64_t result = foo(a, b, c);

  std::cout << std::hex << result;

returns 123456789abc, try the code here, excluding the std::out part, the same code will run on arduino without any problem

0

When passing data to functions you do this...

foo(a,b,c);

You then extract the variables or data passed to the function like..

void foo(unsigned char* A, unsigned char* B, unsigned char* C) {
    A = whatever;
    B = whatever;
    C = whatever;
}
  • wow. I'm not that noob ;; I wanna map the raw 6 byte data to "long long" type variable. memcpy won't work as I want, cause of the endian rules.. – qqq1ppp Jul 10 '18 at 9:44
  • Well your function was written wrong. So is each VAR or CHAR 2 bytes then? – Brian Moreau Jul 10 '18 at 10:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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