HEX, INT, BYTE ... Can I simplify this code?

Hi,

I somehow got this working. But for me it looks like there should be a simpler way. Can I simplify this code and avoid the sprintf / buffer somehow?

// uint64_t pt = 0x1105202216300000;

char buf1[5];
sprintf_P(buf1, PSTR("%02x"), ((byte)(pt >> 32)));
ds3231.setYear((byte)(String(buf1).toInt()));

sprintf_P(buf1, PSTR("%02x"), ((byte)(pt >> 48)));
ds3231.setMonth(String(buf1).toInt());

sprintf_P(buf1, PSTR("%02x"), ((byte)(pt >> 56)));
ds3231.setDate(String(buf1).toInt());

sprintf_P(buf1, PSTR("%02x"), ((byte)(pt >> 24)));
ds3231.setHour(String(buf1).toInt());

sprintf_P(buf1, PSTR("%02x"), ((byte)(pt >> 16)));
ds3231.setMinute(String(buf1).toInt());

sprintf_P(buf1, PSTR("%02x"), ((byte)(pt >> 8)));
ds3231.setSecond(String(buf1).toInt());

greetings and thanks,
André

If you start with an int, why convert it to a string, then to a String, then back to an int?

sprintf_P(buf1, PSTR("%02x"), ((byte)(pt >> 32)));
ds3231.setYear((byte)(String(buf1).toInt()));

ds3231.setYear((byte)( pt >> 32));

Seems to me that this can be written as:

ds3231.setMonth(pt >> 48);

(edit)

You probably also need to use AND to select a certain number of bits, e.g.,

ds3231.setMonth((pt >> 48) & 0xff);

isn't there a problem with these values being in hex?

hex 22 is 34 decimal. the individual nibbles (4-bits) need to be teased out and combined to create a decimal value

#include <stdio.h>
#include <stdint.h>

uint64_t pt = 0x1105202216300000;
uint8_t  *p = (uint8_t*) & pt;

void
set (
    uint8_t     val,
    const char *lbl )
{
    int dec;
    dec  = val & 0xF;
    dec += (val >> 4) * 10;

    printf ("set: %02x  %02d  %s\n", val, dec, lbl);
}

int
main ()
{
    printf (" %llx\n", pt);

    for (int i = 0; i < sizeof(uint64_t); i++)
        printf (" %02x", p [i]);
    printf ("\n");

    set (p [7], "month");
    set (p [6], "day");
    set (p [4], "year");
    set (p [3], "hour");
    set (p [2], "minute");

    return 0;
}

the format is awkward unless it really is intended to be interpreted as nibbles

sadly, the bit mask does not work.

ds3231.setYear((pt >> 32) & 0xff);

result: 34

sprintf_P(buf1, PSTR("%02x"), ((byte)(pt >> 32)));
ds3231.setYear(String(buf1).toInt());

result: 22

Here is a useful function:


byte bcdToNumber(byte b) {
  // convert BCD (binary-coded decimal) to an ordinary number
  byte tens = (b >> 4) & 0xF;
  byte ones = b & 0xF;
  return (byte)((tens * 10) + ones);
}

That function allows you to do this:

ds3231.setYear(bcdToNumber((byte)((pt >> 32) & 0xff)));

You might want tot post your entire sketch, so we can see the actual format of pt.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.