This is only an example/test code that I used to see if the i/o expander would still work with the light sensors (which it did). If anyone needs to make up their own, they may remove all sub-functions and whatever is in the loop function to get it to work. All you have to do to go to a certain address of the i/o expander is to digitalWrite Apin through Epin to the values of A through E. (see the beginning of the reads sub-function).

For this i/o expander, we used 4 4051's–three were attached to the first three address lines of the first.

Here is the datasheet

*Look at the bottom of the page for an update to the convert subfunction.

//This is i/o expander has 18 possible outputs--possible 32 if convert is edited
//it's loop will only go through the lowest 6 addresses and will read the light sensor at each, one at a time


int reads(int led);//read led
int readsavg(int n, int led);//takes average of n readings for led
int convert(int i);

int anodePin=4;//all led's use this pin for their long leg

int Apin=14;//A0
int Bpin=15;//A1
int Cpin=16;//A2
int Dpin=17;//A3
int Epin=18;//A4
int cathodePin0=19;//A5

int A;
int B;
int C;
int D;
int E;

void setup(){
  _SFR_IO8(0x35) |= 4;
  _SFR_IO8(0x35) |= (1<<4);
  
  pinMode(anodePin, OUTPUT);  //set pins associated with led light sensors to outputs
  pinMode(Apin, OUTPUT);
  pinMode(Bpin, OUTPUT);
  pinMode(Cpin, OUTPUT);
  pinMode(Dpin, OUTPUT);
  pinMode(Epin, OUTPUT);
  pinMode(cathodePin0, OUTPUT);
  
  
  digitalWrite(anodePin, HIGH);
  digitalWrite(cathodePin0,LOW);
  
  digitalWrite(Apin,LOW);
  digitalWrite(Bpin,LOW);
  digitalWrite(Cpin,LOW);
  digitalWrite(Dpin,LOW);
  digitalWrite(Epin,LOW);
  
  Serial.begin(9600);
}
void loop(){
  int n=3;
  for(int j=0; j<6; j++){
    int i=readsavg(n,j);
    Serial.print("j is");
    Serial.println(j);
    Serial.print("i is");
    Serial.println(i); 
    delay(1000);
  }
}
int reads(int led){
  led=led;
  int val = 0;
  int vcc=anodePin;
  convert(led);//get address of led
  //set multiplexer's to read that address
  digitalWrite(Apin, A);
  digitalWrite(Bpin, B);
  digitalWrite(Cpin, C);
  digitalWrite(Dpin, D);
  digitalWrite(Epin, E);
  
  
  digitalWrite(vcc,   HIGH);
  digitalWrite(cathodePin0, LOW);
  
 /* Serial.print(A);
  Serial.print(B);
  Serial.print(C);
  Serial.print(D);
  Serial.println(E);*/
  
  //already emitting light
  
  delay(50);
  
  //switch potentials -- charge LED to -5V
  digitalWrite(vcc,   LOW);
  digitalWrite(cathodePin0, HIGH);
  
  //measure time for potential to equalize (for cathode to be LOW)
  
  //switch pinmode 
  pinMode(cathodePin0,  INPUT);
  
  //measure time it takes for cathodePin to go to zero
  //this value probably depends on the chip clock or something
  while((digitalRead(cathodePin0) != 0)&&(val<100)){
    delay(1);
    val++;      
  }
  pinMode(cathodePin0,  OUTPUT);
  
  digitalWrite(vcc,   HIGH);
  digitalWrite(cathodePin0, LOW);
  //Serial.println(val, DEC);
  return val;
}

int readsavg(int n, int led){
  int val=0;
  for(int i=0; i<n; i++){
    val=val+reads(led);//read n times and sum
  }
  val=val/n;//divide by n for average
  return val;
}
int convert(int i){
  //converts a decimal number from 0 to 17, inclusively, to binary
  A=i/16;
  if(A==1){
    i=i-16;
    B=0;
    C=0;
    D=0;
    E=i;
  }
  if(A==0){
    B=i/8;
    if(B==1){
      i=i-8;
      C=i/4;
      if(C==1){
        i=i-4;
        D=i/2;
        if(D==1){
          i=i-2;
          E=i;
        }
        if(D==0){
          E=i;
        }
      }
      if(C==0){
        D=i/2;
        if(D==1){
          i=i-2;
          E=i;
        }
        if(D==0){
          E=i;
        }
      }
    }
    if(B==0){
      C=i/4;
      if(C==1){
        i=i-4;
        D=i/2;
        if(D==1){
          i=i-2;
          E=i;
        }
        if(D==0){
          E=i;
        }
      }
      if(C==0){
        D=i/2;
        if(D==1){
          i=i-2;
          E=i;
        }
        if(D==0){
          E=i;
        }
      }
    }
  }
}

**This is an update to the convert subfunction: I realized that the above chain of if statements was stupid and that there is a much better way to do it if you just put a bit more thought into it. So here it is:

void convert(int i){
  //This function handles numbers from 0 to 31
  A=i/16;
  i=i-(A*16);
  B=i/8;
  i=i-(B*8);
  C=i/4;
  i=i-(C*4);
  D=i/2;
  i=(D*2);
  E=i;
}

//so much nicer right

Here is the promised circuits diagram: