SIK Experiment Guide for Arduino - V3.2
This Tutorial is Retired!
This tutorial covers concepts or technologies that are no longer current. It's still here for you to read and enjoy, but may not be as useful as our newest tutorials.
View the updated tutorial: SIK Experiment Guide for Arduino - V3.3
Experiment 12: Driving a Motor
Introduction
Back in experiment 8, you got to work with a servo motor. Now, we are going to tackle spinning a motor. This requires the use of a transistor, which can switch a larger amount of current than the RedBoard or Arduino Uno R3 can.
When using a transistor, you just need to make sure its maximum specs are high enough for your use case. The transistor we are using for this circuit is rated at 40V max and 200 milliamps max – perfect for our toy motor! When the motor is spinning and suddenly turned off, the magnetic field inside it collapses, generating a voltage spike. This can damage the transistor. To prevent this, we use a "flyback diode", which diverts the voltage spike around the transistor.
Parts Needed
You will need the following parts:
- 1x Breadboard
- 1x RedBoard or Arduino Uno
- 1x Motor
- 1x 330Ω Resistor
- 1x NPN transistor
- 1x Diode 1N4148
- 6x Jumper Wires
Didn't get the SIK?
If you are following through this experiment and didn't get the SIK, we suggest using these parts:
You will also need either a RedBoard or Arduino Uno R3.
Suggested Reading
Before continuing on with this experiment, we recommend you be familiar with the concepts in the following tutorial:
Hardware Hookup
Ready to start hooking everything up? Check out the Fritzing diagram below, to see how everything is connected.
Polarized Components | Pay special attention to the component’s markings indicating how to place it on the breadboard. Polarized components can only be connected to a circuit in one direction. |
Please note: When you’re building the circuit be careful not to mix up the transistor and the temperature sensor, they’re almost identical. Look for “P2N2222A” on the body of the transistor.
Fritzing Diagram for RedBoard
Fritzing Diagram for Arduino
Open the Sketch
Open Up the Arduino IDE software on your computer. Coding in the Arduino language will control your circuit. Open the code for Circuit 12 by accessing the “SIK Guide Code” you downloaded and placed into your “Examples” folder earlier.
To open the code go to: File > examples > SIK Guide Code > Circuit_12
You can also copy and paste the following code into the Arduino IDE. Hit upload, and see what happens!
language:cpp
/*
SparkFun Inventor's Kit
Example sketch 12
SPINNING A MOTOR
Use a transistor to spin a motor at different speeds.
We'll also show you how to input data from the serial port
(see the serialSpeed() function below).
Motors are the basis for thousands of things in our daily lives,
and the Arduino can control them. Here we'll use pulse-width
modulation (PWM) to vary the speed of a motor.
The Arduino pins are strong enough to light small LEDs (up to
40 milliAmps), but they're not strong enough to run motors and
other power-hungry parts. (This motor needs 50-100mA).
Because the motor needs more current than an Arduino pin can
provide, we'll use a transistor to do the heavy lifting.
A transistor is a solid-state switch. When we give it a small
amount of current, it can switch a much larger current.
The transistors in your kit (2N2222) can switch up to 200mA.
You can turn a transistor on and off using the digitalWrite()
function, but you can also use the analogWrite() function to
vary the speed of the motor. The analogWrite() function pulses
a pin, varying the width of the pulse from 0% to 100%. We call
this technique "PWM", for "Pulse-Width Modulation".
One thing to keep in mind is that when you lower the speed of
a motor using PWM, you're also reducing the torque (strength)
of the motor. For PWM values below 50 or so, the motor won't have
enough torque to start spinning. It will start spinning when you
raise the speed a bit.
Hardware connections:
Transistor:
The transistor has three pins. Looking at the flat side with the
pins down, the order is COLLECTOR, BASE, EMITTER.
Connect the black wire on the motor to the
COLLECTOR pin on the transistor.
Connect the BASE pin through a 330 Ohm resistor to
digital pin 9.
Connect the EMITTER pin to GND.
Motor:
You've already connected the black wire on the motor to the
COLLECTOR pin on the transistor.
Connect the other (red) wire on the motor to 5V.
Flyback diode:
When the motor is spinning and suddenly turned off, the
magnetic field inside it collapses, generating a voltage spike.
This can damage the transistor. To prevent this, we use a
"flyback diode", which diverts the voltage spike "around" the
transistor.
Connect the side of the diode with the band (cathode) to 5V
Connect the other side of the diode (anode) to the black wire
on the motor.
This sketch was written by SparkFun Electronics,
with lots of help from the Arduino community.
This code is completely free for any use.
Visit http://learn.sparkfun.com/products/2 for SIK information.
Visit http://www.arduino.cc to learn about the Arduino.
Version 2.0 6/2012 MDG
*/
// We'll be controlling the motor from pin 9.
// This must be one of the PWM-capable pins.
const int motorPin = 9;
void setup()
{
// Set up the motor pin to be an output:
pinMode(motorPin, OUTPUT);
// Set up the serial port:
Serial.begin(9600);
}
void loop()
{
// Here we've used comments to disable some of the examples.
// To try different things, uncomment one of the following lines
// and comment the other ones. See the functions below to learn
// what they do and how they work.
// motorOnThenOff();
// motorOnThenOffWithSpeed();
// motorAcceleration();
serialSpeed();
}
// This function turns the motor on and off like the blinking LED.
// Try different values to affect the timing.
void motorOnThenOff()
{
int onTime = 3000; // milliseconds to turn the motor on
int offTime = 3000; // milliseconds to turn the motor off
digitalWrite(motorPin, HIGH); // turn the motor on (full speed)
delay(onTime); // delay for onTime milliseconds
digitalWrite(motorPin, LOW); // turn the motor off
delay(offTime); // delay for offTime milliseconds
}
// This function alternates between two speeds.
// Try different values to affect the timing and speed.
void motorOnThenOffWithSpeed()
{
int Speed1 = 200; // between 0 (stopped) and 255 (full speed)
int Time1 = 3000; // milliseconds for speed 1
int Speed2 = 50; // between 0 (stopped) and 255 (full speed)
int Time2 = 3000; // milliseconds to turn the motor off
analogWrite(motorPin, Speed1); // turns the motor On
delay(Time1); // delay for onTime milliseconds
analogWrite(motorPin, Speed2); // turns the motor Off
delay(Time2); // delay for offTime milliseconds
}
// This function slowly accelerates the motor to full speed,
// then back down to zero.
void motorAcceleration()
{
int speed;
int delayTime = 20; // milliseconds between each speed step
// accelerate the motor
for(speed = 0; speed <= 255; speed++)
{
analogWrite(motorPin,speed); // set the new speed
delay(delayTime); // delay between speed steps
}
// decelerate the motor
for(speed = 255; speed >= 0; speed--)
{
analogWrite(motorPin,speed); // set the new speed
delay(delayTime); // delay between speed steps
}
}
// This function will let you type a speed into the serial
// monitor window. Open the serial monitor using the magnifying-
// glass icon at the top right of the Arduino window. Then
// type your desired speed into the small text entry bar at the
// top of the window and click "Send" or press return. The motor
// will then operate at that speed. The valid range is 0 to 255.
void serialSpeed()
{
int speed;
Serial.println("Type a speed (0-255) into the box above,");
Serial.println("then click [send] or press [return]");
Serial.println(); // Print a blank line
// In order to type out the above message only once,
// we'll run the rest of this function in an infinite loop:
while(true) // "true" is always true, so this will loop forever.
{
// First we check to see if incoming data is available:
while (Serial.available() > 0)
{
// If it is, we'll use parseInt() to pull out any numbers:
speed = Serial.parseInt();
// Because analogWrite() only works with numbers from
// 0 to 255, we'll be sure the input is in that range:
speed = constrain(speed, 0, 255);
// We'll print out a message to let you know that the
// number was received:
Serial.print("Setting speed to ");
Serial.println(speed);
// And finally, we'll set the speed of the motor!
analogWrite(motorPin, speed);
}
}
}
Code To Note
while (Serial.available() > 0)
The Arduino's serial port can be used to receive as well as send data. Because data could arrive at any time, the Arduino stores, or "buffers" data coming into the port until you're ready to use it. The Serial.available()
command returns the number of characters that the port has received, but haven't been used by your sketch yet. Zero means no data has arrived.
speed = Serial.parseInt();
If the port has data waiting for you, there are a number of ways for you to use it. Since we're typing numbers into the port, we can use the handy Serial.parseInt()
command to extract, or "parse" integer numbers from the characters it's received. If you type "1" "0" "0" to the port, this function will return the number 100.
What You Should See
The DC Motor should spin if you have assembled the circuit’s components correctly, and also verified/uploaded the correct code. If your circuit is not working check the troubleshooting section.
Real World Application
Radio Controlled (RC) cars use Direct Current (DC) motors to turn the wheels for propulsion.
Troubleshooting
Motor Not Spinning
If you sourced your own transistor, double check with the data sheet that the pinout is compatible with a P2N2222AG (many are reversed).
Still No Luck
If you sourced your own motor, double check that it will work with 5 volts and that it does not draw too much power.
Still Not Working
Sometimes the Arduino will disconnect from the computer. Try un-plugging and then re-plugging it into your USB port.