I was thinking about if it is possible to simulate PWM (AKA pulse width modulation).
Is it possible to reach the speed of the PWM using the delay() function ?.
Note : I am talking about the pins which does not support PWM, Arduino uno Pin 13 for example.
-
Why do you want to? Please specify what speeds you are hoping to achieve. The hardware can output 8 MHz. Simulated PWM cannot.– Nick Gammon ♦Commented Jan 14, 2016 at 8:25
4 Answers
It is possible to create a PWM signal from a non-PWM digital pin although you would not want to use delay, but timer interrupts for accuracy and finite timing. PWM intervals are typically measured in (μs[microseconds] vs ms[milliseconds]).
The standard Arduino servo library does this: Servo.
It would be possible to do it. Would it be a smart thing to do ?
I do not think so. Micro-controllers (not just Atmel's) have dedicated hardware modules to manage the signals for PWM. What happens when you use AnalogWrite is the compiler/interpreter/whatever uses these informations to modify the appropriate registers so the toggling is not managed by the code.
If you use the delay() functions, you are simply letting clock cycles pass by until the time you set is passed which is a lot less efficient. Plus, you would probably not get the same PWM frequency.
What you are talking about is more appropriately called Bit-Banging. Check out this link. It even has an example of what you are trying to do. @Jason is correct that it causes a number of issues. The link above will also run you through the draw backs of this method which I will summarize.
- Jittery due to interrupts (Interrupts can be disabled)
- The Processor cannot do anything else and keep the output working
- Frequency and Duty Cycle are difficult to determine
-
-
@Gerben Right, so in that case I'd use millis() and use a similar method without delaying the function. That would get rid of the first issue. The second problem might also be fixed as long as your Timer ran fast enough to catch each cycle.– JAM1693Commented Nov 25, 2015 at 16:28
-
I think it depends on what you want to use it for. I compared using PWM and bit banging to run a small DC motor. PWM produced an audible whine that I found very irritating. Using the delay function removed that (a delay on/off cycle of 10 milliseconds). I also found that it was relatively easy to control not only the ratio of on/off (PWM) but also the length of the cycle. This was useful for starting the motor with a slightly higher "push" to get it moving. (I'm sure that this could be done using PWM too) With respect to performance of the engine, I didn't find much actual difference.
The key issue with a DC motor is that while the digitalWrite() is LOW, the inertia of the motor carries the rotation on and so the effect of the delay is smoothed. In addition the RPM of the motor wasn't critical for my application.
However, if one was running a LED then using delay() might be visibly discernable and cause discomfort (and possibly seizures?). For this, I'd definitely use PWM.
regards Mark