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 itint pinPWM = 11; // Pin I am using as PWM output to power the motor directlyint iPWMValue = 53; // This constant value controls the speedboolean bReleased = true; // Used to ensure the user must release the button fully before pressing againvoid setup() { // Nothing to setup}void loop() { if ((digitalRead(pinButton) == HIGH) && (bReleased == true)) {bReleased = false; // Set the bReleased flaganalogWrite(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: