Lab 5: Motors

Topics

1. First Build
2. Hardware Theory
1. Voltage Division
2. Introduction to Higher Current Devices
3. Temperature Sensor
3. Software Theory
4. Exercises

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:

• Diode:  black with a gray stripe on negative end. It looks like it's backward in this diagram, but it serves an important purpose.
• Transistor: Different transistors have different pin orientations. You must determine what sort of transistor you have and what its orientation should be. Use your google-fu.
• Motor: it doesn't matter which wire goes where. Swapping wires changes the motor's direction of rotation.

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:

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.

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:

• Set it to either 2000µ or 20m.

• The first represents currents up to 2mA or 2000µA.
• The second represents currents up to 20mA.
• Current is measured in a circuit by inserting the leads of the multimeter into the circuit.
• Disconnect  the ground wire from your circuit.
• Touch the red probe to the end of the last resistor in your circuit.
• Touch the black probe to the grounding wire.
• Caution: there is a fuse in your multimeter that will blow if you measure current incorrectly. If you are going to measure a current of over 200mA (like the current between 5V and Ground) you must be in the 10A mode. If not, your multimeter will stop measuring current.
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:
• Set it to 20 in the DC Voltage section (V with Solid and dashed lines above).
• This represents voltages up to 20V.

• Touch the red and black probes to the positive and negative sides to wires in your active circuit on either side of where you want to measure a voltage difference or drop.

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 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.

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.

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!

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

• Conversion factor: A 10mV change in this component is equivalent to a 1°C change in temperature. That means there's 0.01 V/°C. To convert from Volts to Celsius you need to invert that value: 100°C/V
• Offset: 0V represents -50°C. We have an offset of -50°C.
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);`
• returnDataType: If a function is a value returning function, the returnDataType will be something like int, float, or char and so on. If the function is a command that does not return any value, we use the word void for the return data type.
• functionName: this is what you will call your function. It should begin with a letter. After that it can contain letter, numbers and underscores but not spaces.
• ParameterList: a comma separated list of data types and variable names. These are the slots for arguments to the function. You can have no parameters, or several.

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

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

void loop()
{
float volts;

Serial.println(volts);
}

// Function Definition
{
float volts;
volts = reading/1023.0 * 5.0;  //Perform conversion
return volts; //Return result
}
```

4. Exercises

Part 1: Voltage Division

• Using your multimeter, measure the voltage drop from the indicated points, V1 and V2, to ground.
• Write a voltmeter sketch:
• read analog values from A1
• convert them to float type volt values using the AnalogToVolts() function from the notes
• print the result to the serial monitor
• use a long wire attached to A1 to probe the circuit. See if the values you see in the serial monitor match your previous observations.
• demonstrate your sketch to the lab instructor.
• After the lab:
• Use Ohm's law to confirm that your measurements are close to the theoretical values. Please show your work.
• Submit your observed and calculated values for V1 and V2 online.

Part 2:  Temperature Controlled Fan

In this exercise you will build a "fan" that turns on when the temperature passes 27°C.
• Add a temperature sensor to the First Build circuit and connect its output to pin A1. Again, BE SURE TO PLUG THIS IN CORRECTLY!
• Modify your part 1 sketch so it:
• converts the volt value of the reading on pin A1 from volts to a temperature in degrees Celsius
• prints the temperature to the Serial Monitor
• turns on the "fan" (motor with visual aid) if that temperature is higher than 27°C. The fan should be off otherwise.
• Test your sketch. Demonstrate it to the lab instructor if you have any questions.
• Use your own body heat to activate the sensor.
• Reduce the threshold if you can't warm the sensor enough to turn on the "fan"
• When the fan turns on, do you notice anything about the readings your temperature sensor gives? (If you don't notice anything try another power supply.) What do you think is happening? How would you solve this?

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

Modify Part 1 so that it prints temperatures in Fahrenheit.
• Use a value returning function to do the conversion.
According to Wikipedia the formula to convert Celsius to Fahrenheit is:
°F = °C × 95 + 32
Beware of integer roundoff errors!
• Demonstrate your sketch to the lab instructor.

Deliverables:

During the lab:

• Screenshots / Pictures / Copy-paste of: (3 marks):