Project 011
From keywoniki
Contents |
[edit] Input, Sensing, Feedback
For MAS961-2009, "How to Make Something That Makes (Almost) Anything" class.
[edit] Sketches
Three examples to sense and correct displacement:
- Strip
- Bottle
- Building blocks
[edit] Evil Bottle
On average Americans are exposed to 300,000 logos and brand impressions a day.
Imagine a bottle whose branding and marketing label follows you, as you twist open the bottle...
Most recent video: http://www.vimeo.com/3537834
How the circuit works
Bottlecap is connected to a potentiometer which drives a servo motor and turns the rest of the bottle.
[edit] Schematic
[edit] Voltage Divider
[edit] Voltage Divider with Arduino
[edit] Read Voltage in
02 - analogread voltage
/*
Analog read in voltage divider output
By Keywon Chung
keywon@media.mit.edu
Last revision 2009-03-07
5v coming out of arduino digital pin 3
voltage divided by a 10k resistor and a 10K pot
output from the 10k pot to see 0-2.5v (0-2.41v in reality) is fed into analog in pin 5
*/
int vccPin = 3;
int potPin = 5;
int potValue = 0;
void setup() {
Serial.begin(9600);
pinMode(vccPin, OUTPUT);
}
void loop() {
// set Vcc at 5v (4.8v in reality)
digitalWrite(vccPin, HIGH);
// read the divided voltage from potentiometer (approx 0-2.4v)
potValue = analogRead(potPin);
// send value to servproxy
Serial.print(potValue);
// just for readability
Serial.print(" ");
}
Output: 0-498 range (about half of 0-1024, 2^10-bit resolution)
Code added in loop() to convert 0-498 to 0-300 degrees:
potValue = 0.6 * potValue;
Output: 0-299 range (about half of 0-1024, 2^10-bit resolution)
[edit] Drive LED
/*
Analog read in voltage divider output
By Keywon Chung
keywon@media.mit.edu
Last revision 2009-03-07
5v coming out of arduino digital pin 3
voltage divided by a 10k resistor and a 10K pot
output from the 10k pot to see 0-2.5v (0-2.41v in reality) is fed into analog in pin 5
*/
int vccPin = 3;
int potPin = 5;
int potValue = 0;
int ledPin = 11; // pwm pin for gradual on and off
void setup() {
Serial.begin(9600);
pinMode(vccPin, OUTPUT);
}
void loop() {
// set Vcc at 5v (4.8v in reality)
digitalWrite(vccPin, HIGH);
// read the divided voltage from potentiometer (approx 0-2.4v)
potValue = analogRead(potPin);
// convert 0-498 analog in reading to 0-300 degrees
potValue = 0.6 * potValue;
if (potValue > 255) {potValue = 255;}
analogWrite(ledPin, potValue);
// send value to servproxy
Serial.print(potValue);
// just for readability
Serial.print(" ");
}
[edit] Drive Servo
- Download servo library and save it in Arduino0XX > hardware > libraries > (Servo > Servo.o, Servo.cpp, Servo.h)
Used MX-50HP servo http://www.acroname.com/robotics/parts/R28-MX-50HP.html
/*
Fake PID:
Read in voltage divider output from a potentiometer
turn servo to a matching angle to the pot
By Keywon Chung
keywon@media.mit.edu
Last revision 2009-03-07
5v coming out of arduino digital pin 3
voltage divided by a 10k resistor and a 10K pot
voltage drop acress the 10k pot (0- 2.5v, 0-2.41v in reality) is fed into analog in pin 5
voltage reading is converted to 0 - 300 degree angles
the angle is passed onto the servo
*/
#include <Servo.h>
int vccPin = 3;
int potPin = 5;
int potValue = 0;
int ledPin = 11; // pwm pin
int ledValue = 0;
int servoAngle = 0;
// create servo object to control a servo
// a maximum of eight servo objects can be created
Servo myservo1;
void setup() {
Serial.begin(9600);
pinMode(vccPin, OUTPUT);
// attaches the servo on pin 6 to the servo object: pwm pin
myservo1.attach(6);
}
void loop() {
// set Vcc at 5v (4.8v in reality)
digitalWrite(vccPin, HIGH);
// read the divided voltage from potentiometer (approx 0-2.4v)
// this outputs about 0 - 500 (half of 0 - 1024)
potValue = analogRead(potPin);
// convert 0-500 analog in reading to 0-360 degrees
// and then invert it, because turning pot clockwise turns the servo ccw
// pot itself can only turn about 280 degrees, so subtract the desired angle from 280
servoAngle = 280 - (0.72 * potValue);
servoAngle = 0.7 * servoAngle; // just manual speed compensation
myservo1.write(servoAngle);
// convert 0-500 to 0-255
ledValue = potValue/5 * 2.5;
analogWrite(ledPin, ledValue);
// send value to servproxy
Serial.print(potValue);
// just for readability
Serial.print(" ");
myservo1.refresh();
delay(20);
}
[edit] Time Lag
Code is still work in progress...
/*
Fake PID:
Read in voltage divider output from a potentiometer
turn servo to a matching angle to the pot
By Keywon Chung
keywon@media.mit.edu
Last revision 2009-03-07
5v coming out of arduino digital pin 3
voltage divided by a 10k resistor and a 10K pot
voltage drop acress the 10k pot (0- 2.5v, 0-2.41v in reality) is fed into analog in pin 5
voltage reading is converted to 0 - 300 degree angles
the angle is passed onto the servo
*/
#include <Servo.h>
int vccPin = 3;
int potPin = 5;
int potValue = 0;
int ledPin = 11; // pwm pin
int ledValue = 0;
int servoAngle = 0;
int oldAngle = -10;
int loopCount = 0;
// create servo object to control a servo
// a maximum of eight servo objects can be created
Servo myservo1;
void setup() {
Serial.begin(9600);
pinMode(vccPin, OUTPUT);
// attaches the servo on pin 6 to the servo object: pwm pin
myservo1.attach(6);
}
void loop() {
// set Vcc at 5v (4.8v in reality)
digitalWrite(vccPin, HIGH);
// read the divided voltage from potentiometer (approx 0-2.4v)
// this outputs about 0 - 500 (half of 0 - 1024)
potValue = analogRead(potPin);
// convert 0-500 analog in reading to 0-360 degrees
// and then invert it, because turning pot clockwise turns the servo ccw
// pot itself can only turn about 280 degrees, so subtract the desired angle from 280
servoAngle = 280 - (0.72 * potValue);
servoAngle = 0.7 * servoAngle; // just manual speed adjustment
// turn servo only when pot has turned above a threshold
// 10 degree difference within 60 millisecond (3 loops)
if (loopCount == 3) {
if (servoAngle - oldAngle > 20 || oldAngle - servoAngle > 20) {
//delay(500);
myservo1.write(servoAngle);
oldAngle = servoAngle;
}
loopCount = 0;
}
// convert 0-500 to 0-255
ledValue = potValue/5 * 2.5;
analogWrite(ledPin, ledValue);
// send value to servproxy
Serial.print(potValue);
// just for readability
Serial.print(" ");
myservo1.refresh();
delay(20);
loopCount++;
}

