LEDs do not shine well through 4051-demux

Hi

i have 8 LEDs which are connected to a 4051.
the problem is, that they don't shine with their full.. shinyness(?) .. as the demux is "polled" in loop

when I do a delay in each demux-loop.. they shine well, so it has something to do with the 4051, that switches the connectons in speed X .. am i right?

how would i solve this?

there are also some parasite LEDs :confused:

Multiplexing leds will reduce intensity, you may have to increase the current flow to each led.

Let us see your circuit.
Edit:
And your sketch.

.

i have 8 LEDs which are connected to a 4051.

Why? That is quite a silly thing to do.
The multiplexing makes the LEDs dimmer like Larry said, and it it also totally unnecessary and a wasteful thing to do in terms of CPU usage.

Also the 4051 has an internal resistance that would add to the lack of brightness.

If you use an addressable latch like the 74HC259 or the MC14099 then you can have the same result without the stupid multiplexing.

The 4051 selects one of the eight outputs to be connected to the Z input. This means that only one LED can be turned on at a time. If you change between LEDs very fast, you will get something that looks like pulse width modulation with the pulse width based on how many LEDs are on and how fast your program switches between the three bit input code. The more LEDS you turn on, the dimmer they will become. The problem with putting more current through them to get them to be brighter is that you will make them too bright when only one or two are on. You could make it work if you use the enable pin to determine the on time for each LED and make your three bits count at a constant rate. This method has the advantage of being able to turn all the LEDs off at once and they will always be the same brightness no matter how many are on. This assumes that you can put enough current through the LEDs to make them bright at a 12% duty cycle.
If you are trying to use as few IO pins as possible, try an I2C port expander like the PCA or PCF series. The PCA8574 will give you 8 additional IO pins to play with and the PCA9555 will give you 16. These devices have latched outputs so they will stay in whatever condition you set them in until you need to change the condition.

The more LEDS you turn on, the dimmer they will become.

Sorry that is not correct.

The problem with putting more current through them to get them to be brighter is that you will make them too bright when only one or two are on.

No you are misunderstanding things.

Grumpy_Mike:
Why? That is quite a silly thing to do.
The multiplexing makes the LEDs dimmer like Larry said, and it it also totally unnecessary and a wasteful thing to do in terms of CPU usage.

Also the 4051 has an internal resistance that would add to the lack of brightness.

If you use an addressable latch like the 74HC259 or the MC14099 then you can have the same result without the stupid multiplexing.

i'm new to all this stuff so i often tend to do some silly things :smiley: .. but that with the 74HC259 / MC14099 seems like exact the thing I have been looking for :slight_smile:

what is the difference between the 74HC 595 and the 74HC 259 ??

what is the difference between the 74HC 595 and the 74HC 259

They are two totally different chips that do different logic functions. Look at the data sheet for a detailed explanation, but basically the 595 is a shift register and the 259 is an addressable latch.

See the data sheets:
http://cache.nxp.com/documents/data_sheet/74HC_HCT259.pdf?pspll=1

http://www.nxp.com/documents/data_sheet/74HC_HCT595.pdf

Crossroads would suggest TPIC6A595

.

did i understand it correctly? .,. the 259-latch is a "shift-register with memory"?

AdmiralCrunch:
did i understand it correctly? .,. the 259-latch is a "shift-register with memory"?

"This device contains an 8-bit serial-in, parallel-out
shift register that feeds an 8-bit, D-type storage
register"

One byte of memory :wink:

Edit
Sorry this is the 595.

.

Notice the 259 has 3 address lines that must be enabled to access any 1 of 8 bits in the latch. 8 bit latches. 23 = 8
Edit
You can therefore access any bit in the latch without disturbing the other bits by selecting the address of that bit first.

The 595 has one 8 bit latch. Bit location is not individually addressable as in the 259.
You must write all 8 bits to change the latch contents.

In hardware terms the 259 is much closer to the concept of the 4051 than the 595 shift register. It is like the 4051 in that it has address lines to select the multiplex output you want to change but it has a latch on each output so when a logic level set, it is rememberd, that is it is held until changed again.
The 595 has data shuffled along a shift register until the music stops ( the latch pin is toggled ) and then the output state is frozen on the outputs. Both chips can be used to do the same thing and here the 595 almost always gets used, but it need not be.

until the music stops

Like musical chairs :wink:

LarryD:
Like musical chairs :wink:

Exactly. :slight_smile:

Hi guys :slight_smile:

thank you all for the help so far :slight_smile: .. i have now bought some 74HC259 and they seem to work fine, but i have a wierd behaviour i can't explain if i try to leave/store a value in a latch and go on to change other values.. i even cant explain whats going on or reproduce.. so i made a video :smiley:

maybe someone knows the behaviour..

this are my functions.. switchMux() is for switching the HC259.. setColor() lights the LEDs
(to trace the error, i have unconnected everything except the red)

void light::switchMux(int i) {         
    _muxBit1 = bitRead(i,0);
    _muxBit2 = bitRead(i,1);
    _muxBit3 = bitRead(i,2);     
    digitalWrite(_ledMuxPin1, _muxBit1);
    digitalWrite(_ledMuxPin2, _muxBit2);
    digitalWrite(_ledMuxPin3, _muxBit3); 
}

void light::switchMux(int i) {         
    _muxBit1 = bitRead(i,0);
    _muxBit2 = bitRead(i,1);
    _muxBit3 = bitRead(i,2);     
    digitalWrite(_ledMuxPin1, _muxBit1);
    digitalWrite(_ledMuxPin2, _muxBit2);
    digitalWrite(_ledMuxPin3, _muxBit3); 
}

and then in the sketch i call

 light.switchMux(i);
 light.setColor(color[i]._rgb[0],color[i]._rgb[1],color[i]._rgb[2]);

according to the output on the serial-monotor the multiplexing of the switch-buttons is fine.. every else seems to be ok, too.. so whats going wrong??

You need to post a schematic and the full code. The bits of code you have posted already don't make much sense in isolation.

Hi,

i know that is much, thats because i didn't post it.. but here it is.. would be really nice if someone could take a look..

the code is following.

sketch

  #include <Bounce.h>
    
  #include <cfg.h>
  #include <light.h>
  #include <btnTrackSelect.h>
  #include <faderTrackVolume.h>  
  
  cfg cfg;
  light light(cfg.ledMuxPin1, cfg.ledMuxPin2, cfg.ledMuxPin3, cfg.muxRedPin, cfg.muxGreenPin, cfg.muxBluePin);
  
  btnTrackSelect btnTrackSelect[16];
  faderTrackVolume faderTrackVolume[16];  
  
  Bounce btnShift = Bounce(cfg.btnShiftPin, 10);  // 10 ms debounce
  
  

  // ################## SETUP
  
  void setup() {
    // 4051
    pinMode(cfg.muxPin1, OUTPUT);
    pinMode(cfg.muxPin2, OUTPUT);
    pinMode(cfg.muxPin3, OUTPUT);
    
      
    // btnTrackSelect
    pinMode(cfg.btnTrackSelectPin, INPUT); 
    // faderTrackVolume
    pinMode(cfg.faderTrackVolumePin, INPUT);
  
    // SHIFT
    pinMode(cfg.btnShiftPin, INPUT_PULLUP);  
     
   
    
   
  }




  // ################## MAIN LOOP
  
  void loop() {
    if(cfg.modus != cfg.modusNext) {
      Serial.println("MODUS CHANGED: "); Serial.print(cfg.modus);
      cfg.modus = cfg.modusNext;    
    }
  
     if (cfg.modus == "EDIT") {          
      readMenuEncoders();
    }
  
  
    for (int i = 0; i <= 7; i++) {    
      // count through MUX    
      cfg.MuxBit1 = bitRead(i,0);
      cfg.MuxBit2 = bitRead(i,1);
      cfg.MuxBit3 = bitRead(i,2);   
      digitalWrite(cfg.muxPin1, cfg.MuxBit1);
      digitalWrite(cfg.muxPin2, cfg.MuxBit2);
      digitalWrite(cfg.muxPin3, cfg.MuxBit3);
      
      pollShift();
      pollMuxDigital(i, "btnTrackSelect", cfg.btnTrackSelectPin);
      //pollMuxAnalog(i, "faderTrackVolume", cfg.faderTrackVolumePin);
       
            
    
    } 
     
    
 
   
  }






/*
 * Polls Shift-Button and sets Status-Var
 */
void pollShift() {
    if (btnShift.update()) {
      if (btnShift.fallingEdge()) {        
          cfg.shiftStatus = false;                    
      } else {        
          cfg.shiftStatus = true;
      }
    }  
}


/*
 * Polls 4051 with digital Input-Sources
 */
void pollMuxDigital(int i, String element, int digitalPin) {   
  btnTrackSelect[i].btnStatus = digitalRead(digitalPin); 
      
  if(btnTrackSelect[i].btnStatus == HIGH && btnTrackSelect[i].btnStatusOld != btnTrackSelect[i].btnStatus) {     

    if(btnTrackSelect[i]._state == 0) {
      Serial.print(i); Serial.print(" - PRESSED .. "); Serial.println();  
      if(cfg.shiftStatus == true) {
         // EDIT
        edit(i, element);                      
      } else {
        // SEND MIDI 
        btnTrackSelect[i].setBtnState(1);            
      } 
       
    } else if(btnTrackSelect[i]._state == 1) {
      Serial.print(i); Serial.print(" - PRESSED AGAIN.. "); Serial.println();  
      if(cfg.shiftStatus == true) {
         // EDIT
        edit(i, element);                      
      } else {
        // SEND MIDI 
        btnTrackSelect[i].setBtnState(0);            
      } 
    }

      light.switchMux(i);
      light.setColor(btnTrackSelect[i]._rgb[0],btnTrackSelect[i]._rgb[1],btnTrackSelect[i]._rgb[2]);
    
    
  } 
  

 btnTrackSelect[i].btnStatusOld = btnTrackSelect[i].btnStatus;  

  
  if(btnTrackSelect[i].btnStatusOld == HIGH && btnTrackSelect[i].btnStatus == LOW) {
    Serial.print(i); 
    Serial.print(" - UN - statusOld : "); Serial.print(btnTrackSelect[i].btnStatusOld); 
    Serial.println();  
  } 
 
  
}

light.h

#ifndef light_h
#define light_h

#include "Arduino.h"



class light {
    
  public:  
    
    light(int ledMuxPin1, 
          int ledMuxPin2, 
          int ledMuxPin3,          
          int _muxRedPin, 
          int _muxGreenPin, 
          int _muxBluePin,
          int _ledResetPin);    
    
       
    void setColor(int red, int green, int blue);
    void resetAll();
    
    int _ledMuxPin1;
    int _ledMuxPin2;
    int _ledMuxPin3;
    
   
    
    
    int _muxRedPin;
    int _muxGreenPin;
    int _muxBluePin;
    
    int _muxBit1;
    int _muxBit2;
    int _muxBit3;
    
    void switchMux(int i); 
    
    
    // COLORS
    int colors[6][3] = {        
        {255,255,255},
        {255,0,128},
        {0,255,0},
        {0,0,255},
        {255,60,0},
        {255,0,128}
    };
    int orange[3] = {255,60,0};
    int lila[3] = {255,0,128};
    int red[3] = {255,0,128};
    int green[3] = {0,255,0};
    int blue[3] = {0,0,255};
    int white[3] = {255,255,255};
    
  private:
    
    
};

#endif

light.cpp

#include "Arduino.h"
#include "light.h"

light::light(int ledMuxPin1, int ledMuxPin2, int ledMuxPin3, int muxRedPin, int muxGreenPin, int muxBluePin) {
    
    // INITIALIZE MUX-CONTROL
    _ledMuxPin1 = ledMuxPin1;
    _ledMuxPin2 = ledMuxPin2;
    _ledMuxPin3 = ledMuxPin3;    
    pinMode(_ledMuxPin1, OUTPUT);
    pinMode(_ledMuxPin2, OUTPUT);
    pinMode(_ledMuxPin3, OUTPUT);
    
   
    
    // INITIALIZE MUX COLOR-CONTROL
    _muxRedPin = muxRedPin;
    _muxGreenPin = muxGreenPin;
    _muxBluePin = muxBluePin;
    pinMode(_muxRedPin, OUTPUT);
    pinMode(_muxGreenPin, OUTPUT);
    pinMode(_muxBluePin, OUTPUT); 
}


 void light::setColor(int red, int green, int blue) {
    #ifdef COMMON_ANODE
        red = 255 - red;
        green = 255 - green;
        blue = 255 - blue;
    #endif   
     
    analogWrite(_muxRedPin, red);
    analogWrite(_muxGreenPin, green);
    analogWrite(_muxBluePin, blue);     
 }




void light::switchMux(int i) {         
    _muxBit1 = bitRead(i,0);
    _muxBit2 = bitRead(i,1);
    _muxBit3 = bitRead(i,2);     
    digitalWrite(_ledMuxPin1, _muxBit1);
    digitalWrite(_ledMuxPin2, _muxBit2);
    digitalWrite(_ledMuxPin3, _muxBit3); 
}

there is also the cfg.h in which all the pins are defined and the class for btnTrackSelect.. i don't know if i should post it, too.. just tell me if.. it is really much :confused:

EDIT: I made a little mistale in the shematic.. the data-pin of the HC259 is not connected to the DIGITAL 11 PIN .. it is connected to the A0 analog-pin :wink: .. I also had to remove some (i hope non-relevant) code, because forum said only 9000 chars allowed.

someone an idea? .. i'm trying everything, but with no or the same result -.-

I have found out what the problem was :smiley:

if anyone is interested:

I have set the LE of the hc259 to GND.. that was the problem.. the solution is:

  • set the LE to HIGH
  • switch the latch and feed the DATA
  • set the LE to LOW

:slight_smile:

1 Like