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:
LED brightness with analogWrite(pin,128)
Is there something wrong with my code, or is there a special reason why more power is dissipated with analogWrite()
?
1 Answer 1
You need to review your code and also the capabilities of the Arduino UNO.
int
declares an integer. Soint 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 usedelayMicroseconds();
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.
cycle
?analogWrite()
. I can't really understand why, though, so I'd really appreciate it if you could provide some clarification. :)