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.

dda
1,5951 gold badge12 silver badges17 bronze badges
asked Jul 10, 2018 at 5:47
4
  • 1
    What is the right order of the six bytes? And how are they contained in the char arrays from the functions parameters? Commented Jul 10, 2018 at 7:06
  • @chrisl 0x123412341234 to {0x12,0x34,0x12,0x34,0x12,0x34} Commented Jul 10, 2018 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? Commented Jul 10, 2018 at 10:10
  • @chrisl nope. each of the parameters inputs 6 byte of data. and I want to convert it like what I said/ Commented Jul 11, 2018 at 8:14

3 Answers 3

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!

answered Jul 10, 2018 at 10:35
0
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

answered Jul 10, 2018 at 15:57
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;
}
answered Jul 10, 2018 at 9:23
2
  • 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.. Commented Jul 10, 2018 at 9:44
  • Well your function was written wrong. So is each VAR or CHAR 2 bytes then? Commented Jul 10, 2018 at 10:10

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.