IR sensors and 4067 expansion

hi

im sensing the values from (currently) 5 ir sensors, and replaying that sensor reading to an led.

i want to expand my circuit to 16 leds and 16 ir sensors, so i’ve opted for the HEF4067 chip, which is quite well documented.

i have the test code running and this is fine, i can read from the 8 sensors i have currently wired in as i should be able to.

my issue is working this test code into my main code.

the main issue being that i the 4067 is read multiplexed, and im not sure how to use this data later.

most of the variable are setup to start
then in the setup, i take a 1 second calibration of the sensors, and then map this across the data range

in this i did have;

sensorValue1 = analogRead(A0);

but now i have

sensorValue1 = analogRead(readMux(0));
(which i know is wrong)

then in the main loop, i have the constant checking of the irs and the triggering of the leds.

can i get some pointers on the calibration loop, and the main loop with the 4067 code, or a way of breaking the 4067 code down to get better individual readings, like to change the

int readMux(int channel){
int controlPin = {s0, s1, s2, s3};

int muxChannel[16][4]={
{0,0,0,0}, //channel 0
{1,0,0,0}, //channel 1

to be more like;

int readMux(s0){0,0,0,0}
int readMux(s0){1,0,0,0}

(again, i know this code is wrong, but i can use the variable easier!)

etc.

/*
Kelvin Mead
May 2013

Interactive LED panels

Design for 8 LEDs, 8 IR sensors and 8 IR Emitters
Addition for 4067, 16 channel input expander

 */

// set up the leds on the pwm outputs
  int led1 = 5;
  int led2 = 6;
  int led3 = 9;
  int led4 = 10;
  int led5 = 3;
  int led6 = 11;

//Mux control pins
  int s0 = 2;
  int s1 = 4;
  int s2 = 7;
  int s3 = 8;

//Mux in "SIG" pin
  int SIG_pin = 0;
  
// fade speed
// 1 is instant, 9 is slow (not slow enough though)
  int fadespeed = 9;
  int ramp = 0;
  
// this is for changing the fade time without using the delay command  
  long previousMillis = 0;
  // speed for the fades in milliseconds
  long interval = 25;
  
// lowest brightness setting (eliminates tiny flickering errors on divisable fades
  int lowestbrightness = 1;

// full brightness  
  int maxBright = 255;
  
  //calibration routine
  int sensorValue1 = 0;         // the sensor value
// AND ALL THE VALUES IN BETWEEN << REDUCED FOR FORUM RULES
  int sensorValue8 = 0;         // the sensor value
  int sensorMin1 = 1023;        // minimum sensor value
// AND ALL THE VALUES IN BETWEEN << REDUCED FOR FORUM RULES
  int sensorMin8 = 1023;        // minimum sensor value
  int sensorMax = 1000;         // maximum sensor value

// variables for high and low led
  int sensitivity = 10;
  int highsetting1 = 1000;

void setup() {

// initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  
// setup the leds as outputs
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
//  pinMode(led7, OUTPUT);
//  pinMode(led8, OUTPUT);
  
  
int readMux(int channel){
  int controlPin[] = {s0, s1, s2, s3};

  int muxChannel[16][4]={
    {0,0,0,0}, //channel 0
    {1,0,0,0}, //channel 1
    {0,1,0,0}, //channel 2
    {1,1,0,0}, //channel 3
    {0,0,1,0}, //channel 4
    {1,0,1,0}, //channel 5
    {0,1,1,0}, //channel 6
    {1,1,1,0}, //channel 7
    {0,0,0,1}, //channel 8
    {1,0,0,1}, //channel 9
    {0,1,0,1}, //channel 10
    {1,1,0,1}, //channel 11
    {0,0,1,1}, //channel 12
    {1,0,1,1}, //channel 13
    {0,1,1,1}, //channel 14
    {1,1,1,1}  //channel 15
  };
 
  // turn on LED to signal the start of the calibration period:
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);

  // calibrate during the first five seconds 
  while (millis() < 1000) {
    sensorValue1 = analogRead(readMux(0));
    sensorValue2 = analogRead(readMux(1));
    sensorValue3 = analogRead(readMux(2));
    sensorValue4 = analogRead(readMux(3));
    sensorValue5 = analogRead(readMux(4));
    sensorValue6 = analogRead(readMux(5));
    sensorValue7 = analogRead(readMux(6));
    sensorValue8 = analogRead(readMux(7));
   
    // record the minimum sensor value
    if (sensorValue1 < sensorMin1) {
      sensorMin1 = sensorValue1;
    }
    if (sensorValue2 < sensorMin2) {
      sensorMin2 = sensorValue2;
    }
// AND ALL THE VALUES IN BETWEEN << REDUCED FOR FORUM RULES
    if (sensorValue8 < sensorMin8) {
      sensorMin8 = sensorValue8;
    }
    
  }
  // signal the end of the calibration period
  digitalWrite(13, LOW);    
}

void loop() {
  
  // setup mux pins as outputs
  pinMode(s0, OUTPUT); 
  pinMode(s1, OUTPUT); 
  pinMode(s2, OUTPUT); 
  pinMode(s3, OUTPUT); 

// and set to low to initiate 
  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);

// setup the ir sensors as inputs  
int readMux(int channel){
  int controlPin[] = {s0, s1, s2, s3};

  int muxChannel[16][4]={
    {0,0,0,0}, //channel 0
    {1,0,0,0}, //channel 1
    {0,1,0,0}, //channel 2
    {1,1,0,0}, //channel 3
    {0,0,1,0}, //channel 4
    {1,0,1,0}, //channel 5
    {0,1,1,0}, //channel 6
    {1,1,1,0}, //channel 7
    {0,0,0,1}, //channel 8
    {1,0,0,1}, //channel 9
    {0,1,0,1}, //channel 10
    {1,1,0,1}, //channel 11
    {0,0,1,1}, //channel 12
    {1,0,1,1}, //channel 13
    {0,1,1,1}, //channel 14
    {1,1,1,1}  //channel 15
  };

  //loop through the 4 sig
  for(int i = 0; i < 4; i ++){
    digitalWrite(controlPin[i], muxChannel[channel][i]);
  }

  //read the value at the SIG pin
  int val = analogRead(SIG_pin);

  //return the value
  return val;
  
}
  // read sensor values
  sensorValue1 = analogRead(readMux(0));
  sensorValue2 = analogRead(readMux(0));
  sensorValue3 = analogRead(readMux(0));
  sensorValue4 = analogRead(readMux(0));
  sensorValue5 = analogRead(readMux(0));
  sensorValue6 = analogRead(readMux(0));
  sensorValue7 = analogRead(readMux(0));
  sensorValue8 = analogRead(readMux(0));

  // apply the calibration to the sensor reading
  int mappedValue1 = map(sensorValue1, sensorMin1, sensorMax, 0, 255);
// AND ALL THE VALUES IN BETWEEN << REDUCED FOR FORUM RULES
  int mappedValue8 = map(sensorValue8, sensorMin8, sensorMax, 0, 255);

/*
static int lastBright1 = 0;            // set the lastbright variable
if (mappedValue1<sensitivity) {                 // check to see if the ir is detecting above the base level 
  analogWrite(led1, LOW);              // turn the led off
      unsigned long currentMillis = millis();
      if (lastBright1 > 0 && (currentMillis - previousMillis > interval))             // check to see if the last brightness is more than 0 and the interval time has passed
      lastBright1 = lastBright1/100*fadespeed;  // Dim the light til it reaches 0
      previousMillis = currentMillis;
}  else {
  lastBright1 = maxBright;                  //  Set the brightness to full
}
  if (lastBright1 < lowestbrightness) {              // check to see if the led has got to a low level
    lastBright1 = 0;                   // then turn the led off
  }
  analogWrite(led1, lastBright1);      // write the brightness to the led
*/




static int lastBright1 = 0;                        
if (mappedValue1<sensitivity) {                    
  analogWrite(led1, LOW);                          
      if (lastBright1 > 0)                        
      lastBright1 = lastBright1/10*fadespeed;      
}  else {                              
     lastBright1 = maxBright;                        
}
  if (lastBright1 < lowestbrightness) {            
    lastBright1 = 0;                               
  }
  analogWrite(led1, lastBright1);                






  static int lastBright2 = 0;
  if (mappedValue2<sensitivity) {
      if (lastBright2 > 0)
      lastBright2 = lastBright2/10*fadespeed;  
}  else {
  lastBright2 = maxBright; 
}
  if (lastBright2 < lowestbrightness) {
    lastBright2 = 0;
  }
analogWrite(led2, lastBright2);

  
  static int lastBright3 = 0;
if (mappedValue3<sensitivity) {
      if (lastBright3 > 0)
      lastBright3 = lastBright3/10*fadespeed;  
}  else {
  lastBright3 = maxBright; 
}
  if (lastBright3 < lowestbrightness) {
    lastBright3 = 0;
  }
analogWrite(led3, lastBright3);

  
  static int lastBright4 = 0;
  if (mappedValue4<sensitivity) {
      if (lastBright4 > 0)
      lastBright4 = lastBright4/10*fadespeed;  
}  else {
  lastBright4 = maxBright; 
}
  if (lastBright4 < 0) {
    lastBright4 = 0;
  }  
analogWrite(led4, lastBright4);

// THIS GOES ON FOR ANOTHER 4 LEDS / SENSORS BUT THE FORUM TEXT MAX IS 9500 CHARACTERS!

  }  


// delay for the crack of it
  delay(10);

}

Don't you just need to extract the bits from the channel number like this?

int readMux (int channel)
{
  digitalWrite (s3, channel & 8) ;
  digitalWrite (s2, channel & 4) ;
  digitalWrite (s1, channel & 2) ;
  digitalWrite (s0, channel & 1) ;
  return analogRead (A0) ;
}

i might have to, i don't understand what you've written there.

i've dropped it in my code, at the same point as

int readMux(int channel){
int controlPin = {s0, s1, s2, s3};

int muxChannel[16][4]={
{0,0,0,0}, //channel 0
{1,0,0,0}, //channel 1

but i just get errors.

nope, im fighting with this for hours and hours...

i just can't put this code in any part of my code and make useful sense of it.

help :slight_smile:

MarkT:
Don't you just need to extract the bits from the channel number like this?

int readMux (int channel)

{
  digitalWrite (s3, channel & 8) ;
  digitalWrite (s2, channel & 4) ;
  digitalWrite (s1, channel & 2) ;
  digitalWrite (s0, channel & 1) ;
  return analogRead (A0) ;
}

ah ha, i've kinda worked this out now.

and its not something i've seen before, but the

int readMux(int channel){
int controlPin = {s0, s1, s2, s3};

int muxChannel[16][4]={
{0,0,0,0}, //channel 0
{1,0,0,0}, //channel 1

lives outside the void loop ()

at the end. i get things running before, but never seen a slotted bit of code at the end of the program!?!