Combining 4 bytes in to uint32_t

I'm trying to combine 4 bytes into a uint32_t to send to a shift register which controls a 4 digit 7 segment display.

this is the bit pattern for the 4 bytes, This will display 0123 on the display so it is not the same a 1 = 00000001 in Binary.

I expect the combined bytes to look like this is:
00111111000000110011111101100111

the output is actually:
1001001000010010100100101001001
not understanding why they don't match

also, how do I get the "0B" in front of the combines bytes

void setup() {
  int32_t combined = 0;
  uint8_t byte3 = 00111111; //0 63 
  uint8_t byte2 = 00000011; //1 63 
  uint8_t byte1 = 00111111; //2 3
  uint8_t byte0 = 01100111; //3 

  Serial.begin(9600);
  delay(1000);
  Serial.println("Starting");

  //ex 1
  combined = ((uint32_t)byte3 << 24) |((uint32_t)byte2 << 16) | ((uint32_t)byte1 << 8) | (uint32_t)byte0;
  Serial.print("Before Sign Extension: ");
  Serial.println(combined, BIN);

}

void loop() {
  
}
Serial.print ("0b");
Serial.println(combined, BIN);

Those are octal values, not binary.
Try putting "0b" in front of them.

Here I break down a 32 bit into its 8 bitties. You should be able to figure the reverse process.

if (!PassTwo)
        {
          rx_frame.FIR.B.FF = CAN_frame_std;
          rx_frame.MsgID = 1;
          rx_frame.FIR.B.DLC = 8;
          rx_frame.data.u8[0] = *item & 0xFF;
          rx_frame.data.u8[1] = (*item >> 8) & 0xFF;
          rx_frame.data.u8[2] = (*item >> 16) & 0xFF;
          rx_frame.data.u8[3] = (*item >> 24) & 0xFF;
          PassTwo = true;
        } else {
          rx_frame.data.u8[4] = *item & 0xFF;;
          rx_frame.data.u8[5] = (*item >> 8) & 0xFF;
          rx_frame.data.u8[6] = (*item >> 16) & 0xFF;
          rx_frame.data.u8[7] = (*item >> 24) & 0xFF;
          ESP32Can.CANWriteFrame(&rx_frame); // send items over CAN buss
          PassTwo = false;
        }
1 Like

Wait what? why are you using int32 and not uint32?

int32....typo

So I now get the correct combined value. in order to pass it to the "shiftOut" it needs to have the "0b in front of it, how do I combine them and pass it?

I keep getting 'data' was not declared in this scope

if I try to assign the "combined" value to "data" which is sent to the shift register.

const int dataPin = 5;
const int clockPin = 4;

void setup() { 
    Serial.begin(9600);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  uint32_t data = 0;
  uint32_t combined = 0;
  uint8_t byte3 = 0b00000011; //1
  uint8_t byte2 = 0b01101101; //2
  uint8_t byte1 = 0b01100111; //3
  uint8_t byte0 = 0b01010011; //4
  combined = ((uint32_t)byte3 << 24) |((uint32_t)byte2 << 16) | ((uint32_t)byte1 << 8) | (uint32_t)byte0;
  Serial.print("COMBINED: ");
  Serial.println(combined, BIN);
}


void loop() { 

  //uint32_t data = 0b11011011010110011101010011; //1-2-3-4  this works
  //uint32_t data = 0x036D6753; //1-2-3-4 this works
  shiftOut(dataPin, clockPin, LSBFIRST, data );
  shiftOut(dataPin, clockPin, LSBFIRST, data >> 8 );
  shiftOut(dataPin, clockPin, LSBFIRST, data >> 16 );
  shiftOut(dataPin, clockPin, LSBFIRST, data >> 24 );

delay (500);
}//end loop

No.

Incorrect.

Why? You already have the 32 bit value stored in the variable combined.

There is no variable called data declared within the loop() function.

Your variable called data that you declared in the setup() function cannot be seen from the loop() function.

Maybe I'm missing something here? Why do you need to combine them at all? Just send the 4 bytes out one after the other as they are.

As for bytes and bits it doesn't matter. A byte is a byte is a byte. Displaying it as bits or bytes or a decimal number or nano parsecs doesn't make any difference, it's still a byte, which is still 8 bits.

I think you are doing a lot of unnecessary messing about.

1 Like

jeez, what a bone head I am... I was so focused on one part and didn't realize I put that in setup...

so i should do this?

shiftOut(dataPin, clockPin, LSBFIRST, byte0 );
shiftOut(dataPin, clockPin, LSBFIRST, byte1 >> 8 );
shiftOut(dataPin, clockPin, LSBFIRST, byte2 >> 16 );
shiftOut(dataPin, clockPin, LSBFIRST, byte3 >> 24 );

that didn't work

No,
This:

shiftOut(dataPin, clockPin, LSBFIRST, byte0);
shiftOut(dataPin, clockPin, LSBFIRST, byte1);
shiftOut(dataPin, clockPin, LSBFIRST, byte2);
shiftOut(dataPin, clockPin, LSBFIRST, byte3);

You are already shifting the bits up by shifting them out, you don't need to do it again in the code.

wow, that just made things a lot easier. i definitely went down the wrong path.

Think about what the hardware is actually doing when it does what you ask of it.

I have seen similar attempts to combine data for Serial.print, which is also unnecessary, you just print things individually in the order they need to be sent.

I'm not familiar with the shiftOut function, but from your description of what you are doing I would think SPI would be a better choice. SPI is basically a shift register with some clock circuitry, it is intended for this kind of thing.

...but has the potential drawback that it uses a defined set of pins

Also doesn’t work well with MAX7219 for some reason but shift out works very well