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: