PWM output not smooth on 2 leds

Going nuts here, I shamelessly copied a piece of code to SMOOTHLY fade an led. It works great. I added a second led with an offset and it still works but the second led is very jerky. I can switch the leds around on all the PWM pins on a Uno or a Nano and the first led called is smooth, the second is jerky. Any ideas???

int ledPin = 11; //setup 2 pins with leds and resistors
int ledPin2 = 10;

int value, value2; // set variables to hold calculated output
unsigned long time=0;
int cycle = 2000; // cycle time
int displace = 500; // 90 degree offset

void setup() {
 
  pinMode (ledPin, OUTPUT); // not really needed
  pinMode (ledPin2, OUTPUT);

}

void loop() 
 {
   time = millis();
   value = 128+127*cos(2*PI/cycle*time);
   value2 = 128+127*cos(2*PI/cycle*(displace-time));

   analogWrite(ledPin, value);           // sets the value (range from 0 to 255) 
   analogWrite(ledPin2, value2);           // sets the value (range from 0 to 255) 
 }

look at what is different from the first lot of code and debug from there, try changing the displace time to different increments and see if it makes it worse or better.

Changing offset had no effect on the rough level changes. ledPin is very smooth and ledPin2 is very rough. Are there any interrupts in the math functions I used?

ive just tried out this piece of code and removed the bits you added in and all i get is a blinking led. i could not get it to fade. have you tried the fade example?

As a test, if you remove the displacement to make both calculations the same, do you get smooth, synced fades on both LEDs?

Your calculations mix int and unsigned long and may be overflowing. The subtraction on the second calculation could be causing different overflow behaviour.

I had not tried setting the cycle and displacement equal to each other. No joy, D3 is smooth as silk and D5 is stair stepped. But thanks for the feedback.

I meant make both calculations the same (apart from the result variables).

value = 128+127*cos(2*PI/cycle*time);
   value2 = 128+127*cos(2*PI/cycle*time);

Interesting, I see the same thing you do, and it's not clear to me exactly why that should be the case.

Oh, I see, you're running into float accuracy.

The key issue is that you're running time backwards for the second timer.

Thus, the values of (displace-time) will be around 4.2something billion (at first at least) - but then you're multiplying it by PI, which promotes it to a float. Now with a 4.2 billion-some float, differences of just a few milliseconds fall below the granularity of floating point numbers.

This also means that if you let it run long enough, the first LED would become uneven, and the second led would become smooth, and then back again. This should fix that issue too

void loop() 
 {
   time = millis()%cycle ; //ensure that time never gets big, and by making it the cycle length, we prevent a glitch as it rolls over from cycle-1 to 0, because the sine wave will be in the same spot.
   value = 128+127*cos(2*PI/cycle*time);
   value2 = 128+127*cos(2*PI/cycle*(displace+time)); //don't let that term overflow

   analogWrite(ledPin, value);           // sets the value (range from 0 to 255) 
   analogWrite(ledPin2, value2);           // sets the value (range from 0 to 255) 
 }

Thanks Hackscribble, I tried your suggestion and sure enough both are smooth. Not at all sure why but at least they are smooth and if necessary I can find some other way to get the 90 degree phase shift. Perhaps the SIN function :slight_smile:

But typing this now I don't understand why it should be so jerky unless there is some interrupt going on. But thanks for a good starting point.

FYI, using the SIN function without the (display-time) works perfect. Thanks everyone for helping me get my head out of my....

Hi.
Have you tried doing the

displace+time

calculation separately and not in the cos function.

somevariable = displace+time

then cos(........somevariable)

Tom.... :slight_smile:

adwsail:
Thanks Hackscribble, I tried your suggestion and sure enough both are smooth. Not at all sure why but at least they are smooth and if necessary I can find some other way to get the 90 degree phase shift. Perhaps the SIN function :slight_smile:

But typing this now I don't understand why it should be so jerky unless there is some interrupt going on. But thanks for a good starting point.

Read my post - I explained why it's jerky, and gave you tested working code that does the same thing your original code tried to do.

Missed your post Drazzy and just tried it. Works a treat and thanks for the detailed explanation. Not sure how I missed that but I'm learning.