Skip to content

Instantly share code, notes, and snippets.

@olizilla
Last active December 20, 2015 10:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olizilla/6114788 to your computer and use it in GitHub Desktop.
Save olizilla/6114788 to your computer and use it in GitHub Desktop.
Using the Adafruit motor shield to power chunky motors. If you don't get enough grunt from the motor *do not just run 2A through it*. Smoking occurs. see: http://learn.adafruit.com/adafruit-motor-shield
#include <AFMotor.h>
/*
Graccefully spin up, run, spin down and reverse a motor
*/
AF_DCMotor motor(2, MOTOR12_64KHZ); // create motor #2, 64KHz pwm
// FORWARD = 1, BACKEWARD = 2, RELEASE = 4
const int UP = 1;
const int DOWN = 2;
const int STOP = 4;
int spd = 0;
int minSpd = 0;
int maxSpd = 255;
int acceleration = 1;
int loopDelay = 50;
int pause = 3000;
unsigned long duration = 4000;
unsigned long time;
unsigned long lastTime;
unsigned long diffTime;
unsigned long maxStarted;
int topSwitchPin = 6;
int bottomSwitchPin = 3;
int lastSwitch; // which pin fired last.
// INITIAL DIRECTION AND SHOULD WE BE RUNNING. TODO: we need a switch to stop and reset.
int dir = UP;
boolean running = true;
void setup() {
time = millis();
Serial.begin(9600); // set up Serial library at 9600 bps
motor.setSpeed(0); // set the speed to 200/255
pinMode(topSwitchPin, INPUT);
pinMode(bottomSwitchPin, INPUT);
logState();
delay(2000);
logState();
}
void loop() {
if(running){
checkSwitches();
if (spd <= minSpd) { // At rest.
pauseThenReverse(); // Time to pause and reverse.
} else if (spd >= maxSpd) { // At max speed.
spd = maxSpd;
if(maxStarted == 0){ // We just got to maxSpeed so record the startTime.
maxStarted = millis();
Serial.print("Max start: ");
logState();
}
unsigned long currentMillis = millis();
if (currentMillis - maxStarted >= duration){ // time to start slowing down.
maxStarted = 0;
acceleration = acceleration * -1; // flip accel to decel.
changeSpeed();
Serial.print("Max stop: ");
logState();
}
} else { // accelerating / decelerating
changeSpeed();
delay(loopDelay);
}
}
}
void changeSpeed(){
spd = constrain(spd + acceleration, minSpd, maxSpd);
motor.setSpeed(spd);
}
// Switches signal that we've gone as far as we can and so force a pause and reverse.
void checkSwitches(){
checkSwitch(topSwitchPin, DOWN);
checkSwitch(bottomSwitchPin, UP);
}
// Switch helper method to reduce the boilerplate
void checkSwitch(int pin, int newDirection) {
int state = digitalRead(pin);
if (state == 0){
if (pin == lastSwitch){ return; } // ignore multiple fires of the same pin...
motor.run(STOP);
lastSwitch = pin;
Serial.print("Switching pin: ");
Serial.print(pin);
Serial.print(" new direction: ");
Serial.print(newDirection);
Serial.print(" ");
logState();
pauseThenGo(newDirection); // this delays for `pause`
}
}
void pauseThenReverse() {
if (dir == UP) {
pauseThenGo(DOWN);
} else {
pauseThenGo(UP);
}
}
void pauseThenGo(int newDirection) {
motor.run(STOP);
maxStarted = 0; // clean up just in case.
Serial.print("Stop: ");
logState();
dir = newDirection;
acceleration = acceleration * -1; // flip accel to decel.
delay(pause);
changeSpeed();
motor.run(dir);
Serial.print("Go: ");
logState();
}
void logState(){
Serial.print("Time: ");
lastTime = time;
time = millis();
diffTime = time - lastTime;
//prints time since program started
Serial.print(diffTime);
Serial.print(" spd:");
Serial.print(spd);
Serial.println();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment