Is there a way to get the total bit count from an unsigned long?

I’m playing with the IRremote library, and I would like to be able to dynamically send IR codes using their HEX code, but the number of bits in the hex code are not always the same, and the number of bits is a required argument in the send commands.

SO, for example, when I send the code 0x366932, I need to be able to send it along with the number of bits in the code (24 in this case).

So I need something like this:

unsigned long num1 = 0x366932;
unsigned long num2 = 0xA23D22DD;

irsend.send(num1, numOfBits(num1)); // 0x366932, 24
irsend.send(num2, numOfBits(num2)); // 0xA23D22DD, 32

Is this possible?

if you let numOfBits be something like this

uint8_t numOfBits(uint32_t var) {
  uint8_t bits=0;
  while (var) {
    bits++;
    var=var>>1;
  }
  return bits;
}

EasyGoing1:
I’m playing with the IRremote library, and I would like to be able to dynamically send IR codes using their HEX code, but the number of bits in the hex code are not always the same, and the number of bits is a required argument in the send commands.

SO, for example, when I send the code 0x366932, I need to be able to send it along with the number of bits in the code (24 in this case).

So I need something like this:

unsigned long num1 = 0x366932;

unsigned long num2 = 0xA23D22DD;

irsend.send(num1, numOfBits(num1)); // 0x366932, 24
irsend.send(num2, numOfBits(num2)); // 0xA23D22DD, 32




Is this possible?

It’s an unsigned long. It always has 32 bits. No matter what number you store in it, there are 32 bits. You should send 32 bits. The first 8 or 10 or 12 may be 0’s, but they’re there.

Works in this limited case. Other values not tested.

// send number of bits in argument as part of stream

//https://forum.arduino.cc/index.php?topic=635059.0

unsigned long num1 = 0x366932;
unsigned long num2 = 0xA23D22DD;

void setup() {
  Serial.begin(115200);
  if (num1 > 0xffffff) {
    Serial.println("32");
  }
  else
    Serial.println("24");

  if (num2 > 0xffffff) {
    Serial.println("32");
  }
  else
    Serial.println("24");
}

void loop() {
}

Delta_G:
It's an unsigned long. It always has 32 bits. No matter what number you store in it, there are 32 bits. You should send 32 bits. The first 8 or 10 or 12 may be 0's, but they're there.

Brilliant!

So what you're telling me is that I couldn't store this number in an unsigned long even if I wanted to

0x78BC12BAED

? ?

So what you're telling me is that I couldn't store this number in an unsigned long even if I wanted to

Look at the title you gave this thread. You explicitly asked about the number of bits in an unsigned long, which is 32 on most Arduinos so no, 0x78BC12BAED, will not fit in a 32 bit unsigned long

Deva_Rishi:
if you let numOfBits be something like this

uint8_t numOfBits(uint32_t var) {

uint8_t bits=0;
 while (var) {
   bits++;
   var=var>>1;
 }
 return bits;
}

That works … looks like you’re bit shifting? I really need to change the way I think about Arduino code … this makes a lot of sense and it’s so simple yet the notion of doing it this way never crossed my mind.

UKHeliBob:
Look at the title you gave this thread. You explicitly asked about the number of bits in an unsigned long, which is 32 on most Arduinos so no, 0x78BC12BAED, will not fit in a 32 bit unsigned long

Right, I just tested a longer number on a Nano and it didn't give me the number that I assigned to the variable, but it did give me a number. For example:

unsigned long num3 = 0x78BC12BAED;

When I printed it using String(num3,HEX); came back as this:

bc12baed

looks like it truncated it

Why the use of String when you could just print num3 ?

The IRremote library doesn't seem to have a .send() command. The .sendRaw() command takes an unsigned integer array as the first argument, the number of elements of the array for the 2nd argument, and the frequency for the 3rd argument.

void  sendRaw     (const unsigned int buf[],  unsigned int len,  unsigned int hz) ;

The brand-specific send commands do take the number of bits as the 2nd argument, but the only one I see for sending raw data is for Sharp, and it explicitly takes an unsigned long as the 1st argument.

void  sendSharpRaw   (unsigned long data,  int nbits) ;

EasyGoing1:
Right, I just tested a longer number on a Nano and it didn't give me the number that I assigned to the variable, but it did give me a number. For example:

unsigned long num3 = 0x78BC12BAED;

When I printed it using String(num3,HEX); came back as this:

bc12baed

looks like it truncated it

Yes, that's what happens. A long or unsigned long is 32 bits. If you try to give it more it will just take the low 32 bits.

Same with a byte, it's only 8 bits and if you try to give it any more it will just take the bottom 8 bits.

It will also never ever have less than 32 bits. Even if you write:

unsigned long var = 0x1;

That's still a 32 bit number. It's stored as 0b00000000000000000000000000000001 and you'd send it as 32 bits long if you are smart. There's something called endianess (that you can google) and it means that if you give it that number with a size less than 32 there's no guarantee that the part that gets sent is the part you care about in the low order bits. It might send a bunch of zeros instead. So you should be using 32 as the size if the variable is unsigned long and you're on one of the normal Arduinos where long is 32 bit.

EasyGoing1:
So I need something like this:

unsigned long num1 = 0x366932;

unsigned long num2 = 0xA23D22DD;

irsend.send(num1, numOfBits(num1)); // 0x366932, 24
irsend.send(num2, numOfBits(num2)); // 0xA23D22DD, 32




Is this possible?

No. In the IRremote library, the value you receive in results.value can't be sent successfully without also knowing results.decode_type and results.bits (and in the case of PANASONIC and SHARP: results.address).
When you receive a signal through the IRremote library you find those values in:
results.decode_type
results.address (used by decode_type PANASONIC and SHARP)
results.value
results.bits
If results.decode_type is UNKNOWN then you have to save the results.rawlen unsigned integers in the buffer pointed to by results.rawbuf.