0

PComp Week 4: Servo Motor Control, Tone Output with Arduino

Posted October 2nd, 2009 in ITP and tagged by Cindy

img_2857

First Lab: Servo Motor Control with Arduino.

Program an Arduino to make motion with a microcontroller called servo motor. The Arduino controlls the servomotor’s position with values returned from an analog sensor.

Disclaimer : Having no prior mechanical/tinkering knowledge prior to ITP, I was absolutely clueless to how to assemble the dissembled Servo Motor that came with my NYU lab parts kit. Instructions, please! Apparently, I spent nearly 2 hours thinking I had a coding or hardware issue that prevented me from completing this lab properly. The cause of misery? A servo motor whose top propeller head was attached too “loosely” to the screw and prevented it from circling it’s top.

Lesson learned: Set up the breadboard like a conventional circuit layout. Connected an analog input sensor (force sensor seen above) to Analog Pin 0 and a servo motor to Digital Pin 2. Don’t forget to supply the Servo Motor with a resistor and access to power bus row.

Coding: Had to learn the Pulse Method first before seeing the tidy Arduino coding that obscures the calculations under the hood.

/*

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 & Rob Faludi

Created 28 Jan. 2006

Updated 10 Jun. 2008

*/

int servoPin = 2;     // Control pin for servo motor

int minPulse = 500;   // Minimum servo position

int maxPulse = 2500;  // Maximum servo position

int pulse = 0;        // 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;  // the value returned from the analog sensor

int analogPin = 0;    // the analog pin that the sensor’s on

void setup() {

pinMode(servoPin, OUTPUT);  // Set servo pin as an output pin

pulse = minPulse;           // Set the motor position value to the minimum

Serial.begin(9600);

}

void loop() {

analogValue = analogRead(analogPin);      // read the analog input

pulse = map(analogValue,0,1023,minPulse,maxPulse);    // 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

}

}

Here’s in Tom’s lab notes: “This code was written with a potentiometer in mind, so it assumes you’re going to get values from 0 to 1023 from the sensor. If you don’t, the servo won’t move through its whole range. Determine the range of numbers the sensor is giving you and adjust the servo formula to fit. To fix this, use the map() function. You know the input range is the range of the sensor, 0 to 1023. And you know the output range is from minPulse to maxPulse.
Anyhoo, here’s the shorthand code.
/*
Servo control from an analog input using the Arduino Servo library. This example code uses the Arduino Servo library which comes packaged with the Arduino software. In order to make this work, you must include the Servo.h library file, create an instance of the Servo object.
attach a pin to the Servo object, and then write an analog value to the Servo object to set its
position.
The difference between using the Servo library and the older method of pulsing a digital pin is that the library
handles a lot of the work for you. You no longer need to figure out the translation between pulse length and position.
You now can simply specify the angle you’d like your servo to be at and it will turn to that position.
*/
Updated 08 Sep 2009
by Rory Nugent
Created 20 Jan 2009
by Tom Igoe
*/
#include <Servo.h>      // include the servo library
Servo servoMotor;       // creates an instance of the servo object to control a servo
int analogPin = 0;      // the analog pin that the sensor is on
int analogValue = 0;    // the value returned from the analog sensor
int servoPin = 2;       // Control pin for servo motor, may only be pin 9 or 10
void setup() {
servoMotor.attach(servoPin);  // attaches the servo on pin 2 to the servo object
}
void loop()
{
analogValue = analogRead(analogPin);                 // read the analog input (value between 0 and 1023)
analogValue = map(analogValue, 0, 1023, 0, 179);     // map the analog value (0 – 1023) to the angle of the servo (0 – 179)
servoMotor.write(analogValue);                       // write the new mapped analog value to set the position of the servo
delay(15);                                           // waits for the servo to get there
}

Tone Output with Arduino

img_2864

Tone Output Lab: Teaches folks how to output sound effects with the Arduino using the Tone Library, Analog Sensor, and a speaker. The Analog Sensor () would not work for this project, FYI, because hooking a speaker, an analog sensor, and Arduino would only work on the output volume and not the TONE.

Breadboard Layout: Notice the 2 photo sensors (variable resistors) that share a power outlet between them. The Photo sensors divide the voltage, therefore, there is no need for resistors to stem current flow since the two divvy it up between them (preventing a short circuit). The speaker is hooked up with wires leading from ground, power bus row. A resistor is used to stem voltage before it reaches the AnalogIn wire.

See it all on Video!:

Intro to Physical Computing: Servo Motor Control, Tone Output with Arduino from cindy wong on Vimeo.

Tone Output Code (Photo Cells in Setup in Above Photo)

*
Theremin

Plays tones based on a sensor reading uses Tone library by Brett Hagman

http://code.google.com/p/arduino-tone/

circuit:
* photoresistor from +5V to analog in 0
* photoresistor from analog pin 0 to ground
* 8-ohm speaker on digital pin 8

created 10 Sep 2009
by Tom Igoe
*/

#include
Tone noiseMaker; // instance of the tone library

void setup() {
// start the music:
noiseMaker.begin(8);
}

void loop() {
// get a sensor reading:
int sensorReading = analogRead(0);
// map the results from the sensor reading’s range
// to the desired pitch range:
int pitch = map(sensorReading, 200, 900, 100, 1000);
// change the pitch:
noiseMaker.play(pitch);
}

Tone Setup with 3 Variable Resistors (Pentiometers, below)


/*

circuit:

* 3 force-sensing resistors from +5V to analog in 0 through 5

* 3 10K resistors from analog in 0 through 5 to ground

* 8-ohm speaker on digital pin 8

*/

#include <Tone.h>

Tone noiseMaker;    // instance of the tone library

const int threshold = 10;    // minimum reading of the sensors that generates a note

// notes to play, corresponding to the 3 sensors:

int notes[] = {

NOTE_A4, NOTE_B4,NOTE_C4 };

void setup() {

// start the music:

noiseMaker.begin(8);

}

void loop() {

for (int thisSensor = 0; thisSensor < 3; thisSensor++) {

// get a sensor reading:

int sensorReading = analogRead(thisSensor);

// if the sensor is pressed hard enough:

if (sensorReading > threshold) {

// play the note corresponding to this sensor:

noiseMaker.play(notes[thisSensor]);

}

else {

// stop playing:

noiseMaker.stop();

}

}

}

Leave a Reply