Smooth breathing led I am trying to make a simple breathing led circuit in which the intensity of the led varies between 0 and 255. I followed the Fade tutorial on the Arduino site, which gives me what I want, but I notice that the change in brightness is much more noticeable when the intensity is at 0.

In other words, the brightness seems to be bouncing back from 0, rather than slowly gliding back up.

I tried mapping the value of the delay to brightness: del = map(brightness, 0, 255, 10, 1); but that did not do the job.

The mapping seems to work better when I use 30 instead of 10 as longest delay time:  del = map(brightness, 0, 255, 30, 1); but I think what I really need is to implement some sort of sinusoidal function to make transitions smoother, but I am really struggling with the math... Any suggestions?

Here is the code:

int led = 9;           // the PWM pin the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 1;    // how many points to fade the LED by
int del;

// the setup routine runs once when you press reset:
void setup() {
  // declare pin 9 to be an output:
  pinMode(led, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  // set the brightness of pin 9:
  analogWrite(led, brightness);

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness &lt;= 0 || brightness &gt;= 255) {
    fadeAmount = -fadeAmount;
  }

  // here I map the delay to brightness
  del = map(brightness, 0, 255, 10, 1);


  delay(del);
}
There's two ways you could algorithmically do what you want, both with different results.

The first is with a sinewave:

for (int i = 0; i &lt; 360; i++) {
    analogWrite(5, (sin(i * 0.0174533) + 1) * 127));
    delay(3);
}


Basically you work your way 360 degrees around a circle and take one axis (e.g., the vertical one), offset it so that the values are all positive (sin gives a value between -1 and +1), then multiply it to fit the full brightness.

This is the smoothest way of fading an LED, but it doesn't respect the different sensitivities your eye has to the different brightnesses (you see more brightness variation when it's dim compared to when it's bright).

The other method is much cruder but does respect those differences in sensitivities. This specific method only gives you 8 brightnesses as opposed to 256, but they are on a log2 curve:

for (int i = 0; i &lt; 9; i++) {
    int v = (1 &lt;&lt; i) - 1;
    analogWrite(5, v);
    delay(100);
}
for (int i = 7; i &gt; 0; i--) {
    int v = (1 &lt;&lt; i) - 1;
    analogWrite(5, v);
    delay(100);
}


The theory of this one is it uses bit-shifting to gradually fill a byte with 1 from the least significant bit upwards.  

When i is 0, this formula:

int v = (i &lt;&lt; i) - 1;


gives:

1 &lt;&lt; 0 == 0b00000001
0b00000001 - 1 = 0b00000000


If i is 4, you get:

1 &lt;&lt; 4 == 0b00010000
0b00010000 - 1 = 0b00001111


So you effectively end up with a set of values:

0: 0
1: 1
2: 3
3: 7
4: 15
5: 31
6: 63
7: 127
8: 255