2014-05-25 17:20:00 -06:00
|
|
|
#include "StepperControl.h"
|
|
|
|
|
|
|
|
static StepperControl* instance;
|
|
|
|
|
|
|
|
StepperControl * StepperControl::getInstance() {
|
|
|
|
if (!instance) {
|
|
|
|
instance = new StepperControl();
|
|
|
|
};
|
|
|
|
return instance;
|
2014-05-28 17:02:22 -06:00
|
|
|
}
|
|
|
|
;
|
2014-05-25 17:20:00 -06:00
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
void StepperControl::reportStatus(StepperControlAxis* axis, int axisStatus) {
|
|
|
|
Serial.print(COMM_REPORT_CMD_STATUS);
|
|
|
|
Serial.print(" ");
|
|
|
|
Serial.print(axis->label);
|
|
|
|
Serial.print(axisStatus);
|
2016-10-02 15:43:39 -06:00
|
|
|
//Serial.print("\r\n");
|
|
|
|
CurrentState::getInstance()->printQAndNewLine();
|
2016-02-06 10:23:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void StepperControl::reportCalib(StepperControlAxis* axis, int calibStatus) {
|
|
|
|
Serial.print(COMM_REPORT_CALIB_STATUS);
|
|
|
|
Serial.print(" ");
|
|
|
|
Serial.print(axis->label);
|
|
|
|
Serial.print(calibStatus);
|
2016-10-02 15:43:39 -06:00
|
|
|
//Serial.print("\r\n");
|
|
|
|
CurrentState::getInstance()->printQAndNewLine();
|
2016-02-06 10:23:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void StepperControl::checkAxisSubStatus(StepperControlAxis* axis, int* axisSubStatus) {
|
|
|
|
int newStatus = 0;
|
|
|
|
bool statusChanged = false;
|
|
|
|
|
|
|
|
if (axis->isAccelerating()) {
|
|
|
|
newStatus = COMM_REPORT_MOVE_STATUS_ACCELERATING;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (axis->isCruising()) {
|
|
|
|
newStatus = COMM_REPORT_MOVE_STATUS_CRUISING;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (axis->isDecelerating()) {
|
|
|
|
newStatus = COMM_REPORT_MOVE_STATUS_DECELERATING;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (axis->isCrawling()) {
|
|
|
|
newStatus = COMM_REPORT_MOVE_STATUS_CRAWLING;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if the status changes, send out a status report
|
|
|
|
if (*axisSubStatus != newStatus && newStatus > 0) {
|
|
|
|
statusChanged = true;
|
|
|
|
}
|
|
|
|
*axisSubStatus = newStatus;
|
|
|
|
|
|
|
|
if (statusChanged) {
|
|
|
|
reportStatus(&axisX, *axisSubStatus);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2014-05-25 17:20:00 -06:00
|
|
|
StepperControl::StepperControl() {
|
2015-08-12 15:23:21 -06:00
|
|
|
|
2016-01-02 15:21:01 -07:00
|
|
|
// Initialize some variables for testing
|
2016-10-02 15:43:39 -06:00
|
|
|
|
2016-01-02 15:21:01 -07:00
|
|
|
//motorConsMissedStepsMax[0] = 50;
|
|
|
|
//motorConsMissedStepsMax[1] = 50;
|
|
|
|
//motorConsMissedStepsMax[2] = 50;
|
2015-11-11 15:09:15 -07:00
|
|
|
|
2016-10-03 14:17:46 -06:00
|
|
|
motorMotorsEnabled = false;
|
|
|
|
|
2015-11-11 15:09:15 -07:00
|
|
|
motorConsMissedSteps[0] = 0;
|
|
|
|
motorConsMissedSteps[1] = 0;
|
|
|
|
motorConsMissedSteps[2] = 0;
|
|
|
|
|
2015-11-02 14:15:49 -07:00
|
|
|
// 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';
|
|
|
|
|
2017-02-03 14:59:16 -07:00
|
|
|
axisX.loadPinNumbers(X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, X_MIN_PIN, X_MAX_PIN, E_STEP_PIN, E_DIR_PIN, E_ENABLE_PIN);
|
2016-12-03 13:58:27 -07:00
|
|
|
axisY.loadPinNumbers(Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, Y_MIN_PIN, Y_MAX_PIN, 0, 0, 0);
|
|
|
|
axisZ.loadPinNumbers(Z_STEP_PIN, Z_DIR_PIN, Z_ENABLE_PIN, Z_MIN_PIN, Z_MAX_PIN, 0, 0, 0);
|
2015-08-12 15:23:21 -06:00
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
axisSubStep[0] = COMM_REPORT_MOVE_STATUS_IDLE;
|
|
|
|
axisSubStep[1] = COMM_REPORT_MOVE_STATUS_IDLE;
|
|
|
|
axisSubStep[2] = COMM_REPORT_MOVE_STATUS_IDLE;
|
|
|
|
|
2015-08-12 15:23:21 -06:00
|
|
|
loadMotorSettings();
|
2016-01-02 15:21:01 -07:00
|
|
|
loadEncoderSettings();
|
2015-11-02 14:15:49 -07:00
|
|
|
// Create the encoder controller
|
|
|
|
|
|
|
|
encoderX = StepperControlEncoder();
|
|
|
|
encoderY = StepperControlEncoder();
|
|
|
|
encoderZ = StepperControlEncoder();
|
|
|
|
|
2017-02-28 14:48:46 -07:00
|
|
|
encoderX.loadPinNumbers(X_ENCDR_A, X_ENCDR_B);
|
|
|
|
encoderY.loadPinNumbers(Y_ENCDR_A, Y_ENCDR_B);
|
|
|
|
encoderZ.loadPinNumbers(Z_ENCDR_A, Z_ENCDR_B);
|
2015-11-02 14:15:49 -07:00
|
|
|
|
2017-01-26 13:18:03 -07:00
|
|
|
motorMotorsEnabled = false;
|
2015-11-02 14:15:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void StepperControl::test() {
|
|
|
|
// read changes in encoder
|
|
|
|
//encoderX.readEncoder();
|
|
|
|
//encoderY.readEncoder();
|
|
|
|
//encoderZ.readEncoder();
|
2017-02-28 14:48:46 -07:00
|
|
|
//reportPosition();
|
|
|
|
|
|
|
|
//bool test = axisX.endStopMin();
|
|
|
|
//Serial.print("R99");
|
|
|
|
//Serial.print(" test = ");
|
|
|
|
//Serial.print(test);
|
|
|
|
//Serial.print("\r\n");
|
2015-11-02 14:15:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void StepperControl::test2() {
|
2015-11-06 15:22:17 -07:00
|
|
|
CurrentState::getInstance()->printPosition();
|
2015-11-02 14:15:49 -07:00
|
|
|
encoderX.test();
|
|
|
|
//encoderY.test();
|
|
|
|
//encoderZ.test();
|
2014-05-25 17:20:00 -06:00
|
|
|
}
|
|
|
|
|
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,
|
2016-10-02 15:43:39 -06:00
|
|
|
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;
|
|
|
|
|
2016-01-02 15:21:01 -07:00
|
|
|
// load motor and encoder settings
|
2015-08-07 15:30:24 -06:00
|
|
|
|
|
|
|
loadMotorSettings();
|
2016-01-02 15:21:01 -07:00
|
|
|
loadEncoderSettings();
|
2015-11-11 15:09:15 -07:00
|
|
|
// load current encoder coordinates
|
2015-12-31 08:01:40 -07:00
|
|
|
//axisX.setCurrentPosition(encoderX.currentPosition());
|
2015-11-11 15:09:15 -07:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2015-11-11 15:09:15 -07:00
|
|
|
motorConsMissedSteps[0] = 0;
|
|
|
|
motorConsMissedSteps[1] = 0;
|
|
|
|
motorConsMissedSteps[2] = 0;
|
|
|
|
|
2015-12-31 08:01:40 -07:00
|
|
|
motorLastPosition[0] = currentPoint[0];
|
|
|
|
motorLastPosition[1] = currentPoint[1];
|
|
|
|
motorLastPosition[2] = currentPoint[2];
|
|
|
|
|
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
|
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
axisX.movementStarted = false;
|
|
|
|
axisY.movementStarted = false;
|
|
|
|
axisZ.movementStarted = false;
|
|
|
|
|
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();
|
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
// Enable motors
|
|
|
|
|
|
|
|
axisSubStep[0] = COMM_REPORT_MOVE_STATUS_START_MOTOR;
|
|
|
|
axisSubStep[1] = COMM_REPORT_MOVE_STATUS_START_MOTOR;
|
|
|
|
axisSubStep[2] = COMM_REPORT_MOVE_STATUS_START_MOTOR;
|
|
|
|
|
|
|
|
reportStatus(&axisX, axisSubStep[0]);
|
|
|
|
reportStatus(&axisY, axisSubStep[1]);
|
|
|
|
reportStatus(&axisZ, axisSubStep[2]);
|
|
|
|
|
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
|
|
|
|
|
|
|
// 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
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
checkAxisSubStatus(&axisX, &axisSubStep[0]);
|
|
|
|
checkAxisSubStatus(&axisY, &axisSubStep[1]);
|
|
|
|
checkAxisSubStatus(&axisZ, &axisSubStep[2]);
|
|
|
|
|
2016-01-08 15:15:08 -07:00
|
|
|
delay(1);
|
|
|
|
//delayMicroseconds(100);
|
2015-06-21 15:39:45 -06:00
|
|
|
|
2015-11-11 15:09:15 -07:00
|
|
|
//encoderX.currentPosition();
|
|
|
|
//encoderY.currentPosition();
|
|
|
|
//encoderZ.currentPosition();
|
2015-11-07 16:23:18 -07:00
|
|
|
|
2016-01-08 15:15:08 -07:00
|
|
|
//axisX.checkTiming();
|
|
|
|
//axisY.checkTiming();
|
|
|
|
//axisZ.checkTiming();
|
2015-11-06 15:22:17 -07:00
|
|
|
|
2016-01-08 15:15:08 -07:00
|
|
|
//checkAxisVsEncoder(&axisX, &encoderX, &motorConsMissedSteps[0], &motorLastPosition[0], &motorConsMissedStepsDecay[0], &motorConsEncoderEnabled[0]);
|
|
|
|
//checkAxisVsEncoder(&axisY, &encoderY, &motorConsMissedSteps[1], &motorLastPosition[1], &motorConsMissedStepsDecay[1], &motorConsEncoderEnabled[1]);
|
|
|
|
//checkAxisVsEncoder(&axisZ, &encoderZ, &motorConsMissedSteps[2], &motorLastPosition[2], &motorConsMissedStepsDecay[2], &motorConsEncoderEnabled[2]);
|
2015-12-04 15:51:20 -07:00
|
|
|
|
|
|
|
if (motorConsMissedSteps[0] > motorConsMissedStepsMax[0]) {
|
|
|
|
axisX.deactivateAxis();
|
|
|
|
Serial.print("R99");
|
|
|
|
Serial.print(" deactivate motor X due to missed steps");
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\n");
|
2016-01-06 15:05:29 -07:00
|
|
|
|
|
|
|
if (axisX.movingToHome()) {
|
|
|
|
encoderX.setPosition(0);
|
|
|
|
axisX.setCurrentPosition(0);
|
|
|
|
Serial.print("R99");
|
|
|
|
Serial.print(" home position X axis detected with encoder");
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\n");
|
2016-01-06 15:05:29 -07:00
|
|
|
}
|
|
|
|
|
2015-12-04 15:51:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (motorConsMissedSteps[1] > motorConsMissedStepsMax[1]) {
|
2016-01-06 15:05:29 -07:00
|
|
|
axisY.deactivateAxis();
|
2015-12-04 15:51:20 -07:00
|
|
|
Serial.print("R99");
|
|
|
|
Serial.print(" deactivate motor Y due to missed steps");
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\n");
|
2016-01-06 15:05:29 -07:00
|
|
|
|
|
|
|
if (axisY.movingToHome()) {
|
|
|
|
encoderY.setPosition(0);
|
|
|
|
axisY.setCurrentPosition(0);
|
|
|
|
Serial.print("R99");
|
|
|
|
Serial.print(" home position Y axis detected with encoder");
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\n");
|
2016-01-06 15:05:29 -07:00
|
|
|
}
|
2015-12-04 15:51:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (motorConsMissedSteps[2] > motorConsMissedStepsMax[2]) {
|
2016-01-06 15:05:29 -07:00
|
|
|
axisZ.deactivateAxis();
|
2015-12-04 15:51:20 -07:00
|
|
|
Serial.print("R99");
|
|
|
|
Serial.print(" deactivate motor Z due to missed steps");
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\n");
|
2016-01-06 15:05:29 -07:00
|
|
|
|
|
|
|
if (axisZ.movingToHome()) {
|
|
|
|
encoderZ.setPosition(0);
|
|
|
|
axisZ.setCurrentPosition(0);
|
|
|
|
Serial.print("R99");
|
|
|
|
Serial.print(" home position Z axis detected with encoder");
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\n");
|
2016-01-06 15:05:29 -07:00
|
|
|
}
|
2015-11-11 15:09:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (axisX.endStopAxisReached(false)) {
|
|
|
|
axisX.setCurrentPosition(0);
|
|
|
|
encoderX.setPosition(0);
|
|
|
|
}
|
|
|
|
|
2015-12-04 15:51:20 -07:00
|
|
|
if (axisY.endStopAxisReached(false)) {
|
|
|
|
axisY.setCurrentPosition(0);
|
|
|
|
encoderY.setPosition(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (axisZ.endStopAxisReached(false)) {
|
|
|
|
axisZ.setCurrentPosition(0);
|
|
|
|
encoderZ.setPosition(0);
|
|
|
|
}
|
|
|
|
|
2015-11-11 15:09:15 -07:00
|
|
|
|
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
|
|
|
|
2015-11-11 15:09:15 -07: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))) {
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("R99 timeout X axis\r\n");
|
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))) {
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("R99 timeout Y axis\r\n");
|
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))) {
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("R99 timeout Z axis\r\n");
|
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) {
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("R99 emergency stop\r\n");
|
2014-10-24 16:02:50 -06:00
|
|
|
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) {
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("R99 error\r\n");
|
2015-12-31 08:01:40 -07:00
|
|
|
|
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++;
|
2016-01-08 15:15:08 -07:00
|
|
|
|
2015-11-11 15:09:15 -07:00
|
|
|
//if (currentMillis % 2500 == 0)
|
2016-01-06 15:05:29 -07:00
|
|
|
if (currentMillis % 750 == 0)
|
|
|
|
//if (1 == 1)
|
2014-10-12 15:57:07 -06:00
|
|
|
{
|
2016-02-03 15:15:51 -07:00
|
|
|
Serial.print(COMM_REPORT_CMD_BUSY);
|
2016-10-02 15:43:39 -06:00
|
|
|
//Serial.print("\r\n");
|
|
|
|
CurrentState::getInstance()->printQAndNewLine();
|
2015-11-11 15:09:15 -07:00
|
|
|
reportPosition();
|
2016-01-06 15:05:29 -07:00
|
|
|
/*
|
2015-12-04 15:51:20 -07:00
|
|
|
Serial.print("R99");
|
|
|
|
Serial.print(" encoder pos ");
|
|
|
|
Serial.print(encoderX.currentPosition());
|
|
|
|
Serial.print(" axis pos ");
|
|
|
|
Serial.print(axisX.currentPosition());
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\n");
|
2015-12-04 15:51:20 -07:00
|
|
|
|
|
|
|
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());
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\n");
|
2016-01-06 15:05:29 -07:00
|
|
|
*/
|
2015-12-04 15:51:20 -07:00
|
|
|
|
2015-11-11 15:09:15 -07:00
|
|
|
//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());
|
2016-09-09 11:18:16 -06:00
|
|
|
//Serial.print("\r\n");
|
2015-11-11 15:09:15 -07:00
|
|
|
|
2014-10-12 15:57:07 -06:00
|
|
|
}
|
|
|
|
|
2014-06-25 14:22:52 -06:00
|
|
|
}
|
|
|
|
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("R99 stopped\r\n");
|
2015-06-21 15:39:45 -06:00
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
// Stop motors
|
|
|
|
|
|
|
|
axisSubStep[0] = COMM_REPORT_MOVE_STATUS_STOP_MOTOR;
|
|
|
|
axisSubStep[1] = COMM_REPORT_MOVE_STATUS_STOP_MOTOR;
|
|
|
|
axisSubStep[2] = COMM_REPORT_MOVE_STATUS_STOP_MOTOR;
|
|
|
|
|
|
|
|
reportStatus(&axisX, axisSubStep[0]);
|
|
|
|
reportStatus(&axisY, axisSubStep[1]);
|
|
|
|
reportStatus(&axisZ, axisSubStep[2]);
|
|
|
|
|
2015-08-02 16:16:35 -06:00
|
|
|
disableMotors();
|
2014-07-23 01:46:21 -06:00
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
// Report end statuses
|
|
|
|
|
2015-11-07 16:23:18 -07:00
|
|
|
currentPoint[0] = axisX.currentPosition();
|
|
|
|
currentPoint[1] = axisY.currentPosition();
|
|
|
|
currentPoint[2] = axisZ.currentPosition();
|
2015-08-07 15:30:24 -06:00
|
|
|
|
2014-05-28 17:02:22 -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
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
// Report axis idle
|
|
|
|
|
|
|
|
axisSubStep[0] = COMM_REPORT_MOVE_STATUS_IDLE;
|
|
|
|
axisSubStep[1] = COMM_REPORT_MOVE_STATUS_IDLE;
|
|
|
|
axisSubStep[2] = COMM_REPORT_MOVE_STATUS_IDLE;
|
|
|
|
|
|
|
|
reportStatus(&axisX, axisSubStep[0]);
|
|
|
|
reportStatus(&axisY, axisSubStep[1]);
|
|
|
|
reportStatus(&axisZ, axisSubStep[2]);
|
|
|
|
|
|
|
|
disableMotors();
|
|
|
|
|
|
|
|
// Return error
|
|
|
|
|
2014-07-25 14:32:37 -06:00
|
|
|
return error;
|
2014-05-25 17:20:00 -06:00
|
|
|
}
|
2014-09-04 15:10:47 -06:00
|
|
|
|
|
|
|
//
|
|
|
|
// Calibration
|
|
|
|
//
|
|
|
|
|
|
|
|
int StepperControl::calibrateAxis(int axis) {
|
|
|
|
|
2016-01-02 15:21:01 -07:00
|
|
|
// Load motor and encoder settings
|
2014-09-21 14:42:44 -06:00
|
|
|
|
2015-08-07 15:30:24 -06:00
|
|
|
loadMotorSettings();
|
2016-01-02 15:21:01 -07:00
|
|
|
loadEncoderSettings();
|
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-12-31 08:01:40 -07:00
|
|
|
float * missedSteps;
|
2016-01-03 14:28:06 -07:00
|
|
|
int * missedStepsMax;
|
|
|
|
long * lastPosition;
|
|
|
|
float * encoderStepDecay;
|
|
|
|
bool * encoderEnabled;
|
2016-02-06 10:23:24 -07:00
|
|
|
int * axisStatus;
|
2015-11-20 14:44:12 -07:00
|
|
|
|
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:
|
2016-01-03 14:28:06 -07:00
|
|
|
calibAxis = &axisX;
|
|
|
|
calibEncoder = &encoderX;
|
|
|
|
parEndInv = MOVEMENT_INVERT_ENDPOINTS_X;
|
|
|
|
parNbrStp = MOVEMENT_AXIS_NR_STEPS_X;
|
|
|
|
invertEndStops = endStInv[0];
|
|
|
|
missedSteps = &motorConsMissedSteps[0];
|
|
|
|
missedStepsMax = &motorConsMissedStepsMax[0];
|
|
|
|
lastPosition = &motorLastPosition[0];
|
|
|
|
encoderStepDecay = &motorConsMissedStepsDecay[0];
|
|
|
|
encoderEnabled = &motorConsEncoderEnabled[0];
|
2016-02-06 10:23:24 -07:00
|
|
|
axisStatus = &axisSubStep[0];
|
2015-08-13 15:07:36 -06:00
|
|
|
break;
|
2015-08-07 15:30:24 -06:00
|
|
|
case 1:
|
2016-01-03 14:28:06 -07:00
|
|
|
calibAxis = &axisY;
|
|
|
|
calibEncoder = &encoderY;
|
|
|
|
parEndInv = MOVEMENT_INVERT_ENDPOINTS_Y;;
|
|
|
|
parNbrStp = MOVEMENT_AXIS_NR_STEPS_Y;
|
|
|
|
invertEndStops = endStInv[1];
|
|
|
|
missedSteps = &motorConsMissedSteps[1];
|
|
|
|
missedStepsMax = &motorConsMissedStepsMax[1];
|
|
|
|
lastPosition = &motorLastPosition[1];
|
|
|
|
encoderStepDecay = &motorConsMissedStepsDecay[1];
|
|
|
|
encoderEnabled = &motorConsEncoderEnabled[1];
|
2016-02-06 10:23:24 -07:00
|
|
|
axisStatus = &axisSubStep[1];
|
2015-08-07 15:30:24 -06:00
|
|
|
break;
|
|
|
|
case 2:
|
2016-01-03 14:28:06 -07:00
|
|
|
calibAxis = &axisZ;
|
|
|
|
calibEncoder = &encoderZ;
|
|
|
|
parEndInv = MOVEMENT_INVERT_ENDPOINTS_Z;
|
|
|
|
parNbrStp = MOVEMENT_AXIS_NR_STEPS_Z;
|
|
|
|
invertEndStops = endStInv[2];
|
|
|
|
missedSteps = &motorConsMissedSteps[2];
|
|
|
|
missedStepsMax = &motorConsMissedStepsMax[2];
|
|
|
|
lastPosition = &motorLastPosition[2];
|
|
|
|
encoderStepDecay = &motorConsMissedStepsDecay[2];
|
|
|
|
encoderEnabled = &motorConsEncoderEnabled[2];
|
2016-02-06 10:23:24 -07:00
|
|
|
axisStatus = &axisSubStep[2];
|
2015-08-07 15:30:24 -06:00
|
|
|
break;
|
|
|
|
default:
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("R99 Calibration error: invalid axis selected\r\n");
|
2015-08-07 15:30:24 -06:00
|
|
|
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()) {
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("R99 Calibration error: end stop active before start\r\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-12-31 08:01:40 -07:00
|
|
|
Serial.print(" move to start for calibration");
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\n");
|
2015-08-07 15:30:24 -06:00
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
*axisStatus = COMM_REPORT_MOVE_STATUS_START_MOTOR;
|
|
|
|
reportStatus(&axisX, axisSubStep[0]);
|
2014-09-04 15:10:47 -06:00
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
// Move towards home
|
2015-12-02 15:31:29 -07:00
|
|
|
calibAxis->enableMotor();
|
|
|
|
calibAxis->setDirectionHome();
|
2015-12-31 08:01:40 -07:00
|
|
|
calibAxis->setCurrentPosition(calibEncoder->currentPosition());
|
2015-12-02 15:31:29 -07:00
|
|
|
|
2015-12-31 08:01:40 -07:00
|
|
|
stepsCount = 0;
|
|
|
|
*missedSteps = 0;
|
|
|
|
movementDone = false;
|
2015-12-02 15:31:29 -07:00
|
|
|
|
2015-12-31 08:01:40 -07:00
|
|
|
motorConsMissedSteps[0] = 0;
|
|
|
|
motorConsMissedSteps[1] = 0;
|
|
|
|
motorConsMissedSteps[2] = 0;
|
2014-09-21 14:42:44 -06:00
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
*axisStatus = COMM_REPORT_MOVE_STATUS_CRAWLING;
|
|
|
|
reportStatus(&axisX, axisSubStep[0]);
|
|
|
|
|
|
|
|
reportCalib(&axisX, COMM_REPORT_CALIBRATE_STATUS_TO_HOME);
|
|
|
|
|
2014-09-21 14:42:44 -06:00
|
|
|
while (!movementDone && error == 0) {
|
2014-09-04 15:10:47 -06:00
|
|
|
|
2016-01-08 15:15:08 -07:00
|
|
|
//checkAxisVsEncoder(&axisX, &encoderX, &motorConsMissedSteps[0], &motorLastPosition[0], &motorConsMissedStepsDecay[0], &motorConsEncoderEnabled[0]);
|
2015-12-31 08:01:40 -07: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) {
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("R99 emergency stop\r\n");
|
2014-10-24 16:02:50 -06:00
|
|
|
movementDone = true;
|
|
|
|
error = 1;
|
|
|
|
}
|
|
|
|
}
|
2015-12-31 08:01:40 -07:00
|
|
|
|
|
|
|
// Ignore the missed steps at startup time
|
|
|
|
//if (stepsCount < 20) {
|
|
|
|
// *missedSteps = 0;
|
|
|
|
//}
|
|
|
|
|
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-31 08:01:40 -07:00
|
|
|
if ((!calibAxis->endStopMin() && !calibAxis->endStopMax()) && !movementDone && (*missedSteps < *missedStepsMax)) {
|
2014-09-04 15:10:47 -06:00
|
|
|
|
2015-12-31 08:01:40 -07:00
|
|
|
calibAxis->setStepAxis();
|
2014-09-04 15:10:47 -06:00
|
|
|
|
2016-01-08 15:15:08 -07:00
|
|
|
delayMicroseconds(100000 / 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
|
2016-02-03 15:15:51 -07:00
|
|
|
Serial.print(COMM_REPORT_CMD_BUSY);
|
2016-10-02 15:43:39 -06:00
|
|
|
//Serial.print("\r\n");
|
|
|
|
CurrentState::getInstance()->printQAndNewLine();
|
2014-10-12 15:57:07 -06:00
|
|
|
}
|
2015-12-31 08:01:40 -07:00
|
|
|
|
|
|
|
if (stepsCount % (speedMin[axis] / 6) == 0 /*|| *missedSteps > 3*/)
|
|
|
|
{
|
2015-12-02 15:31:29 -07:00
|
|
|
Serial.print("R99");
|
2015-12-31 08:01:40 -07:00
|
|
|
Serial.print(" step count ");
|
|
|
|
Serial.print(stepsCount);
|
2015-12-02 15:31:29 -07:00
|
|
|
Serial.print(" missed steps ");
|
2015-12-31 08:01:40 -07:00
|
|
|
Serial.print(*missedSteps);
|
2015-12-02 15:31:29 -07:00
|
|
|
Serial.print(" max steps ");
|
2015-12-31 08:01:40 -07:00
|
|
|
Serial.print(*missedStepsMax);
|
2015-12-02 15:31:29 -07:00
|
|
|
Serial.print(" cur pos mtr ");
|
|
|
|
Serial.print(calibAxis->currentPosition());
|
|
|
|
Serial.print(" cur pos enc ");
|
|
|
|
Serial.print(calibEncoder->currentPosition());
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\n");
|
2015-12-31 08:01:40 -07:00
|
|
|
}
|
2014-10-12 15:57:07 -06:00
|
|
|
|
2015-12-02 15:31:29 -07:00
|
|
|
calibAxis->resetMotorStep();
|
2016-01-08 15:15:08 -07:00
|
|
|
delayMicroseconds(100000 / speedMin[axis] /2);
|
2014-09-04 15:10:47 -06:00
|
|
|
|
|
|
|
} else {
|
|
|
|
movementDone = true;
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("R99 movement done\r\n");
|
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
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
reportCalib(&axisX, COMM_REPORT_CALIBRATE_STATUS_TO_END);
|
|
|
|
|
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-12-31 08:01:40 -07:00
|
|
|
Serial.print(" at starting point");
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\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);
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\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
|
|
|
|
2015-12-31 08:01:40 -07:00
|
|
|
Serial.print("R99");
|
|
|
|
Serial.print(" axis ");
|
|
|
|
Serial.print(calibAxis->label);
|
|
|
|
Serial.print(" calibrating length");
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\n");
|
2015-12-31 08:01:40 -07:00
|
|
|
|
|
|
|
stepsCount = 0;
|
2014-09-21 14:42:44 -06:00
|
|
|
movementDone = false;
|
2015-12-31 08:01:40 -07:00
|
|
|
*missedSteps = 0;
|
2015-12-02 15:31:29 -07:00
|
|
|
calibAxis->setDirectionAway();
|
2015-12-31 08:01:40 -07:00
|
|
|
calibAxis->setCurrentPosition(calibEncoder->currentPosition());
|
|
|
|
|
|
|
|
motorConsMissedSteps[0] = 0;
|
|
|
|
motorConsMissedSteps[1] = 0;
|
|
|
|
motorConsMissedSteps[2] = 0;
|
2014-09-04 15:10:47 -06:00
|
|
|
|
2016-01-08 15:15:08 -07:00
|
|
|
long encoderStartPoint = calibEncoder->currentPosition();
|
|
|
|
long encoderEndPoint = calibEncoder->currentPosition();
|
|
|
|
|
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) {
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("R99 emergency stop\r\n");
|
2014-10-24 16:02:50 -06:00
|
|
|
movementDone = true;
|
|
|
|
error = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-31 08:01:40 -07:00
|
|
|
// Ignore the missed steps at startup time
|
|
|
|
if (stepsCount < 10) {
|
|
|
|
*missedSteps = 0;
|
|
|
|
}
|
|
|
|
|
2014-09-21 14:42:44 -06:00
|
|
|
// Move until the end stop at the other side of the axis is reached
|
2015-12-31 08:01:40 -07:00
|
|
|
if (((!invertEndStops && !calibAxis->endStopMax()) || (invertEndStops && !calibAxis->endStopMin())) && !movementDone && (*missedSteps < *missedStepsMax)) {
|
2014-09-04 15:10:47 -06:00
|
|
|
|
2015-12-31 08:01:40 -07:00
|
|
|
calibAxis->setStepAxis();
|
2015-08-13 15:07:36 -06:00
|
|
|
stepsCount++;
|
2014-09-04 15:10:47 -06:00
|
|
|
|
2016-01-08 15:15:08 -07:00
|
|
|
//checkAxisVsEncoder(&axisX, &encoderX, &motorConsMissedSteps[0], &motorLastPosition[0], &motorConsMissedStepsDecay[0], &motorConsEncoderEnabled[0]);
|
2015-12-31 08:01:40 -07:00
|
|
|
|
|
|
|
|
2016-01-08 15:15:08 -07:00
|
|
|
delayMicroseconds(100000 / 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
|
2016-02-03 15:15:51 -07:00
|
|
|
Serial.print(COMM_REPORT_CMD_BUSY);
|
2016-10-02 15:43:39 -06:00
|
|
|
//Serial.print("\r\n");
|
|
|
|
CurrentState::getInstance()->printQAndNewLine();
|
2014-10-12 15:57:07 -06:00
|
|
|
}
|
2016-01-08 15:15:08 -07:00
|
|
|
/*
|
|
|
|
if (stepsCount % (speedMin[axis] / 6) == 0)
|
2015-12-31 08:01:40 -07:00
|
|
|
{
|
|
|
|
Serial.print("R99");
|
|
|
|
Serial.print(" step count ");
|
|
|
|
Serial.print(stepsCount);
|
|
|
|
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());
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\n");
|
2015-12-31 08:01:40 -07:00
|
|
|
}
|
2016-01-08 15:15:08 -07:00
|
|
|
*/
|
2014-10-12 15:57:07 -06:00
|
|
|
|
2015-12-02 15:31:29 -07:00
|
|
|
calibAxis->resetMotorStep();
|
2016-01-08 15:15:08 -07:00
|
|
|
delayMicroseconds(100000 / speedMin[axis] /2);
|
2014-09-04 15:10:47 -06:00
|
|
|
|
2014-09-21 14:42:44 -06:00
|
|
|
} else {
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("R99 movement done\r\n");
|
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-12-31 08:01:40 -07:00
|
|
|
Serial.print(" at end point");
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\n");
|
2015-08-07 15:30:24 -06:00
|
|
|
|
2016-01-08 15:15:08 -07:00
|
|
|
encoderEndPoint = calibEncoder->currentPosition();
|
|
|
|
|
|
|
|
// if the encoder is enabled, use the encoder data instead of the step count
|
|
|
|
|
|
|
|
if (encoderEnabled) {
|
|
|
|
stepsCount = abs(encoderEndPoint - encoderStartPoint);
|
|
|
|
}
|
|
|
|
|
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);
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\n");
|
2014-09-22 14:35:01 -06:00
|
|
|
}
|
2014-09-04 15:10:47 -06:00
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
*axisStatus = COMM_REPORT_MOVE_STATUS_STOP_MOTOR;
|
|
|
|
reportStatus(&axisX, axisSubStep[0]);
|
|
|
|
|
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
|
|
|
|
2015-06-14 15:08:57 -06:00
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
*axisStatus = COMM_REPORT_MOVE_STATUS_IDLE;
|
|
|
|
reportStatus(&axisX, axisSubStep[0]);
|
2015-08-02 16:16:35 -06:00
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
reportCalib(&axisX, COMM_REPORT_CALIBRATE_STATUS_IDLE);
|
2016-02-03 15:15:51 -07:00
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
return error;
|
2016-02-03 15:15:51 -07:00
|
|
|
}
|
|
|
|
|
2016-02-06 10:23:24 -07:00
|
|
|
|
2015-08-02 16:16:35 -06:00
|
|
|
// Handle movement by checking each axis
|
|
|
|
void StepperControl::handleMovementInterrupt(void){
|
|
|
|
|
2015-11-11 15:09:15 -07:00
|
|
|
encoderX.readEncoder();
|
2016-01-08 15:15:08 -07:00
|
|
|
encoderY.readEncoder();
|
|
|
|
encoderZ.readEncoder();
|
2015-12-31 08:01:40 -07:00
|
|
|
|
2016-01-08 15:15:08 -07:00
|
|
|
axisX.checkTiming();
|
|
|
|
axisY.checkTiming();
|
|
|
|
axisZ.checkTiming();
|
2015-12-31 08:01:40 -07:00
|
|
|
|
2016-01-08 15:15:08 -07:00
|
|
|
checkAxisVsEncoder(&axisX, &encoderX, &motorConsMissedSteps[0], &motorLastPosition[0], &motorConsMissedStepsDecay[0], &motorConsEncoderEnabled[0]);
|
|
|
|
checkAxisVsEncoder(&axisY, &encoderY, &motorConsMissedSteps[1], &motorLastPosition[1], &motorConsMissedStepsDecay[1], &motorConsEncoderEnabled[1]);
|
|
|
|
checkAxisVsEncoder(&axisZ, &encoderZ, &motorConsMissedSteps[2], &motorLastPosition[2], &motorConsMissedStepsDecay[2], &motorConsEncoderEnabled[2]);
|
2015-12-31 08:01:40 -07:00
|
|
|
|
2015-12-02 15:31:29 -07:00
|
|
|
}
|
|
|
|
|
2015-12-31 08:01:40 -07:00
|
|
|
int debugPrintCount = 0;
|
|
|
|
|
2015-12-02 15:31:29 -07:00
|
|
|
// Check encoder to verify the motor is at the right position
|
2016-01-03 14:28:06 -07:00
|
|
|
void StepperControl::checkAxisVsEncoder(StepperControlAxis* axis, StepperControlEncoder* encoder, float* missedSteps, long* lastPosition, float* encoderStepDecay, bool* encoderEnabled) {
|
2015-12-04 15:51:20 -07:00
|
|
|
|
|
|
|
// If a step is done
|
2015-12-31 08:01:40 -07:00
|
|
|
//if (axis->isStepDone() && axis->currentPosition() % 3 == 0) {
|
2016-01-04 14:52:58 -07:00
|
|
|
if (*encoderEnabled && axis->isStepDone()) {
|
2015-12-02 15:31:29 -07:00
|
|
|
|
2015-12-31 08:01:40 -07:00
|
|
|
bool stepMissed = false;
|
2015-12-04 15:51:20 -07:00
|
|
|
|
2016-01-06 15:05:29 -07:00
|
|
|
/*
|
2015-12-31 08:01:40 -07:00
|
|
|
debugPrintCount++;
|
|
|
|
if (debugPrintCount % 50 == 0)
|
|
|
|
{
|
|
|
|
Serial.print("R99");
|
|
|
|
Serial.print(" encoder pos ");
|
|
|
|
Serial.print(encoder->currentPosition());
|
|
|
|
Serial.print(" axis pos ");
|
|
|
|
Serial.print(axis->currentPosition());
|
|
|
|
Serial.print(" last pos ");
|
|
|
|
Serial.print(*lastPosition);
|
|
|
|
Serial.print(" move up ");
|
|
|
|
Serial.print(axis->movingUp());
|
|
|
|
Serial.print(" missed step cons ");
|
|
|
|
Serial.print(motorConsMissedSteps[0]);
|
|
|
|
Serial.print(" missed step ");
|
|
|
|
Serial.print(*missedSteps);
|
|
|
|
Serial.print(" encoder X pos ");
|
|
|
|
Serial.print(encoderX.currentPosition());
|
|
|
|
Serial.print(" axis X pos ");
|
|
|
|
Serial.print(axisX.currentPosition());
|
2016-01-03 14:28:06 -07:00
|
|
|
Serial.print(" decay ");
|
|
|
|
Serial.print(*encoderStepDecay);
|
|
|
|
Serial.print(" enabled ");
|
|
|
|
Serial.print(*encoderEnabled);
|
2016-09-09 11:18:16 -06:00
|
|
|
Serial.print("\r\n");
|
2015-12-31 08:01:40 -07:00
|
|
|
}
|
2016-01-06 15:05:29 -07:00
|
|
|
*/
|
2015-12-31 08:01:40 -07:00
|
|
|
|
|
|
|
// Decrease amount of missed steps if there are no missed step
|
|
|
|
if (*missedSteps > 0) {
|
2016-01-03 14:28:06 -07:00
|
|
|
(*missedSteps)-= (*encoderStepDecay);
|
2015-12-31 08:01:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check if the encoder goes in the wrong direction or nothing moved
|
|
|
|
if (( axis->movingUp() && *lastPosition >= axis->currentPosition()) ||
|
|
|
|
(!axis->movingUp() && *lastPosition <= axis->currentPosition())) {
|
|
|
|
stepMissed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (abs(axis->currentPosition() - encoder->currentPosition()) > 2) {
|
|
|
|
stepMissed = true;
|
|
|
|
}
|
2015-12-04 15:51:20 -07:00
|
|
|
|
2015-12-31 08:01:40 -07:00
|
|
|
if (stepMissed) {
|
|
|
|
axis->setCurrentPosition(encoder->currentPosition());
|
|
|
|
(*missedSteps)++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*lastPosition = axis->currentPosition();
|
|
|
|
axis->resetStepDone();
|
2015-12-04 15:51:20 -07:00
|
|
|
}
|
2015-08-02 16:16:35 -06:00
|
|
|
}
|
|
|
|
|
2015-12-31 08:01:40 -07: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);
|
|
|
|
|
2017-02-28 14:48:46 -07:00
|
|
|
endStEnbl[0] = intToBool(ParameterList::getInstance()->getValue(MOVEMENT_ENABLE_ENDPOINTS_X));
|
|
|
|
endStEnbl[1] = intToBool(ParameterList::getInstance()->getValue(MOVEMENT_ENABLE_ENDPOINTS_Y));
|
|
|
|
endStEnbl[2] = intToBool(ParameterList::getInstance()->getValue(MOVEMENT_ENABLE_ENDPOINTS_Z));
|
|
|
|
|
2015-12-31 08:01:40 -07:00
|
|
|
timeOut[0] = ParameterList::getInstance()->getValue(MOVEMENT_TIMEOUT_X);
|
|
|
|
timeOut[1] = ParameterList::getInstance()->getValue(MOVEMENT_TIMEOUT_X);
|
|
|
|
timeOut[2] = ParameterList::getInstance()->getValue(MOVEMENT_TIMEOUT_X);
|
|
|
|
|
2017-01-19 12:20:36 -07:00
|
|
|
motor2Inv[0] = intToBool(ParameterList::getInstance()->getValue(MOVEMENT_SECONDARY_MOTOR_INVERT_X));
|
2016-12-03 13:58:27 -07:00
|
|
|
motor2Inv[1] = false;
|
|
|
|
motor2Inv[2] = false;
|
|
|
|
|
2017-01-19 12:20:36 -07:00
|
|
|
motor2Enbl[0] = intToBool(ParameterList::getInstance()->getValue(MOVEMENT_SECONDARY_MOTOR_X));
|
2016-12-03 13:58:27 -07:00
|
|
|
motor2Enbl[1] = false;
|
|
|
|
motor2Enbl[2] = false;
|
|
|
|
|
2017-02-28 14:48:46 -07:00
|
|
|
axisX.loadMotorSettings(speedMax[0], speedMin[0], stepsAcc[0], timeOut[0], homeIsUp[0], motorInv[0], endStInv[0], MOVEMENT_INTERRUPT_SPEED, motor2Enbl[0], motor2Inv[0], endStEnbl[0]);
|
|
|
|
axisY.loadMotorSettings(speedMax[1], speedMin[1], stepsAcc[1], timeOut[1], homeIsUp[1], motorInv[1], endStInv[1], MOVEMENT_INTERRUPT_SPEED, motor2Enbl[1], motor2Inv[1], endStEnbl[1]);
|
|
|
|
axisZ.loadMotorSettings(speedMax[2], speedMin[2], stepsAcc[2], timeOut[2], homeIsUp[2], motorInv[2], endStInv[2], MOVEMENT_INTERRUPT_SPEED, motor2Enbl[2], motor2Inv[2], endStEnbl[2]);
|
2015-12-31 08:01:40 -07:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-01-19 12:20:36 -07:00
|
|
|
bool StepperControl::intToBool(int value) {
|
|
|
|
if (value == 1) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2015-12-31 08:01:40 -07:00
|
|
|
}
|
|
|
|
|
2016-01-02 15:21:01 -07:00
|
|
|
void StepperControl::loadEncoderSettings() {
|
|
|
|
|
|
|
|
// Load encoder settings
|
|
|
|
|
|
|
|
motorConsMissedStepsMax[0] = ParameterList::getInstance()->getValue(ENCODER_MISSED_STEPS_MAX_X);
|
|
|
|
motorConsMissedStepsMax[1] = ParameterList::getInstance()->getValue(ENCODER_MISSED_STEPS_MAX_Y);
|
|
|
|
motorConsMissedStepsMax[2] = ParameterList::getInstance()->getValue(ENCODER_MISSED_STEPS_MAX_Z);
|
|
|
|
|
2016-01-04 14:52:58 -07:00
|
|
|
motorConsMissedStepsDecay[0] = ParameterList::getInstance()->getValue(ENCODER_MISSED_STEPS_DECAY_X);
|
|
|
|
motorConsMissedStepsDecay[1] = ParameterList::getInstance()->getValue(ENCODER_MISSED_STEPS_DECAY_Y);
|
|
|
|
motorConsMissedStepsDecay[2] = ParameterList::getInstance()->getValue(ENCODER_MISSED_STEPS_DECAY_Z);
|
2016-01-02 15:21:01 -07:00
|
|
|
|
2016-01-04 14:52:58 -07:00
|
|
|
motorConsMissedStepsDecay[0] = motorConsMissedStepsDecay[0] / 100;
|
|
|
|
motorConsMissedStepsDecay[1] = motorConsMissedStepsDecay[1] / 100;
|
|
|
|
motorConsMissedStepsDecay[2] = motorConsMissedStepsDecay[2] / 100;
|
|
|
|
|
|
|
|
motorConsMissedStepsDecay[0] = min(max(motorConsMissedStepsDecay[0],0.01),99);
|
|
|
|
motorConsMissedStepsDecay[1] = min(max(motorConsMissedStepsDecay[1],0.01),99);
|
|
|
|
motorConsMissedStepsDecay[2] = min(max(motorConsMissedStepsDecay[2],0.01),99);
|
2016-01-02 15:21:01 -07:00
|
|
|
|
|
|
|
if (ParameterList::getInstance()->getValue(ENCODER_ENABLED_X) == 1) {
|
|
|
|
motorConsEncoderEnabled[0] = true;
|
|
|
|
} else {
|
|
|
|
motorConsEncoderEnabled[0] = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ParameterList::getInstance()->getValue(ENCODER_ENABLED_Y) == 1) {
|
|
|
|
motorConsEncoderEnabled[1] = true;
|
|
|
|
} else {
|
|
|
|
motorConsEncoderEnabled[1] = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ParameterList::getInstance()->getValue(ENCODER_ENABLED_Z) == 1) {
|
|
|
|
motorConsEncoderEnabled[2] = true;
|
|
|
|
} else {
|
|
|
|
motorConsEncoderEnabled[2] = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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() {
|
2016-10-03 14:17:46 -06:00
|
|
|
motorMotorsEnabled = true;
|
2016-02-06 10:23:24 -07:00
|
|
|
|
2017-01-19 12:40:17 -07:00
|
|
|
axisX.enableMotor();
|
2015-08-02 16:16:35 -06:00
|
|
|
axisY.enableMotor();
|
|
|
|
axisZ.enableMotor();
|
|
|
|
delay(100);
|
|
|
|
}
|
|
|
|
|
|
|
|
void StepperControl::disableMotors() {
|
2016-10-03 14:17:46 -06:00
|
|
|
motorMotorsEnabled = false;
|
2016-08-29 15:10:12 -06:00
|
|
|
|
2017-01-19 12:40:17 -07:00
|
|
|
axisX.disableMotor();
|
2015-08-02 16:16:35 -06:00
|
|
|
axisY.disableMotor();
|
|
|
|
axisZ.disableMotor();
|
|
|
|
delay(100);
|
|
|
|
}
|
|
|
|
|
2016-10-03 14:17:46 -06:00
|
|
|
bool StepperControl::motorsEnabled() {
|
|
|
|
return motorMotorsEnabled;
|
2016-08-29 15:10:12 -06:00
|
|
|
}
|
|
|
|
|
2015-08-02 16:16:35 -06:00
|
|
|
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();
|
|
|
|
}
|