Combining/stacking binary values

I’m working on a project using 60x buttons and 8x 74hc165 shift registers and I’m stuck. How can I combine, or stack all the “shift_x” variables into “shift_full” as a single 64 character binary string?

void loop() {
  int i;
  digitalWrite(2, LOW);
  shift_8 = SPI.transfer(0x00);
  shift_7 = SPI.transfer(0x00);
  shift_6 = SPI.transfer(0x00);
  shift_5 = SPI.transfer(0x00);
  shift_4 = SPI.transfer(0x00);
  shift_3 = SPI.transfer(0x00);
  shift_2 = SPI.transfer(0x00);
  shift_1 = SPI.transfer(0x00);

  for (i=0; i<=59; i++) {
if (bitRead(shift_full,i) == 0) {
   DmxSimple.write(i+1, 255);
  } else {
    DmxSimple.write(i+1, 0);

You can shift the data left & right into the position you want. For example,
unsigned long data32bit = (shift8<<32) | (shift7<<24) | (shift6 <<16) | shift5;

I don’t know if Arduino handles 64 bit data, but C++ certainly does. See Big Numbers library Nick Gammon put together:

one way would be like this:

unsigned long long shiftFull = 0; //unsigned 64 bit integer
for(byte i = 0; i < 8; i++) {
  shiftFull += SPI.transfer(0x00) << (i << 3);

Although, this just seems clunky and does not leave room for expanding.
Why not just use an array of bytes and use an access function?

byte data[8];
for(byte i = 0; i < 8; i++) {
  data[i] = SPI.transfer(0x00);

boolean getButtonStatus(byte button) {
  return data[button >> 3] & (button % 8); //return the correct bit (0-60)

I’m still relatively new to programming. I don’t understand a lot of what’s going on there yet. I seem to be getting somewhere combining what you both suggested by using “unsigned long long” and shifting using (shift_2<<8). I’ll report back soon.

To shift a integer variable left, use <<. to shift it right, use >>. To set a bit, to a bitwise OR |. To unset a bit, take the bitwise complement of the bit you want to unset ~ and then do a bitwise AND &.

All of these operators have handy ~=, &= etc. assignment operators

Set bit 5: [nobbc]x |= (1<<5);[/nobbc]

Clear bit 7: [nobbc]x &= ~(1<<7);[/nobbc]

Move x left by three bits: [nobbc]x &= ~(1<<7);[/nobbc]

Move x left by one bit, and set bit 0 according to a variable: [nobbc]x = (x<<1) | (var ? 1 : 0);[/nobbc]

Set a digital out according to digit 59, and shift things along: [nobbc]digitalWrite(pin, x&(1<<59) ? HIGH:LOW); x <<= 1;[/nobbc]


Move x left by three bits: [nobbc]x &= ~(1<<7);[/nobbc]

“three”, yet you use (1<<7)


digitalWrite(pin, x&(1<<59) ? HIGH:LOW);

you need to specify unsigned long long by using

digitalWrite(pin, x&(1ULL<<59) ? HIGH:LOW);

otherwise it will default to 16bit and overflow, at least from my experience.

Here is a more commented version:

byte data[8] = {0,0,0,0,0,0,0,0}; //create an array of 8 bytes (64 bits total), all set to 0
byte i = 0;
//I replaced the "for loop" with a "while loop" to make it easier to understand, but they do the same thing
while(i < 8) { //we want our code to execute 8 times, this is how we do it
  data[i] = SPI.transfer(0x00); //SPI.transfer returns a byte, so we store that byte in our array, if it is the 6th byte, then we store it in the 6th array slot
  i++; //we want to keep track of how many times we have run the code

//this is our retrieval function, you enter which bit you want, (0-60) and it will return a 'true' or 'false' depending on whether that bit is set or not
boolean getButtonStatus(byte button) {
  return data[button >> 3] & (button % 8);
  //the best way to understand this is to write it out. For example, say you want bit 26. 
  //Our array stores 8 bits per slot, so 
  //slot 1 holds bits 0-7, 
  //slot 2 holds 8-15, 
  //slot 3 holds 16-23, 
  //slot 4 holds 24-31. 
  //So we know that the 4th array slot holds the bit we want, the 26th bit.
  //So we simply do "button / 8" or "button >> 3" which does the same thing, because 26 / 8 is 3 (or the 4th slot because 0 1 2 3<--4th. 
  //I then BITWISE AND, '&', the byte with "button % 8" because 26 % 8 returns 2 (or the 3rd bit (because 0 1 2<--3rd), 
  //which is what we want because our byte holds bits 24-31, we want the 3rd bit, 24 25 26<--3rd one). 
  //All in all, this returns the 3rd bit in the 4th array slot's byte, which is the 26th bit of the whole array. 
  //Hope that makes sense...

@PaulMurray"three", yet you use (1<<7)

Copy/paste issue.

Also,you need to specify unsigned long long by using

digitalWrite(pin, x&(1ULL<<59) ? HIGH:LOW);

otherwise it will default to 16bit and overflow, at least from my experience.

Yup - missed that. Just plain careless.