farmbot-arduino-firmware/src/StepperControl.cpp

754 lines
20 KiB
C++
Raw Normal View History

#include "StepperControl.h"
2015-06-14 15:08:57 -06:00
#include "TimerOne.h"
static StepperControl* instance;
StepperControl * StepperControl::getInstance() {
if (!instance) {
instance = new StepperControl();
};
return instance;
}
;
2015-11-06 15:22:17 -07:00
//const int MOVEMENT_INTERRUPT_SPEED = 100; // Interrupt cycle in micro seconds
2015-06-14 15:08:57 -06:00
StepperControl::StepperControl() {
2015-08-12 15:23:21 -06:00
// Initialize some variables
motorConsMissedStepsMax[0] = 50;
motorConsMissedStepsMax[1] = 50;
motorConsMissedStepsMax[2] = 50;
motorConsMissedSteps[0] = 0;
motorConsMissedSteps[1] = 0;
motorConsMissedSteps[2] = 0;
// Create the axis controllers
2015-08-01 16:22:07 -06:00
axisX = StepperControlAxis();
axisY = StepperControlAxis();
axisZ = StepperControlAxis();
2015-08-12 15:23:21 -06:00
axisX.label = 'X';
axisY.label = 'Y';
axisZ.label = 'Z';
2015-08-01 16:22:07 -06:00
axisX.loadPinNumbers(X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, X_MIN_PIN, X_MAX_PIN);
axisY.loadPinNumbers(Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, Y_MIN_PIN, Y_MAX_PIN);
axisZ.loadPinNumbers(Z_STEP_PIN, Z_DIR_PIN, Z_ENABLE_PIN, Z_MIN_PIN, Z_MAX_PIN);
2015-08-12 15:23:21 -06:00
loadMotorSettings();
// Create the encoder controller
encoderX = StepperControlEncoder();
encoderY = StepperControlEncoder();
encoderZ = StepperControlEncoder();
encoderX.loadPinNumbers(X_ENCDR_A, X_ENCDR_B);
encoderY.loadPinNumbers(Y_ENCDR_A, Y_ENCDR_B);
encoderZ.loadPinNumbers(Z_ENCDR_A, Z_ENCDR_B);
Timer1.start();
}
void StepperControl::test() {
// read changes in encoder
//encoderX.readEncoder();
//encoderY.readEncoder();
//encoderZ.readEncoder();
2015-11-06 15:22:17 -07:00
reportPosition();
}
void StepperControl::test2() {
2015-11-06 15:22:17 -07:00
CurrentState::getInstance()->printPosition();
encoderX.test();
//encoderY.test();
//encoderZ.test();
}
2014-06-25 14:22:52 -06:00
/**
* xDest - destination X in steps
* yDest - destination Y in steps
* zDest - destination Z in steps
* maxStepsPerSecond - maximum number of steps per second
* maxAccelerationStepsPerSecond - maximum number of acceleration in steps per second
*/
2015-08-03 15:12:49 -06:00
int StepperControl::moveToCoords( long xDest, long yDest, long zDest,
2014-08-06 16:04:40 -06:00
unsigned int xMaxSpd, unsigned int yMaxSpd, unsigned int zMaxSpd,
bool xHome, bool yHome, bool zHome) {
2014-07-15 14:23:01 -06:00
2014-07-29 16:12:19 -06:00
unsigned long currentMillis = 0;
2014-07-25 14:32:37 -06:00
unsigned long timeStart = millis();
2014-07-15 14:23:01 -06:00
2014-10-24 16:02:50 -06:00
int incomingByte = 0;
2014-07-25 14:32:37 -06:00
int error = 0;
2015-08-07 15:30:24 -06:00
// load motor settings
loadMotorSettings();
// load current encoder coordinates
axisX.setCurrentPosition(encoderX.currentPosition());
2014-08-06 16:04:40 -06:00
// if a speed is given in the command, use that instead of the config speed
if (xMaxSpd > 0 && xMaxSpd < speedMax[0]) {
speedMax[0] = xMaxSpd;
}
if (yMaxSpd > 0 && yMaxSpd < speedMax[1]) {
speedMax[1] = yMaxSpd;
}
if (zMaxSpd > 0 && zMaxSpd < speedMax[2]) {
speedMax[2] = zMaxSpd;
2014-07-29 16:12:19 -06:00
}
2014-08-06 16:04:40 -06:00
2015-08-07 15:30:24 -06:00
axisX.setMaxSpeed(speedMax[0]);
axisY.setMaxSpeed(speedMax[1]);
axisZ.setMaxSpeed(speedMax[2]);
2015-08-01 16:22:07 -06:00
2015-08-07 15:30:24 -06:00
// Load coordinates into axis class
2015-06-24 14:58:45 -06:00
2015-08-02 16:16:35 -06:00
long sourcePoint[3] = {0,0,0};
2015-08-01 16:22:07 -06:00
sourcePoint[0] = CurrentState::getInstance()->getX();
sourcePoint[1] = CurrentState::getInstance()->getY();
sourcePoint[2] = CurrentState::getInstance()->getZ();
2015-08-02 16:16:35 -06:00
long currentPoint[3] = {0,0,0};
2015-08-01 16:22:07 -06:00
currentPoint[0] = CurrentState::getInstance()->getX();
currentPoint[1] = CurrentState::getInstance()->getY();
currentPoint[2] = CurrentState::getInstance()->getZ();
2015-08-02 16:16:35 -06:00
long destinationPoint[3]= {0,0,0};
2015-08-01 16:22:07 -06:00
destinationPoint[0] = xDest;
destinationPoint[1] = yDest;
destinationPoint[2] = zDest;
motorConsMissedSteps[0] = 0;
motorConsMissedSteps[1] = 0;
motorConsMissedSteps[2] = 0;
2015-08-07 15:30:24 -06:00
// Load coordinates into motor control
2015-08-01 16:22:07 -06:00
axisX.loadCoordinates(currentPoint[0],destinationPoint[0],xHome);
axisY.loadCoordinates(currentPoint[1],destinationPoint[1],yHome);
axisZ.loadCoordinates(currentPoint[2],destinationPoint[2],zHome);
2015-06-24 14:58:45 -06:00
2015-08-02 16:16:35 -06:00
// Prepare for movement
2014-07-23 01:46:21 -06:00
storeEndStops();
2014-07-15 14:23:01 -06:00
reportEndStops();
2015-08-01 16:22:07 -06:00
2015-08-12 15:23:21 -06:00
axisX.setDirectionAxis();
axisY.setDirectionAxis();
axisZ.setDirectionAxis();
2015-08-02 16:16:35 -06:00
enableMotors();
2014-06-25 14:22:52 -06:00
2014-08-06 16:04:40 -06:00
// Start movement
2015-06-15 15:16:33 -06:00
axisActive[0] = true;
axisActive[1] = true;
axisActive[2] = true;
2015-06-14 15:08:57 -06:00
2015-08-02 16:16:35 -06:00
axisX.checkMovement();
2015-08-13 15:07:36 -06:00
axisY.checkMovement();
axisZ.checkMovement();
2015-06-14 15:08:57 -06:00
//Timer1.start();
2015-11-06 15:22:17 -07:00
/**///axisX.activateDebugPrint();
2015-06-21 15:39:45 -06:00
2015-06-14 15:08:57 -06:00
// Let the interrupt handle all the movements
2015-06-15 15:16:33 -06:00
while (axisActive[0] || axisActive[1] || axisActive[2]) {
2015-08-01 16:22:07 -06:00
//delay(1);
delayMicroseconds(100);
2015-06-21 15:39:45 -06:00
2015-11-06 15:22:17 -07:00
/**/
//long entX= encoderX.readEncoder();
//encoderX.currentPosition();
//encoderY.currentPosition();
//encoderZ.currentPosition();
2015-11-06 15:22:17 -07:00
axisX.checkTiming();
axisY.checkTiming();
axisZ.checkTiming();
// If a step is taken, check to see if the encoder still matcjes the nr of steps
if (axisX.isStepDone()) {
//Serial.print("R99");
//Serial.print(" encoder pos ");
//Serial.print(encoderX.currentPosition());
//Serial.print(" axis pos ");
//Serial.print(axisX.currentPosition());
//Serial.print("\n");
Serial.print("R99");
Serial.print(" missed step ");
Serial.print(motorConsMissedSteps[0]);
Serial.print(" encoder pos ");
Serial.print(encoderX.currentPosition());
Serial.print(" axis pos ");
Serial.print(axisX.currentPosition());
Serial.print("\n");
if (axisX.currentPosition() != encoderX.currentPosition()) {
//motorConsMissedSteps[0]++;
//motorConsMissedSteps[0]++;
motorConsMissedSteps[0]+=3;
Serial.print("R99");
Serial.print(" missed step ");
//Serial.print(motorConsMissedSteps[0]);
//Serial.print(" encoder pos ");
//Serial.print(encoderX.currentPosition());
//Serial.print(" axis pos ");
//Serial.print(axisX.currentPosition());
Serial.print("\n");
axisX.setCurrentPosition(encoderX.currentPosition());
} else {
if (motorConsMissedSteps[0] > 0) {
motorConsMissedSteps[0]--;
}
}
axisX.resetStepDone();
if (motorConsMissedSteps[0] > motorConsMissedStepsMax[0]) {
axisX.deactivateAxis();
Serial.print("R99");
Serial.print(" deactivate motor ");
Serial.print("\n");
}
}
if (axisX.endStopAxisReached(false)) {
axisX.setCurrentPosition(0);
encoderX.setPosition(0);
}
//encoderX.readEncoder();
2015-11-06 15:22:17 -07:00
//encoderX.test();
2015-08-01 16:22:07 -06:00
axisActive[0] = axisX.isAxisActive();
axisActive[1] = axisY.isAxisActive();
axisActive[2] = axisZ.isAxisActive();
2015-06-21 15:39:45 -06:00
currentPoint[0] = axisX.currentPosition();
currentPoint[1] = axisY.currentPosition();
currentPoint[2] = axisZ.currentPosition();
CurrentState::getInstance()->setX(currentPoint[0]);
CurrentState::getInstance()->setY(currentPoint[1]);
CurrentState::getInstance()->setZ(currentPoint[2]);
2014-07-23 01:46:21 -06:00
storeEndStops();
2015-06-14 15:08:57 -06:00
// Check timeouts
2015-07-13 15:22:43 -06:00
if (axisActive[0] == true && ((millis() >= timeStart && millis() - timeStart > timeOut[0] * 1000) || (millis() < timeStart && millis() > timeOut[0] * 1000))) {
2015-06-14 15:08:57 -06:00
error = 1;
}
2015-07-13 15:22:43 -06:00
if (axisActive[1] == true && ((millis() >= timeStart && millis() - timeStart > timeOut[0] * 1000) || (millis() < timeStart && millis() > timeOut[0] * 1000))) {
2015-06-14 15:08:57 -06:00
error = 1;
}
2015-07-13 15:22:43 -06:00
if (axisActive[2] == true && ((millis() >= timeStart && millis() - timeStart > timeOut[0] * 1000) || (millis() < timeStart && millis() > timeOut[0] * 1000))) {
2015-06-14 15:08:57 -06:00
error = 1;
}
2014-10-24 16:02:50 -06:00
// Check if there is an emergency stop command
if (Serial.available() > 0) {
incomingByte = Serial.read();
if (incomingByte == 69 || incomingByte == 101) {
2015-06-14 15:08:57 -06:00
error = 1;
}
2014-10-24 16:02:50 -06:00
}
2015-06-14 15:08:57 -06:00
if (error == 1) {
2015-08-13 15:07:36 -06:00
Serial.print("R99 error\n");
//Timer1.stop();
2015-06-15 15:16:33 -06:00
axisActive[0] = false;
axisActive[1] = false;
axisActive[2] = false;
2014-06-25 14:22:52 -06:00
}
2014-10-12 15:57:07 -06:00
2015-06-14 15:08:57 -06:00
// Periodically send message still active
2014-06-25 14:22:52 -06:00
currentMillis++;
//if (currentMillis % 2500 == 0)
if (currentMillis % 750 == 0)
2014-10-12 15:57:07 -06:00
{
Serial.print("R04\n");
reportPosition();
//Serial.print("R99");
//Serial.print(" missed step nr ");
//Serial.print(motorConsMissedSteps[0]);
//Serial.print(" encoder pos ");
//Serial.print(encoderX.currentPosition());
//Serial.print(" axis pos ");
//Serial.print(axisX.currentPosition());
//Serial.print("\n");
2014-10-12 15:57:07 -06:00
}
2014-06-25 14:22:52 -06:00
}
2015-08-12 15:23:21 -06:00
Serial.print("R99 stopped\n");
2015-06-21 15:39:45 -06:00
2015-11-06 15:22:17 -07:00
//Timer1.stop();
2015-08-02 16:16:35 -06:00
disableMotors();
2014-07-23 01:46:21 -06:00
currentPoint[0] = axisX.currentPosition();
currentPoint[1] = axisY.currentPosition();
currentPoint[2] = axisZ.currentPosition();
2015-08-07 15:30:24 -06:00
CurrentState::getInstance()->setX(currentPoint[0]);
CurrentState::getInstance()->setY(currentPoint[1]);
CurrentState::getInstance()->setZ(currentPoint[2]);
2014-07-23 01:46:21 -06:00
storeEndStops();
reportEndStops();
2014-07-25 14:32:37 -06:00
reportPosition();
2014-08-27 15:11:09 -06:00
/**///encoderX.test();
2014-07-25 14:32:37 -06:00
return error;
}
2014-09-04 15:10:47 -06:00
//
// Calibration
//
int StepperControl::calibrateAxis(int axis) {
2015-08-07 15:30:24 -06:00
// Load motor settings
2014-09-21 14:42:44 -06:00
2015-08-07 15:30:24 -06:00
loadMotorSettings();
2014-09-21 14:42:44 -06:00
2015-08-13 15:07:36 -06:00
//unsigned long timeStart = millis();
2014-09-04 15:10:47 -06:00
bool movementDone = false;
2014-09-22 14:35:01 -06:00
int paramValueInt = 0;
2014-09-21 14:42:44 -06:00
int stepsCount = 0;
2015-08-13 15:07:36 -06:00
int incomingByte = 0;
int error = 0;
2014-09-04 15:10:47 -06:00
2015-08-07 15:30:24 -06:00
bool invertEndStops = false;
int parEndInv;
int parNbrStp;
2015-08-13 15:07:36 -06:00
2015-11-20 14:44:12 -07:00
long missedSteps = 0;
long missedStepsMax = 0;
2014-09-04 15:10:47 -06:00
// Prepare for movement
storeEndStops();
reportEndStops();
2014-09-21 14:42:44 -06:00
2015-08-07 15:30:24 -06:00
// Select the right axis
2015-12-02 15:31:29 -07:00
StepperControlAxis* calibAxis;
StepperControlEncoder* calibEncoder;
2015-08-07 15:30:24 -06:00
switch (axis) {
2015-08-13 15:07:36 -06:00
case 0:
2015-12-02 15:31:29 -07:00
calibAxis = &axisX;
calibEncoder = &encoderX;
2015-08-13 15:07:36 -06:00
parEndInv = MOVEMENT_INVERT_ENDPOINTS_X;
parNbrStp = MOVEMENT_AXIS_NR_STEPS_X;
invertEndStops = endStInv[0];
2015-11-20 14:44:12 -07:00
missedStepsMax = motorConsMissedStepsMax[0];
2015-08-13 15:07:36 -06:00
break;
2015-08-07 15:30:24 -06:00
case 1:
2015-12-02 15:31:29 -07:00
calibAxis = &axisY;
calibEncoder = &encoderY;
2015-08-13 15:07:36 -06:00
parEndInv = MOVEMENT_INVERT_ENDPOINTS_Y;;
parNbrStp = MOVEMENT_AXIS_NR_STEPS_Y;
2015-11-20 14:44:12 -07:00
invertEndStops = endStInv[1];
missedStepsMax = motorConsMissedStepsMax[1];
2015-08-07 15:30:24 -06:00
break;
case 2:
2015-12-02 15:31:29 -07:00
calibAxis = &axisZ;
calibEncoder = &encoderZ;
2015-08-13 15:07:36 -06:00
parEndInv = MOVEMENT_INVERT_ENDPOINTS_Z;
parNbrStp = MOVEMENT_AXIS_NR_STEPS_Z;
2015-11-20 14:44:12 -07:00
invertEndStops = endStInv[2];
missedStepsMax = motorConsMissedStepsMax[2];
2015-08-07 15:30:24 -06:00
break;
default:
Serial.print("R99 Calibration error: invalid axis selected\n");
return 1;
}
2014-09-21 14:42:44 -06:00
// Preliminary checks
2015-12-02 15:31:29 -07:00
if (calibAxis->endStopMin() || calibAxis->endStopMax()) {
2014-10-12 15:57:07 -06:00
Serial.print("R99 Calibration error: end stop active before start\n");
2014-09-21 14:42:44 -06:00
return 1;
}
2014-10-12 15:57:07 -06:00
2015-08-13 15:07:36 -06:00
Serial.print("R99");
Serial.print(" axis ");
2015-12-02 15:31:29 -07:00
Serial.print(calibAxis->label);
2015-08-13 15:07:36 -06:00
Serial.print(" calibration start");
Serial.print("\n");
2015-08-07 15:30:24 -06:00
2014-09-04 15:10:47 -06:00
// Move towards home
2015-12-02 15:31:29 -07:00
calibAxis->enableMotor();
calibAxis->setDirectionHome();
/**/ //calibEncoder = encoderX;
2014-09-21 14:42:44 -06:00
2015-08-13 15:07:36 -06:00
stepsCount = 0;
2014-09-04 15:10:47 -06:00
movementDone = false;
2014-09-21 14:42:44 -06:00
while (!movementDone && error == 0) {
2014-09-04 15:10:47 -06:00
2014-10-24 16:02:50 -06:00
// Check if there is an emergency stop command
if (Serial.available() > 0) {
incomingByte = Serial.read();
if (incomingByte == 69 || incomingByte == 101) {
movementDone = true;
error = 1;
}
}
2015-12-02 15:31:29 -07:00
//calibEncoder = encoderX;
2015-11-20 14:44:12 -07:00
// Move until the end stop for home position is reached, either by end stop or motot skipping
2015-12-02 15:31:29 -07:00
if ((!calibAxis->endStopMin() && !calibAxis->endStopMax()) && !movementDone && (missedSteps < missedStepsMax)) {
2014-09-04 15:10:47 -06:00
2015-12-02 15:31:29 -07:00
calibAxis->setMotorStep();
2014-09-04 15:10:47 -06:00
2015-08-13 15:07:36 -06:00
delayMicroseconds(1000000 / speedMin[axis] /2);
2014-10-12 15:57:07 -06:00
2015-08-13 15:07:36 -06:00
stepsCount++;
if (stepsCount % (speedMin[axis] * 3) == 0)
2014-10-12 15:57:07 -06:00
{
// Periodically send message still active
Serial.print("R04\n");
}
2015-12-02 15:31:29 -07:00
calibEncoder->test();
encoderX.test();
2015-11-20 14:44:12 -07:00
/**/
2015-12-02 15:31:29 -07:00
Serial.print("R99");
Serial.print(" missed steps ");
Serial.print(missedSteps);
Serial.print(" max steps ");
Serial.print(missedStepsMax);
Serial.print(" cur pos mtr ");
Serial.print(calibAxis->currentPosition());
Serial.print(" cur pos enc ");
Serial.print(calibEncoder->currentPosition());
Serial.print("\n");
2015-11-20 14:44:12 -07:00
// Check the encoder for missed steps
2015-12-02 15:31:29 -07:00
if (calibAxis->currentPosition() != calibEncoder->currentPosition()) {
2015-11-20 14:44:12 -07:00
missedSteps += 3;
} else {
if (missedSteps > 0) {
missedSteps--;
}
2015-12-02 15:31:29 -07:00
calibAxis->setCurrentPosition(calibEncoder->currentPosition());
2015-11-20 14:44:12 -07:00
}
2014-10-12 15:57:07 -06:00
2015-12-02 15:31:29 -07:00
calibAxis->resetMotorStep();
2015-08-13 15:07:36 -06:00
delayMicroseconds(1000000 / speedMin[axis] /2);
2014-09-04 15:10:47 -06:00
} else {
movementDone = true;
2014-09-21 14:42:44 -06:00
// If end stop for home is active, set the position to zero
2015-12-02 15:31:29 -07:00
if (calibAxis->endStopMax())
2014-09-21 14:42:44 -06:00
{
invertEndStops = true;
}
2014-09-04 15:10:47 -06:00
}
}
2014-10-12 15:57:07 -06:00
2015-08-13 15:07:36 -06:00
Serial.print("R99");
Serial.print(" axis ");
2015-12-02 15:31:29 -07:00
Serial.print(calibAxis->label);
2015-08-13 15:07:36 -06:00
Serial.print(" at first end stop");
Serial.print("\n");
2015-08-07 15:30:24 -06:00
2014-09-22 14:35:01 -06:00
// Report back the end stop setting
if (error == 0) {
if (invertEndStops) {
paramValueInt = 1;
} else {
paramValueInt = 0;
}
Serial.print("R23");
Serial.print(" ");
Serial.print("P");
2015-08-07 15:30:24 -06:00
Serial.print(parEndInv);
2014-09-22 14:35:01 -06:00
Serial.print(" ");
Serial.print("V");
2014-10-09 15:35:26 -06:00
Serial.print(paramValueInt);
Serial.print("\n");
2014-09-22 14:35:01 -06:00
}
2014-09-04 15:10:47 -06:00
2014-09-22 14:35:01 -06:00
// Store the status of the system
2014-09-04 15:10:47 -06:00
2014-09-21 14:42:44 -06:00
storeEndStops();
reportEndStops();
2014-09-04 15:10:47 -06:00
2014-09-21 14:42:44 -06:00
// Move into the other direction now, and measure the number of steps
2014-09-04 15:10:47 -06:00
2014-10-12 15:57:07 -06:00
stepsCount = 0;
2014-09-21 14:42:44 -06:00
movementDone = false;
2015-11-20 14:44:12 -07:00
missedSteps = 0;
2015-12-02 15:31:29 -07:00
calibAxis->setDirectionAway();
2014-09-04 15:10:47 -06:00
2014-09-21 14:42:44 -06:00
while (!movementDone && error == 0) {
2014-09-04 15:10:47 -06:00
2014-10-24 16:02:50 -06:00
// Check if there is an emergency stop command
if (Serial.available() > 0) {
incomingByte = Serial.read();
if (incomingByte == 69 || incomingByte == 101) {
movementDone = true;
error = 1;
}
}
2014-09-21 14:42:44 -06:00
// Move until the end stop at the other side of the axis is reached
2015-12-02 15:31:29 -07:00
if (((!invertEndStops && !calibAxis->endStopMax()) || (invertEndStops && !calibAxis->endStopMin())) && !movementDone && (missedSteps < missedStepsMax)) {
2014-09-04 15:10:47 -06:00
2015-12-02 15:31:29 -07:00
calibAxis->setMotorStep();
2015-08-13 15:07:36 -06:00
stepsCount++;
2014-09-04 15:10:47 -06:00
2015-08-13 15:07:36 -06:00
delayMicroseconds(1000000 / speedMin[axis] /2);
2014-10-12 15:57:07 -06:00
2015-08-13 15:07:36 -06:00
if (stepsCount % (speedMin[axis] * 3) == 0)
2014-10-12 15:57:07 -06:00
{
// Periodically send message still active
Serial.print("R04\n");
}
2015-11-20 14:44:12 -07:00
/**/
// Check the encoder for missed steps
2015-12-02 15:31:29 -07:00
if (calibAxis->currentPosition() != calibEncoder->currentPosition()) {
2015-11-20 14:44:12 -07:00
missedSteps += 3;
} else {
if (missedSteps > 0) {
missedSteps--;
}
2015-12-02 15:31:29 -07:00
calibAxis->setCurrentPosition(calibEncoder->currentPosition());
2015-11-20 14:44:12 -07:00
}
2014-10-12 15:57:07 -06:00
2015-12-02 15:31:29 -07:00
calibAxis->resetMotorStep();
2015-08-13 15:07:36 -06:00
delayMicroseconds(1000000 / speedMin[axis] /2);
2014-09-04 15:10:47 -06:00
2014-09-21 14:42:44 -06:00
} else {
2014-09-04 15:10:47 -06:00
movementDone = true;
}
}
2014-10-12 15:57:07 -06:00
2015-08-13 15:07:36 -06:00
Serial.print("R99");
Serial.print(" axis ");
2015-12-02 15:31:29 -07:00
Serial.print(calibAxis->label);
2015-08-13 15:07:36 -06:00
Serial.print(" at second end stop");
Serial.print("\n");
2015-08-07 15:30:24 -06:00
2014-09-22 14:35:01 -06:00
// Report back the end stop setting
if (error == 0) {
Serial.print("R23");
Serial.print(" ");
Serial.print("P");
2015-08-07 15:30:24 -06:00
Serial.print(parNbrStp);
2014-09-22 14:35:01 -06:00
Serial.print(" ");
Serial.print("V");
2014-10-12 15:57:07 -06:00
Serial.print(stepsCount);
2014-10-09 15:35:26 -06:00
Serial.print("\n");
2014-09-22 14:35:01 -06:00
}
2014-09-04 15:10:47 -06:00
2015-12-02 15:31:29 -07:00
calibAxis->disableMotor();
2014-09-04 15:10:47 -06:00
storeEndStops();
reportEndStops();
2014-10-12 15:57:07 -06:00
switch (axis) {
case 0:
CurrentState::getInstance()->setX(stepsCount);
break;
case 1:
CurrentState::getInstance()->setY(stepsCount);
break;
case 2:
CurrentState::getInstance()->setZ(stepsCount);
break;
}
reportPosition();
2015-08-07 15:30:24 -06:00
2014-09-04 15:10:47 -06:00
return error;
}
2015-06-14 15:08:57 -06:00
2015-08-02 16:16:35 -06:00
// Handle movement by checking each axis
void StepperControl::handleMovementInterrupt(void){
encoderX.readEncoder();
//encoderY.readEncoder();
//encoderZ.readEncoder();
2015-11-06 15:22:17 -07:00
/**/
//axisX.checkTiming();
//axisY.checkTiming();
//axisZ.checkTiming();
2015-12-02 15:31:29 -07:00
checkAxisVsEncoder(&axisX, &encoderX, &motorConsMissedSteps[0]);
//checkAxisVsEncoder(&axisX, &encoderX);
//checkAxisVsEncoder(&axisX, &encoderX);
}
// Check encoder to verify the motor is at the right position
void StepperControl::checkAxisVsEncoder(StepperControlAxis* axis, StepperControlEncoder* encoder, int* missedSteps) {
if (axis->currentPosition() != encoder->currentPosition()) {
missedSteps += 3;
} else {
if (missedSteps > 0) {
missedSteps--;
}
axis->setCurrentPosition(encoder->currentPosition());
}
2015-08-02 16:16:35 -06:00
}
bool interruptBusy = false;
void handleMovementInterruptTest(void) {
if (interruptBusy == false) {
interruptBusy = true;
StepperControl::getInstance()->handleMovementInterrupt();
//blinkLed();
interruptBusy = false;
}
}
// Start the interrupt used for moviing
// Interrupt management code library written by Paul Stoffregen
void StepperControl::initInterrupt() {
//Timer1.attachInterrupt(StepperControl::getInstance()->handleMovementInterrupt);
Timer1.attachInterrupt(handleMovementInterruptTest);
Timer1.initialize(MOVEMENT_INTERRUPT_SPEED);
//Timer1.stop();
2015-08-02 16:16:35 -06:00
}
unsigned long StepperControl::getMaxLength(unsigned long lengths[3]) {
unsigned long max = lengths[0];
for (int i = 1; i < 3; i++) {
if (lengths[i] > max) {
max = lengths[i];
}
}
return max;
}
void StepperControl::enableMotors() {
axisX.enableMotor();
axisY.enableMotor();
axisZ.enableMotor();
delay(100);
}
void StepperControl::disableMotors() {
axisX.disableMotor();
axisY.disableMotor();
axisZ.disableMotor();
delay(100);
}
bool StepperControl::endStopsReached() {
if ( axisX.endStopsReached() ||
axisY.endStopsReached() ||
axisZ.endStopsReached()) {
return true;
}
return false;
}
void StepperControl::reportEndStops() {
CurrentState::getInstance()->printEndStops();
}
void StepperControl::reportPosition(){
CurrentState::getInstance()->printPosition();
}
void StepperControl::storeEndStops() {
CurrentState::getInstance()->storeEndStops();
}
/**
* water is dosed by setting the pin for the water high for a number of miliseconds
*
*/
//void StepperControl::doseWaterByTime(long time) {
// digitalWrite(HEATER_1_PIN, HIGH);
// delay(time);
// digitalWrite(HEATER_1_PIN, LOW);
//}
2015-08-07 15:30:24 -06:00
void StepperControl::loadMotorSettings() {
// Load settings
homeIsUp[0] = ParameterList::getInstance()->getValue(MOVEMENT_HOME_UP_X);
homeIsUp[1] = ParameterList::getInstance()->getValue(MOVEMENT_HOME_UP_Y);
homeIsUp[2] = ParameterList::getInstance()->getValue(MOVEMENT_HOME_UP_Z);
speedMax[0] = ParameterList::getInstance()->getValue(MOVEMENT_MAX_SPD_X);
speedMax[1] = ParameterList::getInstance()->getValue(MOVEMENT_MAX_SPD_Y);
speedMax[2] = ParameterList::getInstance()->getValue(MOVEMENT_MAX_SPD_Z);
speedMin[0] = ParameterList::getInstance()->getValue(MOVEMENT_MIN_SPD_X);
speedMin[1] = ParameterList::getInstance()->getValue(MOVEMENT_MIN_SPD_Y);
speedMin[2] = ParameterList::getInstance()->getValue(MOVEMENT_MIN_SPD_Z);
stepsAcc[0] = ParameterList::getInstance()->getValue(MOVEMENT_STEPS_ACC_DEC_X);
stepsAcc[1] = ParameterList::getInstance()->getValue(MOVEMENT_STEPS_ACC_DEC_Y);
stepsAcc[2] = ParameterList::getInstance()->getValue(MOVEMENT_STEPS_ACC_DEC_Z);
motorInv[0] = ParameterList::getInstance()->getValue(MOVEMENT_INVERT_MOTOR_X);
motorInv[1] = ParameterList::getInstance()->getValue(MOVEMENT_INVERT_MOTOR_Y);
motorInv[2] = ParameterList::getInstance()->getValue(MOVEMENT_INVERT_MOTOR_Z);
endStInv[0] = ParameterList::getInstance()->getValue(MOVEMENT_INVERT_ENDPOINTS_X);
endStInv[1] = ParameterList::getInstance()->getValue(MOVEMENT_INVERT_ENDPOINTS_Y);
endStInv[2] = ParameterList::getInstance()->getValue(MOVEMENT_INVERT_ENDPOINTS_Z);
timeOut[0] = ParameterList::getInstance()->getValue(MOVEMENT_TIMEOUT_X);
timeOut[1] = ParameterList::getInstance()->getValue(MOVEMENT_TIMEOUT_X);
timeOut[2] = ParameterList::getInstance()->getValue(MOVEMENT_TIMEOUT_X);
2015-08-12 15:23:21 -06:00
axisX.loadMotorSettings(speedMax[0], speedMin[0], stepsAcc[0], timeOut[0], homeIsUp[0], motorInv[0], endStInv[0], MOVEMENT_INTERRUPT_SPEED);
axisY.loadMotorSettings(speedMax[1], speedMin[1], stepsAcc[1], timeOut[1], homeIsUp[1], motorInv[1], endStInv[1], MOVEMENT_INTERRUPT_SPEED);
axisZ.loadMotorSettings(speedMax[2], speedMin[2], stepsAcc[2], timeOut[2], homeIsUp[2], motorInv[2], endStInv[2], MOVEMENT_INTERRUPT_SPEED);
2015-08-07 15:30:24 -06:00
}