Go Down

Topic: Demultiplexing / 4051 (Read 850 times) previous topic - next topic

Aaron2010

Can someone show me how to integrate the 4051 Demultiplexing code into the analog sensor sketch I have written.  I can't find any detailed documentation on how to do this.  I have referenced the 4051 learning section, read some posts, understand the pin wiring, but can't quite figure out how to integrate the code. The sketch I have written has only 6 sensors in it (because of the arduino pin limitations), and I will eventually expand that number to 24 once i can get the 4051 demultiplexing working.  I just don't see how to merge the two sketches together.

Here is the 4051 sketch:
Code: [Select]
/*

* codeexample for useing a 4051 * analog multiplexer / demultiplexer

* by david c. and tomek n.* for k3 / malm? h?gskola

*

* edited by Ross R.

*/ 



int r0 = 0;      //value of select pin at the 4051 (s0)

int r1 = 0;      //value of select pin at the 4051 (s1)

int r2 = 0;      //value of select pin at the 4051 (s2)

int count = 0;   //which y pin we are selecting



void setup(){



  pinMode(2, OUTPUT);    // s0

  pinMode(3, OUTPUT);    // s1

  pinMode(4, OUTPUT);    // s2

}



void loop () {



  for (count=0; count<=7; count++) {



    // select the bit 

    r0 = bitRead(count,0);    // use this with arduino 0013 (and newer versions)     

    r1 = bitRead(count,1);    // use this with arduino 0013 (and newer versions)     

    r2 = bitRead(count,2);    // use this with arduino 0013 (and newer versions)     



    //r0 = count & 0x01;      // old version of setting the bits

    //r1 = (count>>1) & 0x01;      // old version of setting the bits

    //r2 = (count>>2) & 0x01;      // old version of setting the bits



    digitalWrite(2, r0);

    digitalWrite(3, r1);

    digitalWrite(4, r2);



    //Either read or write the multiplexed pin here



  } 

}


And here is my sketch:
Code: [Select]
int IRpin = 0;                                   
int IRpin1 = 1;
int IRpin2 = 2;
int IRpin3 = 3;
int IRpin4 = 4;
int IRpin5 = 5;

int ledpin = 8;
int ledpin1 = 9;
int ledpin2 = 10;
int ledpin3 = 7;
int ledpin4 = 6;
int ledpin5 = 5;

void setup() {
  Serial.begin(9600);
  pinMode(ledpin, OUTPUT);
  pinMode(ledpin1, OUTPUT);
  pinMode(ledpin2, OUTPUT);
  pinMode(ledpin3, OUTPUT);
  pinMode(ledpin4, OUTPUT);
  pinMode(ledpin5, OUTPUT);
}

void loop() {
 
  digitalWrite(ledpin, HIGH);
  digitalWrite(ledpin1, LOW);
  digitalWrite(ledpin2, LOW);
  digitalWrite(ledpin3, LOW); 
  digitalWrite(ledpin4, LOW);
  digitalWrite(ledpin5, LOW);
  delay(1000);                 
 
  float volts = analogRead(IRpin)*0.0048828125;   
  float distance = 27*pow(volts, -1.15);
  float Inches = (distance / 2.54);
 
  if (Inches <= 6){
  Serial.print("MISS...The ball stopped in ROW1  ");
  Serial.println(  Inches ); 
}


  digitalWrite(ledpin, LOW); 
  digitalWrite(ledpin1, HIGH);
  digitalWrite(ledpin2, LOW);
  digitalWrite(ledpin3, LOW);
  digitalWrite(ledpin4, LOW);
  digitalWrite(ledpin5, LOW);
  delay(1000);                 
 
  float volts1 = analogRead(IRpin1)*0.0048828125;   
  float distance1 = 27*pow(volts1, -1.15);
  float Inches1 = (distance1 / 2.54);
 
  if (Inches1 <= 6){
  Serial.print("MISS...The ball stopped in ROW2  ");
  Serial.println(  Inches1 ); 
}
 
  digitalWrite(ledpin, LOW); 
  digitalWrite(ledpin1, LOW);
  digitalWrite(ledpin2, HIGH);
  digitalWrite(ledpin3, LOW);
  digitalWrite(ledpin4, LOW);
  digitalWrite(ledpin5, LOW);
  delay(1000);   
 
  float volts2 = analogRead(IRpin2)*0.0048828125;   
  float distance2 = 27*pow(volts2, -1.15);
  float Inches2 = (distance2 / 2.54);
 
  if (Inches2 <= 6){
  Serial.print("MISS...The ball stopped in ROW3  ");
  Serial.println(  Inches2 ); 
}
 
  digitalWrite(ledpin, LOW); 
  digitalWrite(ledpin1, LOW);
  digitalWrite(ledpin2, LOW);
  digitalWrite(ledpin3, HIGH);
  digitalWrite(ledpin4, LOW);
  digitalWrite(ledpin5, LOW);
  delay(1000);   
 
  float volts3 = analogRead(IRpin3)*0.0048828125;   
  float distance3 = 27*pow(volts3, -1.15);
  float Inches3 = (distance3 / 2.54);
 
  if (Inches3 <= 23){
  Serial.print("MISS...The ball stopped in Column 3  ");
  Serial.println(  Inches3 ); 
}
 
  digitalWrite(ledpin, LOW); 
  digitalWrite(ledpin1, LOW);
  digitalWrite(ledpin2, LOW);
  digitalWrite(ledpin3, LOW);
  digitalWrite(ledpin4, HIGH);
  digitalWrite(ledpin5, LOW);
  delay(1000);   
 
  float volts4 = analogRead(IRpin4)*0.0048828125;   
  float distance4 = 27*pow(volts4, -1.15);
  float Inches4 = (distance4 / 2.54);
 
  if (Inches4 <= 6){
  Serial.print("MISS...The ball stopped in Column 2  ");
  Serial.println(  Inches4 ); 
}

  digitalWrite(ledpin, LOW); 
  digitalWrite(ledpin1, LOW);
  digitalWrite(ledpin2, LOW);
  digitalWrite(ledpin3, LOW);
  digitalWrite(ledpin4, LOW);
  digitalWrite(ledpin5, HIGH);
  delay(1000);   
 
  float volts5 = analogRead(IRpin5)*0.0048828125;   
  float distance5 = 27*pow(volts5, -1.15);
  float Inches5 = (distance5 / 2.54);
 
  if (Inches5 <= 6){
  Serial.print("MISS...The ball stopped in Column 1  ");
  Serial.println(  Inches5 ); 


  }
}



THANKS FOR THE HELP IN ADVANCE!

-Aaron

pylon

You should learn to handle arrays :

Code: [Select]
IRpins[] = { 0, 1, 2, 3, 4, 5};
ledPins[] = { 8, 9, 10, 7, 6, 5 };


Using this you could shorten your code to about 20% of what it is now.


I'd integrate your device selector into a function
Code: [Select]
void selectInput(uint8_t number) {
  digitalWrite(2, number & 0x01);
  digitalWrite(3, (number >> 1) & 0x01);
  digitalWrite(4, (number >> 2) & 0x01);
}


Keep in mind that your currently use 6 of the 14 digital pins as LED pins, 2 are reserved for the serial communication, leaving 6 for analog input channel selection. With 2 4051 you need this 6 pins for the selection but this gets you only 16 multiplexed analog channels. To get the 24 you need you have to convert some of the analog inputs to digital IO pins.

Aaron2010

I will be using the Mega so ill have the 24 digital pins available,(which select the appropriate sensor now), but still need more analog pins, hence using the 4051.  So i was going to use the demultiplexing example from the Learning page as the setup.  The "led pins" were just a naming convention I didn't change to something more appropriate like sensor pins. using an array is a good idea as well.  I'm just writing it out the long way so i can see everything, since i'm new to programming.

Do you think you could elaborate a little more on how to implement the code because I'm really somewhat stuck at this point?  How do I program the 3 digital pins(or 6 actually, i think?) to select the right sensor, and  how does that translate to the 24 analog pins I need.  in the learning example there is a 2,3,4 (digital pins) and then 5,6,7(digital pins).  Not sure how to navigate this.

so i guess in my new code i will be replacing the
Code: [Select]
digitalWrite(ledpin, LOW); 
  digitalWrite(ledpin1, LOW);
  digitalWrite(ledpin2, HIGH);
  digitalWrite(ledpin3, LOW);
  digitalWrite(ledpin4, LOW);
  digitalWrite(ledpin5, LOW);


with the code the 4051 uses to select the sensor. and i will also be taking those positive leads(that were the selectors)  and hooking them up to 5v instead of the digital pins.
I sort of see where your going with the function but not sure still.  Thanks again

-Aaron

pylon

Does that mean the ledpins in your code are the select pins for the analog input? Strange naming convention...

I gave you a routine to select any of the 8 inputs of the 4051. The easiest for your setup of 24 analog sensors is to use 3 of the 4051s, connect the 3 addressing pins of all three chips to the same 3 digital pins of your Arduino (let's say pin 2, 3, 4 as in my code) and connect the output of the 4051s to three analog inputs (let's say A0, A1 and A2). This way you can select any of the 8 input selection sets and read 3 analog inputs in one round. Example code:

Code: [Select]

uint8_t s,i;
uint16_t values[24];
for (s = 0; s < 8; s++) {
  selectInput(s); // routine from my previous post
  for (i = 0; i < 3; i++) {
    values[(i <<3)+s] = analogRead(i);
  }
}


This will read all your 24 sensors if they are connected as described.

Aaron2010

So here is my new code.
Code: [Select]
int s0 = 10;
int s1 = 9;
int s2 = 8;

int rowTTL = 0;

int  binTTL [] = {
  0, 1, 2, 3, 4, 5, 6, 7};//bin = bin?r, some times it is so easy


int inPin = A4;
int result;

void setup(){
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  Serial.begin(9600);
}


void loop(){

  for(int i=0; i<8; i++){

    rowTTL = binTTL[i];
    sendABCTTL(rowTTL);
    result = analogRead(inPin);
   
   
  float volts = analogRead(inPin)*0.0048828125;   
  float distance = 27*pow(volts, -1.15);
  float Inches = (distance / 2.54);
 
  if (Inches <= 16){
  Serial.print("MISS...The ball stopped in ROW1  ");
    Serial.println( Inches );
  }

  }
}

void sendABCTTL(int rowTTL){
  switch(rowTTL) {
  case 0:
    digitalWrite(s0, LOW);
    digitalWrite(s1, LOW);
    digitalWrite(s2, LOW);
    delay(1000);   
    break;
  case 1:
    digitalWrite(s0, HIGH);
    digitalWrite(s1, LOW);
    digitalWrite(s2, LOW);
    delay(1000);   
    break;
  case 2:
    digitalWrite(s0, LOW);
    digitalWrite(s1, HIGH);
    digitalWrite(s2, LOW);
    delay(1000);   
    break;
  case 3:
    digitalWrite(s0, HIGH);
    digitalWrite(s1, HIGH);
    digitalWrite(s2, LOW);
    delay(1000);   
    break;
  case 4:
    digitalWrite(s0, LOW);
    digitalWrite(s1, LOW);
    digitalWrite(s2, HIGH);
    delay(1000);   
    break;
  case 5:
    digitalWrite(s0, HIGH);
    digitalWrite(s1, LOW);
    digitalWrite(s2, HIGH);
    delay(1000);   
    break;
  case 6:
    digitalWrite(s0, LOW);
    digitalWrite(s1, HIGH);
    digitalWrite(s2, HIGH);
    delay(1000);   
    break;
  case 7:
    digitalWrite(s0, HIGH);
    digitalWrite(s1, HIGH);
    digitalWrite(s2, HIGH);
    delay(1000);   
    break;
  }
}

I have the 4051 up and running but I'm having trouble merging the old code functionality into the new code. 1- my old code allowed me to turn power on to one sensor at a time(so there was no crosstalk between ir sensors), then take the reading and convert it to inches, and print out a statement if the reading was below a certain number(the print statement allowed me to identify the sensor which detected something).    "The ledpin" naming convention is just the pin that gives power to the sensor.    here is a snippet of the old code which i now need to put into the new code.
Code: [Select]
void loop() {
 
  digitalWrite(ledpin, HIGH);
  digitalWrite(ledpin1, LOW);
  digitalWrite(ledpin2, LOW);
  digitalWrite(ledpin3, LOW); 
  digitalWrite(ledpin4, LOW);
  digitalWrite(ledpin5, LOW);
  delay(1000);                 
 
  float volts = analogRead(IRpin)*0.0048828125;   
  float distance = 27*pow(volts, -1.15);
  float Inches = (distance / 2.54);
 
  if (Inches <= 16){
  Serial.print("MISS...The ball stopped in ROW1  ");
  Serial.println(  Inches ); 
}


  digitalWrite(ledpin, LOW); 
  digitalWrite(ledpin1, HIGH);
  digitalWrite(ledpin2, LOW);
  digitalWrite(ledpin3, LOW);
  digitalWrite(ledpin4, LOW);
  digitalWrite(ledpin5, LOW);
  delay(1000);                 
 
  float volts1 = analogRead(IRpin1)*0.0048828125;   
  float distance1 = 27*pow(volts1, -1.15);
  float Inches1 = (distance1 / 2.54);
 
  if (Inches1 <= 16){
  Serial.print("MISS...The ball stopped in ROW2  ");
  Serial.println(  Inches1 ); 
}
 

I need to now integrate that functionality into my new code for each sensor.  i can't figure out  how to merge the two.

-Aaron

pylon

The possibility to turn one sensor on and off is new for me. I guess you have to describe your circuitry in detail to let me get the picture of what you're doing.

In your new code the whole routine void sendABCTTL() does the same as my selectInput but mine is much shorter. Do you really wanna use your's?


Go Up