0

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.

1
  • 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 4

3

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.

1

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.

1

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
3
  • If you disable interrupts, delay will no longer work.
    – Gerben
    Commented Nov 25, 2015 at 16:18
  • @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.
    – JAM1693
    Commented Nov 25, 2015 at 16:28
  • Sorry :-p. Without interrupts, millis is not updated.
    – Gerben
    Commented Nov 25, 2015 at 19:35
0

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.