For your amusement, I've rewritten it to use packed bits in the registers array. It now only needs one byte per '595 chip. I've also fixed the inverted logic problem - #define ON and OFF correctly as HIGH and LOW or visa-versa and it sorts it out for you.
const uint8_t SER_Pin = 11; // MOSI - pin 14 on the 75HC595, data in
const uint8_t RCLK_Pin = 10; // /SS - pin 12 on the 75HC595, store clk
const uint8_t SRCLK_Pin = 13; // SCLK - pin 11 on the 75HC595, shift clock
//How many of the shift registers - change this
#define number_of_74hc595s 1
#define ON LOW
#define OFF HIGH
//// uncomment for Ian's segment ordering
//#define SCRAMBLE
//const uint8_t scramble[]={ 6,5,4,3,2,1,0,7 }; //Map Neo's segment order to mine.
//do not touch
#define numOfRegisterPins number_of_74hc595s * 8
uint8_t registers[number_of_74hc595s];
void setup(){
// Setup pins as output
pinMode(SER_Pin, OUTPUT);
pinMode(RCLK_Pin, OUTPUT);
pinMode(SRCLK_Pin, OUTPUT);
//reset all register pins
clearRegisters();
writeRegisters();
}
//set all register pins to OFF
void clearRegisters(){
for(uint8_t i = 0; i<sizeof(registers); i++){
registers[i] = OFF?0xFF:0;
}
}
//Set and display registers
//Only call AFTER all values are set how you would like (slow otherwise)
void writeRegisters(){
digitalWrite(RCLK_Pin, LOW);
for(uint8_t i = sizeof(registers); i--;){ //loop from N-1 to zero inclusive
uint8_t t=registers[i];
for(uint8_t j = 8; j--;){
digitalWrite(SRCLK_Pin, LOW);
// // Extract bit value and output the simple way
// bool val = !!(t&128);
// digitalWrite(SER_Pin, val);
// Extract bit value and output the fast way
if(!!(t&128)) digitalWrite(SER_Pin, HIGH); else digitalWrite(SER_Pin, LOW);
//delayMicroseconds(10); // dont exceed 100 KHz!
digitalWrite(SRCLK_Pin, HIGH);
t<<=1; //shift to next bit.
}
}
digitalWrite(RCLK_Pin, HIGH);
}
//set an individual pin HIGH or LOW
void setRegisterPin(uint8_t index, bool value){
const uint8_t BitMasks[]={1,2,4,8,16,32,64,128}; // convert bit position to single '1' mask
#ifdef SCRAMBLE
index=(index&0xF8)|scramble[index&7];
#endif
if(value) registers[index>>3]|=BitMasks[index&7]; else registers[index>>3]&=~BitMasks[index&7];
}
void loop(){
// Display segments for "3"
setRegisterPin(0, ON); //a
setRegisterPin(1, ON); //b
setRegisterPin(2, ON); //c
setRegisterPin(3, ON); //d
setRegisterPin(4, OFF); //e
setRegisterPin(5, OFF); //f
setRegisterPin(6, ON); //g
setRegisterPin(7, OFF); //d.p.
writeRegisters(); //MUST BE CALLED TO DISPLAY CHANGES
//Only call once after the values are set how you need.
delay(2);
}
Sketch is called 'Neo1e'.
I'm also using C99 fixed width integer types (from stdint.h) for brevity and efficiency - you'll need an OPTIONAL patch for keywords.txt if you want the IDE's syntax hilighting to support them.