user63956: I've been trying, just out of curiosity, to write my own function that generates a PWM signal, just like analogWrite(), and to make it light up an LED. Here's my attempt so far:
const int pin = 3;
int cycle = 2; // analogWrite() outputs a 498 Hz signal, so each cycle has approximately 2ms

int duty = 0.5; // for a 50% duty cycle

void setup() {
  Serial.begin(9600);
  pinMode(pin,OUTPUT);
}

void loop() {
  digitalWrite(pin,HIGH);
  delay(cycle*duty);
  digitalWrite(pin,LOW);
  delay(cycle*(1-duty));
}

The LED does light up, but very dimly, as shown below:

However, when using analogWrite() with a 50% duty cycle to achieve the same result, the LED shines much brighter:

Is there something wrong with my code, or is there a special reason why more power is dissipated with analogWrite()?

user43025: You need to review your code and also the capabilities of the Arduino UNO.

int declares an integer.  So int duty = 0.5; is going to get rounded to either 0 1. 
delay(0); also will not work.  The instruction will simply get skipped. Likely the reason why you get a brighter LED. Try to use delayMicroseconds(); if you need shorter time but the minimum delay you can have is 4 us for Arduino UNO.
If you are using times as short as 2 us, then from the above comment the delayMicroseconds(); function is not going to be sufficient.  Also, you should consider the loop overhead, which will be a few microseconds.

All in all this is not a great method.  If you do want to create your own PWM signals, it is much better to use the hardware timers.  For example this tutorial on the Arduino website.  You should also be able to find posts about hardware timers on Arduino SE.

63956: <p>I've been trying, just out of curiosity, to write my own function that generates a PWM signal, just like <code>analogWrite()</code>, and to make it light up an LED. Here's my attempt so far:</p>

<pre><code>const int pin = 3;
int cycle = 2; // analogWrite() outputs a 498 Hz signal, so each cycle has approximately 2ms

int duty = 0.5; // for a 50% duty cycle

void setup() {
  Serial.begin(9600);
  pinMode(pin,OUTPUT);
}

void loop() {
  digitalWrite(pin,HIGH);
  delay(cycle*duty);
  digitalWrite(pin,LOW);
  delay(cycle*(1-duty));
}
</code></pre>

<p>The LED does light up, but very dimly, as shown below:</p>

<p><a href="https://i.stack.imgur.com/ik8e8.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ik8e8.jpg" alt="LED brightness with my code"></a></p>

<p>However, when using <code>analogWrite()</code> with a 50% duty cycle to achieve the same result, the LED shines much brighter:</p>

<p><a href="https://i.stack.imgur.com/uNb9x.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/uNb9x.jpg" alt="LED brightness with analogWrite(pin,128)"></a></p>

<p>Is there something wrong with my code, or is there a special reason why more power is dissipated with <code>analogWrite()</code>?</p>
 43025: <p>You need to review your code and also the capabilities of the Arduino UNO.</p>

<ul>
<li><code>int</code> declares an integer.  So <code>int duty = 0.5;</code> is going to get rounded to either 0 1. </li>
<li><code>delay(0);</code> also will not work.  The instruction will simply get skipped. Likely the reason why you get a brighter LED. Try to use <code>delayMicroseconds();</code> if you need shorter time but the minimum delay you can have is 4 us for Arduino UNO.</li>
<li>If you are using times as short as 2 us, then from the above comment the <code>delayMicroseconds();</code> function is not going to be sufficient.  Also, you should consider the loop overhead, which will be a few microseconds.</li>
</ul>

<p>All in all this is not a great method.  If you do want to create your own PWM signals, it is much better to use the hardware timers.  For example <a href="https://playground.arduino.cc/Code/Timer1/" rel="nofollow noreferrer">this tutorial on the Arduino website.</a>  You should also be able to find posts about hardware timers on Arduino SE.</p>
