Questoin on circuit for smooth LED toggling

Status
Not open for further replies.

alexandros

Well-known member
I'm trying to toggle some LEDs through a 74HC595 shift register smoothly. I'm trying the following circuit:
teensy_forum_capacitor_smooth_led.png
It sort of works, but there is interference between LEDs. For example, when I'm turning an LED off, any other LED that is currently on blinks. Can anyone help me improve this circuit? Controlling the LEDs with PWM is not possible for the project I'm using this, so this should be done in the circuit, and the digital control should only turn the LEDs on and off.

Cheers
 
Even if you get the blink problem solved (it's very likely software), this simple hardware probably isn't going to give you a satisfying fade in & out experience. The main problem is three non-linear behaviors will (probably) stack in the wrong way. The capacitor charge / discharge is an exponential function (or would be a smooth exponential if the LED+resistor load was a consistent impedance, which it is not). LEDs work by current, and the capacitor voltage to LED current has an abrupt non-linear step due to the diode's forward voltage drop. Human perception of brightness is also non-linear.
 
Last edited:
I'm trying the following circuit:

What voltage is Vcc for the shift register? What colour are the LEDs? If 3.3V and blue or white you might have almost no headroom
to drive the LEDs.

Show the code you are using please - its important to toggle the latch only once after shifting all the bits. Are all
the pins driving the shift register declared as outputs?

Don't like the capacitor idea, its going to shock-load the shift register outputs like that - if anywhere the caps should be
directly across the LEDs. With 47 ohms to a cap from the shift register you are asking 60mA or 100mA pulses depending on
the supply voltage. That's only going cause issues.

Just use the standard 20mA per LED from 74HC family, ie perhaps 120 ohm series resistors with the LEDs and see if that
works properly - no caps there. Add 100uF on the supply for extra low-speed decoupling perhaps.
 
What voltage is Vcc for the shift register? What colour are the LEDs? If 3.3V and blue or white you might have almost no headroom
to drive the LEDs.

Show the code you are using please - its important to toggle the latch only once after shifting all the bits. Are all
the pins driving the shift register declared as outputs?

Don't like the capacitor idea, its going to shock-load the shift register outputs like that - if anywhere the caps should be
directly across the LEDs. With 47 ohms to a cap from the shift register you are asking 60mA or 100mA pulses depending on
the supply voltage. That's only going cause issues.

Just use the standard 20mA per LED from 74HC family, ie perhaps 120 ohm series resistors with the LEDs and see if that
works properly - no caps there. Add 100uF on the supply for extra low-speed decoupling perhaps.

The voltage is 3V3. I had no idea that the LED color affects the performance of the circuit and code. Most of the LEDs are green, but there's one white and one blue. I just put any LED I had around. The circuit in the OP shows four LEDs for simplicity. This is the code:
Code:
#include <SPI.h>

const int latch_pin = 10;
const int num_of_chips = 1;
byte out_bytes[num_of_chips] = { 0 };

byte smoothCtl[2] = {112, 0};
int smoothCounter = 0;

int channel = 0;
int pin = 0;
int value = 0;

void set_output(){
  digitalWrite(latch_pin, LOW);
  for(int i = num_of_chips - 1; i >= 0; i--)
    SPI.transfer(out_bytes[i]);
  digitalWrite(latch_pin, HIGH);
}

void setup() {
  Serial.begin(115200);
  SPI.begin();
}

void loop() {
  while (Serial.available()) {
    static int temp;
    byte in = Serial.read();
    if (isDigit(in)) {
      temp = temp * 10 + in - '0';
    }
    else if (in == 'c') {
      channel = temp;
      temp = 0;
    }
    else if (in == 'p') {
      pin = temp;
      temp = 0;
    }
    else if (in == 'v') {
      value = temp;
      temp = 0;
      bitWrite(out_bytes[channel], pin, value);
      set_output();
    }
  }
}
If I remove the caps, then how will the LEDs fade in and out smoothly when they are toggled by the shift register? How can I achieve fading in and out with circuit?
 
How can I achieve fading in and out with circuit?

It is possible, but difficult, to achieve smooth LED fading by designing code to always very rapidly update the shift register to generate PWM waveforms.

Fortunately, Elco Jacobs did all this difficult work many years ago and packaged it nicely into the ShiftPWM library.

https://www.pjrc.com/teensy/td_libs_ShiftPWM.html

ShiftPWM is one of the many libraries Teensyduino installs, so all you need to do is click File > Examples > ShiftPWM to get started.

On all Teensy boards newer than 2.0, you must define SHIFTPWM_NOSPI. Read the comments in the examples for details.
 
To achieve nice LED fading by only analog circuitry is complicated, because of the non-linear issues.

One approach might involve first creating a voltage which changes over time as you would wish for the LED current to chance. Even that is not so easy, but let's imagine you can do that part.

Then you would probably use an opamp or maybe opamp + transistor to drive the LED, with a small resistor between the LED and GND. That resistor gives a signal indicating the current, which you would pass to the opamp's negative input to form a feedback loop. If everything is connected properly, and you choose an opamp with the correct input and ouput voltage ranges, it will drive the LED current to match the voltage at the positive input, due to the feedback loop.

For a fade out, the exponential decay of a capacitor discharged by a resistor might give you a useful signal for the positive input. Human perception of light intensity is logarithmic (bright light all looks pretty similar) so the rapid decrease transitioning into a "long tail" might give a nice fade out. Maybe.

But the resistor charging the capacitor is probably not what you want for fade in. That curve quickly rises and then gradually reaches the final value. For a human to perceive fade in, you probably want the opposite where it increase starts slowly.
 
For white/blue LEDs the on voltage is around 3V, so you ideally want the voltage to them to switch between about 2V and 3.3V
to get a reasonable fade (adding the cap in parallel with the LED itself). By using a resistor network you can arrange this, reducing
the load on the shift reg pin as well.
fade_LED.jpg

You can tweak the resistor ratio to ensure the LED is sufficiently off when the logic pin is LOW. Note that the supply is helping
to provide current to the LED reducing the load on the pin. The source impedance at the LED is 90 ohms or so from the
resistors, so for a 0.3s fade a capacitor value around 3300µF might be a starting place.

You can scale both resistors down for more brightness, but the cap then has to scale upwards to match.
 
For white/blue LEDs the on voltage is around 3V, so you ideally want the voltage to them to switch between about 2V and 3.3V
to get a reasonable fade (adding the cap in parallel with the LED itself). By using a resistor network you can arrange this, reducing
the load on the shift reg pin as well.
View attachment 26343

You can tweak the resistor ratio to ensure the LED is sufficiently off when the logic pin is LOW. Note that the supply is helping
to provide current to the LED reducing the load on the pin. The source impedance at the LED is 90 ohms or so from the
resistors, so for a 0.3s fade a capacitor value around 3300µF might be a starting place.

You can scale both resistors down for more brightness, but the cap then has to scale upwards to match.

Your circuit seems to be working fine, at least better than mine. I tried it out with whatever I had around, which was two 220 Ohm resistors and a 4700uF cap and it worked very well! I tried a second LED with the same resistors and a 1000uF cap, but that did not fade almost at all, and was blinking when I was toggling the first one. The first one though (with the 4700uF cap) did not seem to be affected by the second. I'll get some more parts (resistors and caps) and try out with more LEDs.

To achieve nice LED fading by only analog circuitry is complicated, because of the non-linear issues.

One approach might involve first creating a voltage which changes over time as you would wish for the LED current to chance. Even that is not so easy, but let's imagine you can do that part.

Then you would probably use an opamp or maybe opamp + transistor to drive the LED, with a small resistor between the LED and GND. That resistor gives a signal indicating the current, which you would pass to the opamp's negative input to form a feedback loop. If everything is connected properly, and you choose an opamp with the correct input and ouput voltage ranges, it will drive the LED current to match the voltage at the positive input, due to the feedback loop.

For a fade out, the exponential decay of a capacitor discharged by a resistor might give you a useful signal for the positive input. Human perception of light intensity is logarithmic (bright light all looks pretty similar) so the rapid decrease transitioning into a "long tail" might give a nice fade out. Maybe.

But the resistor charging the capacitor is probably not what you want for fade in. That curve quickly rises and then gradually reaches the final value. For a human to perceive fade in, you probably want the opposite where it increase starts slowly.

Thanks for the detailed description, but it sounds way too complicated to even bother to try. The ShiftPWM does work (I wasn't aware of it), but my Teensy seems to be loosing its serial connection very ofter, no idea why. Plus, my project will involve quite a lot of LEDs, and the library mentions it's pretty CPU intensive, so it's probably not the way to go.
 
I have used Mark's circuit and it works much better, at least with green and yellow LEDs (I had no idea that different LED colors behave differently). I went on and developed the circuit so that a smooth and a non-smooth control of the LEDs is possible, by using transistors and switching between the two states. This means that with a 595 shift register, four pins control four LEDs, and the other four control the transistors (an NPN and a PNP transistor pair per LED). Here's the circuit:
teensy_forum_capacitor_trans_smooth.png
This circuit seems to work, but I'd like an opinion from someone who knows more about circuits than I do, as my knowledge is very limited. Is there a chance things will start going crazy if this circuit is inserted in a greater circuit with more shift registers? Or if this circuit is duplicated many times for all shift registers (in the end I would like to use a lot of shift registers, probably around twenty or more).
 
Status
Not open for further replies.
Back
Top