You are on page 1of 9

Physical Computing Prof.

Fabian Winkler Spring 2008

Arduino Workshop Output


Similar to sensor input, there are also two main types of output from the Arduino board 1. digital output (I/O pins 0-13) 2. PWM (pulse-width modulated) output (pins 3, 5,6,9,10 and 11 on the Arduino Diecimila) Digital output can be only in either one of the two states: ON (outputting +5V) or OFF (connected to GND, outputting 0V) PWM outputs create control signals of variable strength by pulsing the output rapidly between 0 and 5V. They do not create a variable voltage ranging from 0-5V but ON/OFF pulses the length of which determines the speed at which a motor spins, the brightness of a lamp, the angle of a robotic arm, etc for more information on PWM output see Physical Computing pp. 112-115. DC Motor Control with a power transistor The Arduinos output pins can only supply (sink or source) a very weak current of approx. 20mA. This means that you cannot connect a larger load (such as a motor, larger number of LEDs, relay, etc.) directly to the output pin. You need an amplifier that is connected to the pin. For smaller loads a regular NPN2222 switching transistor works (up to 200mA current) for larger loads you should consider a power transistor such as the TIP120 (collector current up to 5A, or pulsed up to 8A)

A very simple Arduino controlled TIP120 circuit would look like this:

You can get the +9V voltage directly from the Vin pin on your Arduino (as long as you use a (V power supply of course). If you need a +5V voltage, use one of your 7805 voltage regulators to convert the output from your 9V power supply to +5V. Please look at the section power supply decoupling on p. 254 in Physical Computing if you intend to driver larger loads (multiple LEDs, high brightness LEDs, motors, relays, etc) DC motor control with a SN754410 motor driver IC The SN754410 is a handy IC that allows you to control the speed and direction of a DC motor with only one PWM output and two digital outputs from your Arduino board

Please read pp.255 -260 in Physical computing for how to use the SN754410 motor driver IC with a microcontroller. In the following example we will control a DC motor with a potentiometer. The first half of the 270 degree turning angle of the potentiometer will make the motor run forward. The motors speed will decrease the more the knob is turned toward the potentiometers center position. The second half of the turning angle will make the motor run in reverse,
Winkler, Arduino workshop output, p.2

with increasing speed toward the 270 mark. the percentages in the following picture are related to the motors speed.

Here is the Arduino code: /* * Arduino code for SN754410 H-bridge * motor driver control. A potentiometer's * 270 degree rotational angle is used to * control a DC motor in the following way: * 0-135 degrees - motor runs forward, speed * getting slower the higher the angle, motor * stops at 135 degrees. * 135-270 degrees: motor runs backward, * speed is getting faster the higher the * angle, motor speed is 0 at 135 degrees. * * copyleft Feb. 2008, Fabian Winkler * */ int potPin = 0; int speedPin = 3; int motor1Pin = 6; int motor2Pin = 7; int ledPin = 13; int val = 0; potentiometer void setup() { // set digital i/o pins as outputs: pinMode(speedPin, OUTPUT); pinMode(motor1Pin, OUTPUT); pinMode(motor2Pin, OUTPUT); pinMode(ledPin, OUTPUT); } void loop() { digitalWrite(ledPin, HIGH); // status LED is always on
Winkler, Arduino workshop output, p.3

// // // // // //

analog input pin 0 for the potentiometer H-bridge enable pin for speed control H-bridge leg 1 H-bridge leg 2 status LED variable to store the value coming from the

val = analogRead(potPin); val = val/4;

// read the value from the potentiometer // convert 0-1023 range to 0-255 range

if (val <= 127) { // put motor in forward motion digitalWrite(motor1Pin, LOW); digitalWrite(motor2Pin, HIGH);

// set leg 1 of the H-bridge low // set leg 2 of the H-bridge high

// control speed based on angle of potentiometer analogWrite(speedPin, 254-(val*2)); // output speed as PWM value // this value needs to go from 254 to 0 for input values //from 0 to 127 } // put motor in backward motion else { digitalWrite(motor1Pin, HIGH); digitalWrite(motor2Pin, LOW);

// set leg 1 of the H-bridge high // set leg 2 of the H-bridge low

// control speed based on angle of potentiometer analogWrite(speedPin, (val*2)-256); // output speed as PWM value // this value needs to go from 0 to 254 for input values // from 128 to 255 } } The following is a circuit diagram for the project

Winkler, Arduino workshop output, p.4

And this is one possibility how it can look like on your breadboard:

Regular DC Motors vs. Gearbox Motors In most of your application when a rotary movement is necessary you will need force (torque) over speed. In this case, use a gearbox motor instead of a regular DC motor. The gearbox attached to a motors output shaft amplifies its torque and slows down its speed. If you are using a regular DC motor and adjust its speed with the Arduinos PWM output you will just slow down its speed and reduce its torque! Consider hacking a servo motor for an inexpensive continuously rotating gear motor (see: http://www.seattlerobotics.org/guide/servohack.html) rather than purchasing a regular gearbox motor. In most cases this technique will saved you half the cost. Servo Motor Control Look at pp.121-123 in our course book Physical Computing for a description of servo motors. You should also read What is a servo from the Seattle Robotics Society, http://www.seattlerobotics.org/guide/servos.html

Winkler, Arduino workshop output, p.5

The following is from the Seattle Robotics Societys intro to servo motors. It describes timing, the most important aspect of controlling a servo motors 180 degree movement with a microcontroller: How do you communicate the angle at which the servo should turn? The control wire is used to communicate the angle. The angle is determined by the duration of a pulse that is applied to the control wire. This is called Pulse Coded Modulation. The servo expects to see a pulse every 20 milliseconds (.02 seconds). The length of the pulse will determine how far the motor turns. A 1.5 millisecond pulse, for example, will make the motor turn to the 90 degree position (often called the neutral position). If the pulse is shorter than 1.5 ms, then the motor will turn the shaft to closer to 0 degrees. If the pulse is longer than 1.5ms, the shaft turns closer to 180 degrees.

As you can see in the picture, the duration of the pulse dictates the angle of the output shaft (shown as the green circle with the arrow). Note that the times here are illustrative, and the actual timings depend on the motor manufacturer. The principle, however, is the same. You can start with a range from 1000-2000ms and then work your way toward 500ms to 2500ms. Powering your servo The servo doesn't need a regulated power supply. You can use any power supply between 4.5V and 6V to power the servo (however, keep in mind that if you power the servo from a power supply of less than +5V, that you will need to put a 1kOhm resistor between the I/O line and the servo's control line. If you plan to use the same power supply for the Arduino and the servo, make sure that it can supply at 1000mA of current servos can be quite power-demanding! If you are using two different power supplies, one for the Arduino and one for the servo make sure to connect both grounds (GND) together. A simple example In this simple example we connect a potentiometer to one of the Arduinos analog inputs. The turning of the potentiometers knob should result in a proportional turning of the servos output shaft.
Winkler, Arduino workshop output, p.6

If you notice an unsteady or jerky behavior of the servo motors output, put a 0.1!F capacitor between the Arduinos analog pin 2 and GND. this will smooth out any possible voltage spikes from the potentiometer.

Here is the Arduino code: /* Servo control from an analog input The minimum (minPulse) and maxiumum (maxPulse) values will be different depending on your specific servo motor. Ideally, it should be between 1 and 2 milliseconds, but in practice, 0.5 - 2.5 milliseconds works well for me. Try different values to see what numbers are best for you. This program uses the millis() function to keep track of when the servo was last pulsed. millis() produces an overflow error (i.e. generates a number that's too big to fit in a long variable) after about 5 days. if you're making a program that has to run for more than 5 days, you may need to account for this. by Tom Igoe additions by Carlyn Maw Created 28 Jan. 2006
Winkler, Arduino workshop output, p.7

Updated 7 Jun. 2006 */ int int int int servoPin = 7; minPulse = 1000; maxPulse = 2000; pulse = 0; // Control pin for servo motor // Minimum servo position // Maximum servo position // Amount to pulse the servo

long lastPulse = 0; // the time in milliseconds of the last pulse int refreshTime = 20; // the time needed in between pulses int analogValue = 0; int analogPin = 2; // the value returned from the analog sensor // the analog pin that the potentiometer's on // Set servo pin as an output pin // Set the motor position value to the // minimum

void setup() { pinMode(servoPin, OUTPUT); pulse = minPulse; Serial.begin(9600); }

void loop() { analogValue = analogRead(analogPin); // read the analog input pulse = (analogValue * 19) / 10 + minPulse; // convert the analog // value // to a range between // minPulse // and maxPulse. // pulse the servo again if rhe refresh time (20 ms) have passed: if (millis() - lastPulse >= refreshTime) { digitalWrite(servoPin, HIGH); // Turn the motor on delayMicroseconds(pulse); // Length of the pulse sets the motor position digitalWrite(servoPin, LOW); // Turn the motor off lastPulse = millis(); // save the time of the last pulse } } If you have hacked a servo into a continuously rotating gearbox motor, remember that you will need to control it with a SN754410 and the Arduino code on pp. 3/4! What to do with motors? Please read pp.271-283 Basic Mechanics in our course book Physical Computing Using relays to turn things on and off See Physical Computing p.101 In addition, I have received very good results with the OMRON G5LE-1 5VDC relay from Jameco (part number # 187151) it has contact rating of up to 10A at 120VAC/30VDC and thus would let you easily control light bulbs, larger AC motors, fans, etc.

Winkler, Arduino workshop output, p.8

Further Output Additional interesting output options such as sound, light, video, video control are discussed in our course book Physical Computing in Chapter 13 (read specifically pp.366-379)

Winkler, Arduino workshop output, p.9

You might also like