PWM not working correctly - pls help.

Hello,

I am using PWM (pin 3) for fade in and fade out of multiple LEDs connected behind transistor (I even try connect LED directly to pin 3).

analogWrite(3, 0); = LEDs are turned off

This work good but when I incremet value to: analogWrite(3, 1); , all LEDs start shine maybe on 50%!! Is it possible to change PWM so all LEDs start shine on 1 - 5 %???

I am using high brightness LEDs (50cd). I even try lower brightness but all time I can control my LEDs from OFF/50% to 100%.

Thank you.

(sorry for my bad language)

My first guess would be that there is a capacitor in the circuit that is stretching the pulses and causing the transistor to conduct even after the output has been turned off. Another possibility is a software error. Is Pin 3 set as an output?

Hi,

capacitators are not in my scheme. Even if I connect one LED diode with resistor to Arduino and set analogWrite(3, 1);, LED start glow high (cca 50% of max). I tryed this:

cyc:
digitalWrite(3, TRUE);
delaymicroseconds(1);
digitalWrite(3, false);
delay(20);
goto cyc;

LED glow just a little (cca 5% of max). But it is hard to control fade in and out with this way. I read something about 10kHz PWM etc. Is it possible to "slow" PWM? Or have someone another tip?

Thank you.

Please post your schematic and your sketch, then we may be able to tell what is wrong.

Hi,

I am sure scheme is ok. Code looks good too. I tryed to slow down fade in and out and it looks that "fade out" of all LEDs are smooth (LEDs brightness slow from 100% to 0% better but "fade in" is jumped to 50% and than slowly increase to 100%. I tryed even different LEDs. I think PWM is set fast so what is default rate of PWM at Arduino? 10kHz? 1kHz? Maybe if I will change it to lower setting ... ??? Thanks for tips.

Code:

int tlacitkoMaska = 0; // button value
int hodnota = 1; // PWM value

void setup() {
pinMode(3, OUTPUT); // PWM
pinMode(7, INPUT); // button
}

void loop() {

zacatek:
analogWrite(3, hodnota); // PWM pin 3
for (int c=0; c <= 50; c++) { // testing button here (50*20ms = 1sec)
tlacitkoMaska = digitalRead(7);
if (tlacitkoMaska == HIGH) {
goto preruseni;
}
delay(20);
}

analogWrite(3, 0); // PWM pin 3
for (int c=0; c <= 100; c++) { // testing button here (100*20ms = 2sec)
tlacitkoMaska = digitalRead(7);
if (tlacitkoMaska == HIGH) {
goto preruseni;
}
delay(20);
}

if (hodnota < 255) hodnota = hodnota + 1; // increase brightness of LEDs here
goto zacatek;

preruseni:
analogWrite(3, 0); // turn off leds here
hodnota = 1; // reset PWM to value 1
goto zacatek; // goto beginning

}

I can't see why your sketch isn't working, but I have a few observations:

  • Please use the # button when posting code, it makes it easier to read

  • You should use a separate series resistor for each LED, not one common resistor. This is because LEDs can't be guaranteed to be sufficiently close to identcal to share the current well when connected in parallel.

  • Your code is full of goto statements, which make it hard to understand. Try to rewrite it without using goto.

  • You haven't shown how the button is wired in your schematic, nor have you said whether it is pressed or not when the fade-in is supposed to be happening. So I can't rule out contact bounce as a possible cause.

  • Be careful of using Darlington transistors, especially when the supply to the load being switched is only 5v. Darlingtons are #4 in my Arduino "do not use" list, Five things I never use in Arduino projects | David Crocker's Solutions blog.

Thanks dc42 for reply.

button in scheme is not necessary and I can not use resistor for each leds in my project. In darlington is not problem too, because I even try conect one LED with resistor directly to PWM output and all LEDs do same....

I found this:

LED looks good, it work for this guy and he even increasing PWM value by 5!. May I have broken Arduino?

The code looks like it should work. I think the problem must be in the hardware.

const int ButtonPin = 7;
const int OutputPin = 3;

int hodnota = 1;                 // PWM value

void setup() 
{                
  pinMode(OutputPin, OUTPUT);      // PWM 
  pinMode(ButtonPin, INPUT);         // button
}

void loop()
{
  while (digitalRead(ButtonPin) == LOW)
  {
    analogWrite(OutputPin, hodnota);  // Set brightness

    // One second ON
    for (int c=0; c < 50; c++) 
    {                 // testing button here (50*20ms = 1sec)
      if (digitalRead(ButtonPin) == HIGH)
        break;
      delay(20);
    }

    analogWrite(OutputPin, 0);                               // PWM pin 3  

    // Two Seconds OFF
    for (int c=0; c < 100; c++) 
    {                // testing button here (100*20ms = 2sec)
      if (digitalRead(ButtonPin) == HIGH) 
        break;
      delay(20);
    }

    if (hodnota < 255) 
      hodnota = hodnota + 1;    // increase brightness of LEDs here
  } 

  analogWrite(OutputPin, 0);                  // turn off leds here                                    
  hodnota = 1;                           // reset PWM to value 1  
}

Thanks John for code ... It looks nice but I like goto because it looks "easier to understend" for me.

I will borrow another Arduino from my friend and try it.

Thx all.

I had a "HighPower" LED and it was bright even at PWM value 3. If I used an oldfashined weak indicator LED the fading worked fine, and the LED basically didnt appear lit before value 20 or so. I tried then to view the power-LED in strong light, and the dimming effect was "better".

the new poerLEDs are simply too good :slight_smile:
(NB: I havent looked at the code - the others have done that)

The problem is that it's not a good idea to control the brightness of a LED by varying its voltage.

Take a look at the attached exemplary datasheet, which is taken from a warmwhite LED from Nichia. As you can see from the right figure, the brightness depends nearly linear on the current. That is, if you increased the current from 0 to max, the brightness of the LED would fade in the same way.

The left figure shows the dependency of the current on the voltage. It is an exponential one! This means, even if you increase the voltage only a little bit, the current increases very quickly - and so does the brightness. This is what you are doing with your circuit. The resistor in series to the LED linearizes the behavior a little, but the better way is to use a current source which is controlled by a voltage. There are lots of examples in the internet.

All the theory would be negligible if the PWM pulses were nicely shaped rectangle pulses. Then the voltage would pulse the current and so the brightness. But, as posted by johnwasser, capacitors can screw up the game. Even if you not use any, there are always parasitic ones. And then you have to cope with the nonlinear behavior of the current.

And, as posted by dc42, LEDs should not simply be connected in parallel, at least not if you want them to have the same brightness. Connecting them in parallel, you force all LEDs to have the same voltage. Because of the steep slope of the current curve together with slight differences in the characteristics of each LED, the resultant currents and thus the luminosities might differ. If you instead connect the LEDs in series, all of them will have the same current, but then the voltage has to be sufficient high.

Nichia LED.PNG

Interesting.

Thanks for tips.