diff --git a/Grbl_Esp32/Machines/motor_class_test.h b/Grbl_Esp32/Machines/motor_class_test.h
index c6b94df0..0a8f35bd 100644
--- a/Grbl_Esp32/Machines/motor_class_test.h
+++ b/Grbl_Esp32/Machines/motor_class_test.h
@@ -214,8 +214,8 @@
*/
// ======================= SPI 4 axis xxyz ===========================
-#define MACHINE_NAME "MotorClass Test 4x SPI XXYZ"
-#define N_AXIS 3
+#define MACHINE_NAME "MotorClass Test 4x SPI XXYZ A Servo"
+#define N_AXIS 4
#define TRINAMIC_DAISY_CHAIN
@@ -244,14 +244,14 @@
#define Z_TRINAMIC_DRIVER 2130
-#define Z_RSENSE TMC2130_RSENSE_DEFAULT
-#define Z_STEP_PIN GPIO_NUM_33
-#define Z_DIRECTION_PIN GPIO_NUM_32
-#define Z_CS_PIN X_CS_PIN // Daisy Chain, all share same CS pin
+#define Z_RSENSE TMC2130_RSENSE_DEFAULT
+#define Z_STEP_PIN GPIO_NUM_33
+#define Z_DIRECTION_PIN GPIO_NUM_32
+#define Z_CS_PIN X_CS_PIN // Daisy Chain, all share same CS pin
#define A_SERVO
-#define A_SERVO_PIN GPIO_NUM_33
-
-
-#define SPINDLE_TYPE SPINDLE_TYPE_NONE
+#define A_SERVO_PIN GPIO_NUM_25
+#define A_SERVO_RANGE_MIN 0.0
+#define A_SERVO_RANGE_MAX 5.0
+#define SPINDLE_TYPE SPINDLE_TYPE_NONE
diff --git a/Grbl_Esp32/Motors/MotorClass.cpp b/Grbl_Esp32/Motors/MotorClass.cpp
index ad19e831..2931bd4f 100644
--- a/Grbl_Esp32/Motors/MotorClass.cpp
+++ b/Grbl_Esp32/Motors/MotorClass.cpp
@@ -16,10 +16,10 @@
You should have received a copy of the GNU General Public License
along with Grbl. If not, see .
- TODO
+ TODO
Make sure public/private/protected is cleaned up.
Only a few Unipolar axes have been setup in init()
-
+
Deal with custom machine ... machine_trinamic_setup();
Class is ready to deal with non SPI pins, but they have not been needed yet.
It would be nice in the config message though
@@ -30,10 +30,10 @@
MPCNC (ganged with shared direction pin)
TMC2130 Pen Laser (trinamics, stallguard tuning)
Unipolar
-
+
TODO
4 Axis SPI (Daisy Chain, Ganged with unique direction pins)
-
+
Reference
TMC2130 Datasheet https://www.trinamic.com/fileadmin/assets/Products/ICs_Documents/TMC2130_datasheet.pdf
@@ -45,6 +45,7 @@
Motor* myMotor[6][2]; // number of axes (normal and ganged)
static TaskHandle_t readSgTaskHandle = 0; // for realtime stallguard data diaplay
+static TaskHandle_t servoUpdateTaskHandle = 0;
uint8_t rmt_chan_num[6][2];
rmt_item32_t rmtItem[2];
@@ -52,8 +53,9 @@ rmt_config_t rmtConfig;
bool motor_class_steps; // true if at least one motor class is handling steps
-void init_motors() {
- motor_class_steps = false;
+void init_motors() {
+ bool need_servo_task = false;
+ motor_class_steps = false; // does any class need step info?
// TODO SPI needs to be done before constructors because they have an init that uses SPI
// Should move all inits to the end and conditionally turn on SPI
SPI.begin(); // Yes, I know about the SD issue
@@ -62,27 +64,25 @@ void init_motors() {
#ifdef X_TRINAMIC_DRIVER
myMotor[X_AXIS][0] = new TrinamicDriver(X_AXIS, X_STEP_PIN, X_DIRECTION_PIN, X_TRINAMIC_DRIVER, X_RSENSE, X_CS_PIN, get_next_trinamic_driver_index());
#elif defined(X_SERVO)
- myMotor[X_AXIS][0] = new RcServo(X_AXIS, X_SERVO_PIN);
+ myMotor[X_AXIS][0] = new RcServo(X_AXIS, X_SERVO_PIN, X_SERVO_RANGE_MIN, X_SERVO_RANGE_MAX);
#elif defined(X_UNIPOLAR)
- myMotor[X_AXIS][0] = new UnipolarMotor(X_AXIS, X_PIN_PHASE_0, X_PIN_PHASE_1, X_PIN_PHASE_2, X_PIN_PHASE_3);
- motor_class_steps = true; // could be moved to class
+ myMotor[X_AXIS][0] = new UnipolarMotor(X_AXIS, X_PIN_PHASE_0, X_PIN_PHASE_1, X_PIN_PHASE_2, X_PIN_PHASE_3);
#elif defined(X_STEP_PIN)
myMotor[X_AXIS][0] = new StandardStepper(X_AXIS, X_STEP_PIN, X_DIRECTION_PIN);
#else
- myMotor[X_AXIS][0] = new Nullmotor();
+ myMotor[X_AXIS][0] = new Nullmotor();
#endif
#ifdef X2_TRINAMIC_DRIVER
myMotor[X_AXIS][1] = new TrinamicDriver(X2_AXIS, X2_STEP_PIN, X2_DIRECTION_PIN, X2_TRINAMIC_DRIVER, X2_RSENSE, X2_CS_PIN, get_next_trinamic_driver_index());
#elif defined(X2_SERVO)
- myMotor[X_AXIS][1] = new RcServo(X2_AXIS, X2_SERVO_PIN);
+ myMotor[X_AXIS][1] = new RcServo(X2_AXIS, X2_SERVO_PIN), X2_SERVO_RANGE_MIN, X2_SERVO_RANGE_MAX;
#elif defined(X_UNIPOLAR)
- myMotor[X_AXIS][1] = new UnipolarMotor(X2_AXIS, X2_PIN_PHASE_0, X2_PIN_PHASE_1, X2_PIN_PHASE_2, X2_PIN_PHASE_3);
- motor_class_steps = true; // could be moved to class
+ myMotor[X_AXIS][1] = new UnipolarMotor(X2_AXIS, X2_PIN_PHASE_0, X2_PIN_PHASE_1, X2_PIN_PHASE_2, X2_PIN_PHASE_3);
#elif defined(X2_STEP_PIN)
myMotor[X_AXIS][1] = new StandardStepper(X2_AXIS, X2_STEP_PIN, X2_DIRECTION_PIN);
#else
- myMotor[X_AXIS][1] = new Nullmotor();
+ myMotor[X_AXIS][1] = new Nullmotor();
#endif
@@ -90,23 +90,21 @@ void init_motors() {
#ifdef Y_TRINAMIC_DRIVER
myMotor[Y_AXIS][0] = new TrinamicDriver(Y_AXIS, Y_STEP_PIN, Y_DIRECTION_PIN, Y_TRINAMIC_DRIVER, Y_RSENSE, Y_CS_PIN, get_next_trinamic_driver_index());
#elif defined(Y_SERVO)
- myMotor[Y_AXIS][0] = new RcServo(Y_AXIS, Y_SERVO_PIN);
+ myMotor[Y_AXIS][0] = new RcServo(Y_AXIS, Y_SERVO_PIN, Y_SERVO_RANGE_MIN, Y_SERVO_RANGE_MAX);
#elif defined(Y_UNIPOLAR)
- myMotor[Y_AXIS][0] = new UnipolarMotor(Y_AXIS, Y_PIN_PHASE_0, Y_PIN_PHASE_1, Y_PIN_PHASE_2, Y_PIN_PHASE_3);
- motor_class_steps = true; // could be moved to class
+ myMotor[Y_AXIS][0] = new UnipolarMotor(Y_AXIS, Y_PIN_PHASE_0, Y_PIN_PHASE_1, Y_PIN_PHASE_2, Y_PIN_PHASE_3);
#elif defined(Y_STEP_PIN)
myMotor[Y_AXIS][0] = new StandardStepper(Y_AXIS, Y_STEP_PIN, Y_DIRECTION_PIN);
#else
- myMotor[Y_AXIS][0] = new Nullmotor();
+ myMotor[Y_AXIS][0] = new Nullmotor();
#endif
#ifdef Y2_TRINAMIC_DRIVER
myMotor[Y_AXIS][1] = new TrinamicDriver(Y2_AXIS, Y2_STEP_PIN, Y2_DIRECTION_PIN, Y2_TRINAMIC_DRIVER, Y2_RSENSE, Y2_CS_PIN, get_next_trinamic_driver_index());
#elif defined(Y2_SERVO)
- myMotor[Y_AXIS][1] = new RcServo(Y2_AXIS, Y2_SERVO_PIN);
+ myMotor[Y_AXIS][1] = new RcServo(Y2_AXIS, Y2_SERVO_PIN, Y2_SERVO_RANGE_MIN, Y2_SERVO_RANGE_MAX);
#elif defined(Y2_UNIPOLAR)
- myMotor[Y_AXIS][1] = new UnipolarMotor(Y2_AXIS, Y2_PIN_PHASE_0, Y2_PIN_PHASE_1, Y2_PIN_PHASE_2, Y2_PIN_PHASE_3);
- motor_class_steps = true; // could be moved to class
+ myMotor[Y_AXIS][1] = new UnipolarMotor(Y2_AXIS, Y2_PIN_PHASE_0, Y2_PIN_PHASE_1, Y2_PIN_PHASE_2, Y2_PIN_PHASE_3);
#elif defined(Y2_STEP_PIN)
myMotor[Y_AXIS][1] = new StandardStepper(Y2_AXIS, Y2_STEP_PIN, Y2_DIRECTION_PIN);
#else
@@ -117,124 +115,115 @@ void init_motors() {
#ifdef Z_TRINAMIC_DRIVER
myMotor[Z_AXIS][0] = new TrinamicDriver(Z_AXIS, Z_STEP_PIN, Z_DIRECTION_PIN, Z_TRINAMIC_DRIVER, Z_RSENSE, Z_CS_PIN, get_next_trinamic_driver_index());
#elif defined(Z_SERVO)
- myMotor[Z_AXIS][0] = new RcServo(Z_AXIS, Z_SERVO_PIN);
+ myMotor[Z_AXIS][0] = new RcServo(Z_AXIS, Z_SERVO_PIN, Z_SERVO_RANGE_MIN, Z_SERVO_RANGE_MAX);
#elif defined(Z_UNIPOLAR)
- myMotor[Z_AXIS][0] = new UnipolarMotor(Z_AXIS, Z_PIN_PHASE_0, Z_PIN_PHASE_1, Z_PIN_PHASE_2, Z_PIN_PHASE_3);
- motor_class_steps = true; // could be moved to class
+ myMotor[Z_AXIS][0] = new UnipolarMotor(Z_AXIS, Z_PIN_PHASE_0, Z_PIN_PHASE_1, Z_PIN_PHASE_2, Z_PIN_PHASE_3);
#elif defined(Z_STEP_PIN)
myMotor[Z_AXIS][0] = new StandardStepper(Z_AXIS, Z_STEP_PIN, Z_DIRECTION_PIN);
#else
- myMotor[Z_AXIS][0] = new Nullmotor();
+ myMotor[Z_AXIS][0] = new Nullmotor();
#endif
#ifdef Z2_TRINAMIC_DRIVER
myMotor[Z_AXIS][1] = new TrinamicDriver(Z2_AXIS, Z2_STEP_PIN, Z2_DIRECTION_PIN, Z2_TRINAMIC_DRIVER, Z2_RSENSE, Z2_CS_PIN, get_next_trinamic_driver_index());
#elif defined(Z2_SERVO)
- myMotor[Z_AXIS][1] = new RcServo(Z2_AXIS, Z2_SERVO_PIN);
+ myMotor[Z_AXIS][1] = new RcServo(Z2_AXIS, Z2_SERVO_PIN, Z2_SERVO_RANGE_MIN, Z2_SERVO_RANGE_MAX);
#elif defined(Z2_UNIPOLAR)
- myMotor[Z_AXIS][1] = new UnipolarMotor(Z2_AXIS, Z2_PIN_PHASE_0, Z2_PIN_PHASE_1, Z2_PIN_PHASE_2, Z2_PIN_PHASE_3);
- motor_class_steps = true; // could be moved to class
+ myMotor[Z_AXIS][1] = new UnipolarMotor(Z2_AXIS, Z2_PIN_PHASE_0, Z2_PIN_PHASE_1, Z2_PIN_PHASE_2, Z2_PIN_PHASE_3);
#elif defined(Z2_STEP_PIN)
myMotor[Z_AXIS][1] = new StandardStepper(Z2_AXIS, Z2_STEP_PIN, Z2_DIRECTION_PIN);
#else
- myMotor[Z_AXIS][1] = new Nullmotor();
+ myMotor[Z_AXIS][1] = new Nullmotor();
#endif
// this WILL be done better with settings
#ifdef A_TRINAMIC_DRIVER
myMotor[A_AXIS][0] = new TrinamicDriver(A_AXIS, A_STEP_PIN, A_DIRECTION_PIN, A_TRINAMIC_DRIVER, A_RSENSE, A_CS_PIN, get_next_trinamic_driver_index());
#elif defined(A_SERVO)
- myMotor[A_AXIS][0] = new RcServo(A_AXIS, A_SERVO_PIN);
+ myMotor[A_AXIS][0] = new RcServo(A_AXIS, A_SERVO_PIN, A_SERVO_RANGE_MIN, A_SERVO_RANGE_MAX);
#elif defined(A_UNIPOLAR)
- myMotor[A_AXIS][0] = new UnipolarMotor(A_AXIS, A_PIN_PHASE_0, A_PIN_PHASE_1, A_PIN_PHASE_2, A_PIN_PHASE_3);
- motor_class_steps = true; // could be moved to class
+ myMotor[A_AXIS][0] = new UnipolarMotor(A_AXIS, A_PIN_PHASE_0, A_PIN_PHASE_1, A_PIN_PHASE_2, A_PIN_PHASE_3);
#elif defined(A_STEP_PIN)
myMotor[A_AXIS][0] = new StandardStepper(A_AXIS, A_STEP_PIN, A_DIRECTION_PIN);
#else
- myMotor[A_AXIS][0] = new Nullmotor();
+ myMotor[A_AXIS][0] = new Nullmotor();
#endif
#ifdef A2_TRINAMIC_DRIVER
myMotor[A_AXIS][1] = new TrinamicDriver(A2_AXIS, A2_STEP_PIN, A2_DIRECTION_PIN, A2_TRINAMIC_DRIVER, A2_RSENSE, A2_CS_PIN, get_next_trinamic_driver_index());
#elif defined(A2_SERVO)
- myMotor[A_AXIS][1] = new RcServo(A2_AXIS, A2_SERVO_PIN);
+ myMotor[A_AXIS][1] = new RcServo(A2_AXIS, A2_SERVO_PIN, A2_SERVO_RANGE_MIN, A2_SERVO_RANGE_MAX);
#elif defined(A2_UNIPOLAR)
- myMotor[A_AXIS][1] = new UnipolarMotor(A2_AXIS, A2_PIN_PHASE_0, A2_PIN_PHASE_1, A2_PIN_PHASE_2, A2_PIN_PHASE_3);
- motor_class_steps = true; // could be moved to class
+ myMotor[A_AXIS][1] = new UnipolarMotor(A2_AXIS, A2_PIN_PHASE_0, A2_PIN_PHASE_1, A2_PIN_PHASE_2, A2_PIN_PHASE_3);
#elif defined(A2_STEP_PIN)
myMotor[A_AXIS][1] = new StandardStepper(A2_AXIS, A2_STEP_PIN, A2_DIRECTION_PIN);
#else
- myMotor[A_AXIS][1] = new Nullmotor();
+ myMotor[A_AXIS][1] = new Nullmotor();
#endif
// this WILL be done better with settings
#ifdef B_TRINAMIC_DRIVER
myMotor[B_AXIS][0] = new TrinamicDriver(B_AXIS, B_STEP_PIN, B_DIRECTION_PIN, B_TRINAMIC_DRIVER, B_RSENSE, B_CS_PIN, get_next_trinamic_driver_index());
#elif defined(B_SERVO)
- myMotor[B_AXIS][0] = new RcServo(B_AXIS, B_SERVO_PIN);
+ myMotor[B_AXIS][0] = new RcServo(B_AXIS, B_SERVO_PIN, B_SERVO_RANGE_MIN, B_SERVO_RANGE_MAX);
#elif defined(B_UNIPOLAR)
- myMotor[B_AXIS][0] = new UnipolarMotor(B_AXIS, B_PIN_PHASE_0, B_PIN_PHASE_1, B_PIN_PHASE_2, B_PIN_PHASE_3);
- motor_class_steps = true; // could be moved to class
+ myMotor[B_AXIS][0] = new UnipolarMotor(B_AXIS, B_PIN_PHASE_0, B_PIN_PHASE_1, B_PIN_PHASE_2, B_PIN_PHASE_3);
#elif defined(B_STEP_PIN)
myMotor[B_AXIS][0] = new StandardStepper(B_AXIS, B_STEP_PIN, B_DIRECTION_PIN);
#else
- myMotor[B_AXIS][0] = new Nullmotor();
+ myMotor[B_AXIS][0] = new Nullmotor();
#endif
#ifdef B2_TRINAMIC_DRIVER
myMotor[B_AXIS][1] = new TrinamicDriver(B2_AXIS, B2_STEP_PIN, B2_DIRECTION_PIN, B2_TRINAMIC_DRIVER, B2_RSENSE, B2_CS_PIN, get_next_trinamic_driver_index());
#elif defined(B2_SERVO)
- myMotor[B_AXIS][1] = new RcServo(B2_AXIS, B2_SERVO_PIN);
+ myMotor[B_AXIS][1] = new RcServo(B2_AXIS, B2_SERVO_PIN, B2_SERVO_RANGE_MIN, B2_SERVO_RANGE_MAX);
#elif defined(B2_UNIPOLAR)
- myMotor[B_AXIS][1] = new UnipolarMotor(B2_AXIS, B2_PIN_PHASE_0, B2_PIN_PHASE_1, B2_PIN_PHASE_2, B2_PIN_PHASE_3);
- motor_class_steps = true; // could be moved to class
+ myMotor[B_AXIS][1] = new UnipolarMotor(B2_AXIS, B2_PIN_PHASE_0, B2_PIN_PHASE_1, B2_PIN_PHASE_2, B2_PIN_PHASE_3);
#elif defined(B2_STEP_PIN)
myMotor[B_AXIS][1] = new StandardStepper(B2_AXIS, B2_STEP_PIN, B2_DIRECTION_PIN);
#else
- myMotor[B_AXIS][1] = new Nullmotor();
+ myMotor[B_AXIS][1] = new Nullmotor();
#endif
// this WILL be done better with settings
#ifdef C_TRINAMIC_DRIVER
myMotor[C_AXIS][0] = new TrinamicDriver(C_AXIS, C_STEP_PIN, C_DIRECTION_PIN, C_TRINAMIC_DRIVER, C_RSENSE, C_CS_PIN, get_next_trinamic_driver_index());
#elif defined(C_SERVO)
- myMotor[C_AXIS][0] = new RcServo(C_AXIS, C_SERVO_PIN);
+ myMotor[C_AXIS][0] = new RcServo(C_AXIS, C_SERVO_PIN, C_SERVO_RANGE_MIN, C_SERVO_RANGE_MAX);
#elif defined(C_UNIPOLAR)
- myMotor[C_AXIS][0] = new UnipolarMotor(C_AXIS, C_PIN_PHASE_0, C_PIN_PHASE_1, C_PIN_PHASE_2, C_PIN_PHASE_3);
- motor_class_steps = true; // could be moved to class
+ myMotor[C_AXIS][0] = new UnipolarMotor(C_AXIS, C_PIN_PHASE_0, C_PIN_PHASE_1, C_PIN_PHASE_2, C_PIN_PHASE_3);
#elif defined(C_STEP_PIN)
myMotor[C_AXIS][0] = new StandardStepper(C_AXIS, C_STEP_PIN, C_DIRECTION_PIN);
#else
- myMotor[C_AXIS][0] = new Nullmotor();
+ myMotor[C_AXIS][0] = new Nullmotor();
#endif
#ifdef C2_TRINAMIC_DRIVER
myMotor[C_AXIS][1] = new TrinamicDriver(C2_AXIS, C2_STEP_PIN, C2_DIRECTION_PIN, C2_TRINAMIC_DRIVER, C2_RSENSE, C2_CS_PIN, get_next_trinamic_driver_index());
#elif defined(C2_SERVO)
- myMotor[C_AXIS][1] = new RcServo(C2_AXIS, C2_SERVO_PIN);
+ myMotor[C_AXIS][1] = new RcServo(C2_AXIS, C2_SERVO_PIN, C2_SERVO_RANGE_MIN, C2_SERVO_RANGE_MAX);
#elif defined(C2_UNIPOLAR)
- myMotor[C_AXIS][1] = new UnipolarMotor(C2_AXIS, C2_PIN_PHASE_0, C2_PIN_PHASE_1, C2_PIN_PHASE_2, C2_PIN_PHASE_3);
- motor_class_steps = true; // could be moved to class
+ myMotor[C_AXIS][1] = new UnipolarMotor(C2_AXIS, C2_PIN_PHASE_0, C2_PIN_PHASE_1, C2_PIN_PHASE_2, C2_PIN_PHASE_3);
#elif defined(C2_STEP_PIN)
myMotor[C_AXIS][1] = new StandardStepper(C2_AXIS, C2_STEP_PIN, C2_DIRECTION_PIN);
#else
- myMotor[C_AXIS][1] = new Nullmotor();
+ myMotor[C_AXIS][1] = new Nullmotor();
#endif
for (uint8_t axis = X_AXIS; axis < N_AXIS; axis++) {
- for (uint8_t gang_index = 0; gang_index < 2; gang_index++) {
- myMotor[axis][gang_index]->test();
- }
+ for (uint8_t gang_index = 0; gang_index < 2; gang_index++)
+ myMotor[axis][gang_index]->test();
}
-
- #ifdef STEPPERS_DISABLE_PIN
- grbl_msg_sendf(CLIENT_SERIAL,
+
+#ifdef STEPPERS_DISABLE_PIN
+ grbl_msg_sendf(CLIENT_SERIAL,
MSG_LEVEL_INFO,
"Global stepper enable pin:%d",
STEPPERS_DISABLE_PIN);
- pinMode(STEPPERS_DISABLE_PIN, OUTPUT); // global motor enable pin
+ pinMode(STEPPERS_DISABLE_PIN, OUTPUT); // global motor enable pin
- #endif
+#endif
motors_set_disable(true);
// tuning gets turned on if this is defined and laser mode is on at boot time.
@@ -249,7 +238,26 @@ void init_motors() {
0 // core
);
}
-#endif
+#endif
+
+ // certain motors need features to be turned on. Check them here
+ for (uint8_t axis = X_AXIS; axis < N_AXIS; axis++) {
+ for (uint8_t gang_index = 0; gang_index < 2; gang_index++) {
+ if (myMotor[axis][gang_index]->type_id == RC_SERVO_MOTOR) need_servo_task = true;
+ if (myMotor[axis][gang_index]->type_id == UNIPOLAR_MOTOR) motor_class_steps = true;
+ }
+ }
+
+ if (need_servo_task) {
+ xTaskCreatePinnedToCore(servoUpdateTask, // task
+ "servoUpdateTask", // name for task
+ 4096, // size of task stack
+ NULL, // parameters
+ 1, // priority
+ &servoUpdateTaskHandle,
+ 0 // core
+ );
+ }
}
@@ -289,29 +297,47 @@ void readSgTask(void* pvParameters) {
}
}
+void servoUpdateTask(void* pvParameters) {
+ TickType_t xLastWakeTime;
+ const TickType_t xUpdate = SERVO_TIMER_INT_FREQ; // in ticks (typically ms)
+
+
+ xLastWakeTime = xTaskGetTickCount(); // Initialise the xLastWakeTime variable with the current time.
+ while (true) { // don't ever return from this or the task dies
+
+ //grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Servo update");
+
+ for (uint8_t axis = X_AXIS; axis < N_AXIS; axis++) {
+ for (uint8_t gang_index = 0; gang_index < 2; gang_index++)
+ myMotor[axis][gang_index]->update();
+ }
+
+ vTaskDelayUntil(&xLastWakeTime, xUpdate);
+ }
+}
+
void motors_set_disable(bool disable) {
static bool _current_disable = true;
if (disable == _current_disable)
return;
-
+
_current_disable = disable;
//grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "motors_set_disable(%d)", disable);
// now step through all the motors
for (uint8_t gang_index = 0; gang_index < 2; gang_index++) {
- for (uint8_t axis = X_AXIS; axis < N_AXIS; axis++) {
+ for (uint8_t axis = X_AXIS; axis < N_AXIS; axis++)
myMotor[axis][gang_index]->set_disable(disable);
- }
}
// global disable pin
- #ifdef STEPPERS_DISABLE_PIN
- if (bit_istrue(settings.flags, BITFLAG_INVERT_ST_ENABLE)) {
- disable = !disable; // Apply pin invert.
- }
- digitalWrite(STEPPERS_DISABLE_PIN, disable);
- #endif
+#ifdef STEPPERS_DISABLE_PIN
+ if (bit_istrue(settings.flags, BITFLAG_INVERT_ST_ENABLE)) {
+ disable = !disable; // Apply pin invert.
+ }
+ digitalWrite(STEPPERS_DISABLE_PIN, disable);
+#endif
}
/*
@@ -331,17 +357,15 @@ void motor_read_settings() {
void motors_set_homing_mode(bool is_homing) {
//grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "motors_set_homing_mode(%d)", is_homing);
for (uint8_t gang_index = 0; gang_index < 2; gang_index++) {
- for (uint8_t axis = X_AXIS; axis < N_AXIS; axis++) {
+ for (uint8_t axis = X_AXIS; axis < N_AXIS; axis++)
myMotor[axis][gang_index]->set_homing_mode(is_homing);
- }
}
}
void motors_set_direction_pins(uint8_t onMask) {
for (uint8_t gang_index = 0; gang_index < 2; gang_index++) {
- for (uint8_t axis = X_AXIS; axis < N_AXIS; axis++) {
+ for (uint8_t axis = X_AXIS; axis < N_AXIS; axis++)
myMotor[axis][gang_index]->set_direction_pins(onMask);
- }
}
}
@@ -349,20 +373,20 @@ void motors_set_direction_pins(uint8_t onMask) {
currently much of the step pulse I/O is done in stepper.cpp
Some classes like UnipolarMotorClass do it themselves.
This gives every class a notification of step.
- Note: global variable (bool motor_class_steps) decides whether this
+ Note: global variable (bool motor_class_steps) decides whether this
is needed to be called.
*/
void motors_step(uint8_t step_mask, uint8_t dir_mask) {
for (uint8_t gang_index = 0; gang_index < 2; gang_index++) {
- for (uint8_t axis = X_AXIS; axis < N_AXIS; axis++) {
+ for (uint8_t axis = X_AXIS; axis < N_AXIS; axis++)
myMotor[axis][gang_index]->step(step_mask, dir_mask);
- }
}
}
// ============================== Class Methods ================================================
Motor :: Motor() {
+ type_id = MOTOR;
}
void Motor :: init() {
@@ -376,18 +400,10 @@ void Motor :: set_disable(bool disable) {}
void Motor :: set_direction_pins(uint8_t onMask) {}
void Motor :: step(uint8_t step_mask, uint8_t dir_mask) {}
bool Motor :: test() {return true;}; // true = OK
+void Motor :: update() {}
void Motor :: set_axis_name() {
- char ganged[3];
-
- if (dual_axis_index) {
- strcpy(ganged, "2");
- } else {
- strcpy(ganged, "");
- }
-
- sprintf(_axis_name, "%c%s", report_get_axis_letter(axis_index), ganged);
-
+ sprintf(_axis_name, "%c%s", report_get_axis_letter(axis_index), dual_axis_index ? "2" : "");
}
void Motor :: set_homing_mode(bool is_homing) {
diff --git a/Grbl_Esp32/Motors/MotorClass.h b/Grbl_Esp32/Motors/MotorClass.h
index 77dfa94c..7404e8d0 100644
--- a/Grbl_Esp32/Motors/MotorClass.h
+++ b/Grbl_Esp32/Motors/MotorClass.h
@@ -31,6 +31,8 @@
*/
+
+/*
#define TRINAMIC_RUN_MODE_STEALTHCHOP 0 // very quiet
#define TRINAMIC_RUN_MODE_COOLSTEP 1 // everything runs cooler so higher current possible
#define TRINAMIC_RUN_MODE_STALLGUARD 2 // everything runs cooler so higher current possible
@@ -43,26 +45,30 @@
#define TMC2130_RSENSE_DEFAULT 0.11f
#define TMC5160_RSENSE_DEFAULT 0.075f
+*/
-// ============ defaults =================
-#ifndef TRINAMIC_RUN_MODE
- #define TRINAMIC_RUN_MODE TRINAMIC_RUN_MODE_COOLSTEP
-#endif
-
-#ifndef TRINAMIC_HOMING_MODE
- #define TRINAMIC_HOMING_MODE TRINAMIC_HOMING_NONE
-#endif
#ifndef MOTORCLASS_H
#define MOTORCLASS_H
#include "../grbl.h"
#include // https://github.com/teemuatlut/TMCStepper
+#include "TrinamicDriverClass.h"
+#include "RcServoClass.h"
extern uint8_t rmt_chan_num[MAX_AXES][2];
extern rmt_item32_t rmtItem[2];
extern rmt_config_t rmtConfig;
+typedef enum {
+ MOTOR,
+ NULL_MOTOR,
+ STANDARD_MOTOR,
+ TRINAMIC_SPI_MOTOR,
+ UNIPOLAR_MOTOR,
+ RC_SERVO_MOTOR
+} motor_class_id_t;
+
// ========== global functions ===================
// These are used for setup and to talk to the motors as a group.
@@ -75,6 +81,8 @@ void motors_set_disable(bool disable);
void motors_set_direction_pins(uint8_t onMask);
void motors_step(uint8_t step_mask, uint8_t dir_mask);
+void servoUpdateTask(void* pvParameters);
+
extern bool motor_class_steps; // true if at least one motor class is handling steps
// ==================== Classes ====================
@@ -93,10 +101,14 @@ class Motor {
virtual void step(uint8_t step_mask, uint8_t dir_mask); // only used on Unipolar right now
virtual bool test();
virtual void set_axis_name();
+ virtual void update();
+ motor_class_id_t type_id;
uint8_t axis_index; // X_AXIS, etc
uint8_t dual_axis_index; // 0 = primary 1=ganged
uint8_t is_active = false;
+ bool _showError;
+ bool _use_mpos = true;
bool _is_homing;
char _axis_name[10];// this the name to use when reporting like "X" or "X2"
@@ -149,6 +161,7 @@ class TrinamicDriver : public StandardStepper {
uint32_t calc_tstep(float speed, float percent);
};
+
class UnipolarMotor : public Motor {
public:
UnipolarMotor();
@@ -171,20 +184,30 @@ class UnipolarMotor : public Motor {
class RcServo : public Motor {
public:
RcServo();
- RcServo(uint8_t axis_index, uint8_t pwm_pin);
+ RcServo(uint8_t axis_index, uint8_t pwm_pin, float min, float max);
void config_message();
void init();
void _write_pwm(uint32_t duty);
void set_disable(bool disable);
+ void update();
+ void read_settings();
uint8_t _pwm_pin;
uint8_t _channel_num;
uint32_t _current_pwm_duty;
+
+ float _position_min;
+ float _position_max; // position in millimeters
+ float _homing_position;
+
+ float servo_pulse_min;
+ float servo_pulse_max;
void set_location();
+ void _get_calibration();
};
-#endif
\ No newline at end of file
+#endif
diff --git a/Grbl_Esp32/Motors/RcServoClass.cpp b/Grbl_Esp32/Motors/RcServoClass.cpp
index 8f063a96..c5d0741c 100644
--- a/Grbl_Esp32/Motors/RcServoClass.cpp
+++ b/Grbl_Esp32/Motors/RcServoClass.cpp
@@ -1,15 +1,39 @@
/*
- StandardStepperClass.cpp
+ RcServo.cpp
- This is used for a stepper motor that just requires step and direction
- pins.
-
- TODO: Add an enable pin
+ This allows an RcServo to be used like any other motor. Serrvos
+ do have limitation in travel and speed, so you do need to respect that.
Part of Grbl_ESP32
2020 - Bart Dring
- Grbl is free software: you can redistribute it and/or modify
+ Servos have a limited travel, so they map the travel across a range in
+ the current work coordinatee system. The servo can only travel as far
+ as the range, but the internal axis value can keep going.
+
+ Range: The range is specified in the machine definition file with...
+
+ #define X_SERVO_RANGE_MIN 0.0
+ #define X_SERVO_RANGE_MAX 5.0
+
+ Direction: The direction can be changed using the $3 setting for the axis
+
+ Homing: During homing, the servo will move to one of the endpoints. The
+ endpoint is determined by the $23 setting for the axis. Do not define
+ a homing cycle for the axis with the servo.
+ You do need at least 1 homing cycle. TODO: Fix this
+
+ Calibration. You can tweak the endpoints using the $10n and $13n setting,
+ where n is the axis. The value is a percent. If you secify a percent outside the
+ the range specified by the values below, it will be reset to 100.0 (100% ... no change)
+ The calibration adjusts in direction of positive momement, so a value above 100% moves
+ towards the higher axis value.
+
+ #define SERVO_CAL_MIN
+ #define SERVO_CAL_MAX
+
+
+ Grbl_ESP32 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
@@ -22,42 +46,17 @@
*/
-// this is the pulse range of a the servo. Typical servos are 0.001 to 0.002 seconds
-// some servos have a wider range. You can adjust this here or in the calibration feature
-#define SERVO_MIN_PULSE_SEC 0.001 // min pulse in seconds
-#define SERVO_MAX_PULSE_SEC 0.002 // max pulse in seconds
-
-#define SERVO_POSITION_MIN_DEFAULT 0.0 // mm
-#define SERVO_POSITION_MAX_DEFAULT 20.0 // mm
-
-#define SERVO_PULSE_FREQ 50 // 50Hz ...This is a standard analog servo value. Digital ones can repeat faster
-
-#define SERVO_PULSE_RES_BITS 16 // bits of resolution of PWM (16 is max)
-#define SERVO_PULSE_RES_COUNT 65535 // see above TODO...do the math here 2^SERVO_PULSE_RES_BITS
-
-#define SERVO_TIME_PER_BIT ((1.0 / (float)SERVO_PULSE_FREQ) / ((float)SERVO_PULSE_RES_COUNT) ) // seconds
-
-#define SERVO_MIN_PULSE (uint16_t)(SERVO_MIN_PULSE_SEC / SERVO_TIME_PER_BIT) // in timer counts
-#define SERVO_MAX_PULSE (uint16_t)(SERVO_MAX_PULSE_SEC / SERVO_TIME_PER_BIT) // in timer counts
-
-#define SERVO_PULSE_RANGE (SERVO_MAX_PULSE-SERVO_MIN_PULSE)
-
-#define SERVO_CAL_MIN 20.0 // Percent: the minimum allowable calibration value
-#define SERVO_CAL_MAX 180.0 // Percent: the maximum allowable calibration value
-
-#define SERVO_TIMER_INT_FREQ 20.0 // Hz This is the task frequency
-
-#define SERVO_HOMING_OFF 0 // servo is off during homing
-#define SERVO_HOMING_TARGET 1 // servo is send to a location during homing
-
RcServo :: RcServo() {
}
-RcServo :: RcServo(uint8_t axis_index, uint8_t pwm_pin) {
+RcServo :: RcServo(uint8_t axis_index, uint8_t pwm_pin, float min, float max) {
+ type_id = RC_SERVO_MOTOR;
this->axis_index = axis_index % MAX_AXES;
this->dual_axis_index = axis_index < MAX_AXES ? 0 : 1; // 0 = primary 1 = ganged
this->_pwm_pin = pwm_pin;
+ _position_min = min;
+ _position_max = max;
set_axis_name();
init();
config_message();
@@ -65,19 +64,25 @@ RcServo :: RcServo(uint8_t axis_index, uint8_t pwm_pin) {
}
void RcServo :: init() {
+ read_settings();
_channel_num = sys_get_next_PWM_chan_num();
- ledcSetup(_channel_num, SERVO_PULSE_FREQ, SERVO_PULSE_RES_BITS);
+ ledcSetup(_channel_num, SERVO_PULSE_FREQ, SERVO_PULSE_RES_BITS);
ledcAttachPin(_pwm_pin, _channel_num);
_current_pwm_duty = 0;
+ pinMode(GPIO_NUM_4, OUTPUT);
+ digitalWrite(GPIO_NUM_4, HIGH);
+
}
-void RcServo :: config_message() {
- grbl_msg_sendf(CLIENT_SERIAL,
- MSG_LEVEL_INFO,
- "%s Axis RC Servo motor PWM:%d",
- _axis_name,
- _pwm_pin);
+void RcServo :: config_message() {
+ grbl_msg_sendf(CLIENT_SERIAL,
+ MSG_LEVEL_INFO,
+ "%s Axis RC Servo motor Output:%d Min:%5.3fmm Max:%5.3fmm",
+ _axis_name,
+ _pwm_pin,
+ _position_min,
+ _position_max);
}
void RcServo::_write_pwm(uint32_t duty) {
@@ -86,7 +91,8 @@ void RcServo::_write_pwm(uint32_t duty) {
return;
_current_pwm_duty = duty;
-
+
+ //grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "%s Servo Pwm %d", _axis_name, duty);
ledcWrite(_channel_num, duty);
}
@@ -96,3 +102,88 @@ void RcServo::set_disable(bool disable) {
_write_pwm(0);
}
+void RcServo::update() {
+ set_location();
+}
+
+void RcServo::set_location() {
+ uint32_t servo_pulse_len;
+ float servo_pos, mpos, offset;
+ // skip location if we are in alarm mode
+
+ //grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "locate");
+
+ if (sys.state == STATE_ALARM) {
+ set_disable(true);
+ return;
+ }
+
+ if (sys.state == STATE_HOMING) {
+ if (bit_istrue(settings.homing_dir_mask, bit(axis_index))) {
+ servo_pos = _position_min; // go to servos home position
+ } else {
+ servo_pos = _position_max; // go to servos home position
+ }
+
+ } else {
+ mpos = system_convert_axis_steps_to_mpos(sys_position, axis_index); // get the axis machine position in mm
+ offset = gc_state.coord_system[axis_index] + gc_state.coord_offset[axis_index]; // get the current axis work offset
+ servo_pos = mpos - offset; // determine the current work position
+ }
+
+ // determine the pulse length
+ servo_pulse_len = (uint32_t)mapConstrain(servo_pos, _position_min, _position_max, servo_pulse_min, servo_pulse_max);
+ _write_pwm(servo_pulse_len);
+
+}
+
+void RcServo::read_settings() {
+ _get_calibration();
+}
+
+// this should change to use its own settings.
+void RcServo::_get_calibration() {
+ bool settingsOK = true;
+ float _cal_min, _cal_max;
+
+ //grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Read settings");
+
+ // make sure the min is in range
+ if ((settings.steps_per_mm[axis_index] < SERVO_CAL_MIN) || (settings.steps_per_mm[axis_index] > SERVO_CAL_MAX)) {
+ grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Servo calibration ($10%d) value error. Reset to 100", axis_index);
+ settings.steps_per_mm[axis_index] = 100;
+ settingsOK = false;
+ }
+
+ // make sure the max is in range
+ // Note: Max travel is set positive via $$, but stored as a negative number
+ if ((settings.max_travel[axis_index] < -SERVO_CAL_MAX) || (settings.max_travel[axis_index] > -SERVO_CAL_MIN)) {
+ grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Servo calibration ($13%d) value error. Reset to 100", axis_index);
+ settings.max_travel[axis_index] = -100;
+ settingsOK = false;
+ }
+
+ if (! settingsOK) {
+ write_global_settings(); // they were changed, so write them
+ }
+
+ servo_pulse_min = SERVO_MIN_PULSE;
+ servo_pulse_max = SERVO_MAX_PULSE;
+
+ // apply inverts and store them in local variable
+ if (bit_istrue(settings.dir_invert_mask, bit(axis_index))) { // normal direction
+ _cal_min = 2.0 - (settings.steps_per_mm[axis_index] / 100.0);
+ _cal_max = 2.0 - (settings.max_travel[axis_index] / -100.0);
+ swap(servo_pulse_min, servo_pulse_max);
+ } else { // inverted direction
+ _cal_min = (settings.steps_per_mm[axis_index] / 100.0);
+ //_cal_max = 2.0 - (settings.max_travel[axis_index] / -100.0);
+ _cal_max = (settings.max_travel[axis_index] / -100.0);
+ }
+
+ //grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Servo calibration min%1.2f max %1.2f", _cal_min, _cal_max );
+
+ servo_pulse_min *= _cal_min;
+ servo_pulse_max *= _cal_max;
+}
+
diff --git a/Grbl_Esp32/Motors/RcServoClass.h b/Grbl_Esp32/Motors/RcServoClass.h
new file mode 100644
index 00000000..ed933127
--- /dev/null
+++ b/Grbl_Esp32/Motors/RcServoClass.h
@@ -0,0 +1,26 @@
+
+
+// this is the pulse range of a the servo. Typical servos are 0.001 to 0.002 seconds
+// some servos have a wider range. You can adjust this here or in the calibration feature
+#define SERVO_MIN_PULSE_SEC 0.001 // min pulse in seconds
+#define SERVO_MAX_PULSE_SEC 0.002 // max pulse in seconds
+
+#define SERVO_POSITION_MIN_DEFAULT 0.0 // mm
+#define SERVO_POSITION_MAX_DEFAULT 20.0 // mm
+
+#define SERVO_PULSE_FREQ 50 // 50Hz ...This is a standard analog servo value. Digital ones can repeat faster
+
+#define SERVO_PULSE_RES_BITS 16 // bits of resolution of PWM (16 is max)
+#define SERVO_PULSE_RES_COUNT 65535 // see above TODO...do the math here 2^SERVO_PULSE_RES_BITS
+
+#define SERVO_TIME_PER_BIT ((1.0 / (float)SERVO_PULSE_FREQ) / ((float)SERVO_PULSE_RES_COUNT) ) // seconds
+
+#define SERVO_MIN_PULSE (uint16_t)(SERVO_MIN_PULSE_SEC / SERVO_TIME_PER_BIT) // in timer counts
+#define SERVO_MAX_PULSE (uint16_t)(SERVO_MAX_PULSE_SEC / SERVO_TIME_PER_BIT) // in timer counts
+
+#define SERVO_PULSE_RANGE (SERVO_MAX_PULSE-SERVO_MIN_PULSE)
+
+#define SERVO_CAL_MIN 20.0 // Percent: the minimum allowable calibration value
+#define SERVO_CAL_MAX 180.0 // Percent: the maximum allowable calibration value
+
+#define SERVO_TIMER_INT_FREQ 50.0 // Hz This is the task frequency
diff --git a/Grbl_Esp32/Motors/StandardStepperClass.cpp b/Grbl_Esp32/Motors/StandardStepperClass.cpp
index ad88da9b..b65418e1 100644
--- a/Grbl_Esp32/Motors/StandardStepperClass.cpp
+++ b/Grbl_Esp32/Motors/StandardStepperClass.cpp
@@ -27,6 +27,7 @@ StandardStepper :: StandardStepper() {
}
StandardStepper :: StandardStepper(uint8_t axis_index, gpio_num_t step_pin, uint8_t dir_pin) {
+ type_id = STANDARD_MOTOR;
this->axis_index = axis_index % MAX_AXES;
this->dual_axis_index = axis_index < MAX_AXES ? 0 : 1; // 0 = primary 1 = ganged
this->step_pin = step_pin;
diff --git a/Grbl_Esp32/Motors/TrinamicDriverClass.cpp b/Grbl_Esp32/Motors/TrinamicDriverClass.cpp
index 322194ab..ddb8d22d 100644
--- a/Grbl_Esp32/Motors/TrinamicDriverClass.cpp
+++ b/Grbl_Esp32/Motors/TrinamicDriverClass.cpp
@@ -21,6 +21,7 @@
*/
#include
+#include "TrinamicDriverClass.h"
#define TRINAMIC_FCLK 12700000.0 // Internal clock Approx (Hz) used to calculate TSTEP from homing rate
@@ -30,6 +31,7 @@ TrinamicDriver :: TrinamicDriver( uint8_t axis_index,
uint16_t driver_part_number,
float r_sense, uint8_t cs_pin,
int8_t spi_index) {
+ type_id = TRINAMIC_SPI_MOTOR;
this->axis_index = axis_index % MAX_AXES;
this->dual_axis_index = axis_index < 6 ? 0 : 1; // 0 = primary 1 = ganged
_driver_part_number = driver_part_number;
diff --git a/Grbl_Esp32/Motors/TrinamicDriverClass.h b/Grbl_Esp32/Motors/TrinamicDriverClass.h
new file mode 100644
index 00000000..88be792a
--- /dev/null
+++ b/Grbl_Esp32/Motors/TrinamicDriverClass.h
@@ -0,0 +1,33 @@
+#define TRINAMIC_RUN_MODE_STEALTHCHOP 0 // very quiet
+#define TRINAMIC_RUN_MODE_COOLSTEP 1 // everything runs cooler so higher current possible
+#define TRINAMIC_RUN_MODE_STALLGUARD 2 // everything runs cooler so higher current possible
+
+#define TRINAMIC_HOMING_NONE 0
+#define TRINAMIC_HOMING_STALLGUARD 1
+
+#define NORMAL_TCOOLTHRS 0xFFFFF // 20 bit is max
+#define NORMAL_THIGH 0
+
+#define TMC2130_RSENSE_DEFAULT 0.11f
+#define TMC5160_RSENSE_DEFAULT 0.075f
+
+// ============ defaults =================
+#ifndef TRINAMIC_RUN_MODE
+ #define TRINAMIC_RUN_MODE TRINAMIC_RUN_MODE_COOLSTEP
+#endif
+
+#ifndef TRINAMIC_HOMING_MODE
+ #define TRINAMIC_HOMING_MODE TRINAMIC_HOMING_NONE
+#endif
+
+
+#ifndef TRINAMICDRIVERCLASS_H
+#define TRINAMICDRIVERCLASS_H
+
+#include "MotorClass.h"
+#include // https://github.com/teemuatlut/TMCStepper
+
+
+
+
+#endif
\ No newline at end of file
diff --git a/Grbl_Esp32/Motors/UnipolarMotorClass.cpp b/Grbl_Esp32/Motors/UnipolarMotorClass.cpp
index 065beab5..d0a874bd 100644
--- a/Grbl_Esp32/Motors/UnipolarMotorClass.cpp
+++ b/Grbl_Esp32/Motors/UnipolarMotorClass.cpp
@@ -4,6 +4,7 @@ UnipolarMotor :: UnipolarMotor() {
UnipolarMotor :: UnipolarMotor(uint8_t axis_index, uint8_t pin_phase0, uint8_t pin_phase1, uint8_t pin_phase2, uint8_t pin_phase3) {
+ type_id = UNIPOLAR_MOTOR;
this->axis_index = axis_index % MAX_AXES;
this->dual_axis_index = axis_index < MAX_AXES ? 0 : 1; // 0 = primary 1 = ganged
_pin_phase0 = pin_phase0;
diff --git a/Grbl_Esp32/settings.cpp b/Grbl_Esp32/settings.cpp
index 3ccd064a..1df2d9ba 100644
--- a/Grbl_Esp32/settings.cpp
+++ b/Grbl_Esp32/settings.cpp
@@ -275,15 +275,20 @@ uint8_t settings_store_global_setting(uint8_t parameter, float value) {
if (value * settings.max_rate[parameter] > (MAX_STEP_RATE_HZ * 60.0)) return (STATUS_MAX_STEP_RATE_EXCEEDED);
#endif
settings.steps_per_mm[parameter] = value;
+ motor_read_settings();
break;
case 1:
#ifdef MAX_STEP_RATE_HZ
if (value * settings.steps_per_mm[parameter] > (MAX_STEP_RATE_HZ * 60.0)) return (STATUS_MAX_STEP_RATE_EXCEEDED);
#endif
settings.max_rate[parameter] = value;
+ motor_read_settings();
break;
case 2: settings.acceleration[parameter] = value * 60 * 60; break; // Convert to mm/min^2 for grbl internal use.
- case 3: settings.max_travel[parameter] = -value; break; // Store as negative for grbl internal use.
+ case 3:
+ settings.max_travel[parameter] = -value;
+ motor_read_settings();
+ break; // Store as negative for grbl internal use.
case 4: // run current
settings.current[parameter] = value;
settings_spi_driver_init();
@@ -323,6 +328,7 @@ uint8_t settings_store_global_setting(uint8_t parameter, float value) {
case 3:
settings.dir_invert_mask = int_value;
st_generate_step_dir_invert_masks(); // Regenerate step and direction port invert masks.
+ motor_read_settings();
break;
case 4: // Reset to ensure change. Immediate re-init may cause problems.
if (int_value) settings.flags |= BITFLAG_INVERT_ST_ENABLE;