Arduino: Bit shifting from an array

My latest project required me to expand the number of pins my Arduino has to offer. So out comes the trusty 74HC595N. My project uses various states and I didn’t want to have to shift out or set bitmasks repeatedly throughout my code. So I put together a function that would take an array and set the state of the 74HC595N based on that.

void setStates(int data[])
{
  long int toSend = 0;

  for(int i=7; i>=0; i--)
  {
    toSend |= data[i];
    if(i >0)
    {
      toSend <<= 1;
    }
  }
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, toSend);
  digitalWrite(latchPin, HIGH);
  return;
}

This function takes an array, where each element represents one of the outputs of the 74HC595N respectively, so each output pin on the 74HC595N can be addressed individually. It starts by creating the integer toSend, giving it the value of 0 so all the bits in toSend are set to 0. It then loops backwards through the array setting the first bit of toSend to the value of the array element. Finally, it then shifts this bit left by one ready to set the next bit. When we are at the last element of the array (technically the first since we’re going backwards, i=0) we don’t shift the bits left, otherwise everything gets pushed along one extra time and the bit set in the first iteration loop would be shifted off the end and lost.

Then, in the Arduino loop() I can set any element to either 1 or 0 (on or off) and call setStates() at the end of the loop to update the 74HC595N. Like this:

void setup()
{
  int data[8] = {};
}

void loop()
{
  if(someConditionIsMet)
  {
    data[3] = 1;
  }
  else
  {
     data[3] = 0;
  }
  if(someOtherConditionIsMet)
  {
  // do something
  if(someNestedConditionIsMet)
    {
    data[2] = 1;
    }
  }
  setStates(data);
}

To make it to work with chained 74HC595N’s, you’ll first need a larger array and to increase the size of i in the for loop (where i = n-1). Since shiftOut() only shifts 8 bits at a time, you need to add extra shiftOut() steps, moving through the value to be sent. Here’s the same function modified for 16 outputs:

void setStates(int data[])
{
  long int toSend = 0;

  for(int i=15; i>=0; i--)
  {
    toSend |= data[i];
    if(i >0)
    {
      toSend <<= 1;
    }
  }
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, (toSend >> 8));
  shiftOut(dataPin, clockPin, MSBFIRST, toSend);
  digitalWrite(latchPin, HIGH);
  return;
}

Hopefully you’ve found this helpful. Let me know of any improvements or suggestions in the comments below.

Advertisements

~ by Jay on October 13, 2014.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

 
%d bloggers like this: