Schedule‎ > ‎

12B: Motors and Servos

Introduction

Arduino programs can perform action in the real world with the help of a motor. In this class we discuss the three kinds of motors that are commonly used with Arduino projects and how to control them. 

DC Motors

DC motors spin when power is applied to them. A DC motor contains permanent magnets in the stator (the fixed portion of the motor) and has a coil of wire in the rotor (the spinning part of the motor). When electricity is applied to the coil the rotor becomes magnetized and tries to align itself with the permanent magnets in the stator. As the rotor gets near alignment a mechanical switch in the motor reverses the flow of electricity in the coil forcing the rotor to align the opposite way. The rotor constantly "chases" magnetic alignment producing continuous motion.

Here is a link to an animation: DC Motor Animation

Arduino Motor Circuit

The motor circuit for the Arduino is pictured on the right. Notice that it also contains a transistor and a diode. Theses are critically important to the circuit. An LED can be powered from an Arduino pin, but motors need much, much more power. So the circuit uses a transistor. The transistor works like a switch. When the Arduino is driving a high level (5v) the transistor is on and current flows in thedirection of the arrow on the bottom of the transistor symbol. When the Arduino is driving a low level (0v) the transistor is off and no current will flow.
 
A transistor is not really a switch, it's a current controlled current source. There are many different kinds of transistors. Some, called Field Effect Transistors (FETs) work much more like switches and are preferred in most projects because they simplify design. For controlling a motor, however, a standard transistor works perfectly.

A transistor has three pins: the base is the control pin in the middle of the symbol. The top pin is the collector and the bottom pin is the emitter. In the motor circuit high current travels between the collector and the emitter with only a small current flowing into the base. 

The diode protects the transistor and the Arduino from damage. It's the most important part of this circuit. Remember, current flows in the direction of the arrow in a diode symbol. At first glance you may think that the diode doesn't do anything because it's pointing the "wrong" way. The motor contains a coil of wire which has high inductance. Higher the inductance means a stronger magnetic field and therefore a stronger motor. Inductance, however, gives the electrons a kind of inertia. When current is flowing through the windings of the motor it doesn't like to stop. Below is a picture of the current flowing through the motor with the motor on: 


The red line shows the small current from base to emitter of the transistor and a large current from collector to emitter. The problem comes when the transistor is quickly turned off. The motor coils will try to force current to flow through the transistor by raising its voltage. Even with a small coil the voltage can reach thousands of volts. Inductance in a coil is how your car generates 22,000 volts to fire the spark plugs from a 12v battery. When the transistor is abruptly turned off the diode gives current a safe place to go: 


The current will quickly die down, safely passing through the diode. If you forget you diode your transistor will eventually burn out and possibly take your Arduino with it. You also have to be aware of inductance when you use a non-piezo speaker. Speakers also use coils of wire.

Exercise 1:  DC Motors

Using a 560 ohm (green-blue-brown) or 270 ohm (red-purple-brown) resistor:  build and run the following (save your code as DC_Motor.ino)

Important:  In loop(),  just before the AnalogWrite add:  cout << "analogWrite of  " << speed << endl;

DC Motors Exercise 1

Show your DC motor working to the teacher for checkoff.  Answer the questions below in the Canvas comment and Submit DC_Motor.ino to Canvas.

Q1:  Try reversing the connections to the motor. What happens?

Q2:  Try entering different values (starting at 0) into the Serial Monitor and notice at what value the motor starts to actually turn. You will find that the motor starts to 'sing' as you increase the analog output.

Q3:  What is the purpose of the transistor in this Exercise?

Q4:  What is the purpose of the diode in this Exercise?



Stepping Motors 

DC motors are very useful when you just need to go and stop. DC motors can be speed controlled using PWM but the control is not accurate. For many robotics and other applications you need a motor that can be controlled precisely. That's what stepping motors are for. Stepping motors are more complicated, they don't just turn on. Stepping motors have multiple windings and need Arduino to generate a series of pulses on each winding to precisely control movement.  

The diagram shows an Arduino connected to a stepping motor. The chip shown is a buffer. It takes the place of the transistor and the diode in the DC motor circuit. If you're planning on using stepping motors be sure to buy a driver chip, they save a lot of work! Stepping motors usually have three to eight wires.

Here is a good description of Stepper Motors and how to get them to work with  your Arduino:  Stepper Motors

The Arduino Stepping Library has classes that help you design your project for stepping motors.

Stepper Motor Applications (from Wikipedia Stepper Motor):

Computer controlled stepper motors are a type of motion-control positioning system. They are typically digitally controlled as part of an open loop system for use in holding or positioning applications.

In the field of lasers and optics they are frequently used in precision positioning equipment such as linear actuators, linear stages, rotation stages, goniometers, and mirror mounts. Other uses are in packaging machinery, and positioning of valve pilot stages for fluid control systems.

Commercially, stepper motors are used in floppy disk drives, flatbed scanners, computer printers, plotters, slot machines, image scanners, compact disc drives, intelligent lighting, camera lenses, CNC machines and, more recently, in 3D printers.


Servos 

Servos are motors where you can set the angle of the rotor. Servos are useful for precise control of object. Servos are common on many robots like this creepy robot spider: 

The T8 Robot Spider


High quality servos use stepping motors for accuracy, but are large and expensive. Servos like the one you have in your kit are a simple DC motor that drives a potentiometer. The potentiometer provides data on the position of the motor. Inside your servo is an Arduino like microchip that runs code that's something like this: 

void setPosition(int target) {
  int pos = getResistance();
  while (target != pos) {
    if (target < pos) { 
      spinForward();
    }else{
      spinBackwards(); 
    }
    delay(1);
    pos = getResistance();
  }
}

The code spins the motor, forward or backwards, until the resistance of the potentiometer matches the desired angle. Servos are often controlled using PWM. PWM is a convenient way to control servos because it uses only one wire and because it's compatible with many hobbies remote control receivers. The servo in your kit is made for a remote controlled airplane or car.

Servomotors vs. stepper motors
Servomotors are generally used as a high-performance alternative to the stepper motor.  The lack of feedback of a stepper motor limits its performance.  Many applications, such as laser cutting machines, may be offered in two ranges, the low-priced range using stepper motors and the high-performance range using servomotors.

Review of Objects and Classes

  • Previously we discussed how to code classes to create objects

Objects

  • Recall that an object in C++ is a location in memory containing a structured collection of variables and functions defined by its class
  • As an example, here is an "RRB_LED" object in memory:
    _redPin
    _greenPin
    _bluePin
    _commonAnode
  • The example object has four pieces of data structured one after the other in memory
  • In addition, the object has access to associated functions
  • To define the data structure of objects, we write a class

Classes

  • A class is a program-code "template" for creating objects
  • Objects are then a particular instance of a class, meaning an object has particular values
  • The particular values are stored in memory as defined by the class template
  • The data values are structured in the order defined by the class:
    class RGB_LED {
    private:
      _redPin = redPin;
      _greenPin = greenPin;
      _bluePin = bluePin;
      _commonAnode = commonAnode;
      pinMode(redPin, OUTPUT);
      pinMode(greenPin, OUTPUT);
      pinMode(bluePin, OUTPUT);
    ...
    }
    

Information Hiding

  • Remember that we always code our class member variables as private
  • The keyword private restricts access to only member functions
  • Keeping member variables private is important so we can make design changes

Object Interface

  • To access private data, we code public member functions like:
      public:
        RGB_LED(int redPin, int greenPin, int bluePin, bool commonAnode);
        void setColor(int red, int green, int blue);
    
    
  • These public functions are the interface to our class
  • The interface is how we communicate with and use our objects

Constructing Objects

  • To create objects from the class, we construct an object like:
    RGB_LED rgb(11, 10, 9, true);
    
  • When the object is created, memory is allocated for the class variables
    _redPin
    _greenPin
    _bluePin
    _commonAnode
  • However, the memory is uninitialized
  • We can use the set functions to assign the memory values:
    rgb.setRedPin(11);
    rgb.setGreenPin(10);
    rgb.setBluePin(9);
  • However, this is cumbersome and provides no guarantee that the programmer using our class will completely initialize the object data
  • A better solution is to code constructor functions

Constructor Functions

  • A constructor is a special type of function whose purpose is to initialize member variables
  • Whenever an object is created from a class, a constructor is always called automatically
  • A default constructor must set the member variables to default values:
    RGB_LED::RGB_LED() {
      _redPin = 11;
      _greenPin = 10;
      _bluePin = 9;
      _commonAnode = true;
    }
    
  • Even though we should always code a default constructor, it is convenient to code other constructors like:
    RGB_LED::RGB_LED(int redPin, int greenPin, int bluePin, bool commonAnode) {
      _redPin = redPin;
      _greenPin = greenPin;
      _bluePin = bluePin;
      _commonAnode = commonAnode;
      pinMode(redPin, OUTPUT);
      pinMode(greenPin, OUTPUT);
      pinMode(bluePin, OUTPUT);
    }
    
  • This lets us construct an object and initialize data members at the same time:
    RGB_LED rgb(11, 10, 9, true);
    
  • When we are done, we have a modular, reusable grouping of variables and functions
  • In this section we look at some ways we can make use of these modules

Exercise 2: Design a Class Color

On paper, write the declaration for a class that represents a color made up of red, green and blue values. . The class will need member variables for red, green and blue. We will want to be able to get (access) and set (change) the color values.  Each of red, green and blue can be of values 0-255. 

Phase One (5m)

  1. First, decide on an appropriate name for the class.  You are creating the .h file for your class.
  2. Decide what member variables are needed and the appropriate data types..
  3. Decide what constructors are needed to initialize the member variables.
  4. Decide what initial values you want the member variables to have.
  5. Decide what functions are needed to access or update the member variables.
  6. Decide what actions need to be taken for the color and declare appropriate member functions (do not implement).
  7. Develop a member function interface (not implementation) that reverses the red and blue color values.
  8. Develop a member function interface (not implementation) that adds 50 to the green value but stops when green becomes >=255.
  9. Develop a member function interface (not implementation) that subtracts 50 from the blue value but stops when blue becomes <= 0;

Phase 2 (4m)

  1. Go write your .h file up on the board and be prepared to present it to the class.
  2. Make sure you & your partner's name is on your paper and then turn in your paper.

Check Yourself

  1. True or false: a class contains (encapsulates) both variables and functions.
  2. To allow only member functions and constructors of an object to access a member variable, use the keyword ________.
  3. True or false: good programming practice is to set the accessibility of all member variables to private.
  4. Public functions are the ________ of a class.
  5. True or false: the purpose of a constructor is to initialize all the member variables.



Comments