Description
Arduino Pot-controlled Servo Motorcycle: TermiCycle
For this lab, I created a motorcycle that is controlled by a potentiometer. A fork is attached to a Servo Motor rotor, which is attached in the middle of a “car” (a square) consisting of 2 spoons taped together to form the sides, connected with plastic lids at the front and back. The head of the fork is taped to half of a fat broken ice cycle stick. The tape in the middle acts as an extended rotor, with openings on either side of the tape at the fork/stick front and back. A twisty tie connects around the servo base, eventually coming through the two holes of the tape and connecting together.
The twisty tie can be tightened to move the fork/stick back if the motorcycle runs lopsided. Additionally, the stick can be adjusted to the left or right to allow adjustment of the fork’s pricks (whether the left most prick or the right one touches first).
In the serial port, if “a” is pressed, the motor switches to automatic mode, allowing constant rotation. The Pulsewidth variable starts moving the rotor counterclockwise, pushing it forward. A counter variable then starts counting up to a threshold (currently 5000), allowing the rotor to continue the forward motion until the counter gets to its threshold, then returns to the original state. The threshold to return is slightly less (at 4000) because there is less load on the server due to not pushing anything and therefore returns faster. A fork in the opposite direction (pushed down with a cardboard piece acting as a spring) keeps the motorcycle positionary against the returning motor’s backward force.
Components Used
1- Arduino Board
1 – Potentiometer
1 – Motorcycle: 2 plastic coffee lids, 4 plastic spoons, 2 plastic forks, 1 Servo Motor, 1 ice-cream stick, 1 cardboard cutout acting as a spring, 1 twistie tie
1– Breadboard
Connecting wires
2 – Paper cutout of Terminator Salvation motorcycle, shaped into a mockup
Code
/* TermiCyle
* Servo with Potentiometer control and Automatic Feature
* Theory and Practice of Tangible User Interfaces
* October 29, 2013
* Use potentiometer to control speed of motorcycle contraption (fork attached to rotor)
* Press "a" to shift to Automatic On. As long as there is voltage from servo, will go fast
* Press a again to turn off.
*/
int servoPin = 7; // Control pin for servo motor
int potPin = 0; // select the input pin for the potentiometer
int pulseWidth = 0; // Amount to pulse the servo
long lastPulse = 0; // the time in millisecs of the last pulse
int refreshTime = 20; // the time in millisecs needed in between pulses
int val; // variable used to store data from potentiometer
int minPulse = 500; // minimum pulse width
boolean automatic = false; //control by pot (false) or continuous run (true)
int keyboard; //input read from serial port
boolean onFirstIteration = true; //first iter. is pushing motor forward, 2nd is returning
int counter = 0; //used to allow updateServo() time to push rotor.
void setup() {
pinMode(servoPin, OUTPUT); // Set servo pin as an output pin
pulseWidth = minPulse; // Set the motor position to the minimum
Serial.begin(9600); // connect to the serial port
Serial.println("servo_serial_better ready");
}
void loop() {
val = analogRead(potPin); // read the value from the sensor, between 0 - 1024
keyboard = Serial.read();
if (keyboard == 'a'){ //if pressing 'a' in serial read entry, cycle automatic feature
if (automatic == false)
{
Serial.println("Automatic on");
automatic = true;
pulseWidth = 0 * 2 + minPulse; //moves to maximum to reach in front
Serial.println("PulseWidth: ");
Serial.println(pulseWidth);
}
else{
Serial.println("Automatic off");
automatic = false;
}
}
if (val > 0 && val <= 999 ) {
//if you are not automatic, use the pot
if (!automatic){
pulseWidth = val*2 + minPulse; // convert angle to microseconds
Serial.print("moving servo to ");
Serial.println(pulseWidth,DEC);
}
else{ //in automatic
//push the motor forward
if(onFirstIteration && counter > 4000){ //# is how soon after "PUSHING" the rotor will return
Serial.println("About to start first iteration");
pulseWidth = minPulse; //maximum reaching forward posn
onFirstIteration = false;
counter = 0;
}
//return the motor back to ready
else if (!onFirstIteration && counter > 5000){
Serial.println("About to start second iteration");
pulseWidth = 999 * 2 + minPulse;
onFirstIteration = true;
counter = 0;
}
counter++; //will cycle the counter up to setpoint => ready to activate motor again.
}
}
updateServo(); // update servo position
}
// called every loop().
void updateServo() {
// pulse the servo again if the refresh time (20 ms) has passed:
if (millis() - lastPulse >= refreshTime) {
digitalWrite(servoPin, HIGH); // Turn the motor on
delayMicroseconds(pulseWidth); // Length of the pulse sets the motor position
digitalWrite(servoPin, LOW); // Turn the motor off
lastPulse = millis(); // save the time of the last pulse
}
}
- Login to post comments