Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
LinearMotion.cpp
- Committer:
- stretch
- Date:
- 2012-04-28
- Revision:
- 0:3058939fa37c
- Child:
- 1:cf60b60a1b5b
File content as of revision 0:3058939fa37c:
#include "LinearMotion.h"
#define STEPS_PER_PIXEL 600
#define Z_STEPS_PER_PIXEL 960
#define STEP_BUFFER 4 // Make a gap of STEPS_PER_PIXEL/STEP_BUFFER between each pixel
#define INITIAL_DELAY 1200 // in us
void LinearMotion::setStepMotors(Stepper * s1, Stepper * s2, Stepper * s3, DigitalOut * solenoid, bool * pause, bool * stop) {
_sol = solenoid;
StepMotor[0] = s1;
StepMotor[1] = s2;
StepMotor[2] = s3;
reversing = false;
_paused = pause;
_stopped = stop;
}
void LinearMotion::interpolate(Vector length, int maxSpeed) {
interpolate(length, maxSpeed, false);
}
void LinearMotion::interpolate(Vector length, int maxSpeed, bool solenoidOn) {
long tempLength;
Stepper * tempStep;
Stepper * reorderedStepMotor[3] = {StepMotor[0], StepMotor[1], StepMotor[2]};
_z = false;
if (abs(length.y) > abs(length.x)) {
tempLength = length.y;
length.y = length.x;
length.x = tempLength;
tempStep = reorderedStepMotor[1];
reorderedStepMotor[1] = reorderedStepMotor[0];
reorderedStepMotor[0] = tempStep;
}
if (abs(length.z) > abs(length.x)) {
tempLength = length.z;
length.z = length.x;
length.x = tempLength;
tempStep = reorderedStepMotor[2];
reorderedStepMotor[2] = reorderedStepMotor[0];
reorderedStepMotor[0] = tempStep;
_z = true;
}
enableSteppers(true);
doLinear(length, reorderedStepMotor, maxSpeed, solenoidOn);
enableSteppers(false);
}
void LinearMotion::interpolateSquare(Vector basePos, Vector heightPos, int maxSpeed, bool solenoidOn) {
long tempLength;
Stepper * tempStep;
Stepper * reorderedStepMotor[3] = {StepMotor[0], StepMotor[1], StepMotor[2]};
Vector homePosition = {-heightPos.x, -heightPos.y, -heightPos.z};
_z_slantways = false;
if (abs(heightPos.y) > abs(heightPos.x)) {
tempLength = heightPos.y;
heightPos.y = heightPos.x;
heightPos.x = tempLength;
tempStep = reorderedStepMotor[1];
reorderedStepMotor[1] = reorderedStepMotor[0];
reorderedStepMotor[0] = tempStep;
}
if (abs(heightPos.z) > abs(heightPos.x)) {
tempLength = heightPos.z;
heightPos.z = heightPos.x;
heightPos.x = tempLength;
tempStep = reorderedStepMotor[2];
reorderedStepMotor[2] = reorderedStepMotor[0];
reorderedStepMotor[0] = tempStep;
_z_slantways = true;
}
if (solenoidOn)
_bmp.openImg("/local/pic.bmp");
reversing = false;
enableSteppers(true);
doLinearSideways(heightPos, basePos, reorderedStepMotor, maxSpeed, solenoidOn);
if (solenoidOn)
_bmp.closeImg();
if (reversing) {
homePosition.x -= basePos.x;
homePosition.y -= basePos.y;
homePosition.z -= basePos.z;
}
interpolate(homePosition, maxSpeed);
}
void LinearMotion::doLinearSideways(Vector delta, Vector nextRow,
Stepper ** stepMotor, int maxSpeed, bool solenoidOn) {
int fxy,fxz;
int rowLoc = 0;
int delay = INITIAL_DELAY;
int delayPos = 0;
Vector lastRow = {-nextRow.x, -nextRow.y, -nextRow.z};
Vector dir = {1, 1, 1};
long stepsPerPixel;
_z_slantways ? stepsPerPixel = Z_STEPS_PER_PIXEL : stepsPerPixel = STEPS_PER_PIXEL;
if(delta.x < 0)
dir.x = 0; //towards motor
if(delta.y < 0)
dir.y = 0; //towards motor
if(delta.z < 0)
dir.z = 0; //towards motor
delta.x = abs(delta.x);
delta.y = abs(delta.y);
delta.z = abs(delta.z);
fxy = delta.x - delta.y;
fxz = delta.x - delta.z;
Vector curPos = {0, 0, 0};
while(!(*_stopped) && (curPos.x<=delta.x) && (curPos.y<=delta.y) && (curPos.z<=delta.z)){
// printf("Moving height: %d, %d, %d\n\r", curPos.x, curPos.y, curPos.z);
if ((curPos.x % stepsPerPixel) == 0) {
Vector * row = NULL;
if (solenoidOn)
_bmp.setRow(rowLoc++);
if (!(solenoidOn && _bmp.isBlankRow())) {
reversing ? row = &lastRow : row = &nextRow;
interpolate(*row, maxSpeed, solenoidOn);
reversing = !reversing;
enableSteppers(true); // Hacky
}
}
++curPos.x;
if ((curPos.x % stepsPerPixel) <= stepsPerPixel/2) {
delayPos++;
delay = delayTime(delay, delayPos);
} else {
delayPos--;
delay = delayTime(delay, -delayPos);
}
stepMotor[0]->stepOn(dir.x);
fxy -= delta.y;
fxz -= delta.z;
if(fxy <= 0){
++curPos.y;
stepMotor[1]->stepOn(dir.y);
fxy += delta.x;
}
if(fxz <= 0){
++curPos.z;
stepMotor[2]->stepOn(dir.z);
fxz += delta.x;
}
wait_us(1);
stepMotor[0]->stepOff();
stepMotor[1]->stepOff();
stepMotor[2]->stepOff();
wait_us(delay);
while(*_paused) {;}
}
}
void LinearMotion::doLinear(Vector delta, Stepper** stepMotor, int maxSpeed, bool solenoidOn) {
int fxy,fxz;
int pixelLoc = 0;
int delay = INITIAL_DELAY;
int farthestDelay = 0;
Vector dir = {1, 1, 1};
long stepsPerPixel;
_z ? stepsPerPixel = Z_STEPS_PER_PIXEL : stepsPerPixel = STEPS_PER_PIXEL;
if(delta.x < 0)
dir.x = 0; //towards motor
if(delta.y < 0)
dir.y = 0; //towards motor
if(delta.z < 0)
dir.z = 0; //towards motor
delta.x = abs(delta.x);
delta.y = abs(delta.y);
delta.z = abs(delta.z);
fxy = delta.x - delta.y;
fxz = delta.x - delta.z;
Vector curPos;
curPos.x = 0;
curPos.y = 0;
curPos.z = 0;
while (!(*_stopped) && (curPos.x<=delta.x)&&(curPos.y<=delta.y)&&(curPos.z<=delta.z)){
if (solenoidOn) {
if ((reversing && ((delta.x - curPos.x - stepsPerPixel / STEP_BUFFER) % stepsPerPixel == 0)) ||
(!reversing && ((curPos.x + stepsPerPixel / STEP_BUFFER) % stepsPerPixel == 0)))
*_sol = _bmp.isPixel(pixelLoc++, reversing);
else if ((reversing && ((delta.x - curPos.x + stepsPerPixel / STEP_BUFFER) % stepsPerPixel == 0)) ||
(!reversing && ((curPos.x - stepsPerPixel / STEP_BUFFER) % stepsPerPixel == 0)) )
*_sol = 0;
}
++curPos.x;
if (delay > maxSpeed) {
delay = delayTime(delay, curPos.x);
farthestDelay = curPos.x;
} else if (delta.x - curPos.x < farthestDelay) {
delay = delayTime(delay, -curPos.x);
}
stepMotor[0]->stepOn(dir.x);
fxy -= delta.y;
fxz -= delta.z;
if (fxy <= 0){
++curPos.y;
stepMotor[1]->stepOn(dir.y);
fxy += delta.x;
}
if (fxz <= 0){
++curPos.z;
stepMotor[2]->stepOn(dir.z);
fxz += delta.x;
}
wait_us(1);
stepMotor[0]->stepOff();
stepMotor[1]->stepOff();
stepMotor[2]->stepOff();
wait_us(delay); //Implement linear accelleration!
if (*_paused) {
enableSteppers(false);
while(*_paused){printf("Pausing!\n\r");}
enableSteppers(true);
}
}
}
int LinearMotion::delayTime (int oldDelay, int stepNumber) {
return oldDelay - (2*oldDelay)/(4*stepNumber + 1);
}
void LinearMotion::enableSteppers(bool en) {
StepMotor[0]->enable(en);
StepMotor[1]->enable(en);
StepMotor[2]->enable(en);
}