Attention: Safety Recall of Vernier Go Direct Charge Station. Click to learn more.

Using Motors with Arduino®

In general, you will encounter three different kinds of motors in your Arduino projects. Each has its own uses, advantages, and disadvantages.

  • DC Motors—simple to connect and use (just two leads), driven via voltage, not very precise
  • Servo Motors—relatively simple to connect and use (three leads), driven to a particular position or at a particular speed via one or two control commands
  • Stepper Motors—complex to connect and use (four or more leads), driven to a particular position via special sequencing of control commands, can move very precise distances at very precise speeds.

The Vernier Digital Control Unit (DCU) provides an easy way to control many types of motors with an Arduino. Many Arduino boards have at least 16 digital output lines, but these lines can only be used directly to turn on low-current electronics, such as LEDs and buzzers. They cannot drive enough current for most motors. Dedicated Arduino “motor shields” are often sold for this purpose, but another option is to use the Vernier DCU.

DC Motor Control with PWM

DC motors are simple electronic components. Apply a voltage across the two leads and the motor spins. Apply a greater voltage and it spins faster. Switch the leads and it spins in the opposite direction.

One limitation with many microcontrollers, like the Arduino, is that it only offers digital lines for output. You can set an output line HIGH (max voltage) or LOW (zero voltage), but you can’t directly output a voltage in between. There is an indirect method however, that allows you to output a voltage some place between max and zero. This process is called pulse-width modulation (PWM). In order to output a voltage midrange between max and zero, a microcontroller can alternate between the HIGH and LOW output settings very quickly. If it switches equally between max and zero, the output voltage is effectively one-half the max. If it is HIGH twice as long as it is LOW, then it is effectively outputting a voltage two-thirds max.

The sample sketch, VernierLibTutorialDCUPWM, uses PWM to gradually speed up and slow down a DC motor. Connect the DC motor to lines D4 and GND on a Vernier DCU. Plug the DCU into the Digital 2 port on the Vernier Arduino Interface Shield or a Digital Protoboard Adapter wired to Arduino pins 6, 7, 8, and 9 as explained in the Connecting Vernier Sensors to the Arduino section.

/* VernierLibTutorialDCUPWM (v2018)
 * This sketch uses pulse-width modulation (PWM) to control
 * the speed of a DC motor connected to a Vernier DCU. The 
 * motor will slowly increase its speed from 0 to max and 
 * then slowly decrease its speed from max to 0.
 * 
 * Plug the DCU into the Digital 2 port on the Vernier Arduino 
 * Interface Shield or into a Digital Protoboard Adapter wired 
 * to Arduino pins 6, 7, 8, and 9. Connect the DC motor to DCU
 * lines D4 and GND.
 */

#include "VernierLib.h" //include Vernier functions in this sketch
VernierLib Vernier; //create an instance of the VernierLib library

int PWMSetting; //create global variable for level of PWM

void setup() {
}

void loop() {
    // demononstrate PWM by fade in from 0 to max in increments of 5 points
    for(int PWMSetting = 0 ; PWMSetting <= 255; PWMSetting +=5) 
    { 
      Vernier.DCUPWM(PWMSetting); //turn on motor to PWM level 
      delay(30); //wait 30 milliseconds to see timing effect                           
    } 
     // fade out from max to 0 in increments of 5 points
     for(int PWMSetting = 255 ; PWMSetting >= 0; PWMSetting -=5) 
     { 
       Vernier.DCUPWM(PWMSetting); //turn on motor to PWM level    
       delay(30); //wait 30 milliseconds to see timing effect                           
      } 
     delay(1000); //wait 1 sec before repeating
   }

Servo Motors

Servo motors are popular with many Arduino users, because they allow for precise control of angular position. A standard servo is small, but strong, and energy-efficient, because it draws power proportional to its load.

The sample sketch, VernierTutorialDCUServo, controls the position of a servo arm in response to raw voltage from any Vernier Analog (BTA) sensor. You will need to include the servo.h library at the beginning of your sketch. If you are using a servo motor with a standard 3-pin plug, you can connect it directly to the 3 pins on the Vernier DCU labeled “Servo.” Be sure to verify that the orientation of the servo connector is correct (black lead to GND and white or yellow lead to 4). If your servo motor does not have a 3-pin plug, you can wire it to the DCU screw terminal using the wiring diagram below.

  • Servo Control line (white or yellow wire) to DCU line D4
  • Servo 5V (red wire) to DCU line XP (power)
  • Servo GND (black wire) to DUC line GND

Plug the sensor and DCU into the Analog 1 and Digital 2 ports, respectively, on the Vernier Arduino Interface Shield or into Analog and Digital Protoboard Adapters wired as explained in the Connecting Vernier Sensors to the Arduino Using a Breadboard section. An external power supply, such as the LabQuest Power Supply, is required to power the servo motor.

/* VernierTutorialDCUServo (v 2017)
 * This sketch controls the arm on a servo motor in response
 * to the voltage from a Vernier analog (BTA)) sensor.
 *  
 * Connect the servo motor to the 3-pin connector on the DCU
 * labeled "Servo" (black lead to GND, white or yellow lead to
 * 4) or wire it to the DCU screw terminal. 
 * Plug the DCU into the Digital 2 port on the Vernier Arduino 
 * Interface Shield or into a Digital Protoboard Adapter wired 
 * to Arduino pins 6, 7, 8, and 9. 
 * Plug the sensor into the Analog 1 port on the Vernier
 * Arduino Interface Shield or into an Analog Protoboard Adapter 
 * wired to Arduino pin A0.
*/

#include <Servo.h> //include library functions fpr servo motor
Servo myservo; //create servo object to control a servo

int sensorPin=0; //initialize global variable for pin assignment to sensor
int sensorVoltage; //create global variable for the sensor reading

void setup() {
  myservo.attach(9); //attach the servo object to Arduino pin 9 
  pinMode(9,OUTPUT); //setup the servo
  pinMode(6, OUTPUT); //setup DCU line for a servo motor 
  pinMode(7, OUTPUT); //setup DCU line for a servo motor
  pinMode(8, OUTPUT); //setup DCU line for a servo motor
  digitalWrite(6, LOW); //turn off DCU line
  digitalWrite(7, LOW); //turn off DCU line
  digitalWrite(8, LOW); //turn off DCU line
}

void loop() {
  sensorVoltage = analogRead(sensorPin); //read raw voltage (value between 0 and 1023) 
  sensorVoltage = map(sensorVoltage, 0, 1023, 0, 179); //scale voltage to angle measure (value between 0 and 179) 
  myservo.write(sensorVoltage); //set servo position according to scaled value 
  delay(15); //wait 15 milliseconds for servo to reach position 
} 

Stepper Motors

There are two basic types of small, permanent-magnet stepper motors: bipolar and unipolar. Bipolar stepper motors have four wires that connect to the ends of two motor coils. Unipolar motors have five, six, or eight wires, four of which will connect to the ends of four motor coils. The easiest way to control a stepper motor with an Arduino is to connect it to the DCU, but the tricky part is identifying how to connect the wires.

If you are using a bipolar stepper motor, the first step is to identify which two wires go to the same coil. You can do this either by looking at a wiring diagram on the manufacturer’s website or by measuring the resistance between a pair of wires with a multimeter. The motor coil will have only a few ohms of resistance (often about 20 ohms on small motors), so find the pairs of wires with low resistance between them. When you have identified the two pairs, wire one pair to DCU lines D1 and D2; wire the other pair to DCU lines D3 and D4. Plug the DCU into the Digital 2 port on the Vernier Arduino Interface Shield or a Digital Protoboard Adapter wired to Arduino pins 6, 7, 8, and 9 as explained in the Connecting Vernier Sensors to the Arduino Using a Breadboard section. Connect an external power supply, such as the LabQuest Power Supply, to the DCU.

If you are using a unipolar stepper, you need to identify which four wires are “live.” The “live” wires will go to the four motor coils; the other wires are ground wires. Use a multimeter to measure the resistance between pairs of wires. The resistance between one “live” wire and a ground wire will be small (about 20 ohms), while the resistance between two ground wires will be negligible (zero). When you have identified the four “live” wires, connect them to DCU lines D1, D2, D3, and D4.

The VernierLib library contains a function to control a stepper motor:

Vernier.DCUStep(stepCount, stepDirection, stepDelay);

where stepCount is the number of steps the motor turns, stepDirection specifies whether the motor rotates clockwise or counterclockwise, and stepDelay is the pause between each step measured in milliseconds (the shorter the delay, the faster the motor turns). Note that the number of degrees the motor turns per step is determined by the manufacturer.

The sample sketch, VernierLibTutorialDCUStepper, will make the stepper motor rotate one complete rotation clockwise, stop for one second, and then rotate one complete rotation counterclockwise. Note if your motor does not rotate as expected, try switching the wires in the DCU screw terminal. Finding the correct wiring pattern is basically a trial-and-error situation.

/* VernierLibTutorialDCUStepper (v2017)
 * This sketch will make a stepper motor rotate one complete
 * rotation clockwise, stop for half a second, and then rotate
 * one complete rotation counterclockwise.
 * 
 * Connect the stepper motor to DCU line D1, D2, D3, and D4.
 * Plug the DCU into the Digital 2 port on the Vernier Arduino
 * Interface Shield or into a Digital Protoboard Adapter wired
 * to Arduino pins 6, 7, 8, and 9.
 */

#include "VernierLib.h" //include Vernier functions in this sketch
VernierLib Vernier; //create an instance of the VernierLib library

int stepCount = 48; //create global variable for number of steps; modify if not making one complete rotation
int stepDirection = 0;//create global variable for direction 0 = CW, 1 = CCW
int stepDelay = 30; //create global variable for step time in ms; modify to change the speed of rotation

void setup() {
}

void loop() {
  Vernier.DCUStep(stepCount,stepDirection, stepDelay); //rotate the motor
  Vernier.DCU(0); //turn off all DCU lines
  delay(500); //wait half second
  stepDirection ++; //increment the step direction
  if (stepDirection > 1) stepDirection = 0; //if finished CCW, reset to CW
}

Arduino® and

Arduino Logo

are trademarks of Arduino SA.

SAVE/SHARE YOUR CART