How do I transfer a byte value to boolean array

I'm building a project using three cascaded TPIC6B595 shift registers to drive 24 LEDs. I've chosen to base my code on the sample given in Bildr's tutorial on shiftregisters -- http://bildr.org/2011/02/74hc595/. The LEDs are functionally grouped and manipulated as groups, providing different indications -- 7-segment display, 10-segment bar graph and 6 segment bar graph. The functional groups do span shift registers, so I can't address any one shift register alone. They all have to be updated at once.

The tutorial's code declares a boolean array equal in size to (the number of registers X outputs per register). For three shift registers, that would be 24 elements. This array is filled with the value to be transmitted serially to the cascaded registers, one boolean element at a time. This single bit manipulation concept works great for parts of my project but one part has me stumped.

#define number_of_74hc595s 3 
#define numOfRegisterPins number_of_74hc595s * 8

boolean registers[numOfRegisterPins];  // Array to store bit patterns for display

/*
 * Basic register manipulating routines
 */
  
//set an individual pin HIGH or LOW
void setRegisterPin(int index, int value){
  registers[index] = value;
}

void clearRegisters(){
  for(int i = numOfRegisterPins - 1; i >=  0; i--){
    registers[i] = LOW;
  }
} 

//Set and display registers
//Only call AFTER all values are set how you would like (slow otherwise)
void writeRegisters(){

  digitalWrite(RCLK_Pin, LOW);

  for(int i = numOfRegisterPins - 1; i >=  0; i--){
    digitalWrite(SRCLK_Pin, LOW);

    int val = registers[i];

    digitalWrite(SER_Pin, val);
    digitalWrite(SRCLK_Pin, HIGH);

  }
  digitalWrite(RCLK_Pin, HIGH);

}

I'm stumped on how to display the digit in the 7-segment display. I have declared a 10 element byte array, each element represents a binary encoding of the digit to display:

// Font table for 7-segment
const static byte charTable[128] = 
{
  //0         1         2         3         4         5         6         7
  B00111111,B00000110,B01011011,B01001111,B01100110,B01101101,B01111101,B00000111,
  //8         9
  B01111111,B01100111
};

Once I have looked up the digit I wish to display in charTable[], how do I fill the boolean array registers[] with the value from charTable[]? I can't just write out the value to the first shift register using digitalWrite(); that would cause havoc with the rest of the code. I think I have to write a routine which calls the function setRegisterPin() eight times, with the bit value of the charTable element for each call. This seems wasteful and high overhead to me.

Is there a slicker way to get this done?

Thanks, Robert.

Since you're storing each pin state in a boolean, you will have to address each boolean individually - that means eight separate assignments in order to update eight pins.

I don't know how well your other output groups align with multiples of eight bits but an approach which would work well if they do is to store each pin state in a bit rather than a boolean. With that approach you would obviously assign eight output states in a single operation, as long as the eight were aligned so that they were held in the same byte. (If your output groupings don't fall neatly into multiples of eight then this would be quite messy and not IMO a good way to go.)

Calling a function which assigns a value to an array element eight times does not strike me as particularly wasteful. You could inline it if you wanted to minimise the runtime cost, but it is not going to be an expansive function anyway. If I were you I'd just resign myself to the fact that this architecture results in setRegisterPin() being called once for each pin every time you refresh the display. There are only twenty four pins at the end of the day - is it such a big deal?

Thank you very much Peter.

PeterH:
(If your output groupings don’t fall neatly into multiples of eight then this would be quite messy and not IMO a good way to go.)

Unfortunately, they don’t align on 8-bit boundaries, so I can’t consider this approach.

PeterH:
If I were you I’d just resign myself to the fact that this architecture results in setRegisterPin() being called once for each pin every time you refresh the display. There are only twenty four pins at the end of the day - is it such a big deal?

I guess I’ll resign myself to the inevitable.

I quickly prototyped the routine to decode the font table and write the pin values. Very simple using bitRead().

void readFontTable (int digit)
{
      for (int i=0; i<8; i++)
      {
        if ( bitRead (charTable[digit],i) )
          setRegisterPin(i, HIGH);
        else
          setRegisterPin(i, LOW);
      }
}

I have only been using the Arduino platform for 1.5 weeks so I am not an expert coder by any stretch.

Couldn't you use bitSet?

I have some code below which sets bits on the 595 register, that might give you ideas:

http://www.gammon.com.au/forum/?id=11518

I was doing 32 of them at one stage (you could do more, of course).

Hi Nick,

Thank you for pointing me at your page on shift registers. I'll take some time to examine the code to see if I can adapt it to my project.