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.
Diff: LinearMotion.cpp
- Revision:
- 0:3058939fa37c
- Child:
- 1:cf60b60a1b5b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LinearMotion.cpp Sat Apr 28 21:08:58 2012 +0000
@@ -0,0 +1,236 @@
+#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);
+}