help with : shiftregister + fading

hey everyone … i am new to programming so i hope someone can help me with my issue, and/or point me to the right direction.

i have some Led’s attached to some shiftregisters ( 74ls138 ) what i am trying to do is to fade one led at a time in a random way. i wrote this code ( based on som posts i found on the net ) but it is not working and happing prblem with the “analogwrite” section.

any suggestion how i can do it ? any help is appreciated.

    #define DATA1 8 
    #define DATA2 9 
    #define DATA3 10 
    int ran;
     
    void setup() { 
      pinMode(DATA1, OUTPUT); 
      pinMode(DATA2, OUTPUT); 
      pinMode(DATA3, OUTPUT); 
    } 
     
    void loop() { 
      
    ran = random(8);
    
    for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
    analogWrite(setPins(ran), fadeValue);        
    delay(30);                            
    }

    for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
    analogWrite(setPins(ran), fadeValue);        
    delay(30);                            
    }  
  }     
 
    void setPins(int number){ 
    boolean d1 = bitRead(number, 0); 
    boolean d2 = bitRead(number, 1); 
    boolean d3 = bitRead(number, 2); 
     
    digitalWrite(DATA1, d1); 
    digitalWrite(DATA2, d2); 
    digitalWrite(DATA3, d3); 
     
    }

You can't fade LEDs that are attached to shift registers very easily. How have you got them wired up? If it is just to the shift register then I would forget about fading.

By the way a 74LS138 is not a shift register, so do you have a shift register or a demultiplexer?

Also that code it totally screwed analogWrite(setPins(ran), fadeValue); is fine BUT the function setPins is a void function and so never returns a number. You must post a schematic of how you have wired things up in order to make sense of what you are trying to do.

Yeah i know that it is diffeclt to fade with shift registers, but my original setup was with TLC5940, and made a working program. but i coudlnt make the hardware, it was suggested ( if you can remember the post with the led arrays "quotes" ) .. it was suggested to use shift registers instead.

and you are right i am using a demultiplexer, i read somewhere in the net that it could be an alternativ, so that's why.

and here is the shematic ( simplifid though ):

i read somewhere in the net that it could be an alternativ

No you can't, with a multiplexer you can only light up one LED at at time.

The light you light up is determined by the logic levels on the inputs A0 to A2. Then you should take pin 6 of this chip and attach it to a PWM capable pin. To light the LED you then do a analogue write to that pin.

Also all those LEDs going to ground should be connected to +5V instead.

No you can't, with a multiplexer you can only light up one LED at at time

ah okay, but sounds good since, i only need to lighten one led at a time.

Then you should take pin 6 of this chip and attach it to a PWM capable pin. To light the LED you then do a analogue write to that pin

i did that, and i i do understand the concept of that lightend led is determined by the logic levels on the inputs A0 to A2, my problem is that i cant figure out how to translate that to programming language.

You do the analogue write to the pin you connect to the enable line, that turns on an off rapidly the LEDs which as I said before need to be configured so that you sink current. This is because when that chip is not enabled the outputs are a logic one. This would normally light up all the LEDs but one but as you have them the wrong way round it will light up none. This is fine because you need to put the common connection to posative not ground. No good getting the software right if the hardware won't do anything.

i changed things, and tried to look again into the code, here what i did :

    #define DATA1 8 
    #define DATA2 9 
    #define DATA3 10 
    #define PinFade 11 
     
    void setup() { 
        pinMode(DATA1, OUTPUT); 
        pinMode(DATA2, OUTPUT); 
        pinMode(DATA3, OUTPUT);
        pinMode(PinFade, OUTPUT);
    } 
     
    void loop() { 
     
        for(byte fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
        analogWrite(PinFade, fadeValue);         
        delay(30);                            
        }
    
        for(byte fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
        analogWrite(PinFade, fadeValue);           
        delay(30);                            
        }  
        delay(100); 
    } 

    void setPins(int number){ 
        boolean d1 = bitRead(number, 0); 
        boolean d2 = bitRead(number, 1); 
        boolean d3 = bitRead(number, 2); 
         
        digitalWrite(DATA1, d1); 
        digitalWrite(DATA2, d2); 
        digitalWrite(DATA3, d3); 
    }

what i am getting is that one LED is fading in and out, while all the others LED’s are on … it is making sens because in the loop function i am only writing to one specific pin.

so i still trying to understand how can i make different Led’s fade in and out, one at a time.

what i am getting is that one LED is fading in and out, while all the others LED's are on

Yes that is what I said you would get unless you switched to current sinking with the LEDS. Yo select an other LED just call your LEDs select function that writes different values to the Address select lines on the demultiplexer.

Okay … now i changed it the way you suggested, and it worked so thanks alot.

I changed my code as so :

  int OUTPUT1 = 2;
  int OUTPUT2 = 3;
  int OUTPUT3 = 4;
  int E3 = 5;
  int d = 0; // for delay
  
  void setup()
  {
    pinMode(OUTPUT1, OUTPUT);
    pinMode(OUTPUT2, OUTPUT);
    pinMode(OUTPUT3, OUTPUT);
    pinMode(E3, OUTPUT);
  }
  
  void allLow()
  // sets all outputs to LOW
  {
    digitalWrite(E3, LOW);
  }
  
  void turnOn(int outputPin)
  // turns on output at pin 'outputPin'
  {
    digitalWrite(E3, HIGH); // enables outputs
    switch(outputPin)
    {
      case 0:
      digitalWrite(OUTPUT1, LOW);
      digitalWrite(OUTPUT2, LOW);
      digitalWrite(OUTPUT3, LOW);
      break;
      
      case 1:
      digitalWrite(OUTPUT1, HIGH);
      digitalWrite(OUTPUT2, LOW);
      digitalWrite(OUTPUT3, LOW);
      break;
      
      case 2:
      digitalWrite(OUTPUT1, LOW);
      digitalWrite(OUTPUT2, HIGH);
      digitalWrite(OUTPUT3, LOW);
      break;
      
      case 3:
      digitalWrite(OUTPUT1, HIGH);
      digitalWrite(OUTPUT2, HIGH);
      digitalWrite(OUTPUT3, LOW);
      break;
      
      case 4:
      digitalWrite(OUTPUT1, LOW);
      digitalWrite(OUTPUT2, LOW);
      digitalWrite(OUTPUT3, HIGH);
      break;
      
      case 5:
      digitalWrite(OUTPUT1, HIGH);
      digitalWrite(OUTPUT2, LOW);
      digitalWrite(OUTPUT3, HIGH);
      break;
      
      case 6:
      digitalWrite(OUTPUT1, LOW);
      digitalWrite(OUTPUT2, HIGH);
      digitalWrite(OUTPUT3, HIGH);
      break;
      
      case 7:
      digitalWrite(OUTPUT1, HIGH);
      digitalWrite(OUTPUT2, HIGH);
      digitalWrite(OUTPUT3, HIGH);
      break;
    }
  }
  
  void RandomLed(int i)
  {
      int ran = random(8);
      
      turnOn(ran);
      delay(i);
      allLow();
  }
  
  void loop()
  {
      RandomLed(1000);
  }

so now i am able to turn on one Led at a time in a random fashion, but still i cannot get the turned on led to fade

i have this code ( from earlier ) :

        for(byte fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
        analogWrite(PinFade, fadeValue);         
        delay(30);                            
        }
    
        for(byte fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
        analogWrite(PinFade, fadeValue);           
        delay(30);                            
        }

i just cant figure it out how to incorporate it with the main code, any hints / suggestions ?

Hi,

Here is a quick stab at it, I have not actualy compiled the code so you may have to debug it but the idea is there. I hava aslo trimmed your code in the switch statment, since all the OPs change anyway you may as well turn them all off and only turn on the one you are interested in. I also disable the OP of the 74138 while updating the inputs then enable it again .

feel free to PM me if you need any help with this…

Cheers Pete

  int OUTPUT1 = 2;
  int OUTPUT2 = 3;
  int OUTPUT3 = 4;
  int E3 = 5;
  int d = 0; // for delay


// function prototypes to alow them to be compiled in any order
  void allLow();
  void turnOn(int outputPin);
  void RandomLed(int i);
  void fade(int i);
// end of templates


  
  void setup()
  {
    pinMode(OUTPUT1, OUTPUT);
    pinMode(OUTPUT2, OUTPUT);
    pinMode(OUTPUT3, OUTPUT);
    pinMode(E3, OUTPUT);
  }


void loop()
{ 
      RandomLed(1000);
}

  
  void allLow()
  // sets all outputs to LOW
  {
    digitalWrite(E3, LOW);
  }
  
  void turnOn(int outputPin)
  // turns on output at pin 'outputPin'
  {

      digitalWrite(E3, LOW);


      digitalWrite(OUTPUT1, LOW);
      digitalWrite(OUTPUT2, LOW);
      digitalWrite(OUTPUT3, LOW);


    switch(outputPin)
    {
      
      case 1:
      digitalWrite(OUTPUT1, HIGH);
      break;
      
      case 2:
      digitalWrite(OUTPUT2, HIGH);
      break;
      
      case 3:
      digitalWrite(OUTPUT1, HIGH);
      digitalWrite(OUTPUT2, HIGH);
      break;
      
      case 4:
      digitalWrite(OUTPUT3, HIGH);
      break;
      
      case 5:
      digitalWrite(OUTPUT1, HIGH);
      digitalWrite(OUTPUT3, HIGH);
      break;
      
      case 6:
      digitalWrite(OUTPUT2, HIGH);
      digitalWrite(OUTPUT3, HIGH);
      break;
      
      case 7:
      digitalWrite(OUTPUT1, HIGH);
      digitalWrite(OUTPUT2, HIGH);
      digitalWrite(OUTPUT3, HIGH);
      break;
    }

    digitalWrite(E3, HIGH); // enables outputs

  }
  
  void RandomLed(int i)
  {
      int ran = random(8);
      
      turnOn(ran);
      fade(i);
      allLow();
  }
  
 
void fade(int i)
{

        for(byte fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) 
       {
        analogWrite(PinFade, fadeValue);         
        delay(i/512);                            
        }
    
        for(byte fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) 
        {
        analogWrite(PinFade, fadeValue);           
        delay(i/512);                            
        }

}

since all the OPs change anyway you may as well turn them all off and only turn on the one you are interested in.

No you miss the point with a demultiplexer used as an output device. You can't turn them all on or all off, you can only change one output at a time. Those outputs that are not addressed output a logic one, the output that is addressed outputs the logic level of what ever is on the input line. So if what is on the input line is a logic one, there is no difference between an addressed line and a line not addressed. The only way to have a logic zero on an output is to address that output and put a logic zero on the input. Therefore to have LEDs off when they are not being addressed you have to drive them with current sinking not sourcing.

This is why a demultiplexer is absolute rubbish for outputting and should not actually be used.

So a function like this:-

void allLow()
  // sets all outputs to LOW
  {
    digitalWrite(E3, LOW);
  }

Will in fact set all the outputs high, there is no way you can set all the outputs low with this chip.

Therefore to have LEDs off when they are not being addressed you have to drive them with current sinking not sourcing.

This is why a demultiplexer is absolute rubbish for outputting and should not actually be used.

that made alot of sans ! now i understand the point better.

void fade(int i)
{

        for(byte fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) 
       {
        analogWrite(PinFade, fadeValue);         
        delay(i/512);                            
        }
    
        for(byte fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) 
        {
        analogWrite(PinFade, fadeValue);           
        delay(i/512);                            
        }

}

shoud the “PinFade” be the same as E3 ? ( the PWM pin ? ) … because that’s what i did, but only one led is fading

shoud the "PinFade" be the same as E3 ? ( the PWM pin ? )

Yes.

but only one led is fading

Yes it will as state above. To change the LED that is fading change the value on the select lines. Add this:-

void selectLED(int num) { // select an LED to control
      if(num & 1 !=0) digitalWrite(OUTPUT1, HIGH); else digitalWrite(OUTPUT1, LOW);
     if(num & 2 !=0) digitalWrite(OUTPUT2, HIGH); else digitalWrite(OUTPUT2, LOW);
     if(num & 4 !=0) digitalWrite(OUTPUT3, HIGH); else digitalWrite(OUTPUT3, LOW);
}

I have written this rather long winded so you can see what is going on better, but not as long winded as you had in the original code. Just call this function passing it the LED number you want to control before doing the fading bit.

Now i changed the code :

  int OUTPUT1 = 2;
  int OUTPUT2 = 3;
  int OUTPUT3 = 4;
  int E3 = 5;
  int d = 0; // for delay


  void turnOn(int outputPin);

 
  void setup()
  {
    pinMode(OUTPUT1, OUTPUT);
    pinMode(OUTPUT2, OUTPUT);
    pinMode(OUTPUT3, OUTPUT);
    pinMode(E3, OUTPUT);
  }
  
  void turnOn(int outputPin)
  // turns on output at pin 'outputPin'
  {

      digitalWrite(E3, LOW);


      digitalWrite(OUTPUT1, LOW);
      digitalWrite(OUTPUT2, LOW);
      digitalWrite(OUTPUT3, LOW);


    switch(outputPin)
    {
      
      case 0:
      for(byte fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) 
      {
        analogWrite(E3, fadeValue);         
        delay(30);                            
      }
      
      case 1:
      digitalWrite(OUTPUT1, HIGH);
      for(byte fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) 
      {
        analogWrite(E3, fadeValue);         
        delay(30);                            
      }
    
      for(byte fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) 
      {
        analogWrite(E3, fadeValue);           
        delay(30);                            
      }
      break;
      
      case 2:
      digitalWrite(OUTPUT2, HIGH);
      for(byte fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) 
      {
        analogWrite(E3, fadeValue);         
        delay(30);                            
      }
    
      for(byte fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) 
      {
        analogWrite(E3, fadeValue);           
        delay(30);                            
      }
      break;
      
      case 3:
      digitalWrite(OUTPUT1, HIGH);
      digitalWrite(OUTPUT2, HIGH);
      for(byte fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) 
      {
        analogWrite(E3, fadeValue);         
        delay(30);                            
      }
    
      for(byte fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) 
      {
        analogWrite(E3, fadeValue);           
        delay(30);                            
      }
      break;
      
      case 4:
      digitalWrite(OUTPUT3, HIGH);
      for(byte fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) 
      {
        analogWrite(E3, fadeValue);         
        delay(30);                            
      }
    
      for(byte fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) 
      {
        analogWrite(E3, fadeValue);           
        delay(30);                            
      }
      break;
      
      case 5:
      digitalWrite(OUTPUT1, HIGH);
      digitalWrite(OUTPUT3, HIGH);
      for(byte fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) 
      {
        analogWrite(E3, fadeValue);         
        delay(30);                            
      }
    
      for(byte fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) 
      {
        analogWrite(E3, fadeValue);           
        delay(30);                            
      }
      break;
      
      case 6:
      digitalWrite(OUTPUT2, HIGH);
      digitalWrite(OUTPUT3, HIGH);
      for(byte fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) 
      {
        analogWrite(E3, fadeValue);         
        delay(30);                            
      }
    
      for(byte fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) 
      {
        analogWrite(E3, fadeValue);           
        delay(30);                            
      }
      break;
      
      case 7:
      digitalWrite(OUTPUT1, HIGH);
      digitalWrite(OUTPUT2, HIGH);
      digitalWrite(OUTPUT3, HIGH);
      for(byte fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) 
      {
        analogWrite(E3, fadeValue);         
        delay(30);                            
      }
    
      for(byte fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) 
      {
        analogWrite(E3, fadeValue);           
        delay(30);                            
      }
      break;
    }

    digitalWrite(E3, HIGH); // enables outputs

  }
  
 
void loop()
{ 

  int ran = random(0,7);
  turnOn(ran);  

}

but i cant understand, it only fade one LED, i mean when i change the “ran” in the "loop-function"with different numbers, the led turns on accordint the that number, but is does not work with “random” of a “for-loop” … what is wrong ?

ups Mike .. i didnt saw your post ! .. should i use the selectLed function instead of my switch/case function ?

  int OUTPUT1 = 2;
  int OUTPUT2 = 3;
  int OUTPUT3 = 4;
  int E3 = 5;
  int d = 0; // for delay


  void turnOn(int outputPin);

 
  void setup()
  {
    pinMode(OUTPUT1, OUTPUT);
    pinMode(OUTPUT2, OUTPUT);
    pinMode(OUTPUT3, OUTPUT);
    pinMode(E3, OUTPUT);
  }
  
void selectLED(int num) { // select an LED to control
     if(num & 1 !=0) digitalWrite(OUTPUT1, HIGH); else digitalWrite(OUTPUT1, LOW); 
     if(num & 2 !=0) digitalWrite(OUTPUT2, HIGH); else digitalWrite(OUTPUT2, LOW); 
     if(num & 4 !=0) digitalWrite(OUTPUT3, HIGH); else digitalWrite(OUTPUT3, LOW); 
     
     for(byte fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) 
      {
        analogWrite(E3, fadeValue);         
        delay(30);                            
      }
    
      for(byte fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) 
      {
        analogWrite(E3, fadeValue);           
        delay(30);                            
      }
}
  
 
void loop()
{ 

  int ran = random(0,7);
  selectLED(ran);

}

is this what you ment ? ( i doubt though … since i cannot get it to work that way )

I wouldn’t know what code to use, but couldn’t you pulse the demulitplexer’s output led value on and off really fast to get the led to seem like it’s fading in and out using different delays and then use that method to “fade” the other leds?

No it is not quite what I meant you have combined the select and fade function. Nevertheless it should work as you have written it. So what dose it do?