Lab 5: Motors


Topics

  1. First Build
    1. The Circuit
    2. The Code
  2. Hardware Theory
    1. Voltage Division
    2. Introduction to Higher Current Devices
      1. Electric Motors
      2. Diodes
      3. Transistors
    3. Temperature Sensor
  3. Software Theory
    1. Functions
  4. Exercises
    1. Voltage Division
    2. Temperature Controlled Fan
    3. Temperature Controlled Fan (IN FREEDOM UNITS!!!)

1. First Build

You will know you got this sketch right if the motor spins at two different speeds. Your lab instructor will supply a visual aid to help you see your motor spinning.

1.1 The Circuit

Build Notes:

Motor Circuit Schematic Motor Circuit Implementation

1.2 The Code

The code for the motor sketch:

/* 
 * Arduino Experimentation Kit Example Code 
 * CIRC-03 .: Spin Motor Spin :. (Transistor and Motor) 
 *
 * Modified Oct 11 2011 by Alex Clarke.
 */

// constants
const int motorPin = 9;

// prototypes for user defined functions
void motorOnThenOff();
void motorTwoSpeed();

void setup()
{
  pinMode(motorPin, OUTPUT);
}

void loop()
{
  //motorOnThenOff();
  motorTwoSpeed();
}

/*
 * motorOnThenOff() - turns motor on then off
 * Notice we use digital writes, 
 * just like with LEDs.
 */
void motorOnThenOff()
{
  const int onTime = 2500; //the number of milliseconds for the motor to turn on for
  const int offTime = 1000; //the number of milliseconds for the motor to turn off for

  digitalWrite(motorPin, HIGH); // turns the motor On
  delay(onTime); // waits for onTime milliseconds
  digitalWrite(motorPin, LOW); // turns the motor Off
  delay(offTime); // waits for offTime milliseconds
}

/*
 * motorTwoSpeed() - turns motor on then off but uses speed values as well
 * Notice we use analog writes to set motor speeds,
 * just like with LED brightness.
 */
void motorTwoSpeed()
{
  const int onSpeed = 200; // a number between 0 (stopped) and 255 (full speed)
  const int onTime = 1000; //the number of milliseconds for the motor to turn on for

  const int offSpeed = 27; // a number between 0 (stopped) and 255 (full speed)
  const int offTime = 2500; //the number of milliseconds for the motor to turn off for

  analogWrite(motorPin, onSpeed); // turns the motor 
  delay(onTime); // waits for onTime milliseconds
  analogWrite(motorPin, offSpeed); // turns the motor Off
  delay(offTime); // waits for offTime milliseconds
}


2. Hardware Theory

This week you will use Ohm's Law and voltage division to predict and measure the voltage at different points in a series circuit. You will also learn one technique for driving higher current circuits with your low current Arduino pins.

2.1 Voltage Division

Last week you learned to use different types of analog input device. Most of them used the Arduino's six analog inputs which are able to sense different voltage levels and convert them to numbers you can use in your sketch. Many analog input devices make creative use of Ohm's law and the concept of voltage division to provide.

You should recall from class that Ohm's law relates Voltage, Current and Resistance like this:

Let:

V be voltage in Volts
I   be current in Amps
R be resistance in Ohms.

Then:

V = I R

You should also have been shown the following diagram that helps you know how to rearrange Ohm's Law to solve for different parts of the equation:

 Ohm's Law

Voltage division is an effect seen in simple series circuits with multiple resistive components.  Between each component of the circuit you can measure a different voltage relative to ground that is related to ratio of the resistance after that point in the circuit to the total resistance of the circuit.

A series circuit in a stable state has one current value that is constant from end to end. The value of this current can be determined with Ohm's law, using the total resistance of all components in the circuit.

Over the circuit the voltage will drop from high to low in the direction of the current. On your Arduino this means it will drop from +5V to 0V. The voltage drops as it passes through resistive components in the circuit. The amount the voltage drops across each of these components can be calculated using Ohm's law. We can then calculate a voltage value for the wires between components in the circuit.

Let's combine Ohm's Law and voltage division to calculate the voltages between the resistors in the following circuit. You may assemble the circuit and verify the calculations with your multimeter if you wish.

3 Resistor Voltage division

First, calculate the current for this circuit:

I = V / R
  = 5V / (560Ω + 560Ω + 2200Ω)
  = 5V / 3320Ω
  ≈ 0.001506A
  ≈ 1.506mA

You can confirm this with your multimeter:

Second, calculate the voltage drop for each resistor:

VR1 = I R1
        ≈ 0.001506A × 560Ω
        ≈ 0.8434V

VR2 is the same as VR1

VR3 = I R3
        ≈ 0.001506A × 2200Ω
        ≈ 3.313V

You can confirm each of these voltage drops with your multimeter:

Last, we can calculate the expected remaining voltage at each point in the circuit. You can do this two ways:
  1. Add together all the voltage drops that ahead of the measured point.
  2. Subtract all the voltage drops before the measured point from the input voltage.
So we should get the input voltage, 5V, if we measure before any resistive components. Using method 1:

Vin ≈ 0.8434V + 0.8434V + 3.313V =  5V

At point V1:

V1 ≈ 0.8434V + 3.3134V = 4.1564V

At point V2:

V2 ≈ 3.3134V

There's a simple equation for calculating the voltage level above ground at some point Vn in a circuit:

Vn = V * RafterVn/RWholeCircuit

Let's try it for V1:

V1 = 5V * (560Ω + 2200Ω) / (560Ω + 560Ω + 2200Ω)
V1 = 5V * 2760Ω / 3320Ω
V1 = 5V * 0.83133
V1 = 4.1567V

Which is about right once you consider the rounding off we did in the earlier example.

2.2 Higher Current Devices

So far we've been able to do what we want with the Arduino's input and output pins. They're fine for controlling low current devices. Some devices, like electric motors, require more power. If you try to drive these devices with the Arduino's pins, the devices may not work, and the Arduino's pins will soon break. To use high current devices you need the ability to control the +5V supply. One component in your kit that allows you to do this is the transistor. Transistors are solid state devices that use a small current to control a much larger current.

2.2.1 Electric Motors

Your ARDX kit comes with a toy electric motor similar to the ones used in RC cars:

Electric Motor

Electric motors move because of magnetism. They contain permanent magnets surrounding a freely spinning electromagnet core. An electromagnet is a piece of iron with wire wound around it. Brushes connect this wire to the two wires sticking out of the motor. When current passes through the wire the core becomes magnetic. Because the core can spin freely it will move so it aligns with the magnets surrounding it. There is a mechanism that switches the current's direction so that the electromagnet never quite lines up with the permanent magnets causing the motor to keep spinning as long as there's a strong current.

Electromagnets can be used to generate power. This is a property of coils of wire, or inductors. Because of this you have to take precautions when you use them to prevent doing damage to sensitive components in the circuit. When you try to turn off an inductor it turns its magnetic field  back into electricity flowing in the same direction as the previous current. This happens very quickly and the voltage can be very high - up to 10 times the source voltage. If you don't do something to dissipate the energy safely it can cause sparks to fly between wires, or it can cause surges of power to pass through electrical components like the transistor in this week's circuit or your Arduino's pins. Diodes are used in a special configuration to dissipate these power surges.

2.2.2 Diodes

Not all diodes emit light. Your ARDX kit has two plain diodes like the one pictured below.

diode

As you have learned, diodes only allow electricity to pass through them in one direction. The positive end is the anode and the negative end is the cathode. Diodes are made of semi-conductors, usually silicon. There are two "flavors" or dopings of silicon inside, a p-type (positive) doping for the anode and an n-type (negative) for the cathode. The side by side arrangement of differently doped semiconductors only allows electricity to flow in one direction.

This property is being exploited in this circuit to protect the transistor. A diode placed parallel to an inductor and backward to the normal flow of electricity in a circuit is called a flyback diode. When current is flowing through the motor and the switching transistor, the diode does nothing because it is backward, or reverse biased. When the the transistor stops flow to ground, the inductor produces a strong forward voltage. The diode connects the two ends of the inductor and forms a low resistance loop - a flyback loop. The surge will go round and round this loop until it dissipates.

You can see a flyback diode in action if you replace the regular diode with an LED. Don't do this for too long though or you may cause damage. Flyback diodes have very low forward voltage, usually less than 1 volt. LEDs typically have a forward voltage of 1.7 volts. Flyback diodes must have a reverse breakdown voltage that can handle the motor's power supply.

2.2.3 Transistors

Transistors are awesome multipurpose components. Their invention enabled the modern era of electronics. Your kit contains two transistors. Be careful not to confuse them with your kit's temperature sensor. If you look carefully at the flat side you should see an inscription like the one pictured below. If you see TMP on it, then you have the wrong part.

Transistor

The transistors in your kit are NPN transistors. NPN stands for negative positive negative which is their internal silicone structure. They are a bit like two diodes that share an anode. When you apply a charge to the base (the middle of the NPN sandwich), it allows current to flow across the transistor. This current can only flow in one direction. The positive side of this flow is the collector and the negative side is the emitter. A small amount of current applied to the base can allow very large amounts of current to flow from the emitter to the collector.

Different transistors have different pin arrangements. You will need to find what pin arrangement corresponds to your specific transistor. Notice the text on the flat side of the transistor? ;-)

2.3 Temperature Sensor

The other transistor-like component in your ARDX kit is actually a complicated integrated circuit (IC) that can sense temperature. If you put it in a 5V circuit it will provide a voltage based reading that is related to its temperature. BE CAREFUL TO PLUG TEMPERATURE SENSORS IN CORRECTLY! In rare instances, plugging a temperature sensor in wrong can lead to burns!

Temperature sensor pins

You need to know some properties of the sensor (datasheet here) to convert its output to a temperature in degrees:

This suggests the following equation:
temperature_in_celsius = output_in_volts * conversion_factor  - offset
temperature_in_celsius = output_in_volts * 100 - 50

3. Software Theory

3.1 Functions

If you look at this week's sample code, you will notice that loop() has almost no code in it. All the work is being done by user written functions. You can use comments to easily change whether the motor is dual-speed or simply on-off.

Functions are really nothing new to you. You defined the behaviour of a function every time you wrote a loop() or setup(). You have been using or calling functions to do almost everything you have done with your Arduino. Some functions, like digitalWrite() and tone(), are commands that perform an action that is controlled by arguments. These are called void functions.  Others functions, like analogRead() and map(), provide you with information that your can use later in your sketch. These are called value returning functions. Both types of functions are meant to hide the messy details of a complicated task and give it a useful name.

User written functions are often declared before they are actually used/called. This forward declaration is also known as a function prototype. The general syntax of a function prototype is:

returnDataType functionName(ParameterList);

Once a function is declared, it must be defined somewhere in the program. The definition of a function has the following general format:
returnDataType functionName(ParameterList)
{
Statement
.
.
.

return data; //only if returnDataType is not void!
}
The first line is a restatement of the prototype without the semicolon at the end. The rest of the function is a sequence of commands. If your function has a non void return type, your function must return a value. The function ends when a return statement is reached, even if there are more lines of code that follow.

Example of Void Function With Arguments

In the First Build sketch we have two very simple functions that take no arguments and return no value. Let's look at one of them, motorOnThenOff():

Prototype:
void motorOnThenOff();

Call:
void loop()
{
motorOnThenOff();
}

Defintion:
void motorOnThenOff(){
const int onTime = 2500; //the number of milliseconds for the motor to turn on for
const int offTime = 1000; //the number of milliseconds for the motor to turn off for

digitalWrite(motorPin, HIGH); // turns the motor On
delay(onTime); // waits for onTime milliseconds
digitalWrite(motorPin, LOW); // turns the motor Off
delay(offTime); // waits for offTime milliseconds
}

If you want to be able to control the motor's on and off times then you would change the function and its call like this:

Prototype:
Add parameters for the parts of the function you want to control.
void motorOnThenOff(int onTime, int offTime);

Call:
Add arguments to the function. Their values will be copied into the function's parameters. You can use different arguments each time you call a function.
void loop()
{
 motorOnThenOff(2500, 2500); //Change the arguments to change on and off times
}

Defintion:
Add parameters the first line. Those can now be used as variables inside the function. In this example the parameters replace the onTime and offTime constants, so delete the lines where they are declared.
void motorOnThenOff(int onTime, int offTime){
 const int onTime = 2500; //the number of milliseconds for the motor to turn on for
 const int offTime = 1000; //the number of milliseconds for the motor to turn off for

 digitalWrite(motorPin, HIGH); // turns the motor On
 delay(onTime); // waits for onTime milliseconds
 digitalWrite(motorPin, LOW); // turns the motor Off
 delay(offTime); // waits for offTime milliseconds
}

Example of Value Returning Function: AnalogToVolts

Here's an example of a program that uses a value returning function:

/*    
 * Analog to Volts Function Demo
 * Created Oct 2011 by Alex Clarke.
 */

// Function Prototype
float AnalogToVolts(int reading);

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  int reading;
  float volts;
  reading = analogRead(A0);
  
  volts = AnalogToVolts(reading);  //Function call

  Serial.println(volts);
}

// Function Definition
float AnalogToVolts(int reading)
{
  float volts;
  volts = reading/1023.0 * 5.0;  //Perform conversion
  return volts; //Return result
}


4. Exercises

Part 1: Voltage Division

Voltage Divide Exercise Diagram

Build the above circuit in a corner of your breadboard, then:

Part 2:  Temperature Controlled Fan

In this exercise you will build a "fan" that turns on when the temperature passes 27°C.

Part 3: Temperature Controlled Fan (IN FREEDOM UNITS!!!)

Modify Part 1 so that it prints temperatures in Fahrenheit.

Deliverables:

During the lab:

In Online before next lab (7 marks):


5. References