Triggering PWM with a push button on an Arduino

I was asked how to control PWM with a push button on an Arduino.  I thought I’d blog it and then I can link them to this post.

Heres my setup:

Under the skull printed paper circle is a brushed DC motor that used to operate the tray on a CD-ROM drive.

Heres the fritzing drawing of it

Note that usually you’d use something like the Arduino motor shield to control a load like a motor with an Arduino, here we are ok because we are just spinning the motor with no load on it.  The danger is that a motor could draw more current through the Arduino than it can handle.

This is my code. 

int pinButton = 13;        // Pin 13 is handy as it has an LED on the Arduino board attached to it
int pinPWM = 11;           // Pin I am using as PWM output to power the motor directly
int iPWMValue = 53;        // This constant value controls the speed
boolean bReleased = true;  // Used to ensure the user must release the button fully before pressing again

void setup() {
  // Nothing to setup


void loop() {
  if ((digitalRead(pinButton) == HIGH) && (bReleased == true)) {
    bReleased = false;              // Set the bReleased flag
    analogWrite(pinPWM, iPWMValue);  // Start PWM output to turn the motor 
    delay(55);                       // How long the PWM signal will be sent to the motor       
    analogWrite(pinPWM, 0);          // Stop the PWM /motor from turning
  if (digitalRead(pinButton) == LOW) {
    bReleased = true;                // Reset the bReleased flag now the user isn’t pressing the button


(( mmmmm…. white space however I want it and braces…. :p ))
(Apologies to Mike Hewitt who I know doesn’t particularly like comments at the ends of lines of code!)

The code uses the boolean variable bReleased to ensure that once the button has been pressed it has to be released before being pressed again.  The motor just turns a set amount each time the button is pressed and holding the button down doesn’t make the motor continuously rotate.

The amount the motor rotates is set by the delay(55) in between the code that starts and finishes the analogWrite (which is what starts and stops the PWM output). So as this delay is between the PWM output starting and stopping it controls how long the PWM output is actually on for.   I found the number 55 by trial and error, trying different values until I got the effect I wanted.

The iPWMValue (53) is defined at the top of the code and used like a constant. A constant is just like a variable except whereas you can expect the value of a variable to change, the value of a constant stays, well, constant.  The reasons you would code like this are for readability and also if you were using the iPWMValue in several places and wanted to change the value you only need to change the value once in one place for that new value to be used everywhere.  Whereas if I had used the value 53 everywhere its harder to follow what the 53 means and if I needed to alter the value I need to find every place I’d used 53 and change it manually.  

The iPWMValue is passed into the analogWrite command to set what part of the PWM cycle is on.  The larger the value the more power is output and the faster the motor will turn. Please take a look at the Arduino PWM tutorial for a better explanation of PWM.    

I got to the value of iPWMValue by trial and error in combination with the delay(55) value to get the effect I wanted on video.  In practice you’d probably use a motor with a gearbox on it, here the motor is driving the disc directly. What I found was that the motor didn’t like being driven too slowly. If there was a gearbox it would be possible to have the motor spinning much faster whilst the actual disc would rotate at the desired slower speed.

Here is a video of the the project doing what it does:

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: