uint64_t value creating from 8 bytes

Hello, guys!

I need to write as uint64_t data from GNSS reciever.
From reciever i got 8 bytes (as an array of 8 bytes), i need to combine it to one 64 bit value.
For instance:
Recieving bytes: 71 65 DB 4B 01 00 00 00 must be writed in reverse sequence: 01 4B DB 65 71 00 00 00,
so the word '14BDB6571' must be stored.

After it should be converted to decimal value 5567636849.

How i can do it?

That is not in reverse. That is some kind of magical mixing with unknown conditions.
If you need '14BDB6571', then you need: 00 00 00 01 4B DB 65 71. So it is in reverse order after all ?

Is the 0x71 the first received byte ?
To do it in reverse, you could use this:

byte buffer[8] = { 0x71, 0x65, 0xDB, 0x4B, 0x01, 0x00, 0x00, 0x00);
uint64_t result = 0;
for( int i=7; i>=0; i--)
{
  result <<= 8;
  result |= (uint64_t) buffer[i];
}

For which Arduino board ?
I think that the Arduino Uno can not print it. Perhaps the Arduino Due or Arduino Zero can convert the uint64_t with sprintf().

Koepel:
That is not in reverse. That is some kind of magical mixing with unknown conditions.

Yes, sorry. It my mistake.
Actually (71 65 DB 4B 01 00 00 00) must be reversed to (00 00 00 01 4B DB 65 71), so i suppose your scetch is correct.

I am use board STM32F103.

If the Serial.println() does not accept the uint64_t, then try the sprintf().
The Serial.println() is from the Arduino code. The sprintf() is from the libraries that belong to the compiler.
The sprintf() is not straightforward for 64 bit. You might have to use "%I64u" or "%llu" or even "%"PRIu64", but I don't understand what that last one is. You could start with the most common "%lld".

You are converting a number from big endian to little endian, take a look at the GCC builtin function for this:

uint64_t number = 1;
number = __builtin_bswap64(number);

Byte swapping magic! :slight_smile:

Koepel:
If the Serial.println() does not accept the uint64_t, then try the sprintf().

Koepel, many thanks!
Your code works perfectly!
Also my Serial.println() works correctly, and i can see a result (and it in decimal already).
But as you said, value uint64_t i can not convert to string and sent to TFT display....

Could you please give a code with sprintf() conversion?

Serial.JPG

Danois90:
You are converting a number from big endian to little endian, take a look at the GCC builtin function for this:

uint64_t number = 1;

number = __builtin_bswap64(number);




Byte swapping magic! :)

Ok, thanks. I'll try this way also!

SHTIRLITZ:
Also my Serial.println() works correctly, and i can see a result (and it in decimal already).
But as you said, value uint64_t i can not convert to string and sent to TFT display....

char *toDec(uint64_t n) {
  static char buf[22];
  char *s = buf + 21;
  *s = '\0';
  if(n==0) {
    *--s = '0';
  }
  else {
    while(n) {
      *--s = '0' + n%10;
      n /= 10;
    }
  }
  return s;
}

Converting it to a char buffer should also be not that difficult:

uint64_t number = __builtin_bswap64((uint64_t)buffer); //Typecasting may fail
char textual[20];
sprintf(textual, "%llu", number);

Maybe only 1 line should suffice (works on my DUE):

uint64_t bignum= 0x7165DB4B01000000; 
void setup() {
 
Serial.begin(250000);

}

void loop() {
bignum = __builtin_bswap64(bignum);
printf(" bignum = %lld\n", bignum);
while(1);
}