PWM issue with Arduino Micro/Leonardo

I'm using an Arduino Micro (Leonardo was added in the title just to help for searching, as 'Micro' is a little generic) as a simple AtoD converter to drive the dimming pin on some LED drivers that only accept pwm. The code portion is working fine, so I don't see a need to post it up. What I am having issues with is the pwm output of the ATmega32U4 itself. I'm using the analogWrite() function like you normally would, and the output is far from consistent.

At 0% duty cycle, the LEDs flicker constantly, even with a 10K pull down resistor on the line. You can see some artifacts on the scope plot below. It's a little tricky capturing everything, as the events happen quite fast, and the trigger can't capture them as I would like. You can see that random pulses pop up in the waveform (about 50us in duration). The pwm signal is measured right from the board, with no additional circuitry connected after that point, so there are no external influences, save for the pull down resistor (removing it makes no difference to the output).

Even at higher duty cycles, these random pulses still show up. They aren't as obvious, but you can see flickering in the LED output. Now, the same kind of issue shows up at 100% duty cycle, but they appear as gaps in the output, again, creating flicker. You can just see the ghost of two of the pulses in the image below.

To see if this was an issue with the software, I connected an Uno in place of the Micro to see what would happen. With the Uno (exact same code), the output is rock solid, and running through the range of duty cycles produced smooth output. I did notice that at 0% and 100% duty cycle, the output was pulled low or high respectively, with no pulsing like I saw on the Micro. Obviously, I could change the code for the Micro to act more like a digital output once the duty cycle hit 0% or 100%, but that still doesn't get rid of the random pulsing.

This is the first time using a board with the ATmega32U4. All of my other projects have used the ATmega328, so I'm wondering if this is a specific issue to the ATmega32U4, or if there is a specific fault with this particular board. The IDE I'm using is v1.0.4

Thanks in advance for the help. Hopefully someone can help me out here.

The behavior you are describing shouldn't be happening. When 0 and 255 are passed to analogWrite(), it turns off PWM and calls digitalWrite() with LOW and HIGH, respectively.

evilc66:
The code portion is working fine, so I don't see a need to post it up.

Post your code.

int wVal, rbVal, auxVal;
int wOut, rbOut, auxOut;

void setup()
{
}

void loop()
{
  wVal=analogRead(A0);
  rbVal=analogRead(A1);
  auxVal=analogRead(A2);
  
  wOut=map(wVal, 0, 1023, 0, 255);
  rbOut=map(rbVal, 0, 1023, 0, 255);
  auxOut=map(auxVal, 0, 1023, 0, 255);
  
  analogWrite(3, wOut);
  analogWrite(6, rbOut);
  analogWrite(9, rbOut);
  analogWrite(10, auxOut);
}

This is just a guess but:-
I think you might be writing to the PWM outputs too frequently and causing them to reset, hence the glitches. Try and add a delay or half a second or so in that loop and see it it settles it down.

How are you certain the behavior you are seeing is when analogWrite() is actually writing a 0?

Maybe the A/D on your Micro is working slightly different than your Uno, causing something other than 0 to be written.

I would suggest you include some kind of debug, a LED, toggle an output (watching with another channel on the scope), or Serial.print(), when the analogRead() returns 0 or analogWrite() is called with a 0. That way you can verify if the behavior you are describing is what is actually happening.

Grumpy_Mike:
This is just a guess but:-
I think you might be writing to the PWM outputs too frequently and causing them to reset, hence the glitches. Try and add a delay or half a second or so in that loop and see it it settles it down.

Al that is doing is putting a 500ms delay between the flicker. It's still there.

I forgot to mention in my first post that I have checked the functionality with the serial monitor (I took out the serial code after I saw that the AtoD was working as expected). 0 on the input gives 0 on the output. 1023 on the input gives 255 on the output. This is the same behavior on all 4 pwm output channels.

Al that is doing is putting a 500ms delay between the flicker. It's still there.

Yes but during the delay time the PWM is glitch free?

Well, in a sense. What ends up happening, at 0% duty cycle for example, is that if the output is low during the active portion of the loop, the LEDs are off. If a random pulse manages to make it through during the active portion, then the LEDs are now on for half a second during the delay. It doesn't get rid of it. It just slows it down.

What about simplifying the code down to:

void setup() {
 analogWrite(3, 0);
}

void loop() {
}

Then move the write to loop().

James, your idea ended up helping me find the problem, but not where I expected it.

So, I tried that code, and the output was very stable. Even tried changing the duty cycle (hard coded), and the result was the same. Same thing with moving the analogWrite() function to the main loop.

When I added the analog input back in, the gremlins reappeared. That got me thinking the issue was with the AtoD in the ATMega32U4, and not the output channels like I had originally though. I poked around a little and put the scope on the 5v reference pin (from the on board regulator) that I was using to feed power to the potentiometers. Lo and behold, there was a 58KHz ripple on the pin. A 10uf electrolytic cap to ground later, the ripple was gone, and the output was stable through the full sweep of duty cycles.

I haven't gone through the board layout to see if there is a difference between the Micro and the Uno as far as filtering of the output of the 5v regulator, but I'd say it's a strong possibility. The actually all use the same On Semi voltage regulator.

Thanks everyone for the help.