Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 6 of 6

Thread: My code behaving weirdly for 22 x pots with 3 x 4051 Mux's - Teensy2

  1. #1
    Member
    Join Date
    Aug 2014
    Location
    Johannesburg South Africa
    Posts
    21

    My code behaving weirdly for 22 x pots with 3 x 4051 Mux's - Teensy2

    Hi,

    So i am still trying to sort out my multiplexing code for analog inputs using arrays.

    Thanks VERY much to Lukas from www.lbsfilm.at for the original code ! GENIUS

    My edited Code :

    Code:
    #include <MIDI.h>
    
    
    // Here I'm defining the address pins for the multiplexers
    int multiAddr0 = 0;
    int multiAddr1 = 1;
    int multiAddr2 = 2; 
    
    
    // Here I'm declaring some arrays for storing old vallues
    int faderValue = 0;
    int previous[] = {  
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 
    int preprevious[] = {
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
      
      
    void setup() {
    Serial.begin(9600); 
      // put your setup code here, to run once
      
      //Setting the address pins to output
      pinMode(multiAddr0, OUTPUT);
      pinMode(multiAddr1, OUTPUT);
      pinMode(multiAddr2, OUTPUT);
    
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      
      // multiplexer loop
    
      for(int input = 7; input > -1; input--)          // This is the first for loop, switching through the addresses
      {
    
        for(int multi = 2; multi > -1; multi--)       //this is the second loop,nested in the above, switching through the 3 multiplexers on each address
        {
          int faderNumber = multi * 8 + input;     // calculating the potis number to store its value in the arrays
    
          faderValue = (analogRead(multi)/8);     // reading from the corresponding analog input 
    
          if (faderValue != previous[faderNumber])    // checking for a change
          {
            if (faderValue != preprevious[faderNumber]) // checking for a change again in the preprevious array (Just to make sure the analog to digital converter isn't flickering between two values)
            {
              usbMIDI.sendControlChange(faderNumber,faderValue, 2); 
              preprevious[faderNumber] = previous[faderNumber];     // ... store the current previous number in preprevious
              previous[faderNumber] = faderValue;                          // and store the current number in previous
    
            }
          }  
    
    
        }
        
        switch (input){ // this switch case statement in the first loop switches the 3 BEC (Binary-Encoded-Decimal) Bits for the address selection
        case 0:
          digitalWrite(multiAddr0,LOW);
          digitalWrite(multiAddr1,LOW);
          digitalWrite(multiAddr2,LOW);
          break;
    
        case 1:
          digitalWrite(multiAddr0,HIGH);
          break;
    
        case 2:
          digitalWrite(multiAddr0,LOW);
          digitalWrite(multiAddr1,HIGH);
          break;
    
        case 3:
          digitalWrite(multiAddr0,HIGH);
          break;
    
        case 4:
          digitalWrite(multiAddr0,LOW);
          digitalWrite(multiAddr1,LOW);
          digitalWrite(multiAddr2,HIGH);
          break;
    
        case 5:
          digitalWrite(multiAddr0,HIGH);
          break;
    
        case 6:
          digitalWrite(multiAddr0,LOW);
          digitalWrite(multiAddr1,HIGH);
          break;
    
        case 7:
          digitalWrite(multiAddr0,HIGH);
          break;
    
    
        }
      }
    
      //end multiplexer
    
    }
    Problems:

    1. The pots aren't in numerical order as i've connected them EG: pot1-pot8 to the mux1 (connected to A0)

    2. The midi signals are corrupt EG: controllers are getting mixed together like this on controller 3 :
    Click image for larger version. 

Name:	Screen Shot 2014-09-03 at 9.47.49 AM.png 
Views:	429 
Size:	83.8 KB 
ID:	2629

    3. Sometimes controller 16 repeatedly sends values without any faders being touched.

    Questions:

    1. What is the correct pin order to connect the pots to the mux's so that they appear as pot1 - controller1, pot2 - controller2 etc ?
    this is what i have now:
    Click image for larger version. 

Name:	74HC4051_d.png 
Views:	1458 
Size:	33.9 KB 
ID:	2630

    2. How do i get the correct controller messages to send though usb midi?

    3. Are there any code errors that are to blame?

  2. #2
    Member
    Join Date
    Aug 2014
    Location
    Anaheim CA
    Posts
    21
    I cannot directly address your code however there are some conditions that must be satisfied in order to properly utilize a CD4051 8 to one Mux chip.
    A, B, C are binary data sent to the MUX address pins to address the particular mux channel required, Note that the address inputs's cannot exceed Vcc and ground as they are digital pins. The teensy has an unipolar input. Thus the inputs Must lie between Vcc and the Vee pin on the Mux in order to keep the Mux chip happy ie not go beyond the ground. So the Vee point must be connected to an analog ground (for low noise). If the Vee pin is floating so will the I/O pin as the device is a bilateral transmission gate. As a side note available from the Datasheet (use the National Semi one, The TI sheet might be confusing) no input can exceed the VCC to GND and the Vee pin must (for bipolar operation operation connect to a negative (well filtered and bypassed) source that is at least one diode (.63V) below the maximum negative voltage being measured. the same is true of the max positive input voltage ie Vin +.63V. Latchup and undefined operation are the general case when these parameters are not respected.. The worst thing that can be done with the CD405XBE is to not configure the Vee pin properly followed by forgetting that the on resistance of any gate is both Vcc dependent and is ~ 1K to 400 ohms ohms as Vcc rises, the on channel resistance decreases. and according to the CDXXXX family specifications is characterized from 3 to 15 V, Vcc.
    In that the analog ground (Vee) is the most negative point.. If Bi-polar voltages must be measured an op-amp must be used to shift the ground level of the input signal to VCC/2. Of course proper gain and scaling do apply to meet the above conditions.
    The rest is readily abstracted from the data sheet. A useful addition is a voltage follower to reduce the input impedance of the SAR sampling capacirotRC timing involved in charging the ADC sampling capacitor.
    Ideal is one per channel to reduce to possibility of crosstalk through cabling and PCB layout but for many cases a voltage follower is good on the common I/O pin.. While remembering to add the address date to select each mux cip as required or tristate the enable pins for the MUX chips that arent't being used. When the Enable pin is high the outputs tri state.. The data sheet however is the final authority.
    I've used this part family for crystal selection @ 15 MHZ with no issues but good layout is important for HF use..

    Doc
    Last edited by Docedison; 09-04-2014 at 04:29 PM. Reason: error in old rusty mind, logic invertted

  3. #3
    Member
    Join Date
    Aug 2014
    Location
    Johannesburg South Africa
    Posts
    21
    Thanks Doc..

    I have checked everything and its fine.

    Now i guess I need help with the code:/

  4. #4
    Member
    Join Date
    Aug 2014
    Location
    Anaheim CA
    Posts
    21
    Perhaps the issue is that (lacking a full schematic) you aren't handling the inhibit properly. The inhibit is a deselect device control. To be able to "Stack" two or more devices you might use the inhibit lead to disable all but the selector you need data from or make it a great deal simpler by using a CD4067BE (1 of 16 data selector) which will handle 16 I/O connections to one point... Providing 5 data control lines for addressing is easily done. The 5th address line would connect to the first selector inhibit and an inverter from that point to the second selector inhibit while the a - d address lines are connected together. This will create a 5 bit address capacity enabling you to address 32 i/o's. If you must use the CD4051BE the inhibit on each chip must be held high to disable that selector or in other words wire 2 4051's the same as 2 4067's where the high address bit is the selector control a 0 on it will enable the chip and a 1 will disable the chip.. making a 22 channel analog data selector would require 3 CD4051BE's or 2 CD4067BE's... If by Any slight chance (They are really OLD parts, discontinued in the mid 70's) you have CD4051AE or CD4067AE parts save them as antiques and buy the BE (Buffered) parts instead. THe AE parts had a somewhat unusual issue issue where the on channel resistance varied with the VCC and could be 2 X 1 or more from 3 to 15 Vcc and IIRC a big issue with bipolar use.
    The selector logic is simple, The usual error made when using that family of parts was not properly dealing with the Vee (most negative supply lead) which needed to be grounded for single supply or connected to the -V supply for bipolar use or in multiple selector use, each inhibit was held low to select that chip only.
    I would, Were I you... post both a schematic and the code used for this project.. The CD40XX series of transmission gates are simple to use and frequently were used as "Glue" or as Don Lancaster (Cmos Cookbook) called them MML "Mickey Mouse Logic". But there is little to beat the simplicity and ease of use of a bidirectional selectable analog gate today.. Single channel devices, CD4016 and CD4066 were invaluable analog switches... I've even made level controls by PWM'ing the control lead on a CD4016 to "adjust" the on time, the the output level for a 20 KHz max audio stream I remember using an SE555 variable duty cycle oscillator to control a CD4016 where I used a 200 KHZ switch frequency and varied it's duty cycle..

    Doc
    Last edited by Docedison; 09-04-2014 at 06:08 PM.

  5. #5
    Member
    Join Date
    Feb 2014
    Location
    australia
    Posts
    83
    hey garthtaylor, im working on a project that is going to use around 8 of the 4051s

    im still in the testing stage so im only using 3 at the moment.

    im not very good at reading the code so this is mine that im useing at the moment
    Code:
    const byte sensor0 = 16;// where the multiplexer in/out
    const byte sensor1 = 14;// port is connected
    const byte touch0 = 0;
    const byte addressA = 2; // the multiplexer address
    const byte addressB = 3; // select lines (A/B/C)
    const byte addressC = 4;
    
    
    void setup ()
      {
      Serial.begin (115200);
      pinMode (addressA, OUTPUT); 
      pinMode (addressB, OUTPUT); 
      pinMode (addressC, OUTPUT); 
      }
    
    int readSensor0 (const byte which)
      {
      digitalWrite (addressA, (which & 1) ? HIGH : LOW);
      digitalWrite (addressB, (which & 2) ? HIGH : LOW);
      digitalWrite (addressC, (which & 4) ? HIGH : LOW);
      delay(200);
       return analogRead (sensor0)*0.125;
     } 
    int readSensor1 (const byte which)
    {
      digitalWrite (addressA, (which & 1) ? HIGH : LOW);
      digitalWrite (addressB, (which & 2) ? HIGH : LOW);
      digitalWrite (addressC, (which & 4) ? HIGH : LOW);
      delay(200);
      return analogRead (sensor1);
     }
    int readtouch0 (const byte which)
    {
      digitalWrite (addressA, (which & 1) ? HIGH : LOW);
      digitalWrite (addressB, (which & 2) ? HIGH : LOW);
      digitalWrite (addressC, (which & 4) ? HIGH : LOW); 
      delay (200);
      return touchRead (touch0);
    }
    void loop (){
    	
      for (byte i = 0; i <=7; i++) {
        Serial.print ("IC 0, Sensor ");
        Serial.print (i);
        Serial.print (", reads: ");
        Serial.println (readSensor0 (i));
       
        Serial.print ("IC 1, Sensor ");
        Serial.print (i);
        Serial.print (", reads: ");
        Serial.println (readSensor1 (i));
       
        Serial.print ("IC 2, Sensor ");
        Serial.print (i);
        Serial.print (", reads: ");
        Serial.println (readtouch0 (i));
        }}
    u will have to change the touch stuff to work with what ur doing.

    but the way this scans the pots is
    1st 4051 pin0
    2nd 4051 pin0
    3rd 4051 pin0
    1st 4051 pin1
    2nd 4051 pin1
    3rd 4051 pin1
    1st 4051 pin2
    2nd 4051 pin2
    3rd 4051 pin2
    1st 4051 pin3
    2nd 4051 pin3
    3rd 4051 pin3
    ...
    1st 4051 pin7
    2nd 4051 pin7
    3rd 4051 pin7 //then repeats after
    1st 4051 pin0
    2nd 4051 pin0
    3rd 4051 pin0

    i havent got to the point of doing it in a array or sending in midi but i hope this helps you as it took me ages to work it out and im sure theres a cleaner way to do it other then the way im doing it

  6. #6
    Member
    Join Date
    Aug 2014
    Location
    Anaheim CA
    Posts
    21
    If you have carefully read the logic table for the CD4051BE you can short circuit a bit of your selection logic by using the inhibit pin (6) as when held high it will tristate the chip output... So all the control logic could be handled by an 8 bit shift register... three outputs for the address lines and 3 for the inhibit pins will allow 1 of 24 inputs to be selected with a byte and simple counters to create the I/O address and what are essentially Chip Select addresses.. A CD4094BE and three CD4051BE's.
    Addressing the 24 inputs would could well require 6 bits of data with two spare outputs and 32 bits can easily be handled by two CD4067BE's, and a 2N3904 to invert the inhibit pin from the 5th bit where the inhibit pin is inverted by the fifth bit to enable tho other pin.. Fewer holes but the 4067 isn't as common as the the 4051.
    There are some very similar cmos crossbar ic's but those. I fear are becoming pure unobtanium.. If your switching requirements were purely digital (mine so far address analog and digital switching) you 'could' use a Pro Mini too as a PLD. Or for really simple switching a EEprom.. like a 27C64 or a 28C128 as an addressable LUT..
    Many times, I've used them for 7 segment displays with ULN 2803's as the current source or sink with a 555 as the mux clock driving a CD4017 data selector and anode/cathode display muxers.. Long in the past.. but still viable as concepts...

    Doc
    Last edited by Docedison; 09-07-2014 at 10:20 AM. Reason: Wrong Transistor Part #

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •