1
0
mirror of https://github.com/bdring/Grbl_Esp32.git synced 2025-09-02 10:53:01 +02:00

Auto assigned PWM channels

All PWM channels are auto assigned now. No need to assign them in machine definition files.
This commit is contained in:
bdring
2020-03-22 12:10:23 -05:00
parent 877bcf7464
commit df5400603b
16 changed files with 354 additions and 414 deletions

View File

@@ -1,10 +1,10 @@
/* /*
atari_1020.cpp atari_1020.cpp
Part of Grbl_ESP32 Part of Grbl_ESP32
copyright (c) 2018 - Bart Dring This file was modified for use on the ESP32 copyright (c) 2018 - Bart Dring This file was modified for use on the ESP32
CPU. Do not use this with Grbl for atMega328P CPU. Do not use this with Grbl for atMega328P
Grbl is free software: you can redistribute it and/or modify Grbl is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
@@ -19,9 +19,9 @@
along with Grbl. If not, see <http://www.gnu.org/licenses/>. along with Grbl. If not, see <http://www.gnu.org/licenses/>.
-------------------------------------------------------------- --------------------------------------------------------------
This contains all the special features required to control an This contains all the special features required to control an
Atari 1010 Pen Plotter Atari 1010 Pen Plotter
*/ */
// This file is enabled by defining CUSTOM_CODE_FILENAME "atari_1020.cpp" // This file is enabled by defining CUSTOM_CODE_FILENAME "atari_1020.cpp"
@@ -35,311 +35,254 @@
static TaskHandle_t solenoidSyncTaskHandle = 0; static TaskHandle_t solenoidSyncTaskHandle = 0;
static TaskHandle_t atariHomingTaskHandle = 0; static TaskHandle_t atariHomingTaskHandle = 0;
int8_t solenoid_pwm_chan_num;
uint16_t solenoid_pull_count; uint16_t solenoid_pull_count;
bool atari_homing = false; bool atari_homing = false;
uint8_t homing_phase = HOMING_PHASE_FULL_APPROACH; uint8_t homing_phase = HOMING_PHASE_FULL_APPROACH;
uint8_t current_tool; uint8_t current_tool;
void machine_init() void machine_init() {
{ solenoid_pull_count = 0; // initialize
solenoid_pull_count = 0; // initialize grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Atari 1020 Solenoid");
// setup PWM channel
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Atari 1020 Solenoid"); solenoid_pwm_chan_num = sys_get_next_PWM_chan_num();
ledcSetup(solenoid_pwm_chan_num, SOLENOID_PWM_FREQ, SOLENOID_PWM_RES_BITS);
// setup PWM channel ledcAttachPin(SOLENOID_PEN_PIN, solenoid_pwm_chan_num);
ledcSetup(SOLENOID_CHANNEL_NUM, SOLENOID_PWM_FREQ, SOLENOID_PWM_RES_BITS); pinMode(SOLENOID_DIRECTION_PIN, OUTPUT); // this sets the direction of the solenoid current
ledcAttachPin(SOLENOID_PEN_PIN, SOLENOID_CHANNEL_NUM); pinMode(REED_SW_PIN, INPUT_PULLUP); // external pullup required
// setup a task that will calculate solenoid position
pinMode(SOLENOID_DIRECTION_PIN, OUTPUT); // this sets the direction of the solenoid current xTaskCreatePinnedToCore(solenoidSyncTask, // task
pinMode(REED_SW_PIN, INPUT_PULLUP); // external pullup required "solenoidSyncTask", // name for task
4096, // size of task stack
// setup a task that will calculate solenoid position NULL, // parameters
xTaskCreatePinnedToCore(solenoidSyncTask, // task 1, // priority
"solenoidSyncTask", // name for task &solenoidSyncTaskHandle,
4096, // size of task stack 0 // core
NULL, // parameters );
1, // priority // setup a task that will do the custom homing sequence
&solenoidSyncTaskHandle, xTaskCreatePinnedToCore(atari_home_task, // task
0 // core "atari_home_task", // name for task
); 4096, // size of task stack
// setup a task that will do the custom homing sequence NULL, // parameters
xTaskCreatePinnedToCore(atari_home_task, // task 1, // priority
"atari_home_task", // name for task &atariHomingTaskHandle,
4096, // size of task stack 0 // core
NULL, // parameters );
1, // priority
&atariHomingTaskHandle,
0 // core
);
} }
// this task tracks the Z position and sets the solenoid // this task tracks the Z position and sets the solenoid
void solenoidSyncTask(void *pvParameters) void solenoidSyncTask(void* pvParameters) {
{ int32_t current_position[N_AXIS]; // copy of current location
int32_t current_position[N_AXIS]; // copy of current location float m_pos[N_AXIS]; // machine position in mm
float m_pos[N_AXIS]; // machine position in mm TickType_t xLastWakeTime;
TickType_t xLastWakeTime; const TickType_t xSolenoidFrequency = SOLENOID_TASK_FREQ; // in ticks (typically ms)
const TickType_t xSolenoidFrequency = SOLENOID_TASK_FREQ; // in ticks (typically ms) xLastWakeTime = xTaskGetTickCount(); // Initialise the xLastWakeTime variable with the current time.
while (true) {
xLastWakeTime = xTaskGetTickCount(); // Initialise the xLastWakeTime variable with the current time. // don't ever return from this or the task dies
while (true) memcpy(current_position, sys_position, sizeof(sys_position)); // get current position in step
{ // don't ever return from this or the task dies system_convert_array_steps_to_mpos(m_pos, current_position); // convert to millimeters
calc_solenoid(m_pos[Z_AXIS]); // calculate kinematics and move the servos
memcpy(current_position, sys_position, sizeof(sys_position)); // get current position in step vTaskDelayUntil(&xLastWakeTime, xSolenoidFrequency);
system_convert_array_steps_to_mpos(m_pos, current_position); // convert to millimeters }
calc_solenoid(m_pos[Z_AXIS]); // calculate kinematics and move the servos
vTaskDelayUntil(&xLastWakeTime, xSolenoidFrequency);
}
} }
// to do...have this return a true or false. This could be used by the normal homing feature to // to do...have this return a true or false. This could be used by the normal homing feature to
// continue with regular homing after setup // continue with regular homing after setup
// return true if this completes homing // return true if this completes homing
bool user_defined_homing() bool user_defined_homing() {
{ // create and start a task to do the special homing
// create and start a task to do the special homing homing_phase = HOMING_PHASE_FULL_APPROACH;
homing_phase = HOMING_PHASE_FULL_APPROACH; atari_homing = true;
atari_homing = true; return true; // this does it...skip the rest of mc_homing_cycle(...)
return true; // this does it...skip the rest of mc_homing_cycle(...)
} }
/* /*
Do a custom homing routine. Do a custom homing routine.
A task is used because it needs to wait until until idle after each move. A task is used because it needs to wait until until idle after each move.
1) Do a full travel move to the right. OK to stall if the pen started closer 1) Do a full travel move to the right. OK to stall if the pen started closer
2) Check for pen 1 2) Check for pen 1
3) If fail Retract 3) If fail Retract
4) move to right end 4) move to right end
5) Check... 5) Check...
....repeat up to 12 times to try to find pen one ....repeat up to 12 times to try to find pen one
TODO can the retract, move back be 1 phase rather than 2? TODO can the retract, move back be 1 phase rather than 2?
*/ */
void atari_home_task(void *pvParameters) void atari_home_task(void* pvParameters) {
{ uint8_t homing_attempt = 0; // how many times have we tried to home
uint8_t homing_attempt = 0; // how many times have we tried to home TickType_t xLastWakeTime;
TickType_t xLastWakeTime; const TickType_t xHomingTaskFrequency = 100; // in ticks (typically ms) .... need to make sure there is enough time to get out of idle
const TickType_t xHomingTaskFrequency = 100; // in ticks (typically ms) .... need to make sure there is enough time to get out of idle char gcode_line[20];
char gcode_line[20]; while (true) {
// this task will only last as long as it is homing
while (true) if (atari_homing) {
{ // this task will only last as long as it is homing // must be in idle or alarm state
if (sys.state == STATE_IDLE) {
if (atari_homing) switch (homing_phase) {
{ case HOMING_PHASE_FULL_APPROACH: // a full width move to insure it hits left end
// must be in idle or alarm state inputBuffer.push("G90G0Z1\r"); // lift the pen
if (sys.state == STATE_IDLE) sprintf(gcode_line, "G91G0X%3.2f\r", -ATARI_PAPER_WIDTH + ATARI_HOME_POS - 3.0); // plus a little extra
{ inputBuffer.push(gcode_line);
switch (homing_phase) homing_attempt = 1;
{ homing_phase = HOMING_PHASE_CHECK;
case HOMING_PHASE_FULL_APPROACH: // a full width move to insure it hits left end break;
inputBuffer.push("G90G0Z1\r"); // lift the pen case HOMING_PHASE_CHECK: // check the limits switch
sprintf(gcode_line, "G91G0X%3.2f\r", -ATARI_PAPER_WIDTH + ATARI_HOME_POS - 3.0); // plus a little extra if (digitalRead(REED_SW_PIN) == 0) {
inputBuffer.push(gcode_line); // see if reed switch is grounded
homing_attempt = 1; inputBuffer.push("G4P0.1\n"); // dramtic pause
homing_phase = HOMING_PHASE_CHECK; sys_position[X_AXIS] = ATARI_HOME_POS * settings.steps_per_mm[X_AXIS];
break; sys_position[Y_AXIS] = 0.0;
case HOMING_PHASE_CHECK: // check the limits switch sys_position[Z_AXIS] = 1.0 * settings.steps_per_mm[Y_AXIS];
if (digitalRead(REED_SW_PIN) == 0) gc_sync_position();
{ // see if reed switch is grounded plan_sync_position();
inputBuffer.push("G4P0.1\n"); // dramtic pause sprintf(gcode_line, "G90G0X%3.2f\r", ATARI_PAPER_WIDTH); // alway return to right side to reduce home travel stalls
inputBuffer.push(gcode_line);
sys_position[X_AXIS] = ATARI_HOME_POS * settings.steps_per_mm[X_AXIS]; current_tool = 1; // local copy for reference...until actual M6 change
sys_position[Y_AXIS] = 0.0; gc_state.tool = current_tool;
sys_position[Z_AXIS] = 1.0 * settings.steps_per_mm[Y_AXIS]; atari_homing = false; // done with homing sequence
} else {
gc_sync_position(); homing_phase = HOMING_PHASE_RETRACT;
plan_sync_position(); homing_attempt++;
}
sprintf(gcode_line, "G90G0X%3.2f\r", ATARI_PAPER_WIDTH); // alway return to right side to reduce home travel stalls break;
inputBuffer.push(gcode_line); case HOMING_PHASE_RETRACT:
sprintf(gcode_line, "G0X%3.2f\r", -ATARI_HOME_POS);
current_tool = 1; // local copy for reference...until actual M6 change inputBuffer.push(gcode_line);
gc_state.tool = current_tool; sprintf(gcode_line, "G0X%3.2f\r", ATARI_HOME_POS);
atari_homing = false; // done with homing sequence inputBuffer.push(gcode_line);
} homing_phase = HOMING_PHASE_CHECK;
else break;
{ default:
homing_phase = HOMING_PHASE_RETRACT; grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Homing phase error %d", homing_phase);
homing_attempt++; atari_homing = false;
} ; // kills task
break; break;
case HOMING_PHASE_RETRACT: }
sprintf(gcode_line, "G0X%3.2f\r", -ATARI_HOME_POS); if (homing_attempt > ATARI_HOMING_ATTEMPTS) {
inputBuffer.push(gcode_line); // try all positions plus 1
sprintf(gcode_line, "G0X%3.2f\r", ATARI_HOME_POS); grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Atari homing failed");
inputBuffer.push(gcode_line); inputBuffer.push("G90\r");
homing_phase = HOMING_PHASE_CHECK; atari_homing = false;
break; ;
default: }
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Homing phase error %d", homing_phase); }
atari_homing = false; }
; // kills task vTaskDelayUntil(&xLastWakeTime, xHomingTaskFrequency);
break; }
}
if (homing_attempt > ATARI_HOMING_ATTEMPTS)
{ // try all positions plus 1
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Atari homing failed");
inputBuffer.push("G90\r");
atari_homing = false;
;
}
}
}
vTaskDelayUntil(&xLastWakeTime, xHomingTaskFrequency);
}
} }
// calculate and set the PWM value for the servo // calculate and set the PWM value for the servo
void calc_solenoid(float penZ) void calc_solenoid(float penZ) {
{ bool isPenUp;
bool isPenUp; static bool previousPenState = false;
static bool previousPenState = false; uint32_t solenoid_pen_pulse_len; // duty cycle of solenoid
uint32_t solenoid_pen_pulse_len; // duty cycle of solenoid isPenUp = ((penZ > 0) || (sys.state == STATE_ALARM)); // is pen above Z0 or is there an alarm
// if the state has not change, we only count down to the pull time
isPenUp = ((penZ > 0) || (sys.state == STATE_ALARM)); // is pen above Z0 or is there an alarm if (previousPenState == isPenUp) {
// if state is unchanged
// if the state has not change, we only count down to the pull time if (solenoid_pull_count > 0) {
if (previousPenState == isPenUp) solenoid_pull_count--;
{ // if state is unchanged solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_PULL; // stay at full power while counting down
if (solenoid_pull_count > 0) } else {
{ solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_HOLD; // pull in delay has expired so lower duty cycle
solenoid_pull_count--; }
solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_PULL; // stay at full power while counting down } else {
} // pen direction has changed
else solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_PULL; // go to full power
{ solenoid_pull_count = SOLENOID_PULL_DURATION; // set the time to count down
solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_HOLD; // pull in delay has expired so lower duty cycle }
} previousPenState = isPenUp; // save the prev state
} digitalWrite(SOLENOID_DIRECTION_PIN, isPenUp);
else // skip setting value if it is unchanged
{ // pen direction has changed if (ledcRead(solenoid_pwm_chan_num) == solenoid_pen_pulse_len)
solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_PULL; // go to full power return;
solenoid_pull_count = SOLENOID_PULL_DURATION; // set the time to count down // update the PWM value
} // ledcWrite appears to have issues with interrupts, so make this a critical section
portMUX_TYPE myMutex = portMUX_INITIALIZER_UNLOCKED;
previousPenState = isPenUp; // save the prev state portENTER_CRITICAL(&myMutex);
ledcWrite(solenoid_pwm_chan_num, solenoid_pen_pulse_len);
digitalWrite(SOLENOID_DIRECTION_PIN, isPenUp); portEXIT_CRITICAL(&myMutex);
// skip setting value if it is unchanged
if (ledcRead(SOLENOID_CHANNEL_NUM) == solenoid_pen_pulse_len)
return;
// update the PWM value
// ledcWrite appears to have issues with interrupts, so make this a critical section
portMUX_TYPE myMutex = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL(&myMutex);
ledcWrite(SOLENOID_CHANNEL_NUM, solenoid_pen_pulse_len);
portEXIT_CRITICAL(&myMutex);
} }
/* /*
A tool (pen) change is done by bumping the carriage against the right edge 3 times per A tool (pen) change is done by bumping the carriage against the right edge 3 times per
position change. Pen 1-4 is valid range. position change. Pen 1-4 is valid range.
*/ */
void user_tool_change(uint8_t new_tool) void user_tool_change(uint8_t new_tool) {
{ uint8_t move_count;
uint8_t move_count; char gcode_line[20];
char gcode_line[20]; protocol_buffer_synchronize(); // wait for all previous moves to complete
if ((new_tool < 1) || (new_tool > MAX_PEN_NUMBER)) {
protocol_buffer_synchronize(); // wait for all previous moves to complete grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Requested Pen#%d is out of 1-4 range", new_tool);
return;
if ((new_tool < 1) || (new_tool > MAX_PEN_NUMBER)) }
{ if (new_tool == current_tool)
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Requested Pen#%d is out of 1-4 range", new_tool); return;
return; if (new_tool > current_tool)
} move_count = BUMPS_PER_PEN_CHANGE * (new_tool - current_tool);
else
if (new_tool == current_tool) move_count = BUMPS_PER_PEN_CHANGE * ((MAX_PEN_NUMBER - current_tool) + new_tool);
return; sprintf(gcode_line, "G0Z%3.2f\r", ATARI_TOOL_CHANGE_Z); // go to tool change height
inputBuffer.push(gcode_line);
if (new_tool > current_tool) for (uint8_t i = 0; i < move_count; i++) {
{ sprintf(gcode_line, "G0X%3.2f\r", ATARI_HOME_POS); //
move_count = BUMPS_PER_PEN_CHANGE * (new_tool - current_tool); inputBuffer.push(gcode_line);
} inputBuffer.push("G0X0\r");
else }
{ current_tool = new_tool;
move_count = BUMPS_PER_PEN_CHANGE * ((MAX_PEN_NUMBER - current_tool) + new_tool); grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Change to Pen#%d", current_tool);
}
sprintf(gcode_line, "G0Z%3.2f\r", ATARI_TOOL_CHANGE_Z); // go to tool change height
inputBuffer.push(gcode_line);
for (uint8_t i = 0; i < move_count; i++)
{
sprintf(gcode_line, "G0X%3.2f\r", ATARI_HOME_POS); //
inputBuffer.push(gcode_line);
inputBuffer.push("G0X0\r");
}
current_tool = new_tool;
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Change to Pen#%d", current_tool);
} }
// move from current tool to next tool.... // move from current tool to next tool....
void atari_next_pen() void atari_next_pen() {
{ if (current_tool < MAX_PEN_NUMBER)
if (current_tool < MAX_PEN_NUMBER) gc_state.tool = current_tool + 1;
{ else
gc_state.tool = current_tool + 1; gc_state.tool = 1;
} user_tool_change(gc_state.tool);
else
{
gc_state.tool = 1;
}
user_tool_change(gc_state.tool);
} }
// Polar coaster has macro buttons, this handles those button pushes. // Polar coaster has macro buttons, this handles those button pushes.
void user_defined_macro(uint8_t index) void user_defined_macro(uint8_t index) {
{ char gcode_line[20];
char gcode_line[20]; switch (index) {
switch (index)
{
#ifdef MACRO_BUTTON_0_PIN #ifdef MACRO_BUTTON_0_PIN
case CONTROL_PIN_INDEX_MACRO_0: case CONTROL_PIN_INDEX_MACRO_0:
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Pen switch"); grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Pen switch");
inputBuffer.push("$H\r"); inputBuffer.push("$H\r");
break; break;
#endif #endif
#ifdef MACRO_BUTTON_1_PIN #ifdef MACRO_BUTTON_1_PIN
case CONTROL_PIN_INDEX_MACRO_1: case CONTROL_PIN_INDEX_MACRO_1:
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Color switch"); grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Color switch");
atari_next_pen(); atari_next_pen();
sprintf(gcode_line, "G90G0X%3.2f\r", ATARI_PAPER_WIDTH); // alway return to right side to reduce home travel stalls sprintf(gcode_line, "G90G0X%3.2f\r", ATARI_PAPER_WIDTH); // alway return to right side to reduce home travel stalls
inputBuffer.push(gcode_line); inputBuffer.push(gcode_line);
break; break;
#endif #endif
#ifdef MACRO_BUTTON_2_PIN #ifdef MACRO_BUTTON_2_PIN
case CONTROL_PIN_INDEX_MACRO_2: case CONTROL_PIN_INDEX_MACRO_2:
// feed out some paper and reset the Y 0 // feed out some paper and reset the Y 0
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Paper switch"); grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Paper switch");
inputBuffer.push("G0Y-25\r"); inputBuffer.push("G0Y-25\r");
inputBuffer.push("G4P0.1\r"); // sync...forces wait for planner to clear inputBuffer.push("G4P0.1\r"); // sync...forces wait for planner to clear
sys_position[Y_AXIS] = 0.0; // reset the Y position sys_position[Y_AXIS] = 0.0; // reset the Y position
gc_sync_position(); gc_sync_position();
plan_sync_position(); plan_sync_position();
break; break;
#endif #endif
default:
default: grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Unknown Switch %d", index);
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Unknown Switch %d", index); break;
break; }
}
} }
void user_m30() void user_m30() {
{ char gcode_line[20];
char gcode_line[20]; sprintf(gcode_line, "G90G0X%3.2f\r", ATARI_PAPER_WIDTH); //
sprintf(gcode_line, "G90G0X%3.2f\r", ATARI_PAPER_WIDTH); // inputBuffer.push(gcode_line);
inputBuffer.push(gcode_line);
} }

View File

@@ -33,7 +33,7 @@
#define CUSTOM_CODE_FILENAME "Custom/atari_1020.cpp" #define CUSTOM_CODE_FILENAME "Custom/atari_1020.cpp"
#ifdef USE_RMT_STEPS #ifdef USE_RMT_STEPS
#undef USE_RMT_STEPS #undef USE_RMT_STEPS
#endif #endif
#define USE_UNIPOLAR #define USE_UNIPOLAR
@@ -52,32 +52,31 @@
#define SOLENOID_DIRECTION_PIN GPIO_NUM_4 #define SOLENOID_DIRECTION_PIN GPIO_NUM_4
#define SOLENOID_PEN_PIN GPIO_NUM_2 #define SOLENOID_PEN_PIN GPIO_NUM_2
#define SOLENOID_CHANNEL_NUM 6
#ifdef HOMING_CYCLE_0 #ifdef HOMING_CYCLE_0
#undef HOMING_CYCLE_0 #undef HOMING_CYCLE_0
#endif #endif
#define HOMING_CYCLE_0 (1 << X_AXIS) // this 'bot only homes the X axis #define HOMING_CYCLE_0 (1 << X_AXIS) // this 'bot only homes the X axis
#ifdef HOMING_CYCLE_1 #ifdef HOMING_CYCLE_1
#undef HOMING_CYCLE_1 #undef HOMING_CYCLE_1
#endif #endif
#ifdef HOMING_CYCLE_2 #ifdef HOMING_CYCLE_2
#undef HOMING_CYCLE_2 #undef HOMING_CYCLE_2
#endif #endif
#define REED_SW_PIN GPIO_NUM_17 #define REED_SW_PIN GPIO_NUM_17
#define LIMIT_MASK 0 #define LIMIT_MASK 0
#ifdef IGNORE_CONTROL_PINS // maybe set in config.h #ifdef IGNORE_CONTROL_PINS // maybe set in config.h
#undef IGNORE_CONTROL_PINS #undef IGNORE_CONTROL_PINS
#endif #endif
#ifndef ENABLE_CONTROL_SW_DEBOUNCE #ifndef ENABLE_CONTROL_SW_DEBOUNCE
#define ENABLE_CONTROL_SW_DEBOUNCE #define ENABLE_CONTROL_SW_DEBOUNCE
#endif #endif
#ifdef INVERT_CONTROL_PIN_MASK #ifdef INVERT_CONTROL_PIN_MASK
#undef INVERT_CONTROL_PIN_MASK #undef INVERT_CONTROL_PIN_MASK
#endif #endif
#define INVERT_CONTROL_PIN_MASK B01110000 #define INVERT_CONTROL_PIN_MASK B01110000
@@ -86,7 +85,7 @@
#define MACRO_BUTTON_2_PIN GPIO_NUM_36 // Paper Switch #define MACRO_BUTTON_2_PIN GPIO_NUM_36 // Paper Switch
#ifdef DEFAULTS_GENERIC #ifdef DEFAULTS_GENERIC
#undef DEFAULTS_GENERIC // undefine generic then define each default below #undef DEFAULTS_GENERIC // undefine generic then define each default below
#endif #endif
#define DEFAULT_STEP_PULSE_MICROSECONDS 3 #define DEFAULT_STEP_PULSE_MICROSECONDS 3
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 200 // 200ms #define DEFAULT_STEPPER_IDLE_LOCK_TIME 200 // 200ms
@@ -160,11 +159,11 @@
#define USE_M30 // use the user defined end of program #define USE_M30 // use the user defined end of program
#ifndef atari_h #ifndef atari_h
#define atari_h #define atari_h
void solenoid_disable(); void solenoid_disable();
void solenoidSyncTask(void *pvParameters); void solenoidSyncTask(void* pvParameters);
void calc_solenoid(float penZ); void calc_solenoid(float penZ);
void atari_home_task(void *pvParameters); void atari_home_task(void* pvParameters);
void atari_next_pen(); void atari_next_pen();
#endif #endif

View File

@@ -24,9 +24,8 @@
#define MACHINE_NAME "MACHINE_FOO_6X" #define MACHINE_NAME "MACHINE_FOO_6X"
// Be sure to change to N_AXIS 6 in nuts_bolts.h
#ifdef N_AXIS #ifdef N_AXIS
#undef N_AXIS #undef N_AXIS
#endif #endif
#define N_AXIS 6 #define N_AXIS 6
@@ -50,7 +49,6 @@
// servos // servos
#define USE_SERVO_AXES #define USE_SERVO_AXES
#define SERVO_Z_PIN GPIO_NUM_22 #define SERVO_Z_PIN GPIO_NUM_22
#define SERVO_Z_CHANNEL_NUM 6
#define SERVO_Z_RANGE_MIN 0.0 #define SERVO_Z_RANGE_MIN 0.0
#define SERVO_Z_RANGE_MAX 5.0 #define SERVO_Z_RANGE_MAX 5.0
#define SERVO_Z_HOMING_TYPE SERVO_HOMING_TARGET // during homing it will instantly move to a target value #define SERVO_Z_HOMING_TYPE SERVO_HOMING_TARGET // during homing it will instantly move to a target value
@@ -58,7 +56,6 @@
#define SERVO_Z_MPOS false // will not use mpos, uses work coordinates #define SERVO_Z_MPOS false // will not use mpos, uses work coordinates
#define SERVO_C_PIN GPIO_NUM_2 #define SERVO_C_PIN GPIO_NUM_2
#define SERVO_C_CHANNEL_NUM 7
#define SERVO_C_RANGE_MIN 0.0 #define SERVO_C_RANGE_MIN 0.0
#define SERVO_C_RANGE_MAX 5.0 #define SERVO_C_RANGE_MAX 5.0
#define SERVO_C_HOMING_TYPE SERVO_HOMING_TARGET // during homing it will instantly move to a target value #define SERVO_C_HOMING_TYPE SERVO_HOMING_TARGET // during homing it will instantly move to a target value
@@ -76,20 +73,20 @@
#define STEPPERS_DISABLE_PIN GPIO_NUM_13 #define STEPPERS_DISABLE_PIN GPIO_NUM_13
#ifdef HOMING_CYCLE_0 // undefine from config.h #ifdef HOMING_CYCLE_0 // undefine from config.h
#undef HOMING_CYCLE_0 #undef HOMING_CYCLE_0
#endif #endif
//#define HOMING_CYCLE_0 (1<<X_AXIS) //#define HOMING_CYCLE_0 (1<<X_AXIS)
#define HOMING_CYCLE_0 ((1<<X_AXIS)|(1<<Y_AXIS)) #define HOMING_CYCLE_0 ((1<<X_AXIS)|(1<<Y_AXIS))
//#define HOMING_CYCLE_0 ((1<<X_AXIS)|(1<<Y_AXIS) |(1<<A_AXIS)|(1<<B_AXIS)) //#define HOMING_CYCLE_0 ((1<<X_AXIS)|(1<<Y_AXIS) |(1<<A_AXIS)|(1<<B_AXIS))
#ifdef HOMING_CYCLE_1 // undefine from config.h #ifdef HOMING_CYCLE_1 // undefine from config.h
#undef HOMING_CYCLE_1 #undef HOMING_CYCLE_1
#endif #endif
//#define HOMING_CYCLE_1 (1<<A_AXIS) //#define HOMING_CYCLE_1 (1<<A_AXIS)
#define HOMING_CYCLE_1 ((1<<A_AXIS)|(1<<B_AXIS)) #define HOMING_CYCLE_1 ((1<<A_AXIS)|(1<<B_AXIS))
#ifdef HOMING_CYCLE_2 // undefine from config.h #ifdef HOMING_CYCLE_2 // undefine from config.h
#undef HOMING_CYCLE_2 #undef HOMING_CYCLE_2
#endif #endif
/* /*
#define HOMING_CYCLE_2 (1<<Y_AXIS) #define HOMING_CYCLE_2 (1<<Y_AXIS)

View File

@@ -31,7 +31,7 @@
#define Y_DIRECTION_PIN GPIO_NUM_25 #define Y_DIRECTION_PIN GPIO_NUM_25
#ifndef COREXY // maybe set in config.h #ifndef COREXY // maybe set in config.h
#define COREXY #define COREXY
#endif #endif
#define STEPPERS_DISABLE_PIN GPIO_NUM_13 #define STEPPERS_DISABLE_PIN GPIO_NUM_13
@@ -41,11 +41,10 @@
#define LIMIT_MASK B11 #define LIMIT_MASK B11
#ifndef USE_SERVO_AXES // maybe set in config.h #ifndef USE_SERVO_AXES // maybe set in config.h
#define USE_SERVO_AXES #define USE_SERVO_AXES
#endif #endif
#define SERVO_Z_PIN GPIO_NUM_27 #define SERVO_Z_PIN GPIO_NUM_27
#define SERVO_Z_CHANNEL_NUM 5
#define SERVO_Z_RANGE_MIN 0.0 #define SERVO_Z_RANGE_MIN 0.0
#define SERVO_Z_RANGE_MAX 5.0 #define SERVO_Z_RANGE_MAX 5.0
#define SERVO_Z_HOMING_TYPE SERVO_HOMING_TARGET // during homing it will instantly move to a target value #define SERVO_Z_HOMING_TYPE SERVO_HOMING_TARGET // during homing it will instantly move to a target value
@@ -53,24 +52,24 @@
#define SERVO_Z_MPOS false // will not use mpos, uses work coordinates #define SERVO_Z_MPOS false // will not use mpos, uses work coordinates
#ifndef IGNORE_CONTROL_PINS // maybe set in config.h #ifndef IGNORE_CONTROL_PINS // maybe set in config.h
#define IGNORE_CONTROL_PINS #define IGNORE_CONTROL_PINS
#endif #endif
// redefine some stuff from config.h // redefine some stuff from config.h
#ifdef HOMING_CYCLE_0 #ifdef HOMING_CYCLE_0
#undef HOMING_CYCLE_0 #undef HOMING_CYCLE_0
#endif #endif
#define HOMING_CYCLE_0 (1<<Y_AXIS) #define HOMING_CYCLE_0 (1<<Y_AXIS)
#ifdef HOMING_CYCLE_1 #ifdef HOMING_CYCLE_1
#undef HOMING_CYCLE_1 #undef HOMING_CYCLE_1
#endif #endif
#define HOMING_CYCLE_1 (1<<X_AXIS) #define HOMING_CYCLE_1 (1<<X_AXIS)
#ifdef HOMING_CYCLE_2 #ifdef HOMING_CYCLE_2
#undef HOMING_CYCLE_2 #undef HOMING_CYCLE_2
#endif #endif
#define SERVO_PEN_PIN GPIO_NUM_27 #define SERVO_PEN_PIN GPIO_NUM_27

View File

@@ -41,10 +41,10 @@
#define STEPPERS_DISABLE_PIN GPIO_NUM_13 #define STEPPERS_DISABLE_PIN GPIO_NUM_13
#ifdef PEN_LASER_V1 #ifdef PEN_LASER_V1
#define X_LIMIT_PIN GPIO_NUM_2 #define X_LIMIT_PIN GPIO_NUM_2
#endif #endif
#ifdef PEN_LASER_V2 #ifdef PEN_LASER_V2
#define X_LIMIT_PIN GPIO_NUM_15 #define X_LIMIT_PIN GPIO_NUM_15
#endif #endif
#define Y_LIMIT_PIN GPIO_NUM_4 #define Y_LIMIT_PIN GPIO_NUM_4
#define LIMIT_MASK B11 #define LIMIT_MASK B11
@@ -57,17 +57,15 @@
//#define USING_SOLENOID // uncomment to use this feature //#define USING_SOLENOID // uncomment to use this feature
#ifdef USING_SERVO #ifdef USING_SERVO
#define USE_SERVO_AXES #define USE_SERVO_AXES
#define SERVO_Z_PIN GPIO_NUM_27 #define SERVO_Z_PIN GPIO_NUM_27
#define SERVO_Z_CHANNEL_NUM 3 #define SERVO_Z_RANGE_MIN 0
#define SERVO_Z_RANGE_MIN 0 #define SERVO_Z_RANGE_MAX 10
#define SERVO_Z_RANGE_MAX 10
#endif #endif
#ifdef USING_SOLENOID #ifdef USING_SOLENOID
#define USE_PEN_SOLENOID #define USE_PEN_SOLENOID
#define SOLENOID_PEN_PIN GPIO_NUM_16 #define SOLENOID_PEN_PIN GPIO_NUM_16
#define SOLENOID_CHANNEL_NUM 6
#endif #endif
// defaults // defaults

View File

@@ -44,11 +44,10 @@
#define STEPPERS_DISABLE_PIN GPIO_NUM_17 #define STEPPERS_DISABLE_PIN GPIO_NUM_17
#ifndef USE_SERVO_AXES // maybe set in config.h #ifndef USE_SERVO_AXES // maybe set in config.h
#define USE_SERVO_AXES #define USE_SERVO_AXES
#endif #endif
#define SERVO_Z_PIN GPIO_NUM_16 #define SERVO_Z_PIN GPIO_NUM_16
#define SERVO_Z_CHANNEL_NUM 5
#define SERVO_Z_RANGE_MIN 0.0 #define SERVO_Z_RANGE_MIN 0.0
#define SERVO_Z_RANGE_MAX 5.0 #define SERVO_Z_RANGE_MAX 5.0
#define SERVO_Z_HOMING_TYPE SERVO_HOMING_TARGET // during homing it will instantly move to a target value #define SERVO_Z_HOMING_TYPE SERVO_HOMING_TARGET // during homing it will instantly move to a target value
@@ -59,20 +58,20 @@
#define LIMIT_MASK B1 #define LIMIT_MASK B1
#ifdef IGNORE_CONTROL_PINS // maybe set in config.h #ifdef IGNORE_CONTROL_PINS // maybe set in config.h
#undef IGNORE_CONTROL_PINS #undef IGNORE_CONTROL_PINS
#endif #endif
#ifndef ENABLE_CONTROL_SW_DEBOUNCE #ifndef ENABLE_CONTROL_SW_DEBOUNCE
#define ENABLE_CONTROL_SW_DEBOUNCE #define ENABLE_CONTROL_SW_DEBOUNCE
#endif #endif
#ifdef CONTROL_SW_DEBOUNCE_PERIOD #ifdef CONTROL_SW_DEBOUNCE_PERIOD
#undef CONTROL_SW_DEBOUNCE_PERIOD #undef CONTROL_SW_DEBOUNCE_PERIOD
#endif #endif
#define CONTROL_SW_DEBOUNCE_PERIOD 100 // really long debounce #define CONTROL_SW_DEBOUNCE_PERIOD 100 // really long debounce
#ifdef INVERT_CONTROL_PIN_MASK #ifdef INVERT_CONTROL_PIN_MASK
#undef INVERT_CONTROL_PIN_MASK #undef INVERT_CONTROL_PIN_MASK
#endif #endif
#define INVERT_CONTROL_PIN_MASK B11111111 #define INVERT_CONTROL_PIN_MASK B11111111
@@ -82,14 +81,14 @@
// redefine some stuff from config.h // redefine some stuff from config.h
#ifdef HOMING_CYCLE_0 #ifdef HOMING_CYCLE_0
#undef HOMING_CYCLE_0 #undef HOMING_CYCLE_0
#endif #endif
#define HOMING_CYCLE_0 (1<<X_AXIS) // this 'bot only homes the X axis #define HOMING_CYCLE_0 (1<<X_AXIS) // this 'bot only homes the X axis
#ifdef HOMING_CYCLE_1 #ifdef HOMING_CYCLE_1
#undef HOMING_CYCLE_1 #undef HOMING_CYCLE_1
#endif #endif
#ifdef HOMING_CYCLE_2 #ifdef HOMING_CYCLE_2
#undef HOMING_CYCLE_2 #undef HOMING_CYCLE_2
#endif #endif
// ============= End CPU MAP ================== // ============= End CPU MAP ==================

View File

@@ -39,11 +39,11 @@
#define STEPPERS_DISABLE_PIN GPIO_NUM_13 #define STEPPERS_DISABLE_PIN GPIO_NUM_13
#ifdef PEN_LASER_V1 #ifdef PEN_LASER_V1
#define X_LIMIT_PIN GPIO_NUM_2 #define X_LIMIT_PIN GPIO_NUM_2
#endif #endif
#ifdef PEN_LASER_V2 #ifdef PEN_LASER_V2
#define X_LIMIT_PIN GPIO_NUM_15 #define X_LIMIT_PIN GPIO_NUM_15
#endif #endif
#define Y_LIMIT_PIN GPIO_NUM_4 #define Y_LIMIT_PIN GPIO_NUM_4
@@ -61,16 +61,14 @@
#define SPINDLE_PWM_OFF_VALUE 0 #define SPINDLE_PWM_OFF_VALUE 0
#ifndef SPINDLE_PWM_MIN_VALUE #ifndef SPINDLE_PWM_MIN_VALUE
#define SPINDLE_PWM_MIN_VALUE 1 // Must be greater than zero. #define SPINDLE_PWM_MIN_VALUE 1 // Must be greater than zero.
#endif #endif
#define SERVO_Y_PIN GPIO_NUM_14 #define SERVO_Y_PIN GPIO_NUM_14
#define SERVO_Y_CHANNEL_NUM 6
#define SERVO_Y_RANGE_MIN 0.0 #define SERVO_Y_RANGE_MIN 0.0
#define SERVO_Y_RANGE_MAX 30.0 #define SERVO_Y_RANGE_MAX 30.0
#define SERVO_Z_PIN GPIO_NUM_27 #define SERVO_Z_PIN GPIO_NUM_27
#define SERVO_Z_CHANNEL_NUM 5
#define SERVO_Z_RANGE_MIN 0.0 #define SERVO_Z_RANGE_MIN 0.0
#define SERVO_Z_RANGE_MAX 20.0 #define SERVO_Z_RANGE_MAX 20.0

View File

@@ -1,6 +1,6 @@
/* /*
template.h template.h
Part of Grbl_ESP32 Part of Grbl_ESP32
Template for a machine configuration file. Template for a machine configuration file.
@@ -135,7 +135,6 @@
// #define USE_SERVO_AXES // #define USE_SERVO_AXES
// #define SERVO_Z_PIN GPIO_NUM_22 // #define SERVO_Z_PIN GPIO_NUM_22
// #define SERVO_Z_CHANNEL_NUM 6
// #define SERVO_Z_RANGE_MIN 0.0 // #define SERVO_Z_RANGE_MIN 0.0
// #define SERVO_Z_RANGE_MAX 5.0 // #define SERVO_Z_RANGE_MAX 5.0
// #define SERVO_Z_HOMING_TYPE SERVO_HOMING_TARGET // during homing it will instantly move to a target value // #define SERVO_Z_HOMING_TYPE SERVO_HOMING_TARGET // during homing it will instantly move to a target value

View File

@@ -4,7 +4,7 @@
Pin assignments for the TMC2130 Pen/Laser controller Pin assignments for the TMC2130 Pen/Laser controller
https://github.com/bdring/Grbl_ESP32_TMC2130_Plotter_Controller https://github.com/bdring/Grbl_ESP32_TMC2130_Plotter_Controller
2018 - Bart Dring 2018 - Bart Dring
2020 - Mitch Bradley 2020 - Mitch Bradley
@@ -28,11 +28,11 @@
#define MACHINE_V2 // version 2 PCB #define MACHINE_V2 // version 2 PCB
#ifdef MACHINE_V1 #ifdef MACHINE_V1
#define MACHINE_NAME "ESP32_TMC2130_PEN V1" #define MACHINE_NAME "ESP32_TMC2130_PEN V1"
#define X_LIMIT_PIN GPIO_NUM_2 #define X_LIMIT_PIN GPIO_NUM_2
#else #else
#define MACHINE_NAME "ESP32_TMC2130_PEN V2" #define MACHINE_NAME "ESP32_TMC2130_PEN V2"
#define X_LIMIT_PIN GPIO_NUM_32 #define X_LIMIT_PIN GPIO_NUM_32
#endif #endif
#define USE_TRINAMIC // Using at least 1 trinamic driver #define USE_TRINAMIC // Using at least 1 trinamic driver
@@ -59,7 +59,6 @@
#endif #endif
#define SERVO_Z_PIN GPIO_NUM_27 // comment this out if PWM spindle/laser control. #define SERVO_Z_PIN GPIO_NUM_27 // comment this out if PWM spindle/laser control.
#define SERVO_Z_CHANNEL_NUM 5
#define SERVO_Z_RANGE_MIN 0.0 #define SERVO_Z_RANGE_MIN 0.0
#define SERVO_Z_RANGE_MAX 5.0 #define SERVO_Z_RANGE_MAX 5.0
#define SERVO_Z_HOMING_TYPE SERVO_HOMING_TARGET // during homing it will instantly move to a target value #define SERVO_Z_HOMING_TYPE SERVO_HOMING_TARGET // during homing it will instantly move to a target value

View File

@@ -6,7 +6,6 @@
#endif #endif
#define SPINDLE_PWM_MAX_VALUE ((1<<SPINDLE_PWM_BIT_PRECISION) - 1) #define SPINDLE_PWM_MAX_VALUE ((1<<SPINDLE_PWM_BIT_PRECISION) - 1)
#define SPINDLE_PWM_CHANNEL 0
// Grbl setting that are common to all machines // Grbl setting that are common to all machines
// It should not be necessary to change anything herein // It should not be necessary to change anything herein

View File

@@ -29,122 +29,116 @@
static TaskHandle_t servosSyncTaskHandle = 0; static TaskHandle_t servosSyncTaskHandle = 0;
#ifdef SERVO_X_PIN #ifdef SERVO_X_PIN
ServoAxis X_Servo_Axis(X_AXIS, SERVO_X_PIN, SERVO_X_CHANNEL_NUM); ServoAxis X_Servo_Axis(X_AXIS, SERVO_X_PIN);
#endif #endif
#ifdef SERVO_Y_PIN #ifdef SERVO_Y_PIN
ServoAxis Y_Servo_Axis(Y_AXIS, SERVO_Y_PIN, SERVO_Y_CHANNEL_NUM); ServoAxis Y_Servo_Axis(Y_AXIS, SERVO_Y_PIN);
#endif #endif
#ifdef SERVO_Z_PIN #ifdef SERVO_Z_PIN
ServoAxis Z_Servo_Axis(Z_AXIS, SERVO_Z_PIN, SERVO_Z_CHANNEL_NUM); ServoAxis Z_Servo_Axis(Z_AXIS, SERVO_Z_PIN);
#endif #endif
#ifdef SERVO_A_PIN #ifdef SERVO_A_PIN
ServoAxis A_Servo_Axis(A_AXIS, SERVO_A_PIN, SERVO_A_CHANNEL_NUM); ServoAxis A_Servo_Axis(A_AXIS, SERVO_A_PIN);
#endif #endif
#ifdef SERVO_B_PIN #ifdef SERVO_B_PIN
ServoAxis B_Servo_Axis(B_AXIS, SERVO_B_PIN, SERVO_B_CHANNEL_NUM); ServoAxis B_Servo_Axis(B_AXIS, SERVO_B_PIN);
#endif #endif
#ifdef SERVO_C_PIN #ifdef SERVO_C_PIN
ServoAxis C_Servo_Axis(C_AXIS, SERVO_C_PIN, SERVO_C_CHANNEL_NUM); ServoAxis C_Servo_Axis(C_AXIS, SERVO_C_PIN);
#endif #endif
void init_servos() { void init_servos() {
// ======================== X Axis =========================== // ======================== X Axis ===========================
#ifdef SERVO_X_PIN #ifdef SERVO_X_PIN
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "X Servo range %4.3f to %4.3f", SERVO_X_RANGE_MIN, SERVO_X_RANGE_MAX); grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "X Servo range %4.3f to %4.3f", SERVO_X_RANGE_MIN, SERVO_X_RANGE_MAX);
X_Servo_Axis.init(); X_Servo_Axis.init();
X_Servo_Axis.set_range(SERVO_X_RANGE_MIN, SERVO_X_RANGE_MAX); X_Servo_Axis.set_range(SERVO_X_RANGE_MIN, SERVO_X_RANGE_MAX);
#ifdef SERVO_X_HOMING_TYPE #ifdef SERVO_X_HOMING_TYPE
X_Servo_Axis.set_homing_type(SERVO_X_HOMING_TYPE); X_Servo_Axis.set_homing_type(SERVO_X_HOMING_TYPE);
#endif #endif
#ifdef SERVO_X_HOME_POS #ifdef SERVO_X_HOME_POS
X_Servo_Axis.set_homing_position(SERVO_X_HOME_POS); X_Servo_Axis.set_homing_position(SERVO_X_HOME_POS);
#endif #endif
#ifdef SERVO_X_MPOS // value should be true or false #ifdef SERVO_X_MPOS // value should be true or false
X_Servo_Axis.set_use_mpos(SERVO_X_MPOS); X_Servo_Axis.set_use_mpos(SERVO_X_MPOS);
#endif #endif
#endif #endif
// ======================== Y Axis =========================== // ======================== Y Axis ===========================
#ifdef SERVO_Y_PIN #ifdef SERVO_Y_PIN
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Y Servo range %4.3f to %4.3f", SERVO_Y_RANGE_MIN, SERVO_Y_RANGE_MAX); grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Y Servo range %4.3f to %4.3f", SERVO_Y_RANGE_MIN, SERVO_Y_RANGE_MAX);
Y_Servo_Axis.init(); Y_Servo_Axis.init();
Y_Servo_Axis.set_range(SERVO_Y_RANGE_MIN, SERVO_Y_RANGE_MAX); Y_Servo_Axis.set_range(SERVO_Y_RANGE_MIN, SERVO_Y_RANGE_MAX);
#ifdef SERVO_Y_HOMING_TYPE #ifdef SERVO_Y_HOMING_TYPE
Y_Servo_Axis.set_homing_type(SERVO_Y_HOMING_TYPE); Y_Servo_Axis.set_homing_type(SERVO_Y_HOMING_TYPE);
#endif #endif
#ifdef SERVO_Y_HOME_POS #ifdef SERVO_Y_HOME_POS
Y_Servo_Axis.set_homing_position(SERVO_Y_HOME_POS); Y_Servo_Axis.set_homing_position(SERVO_Y_HOME_POS);
#endif #endif
#ifdef SERVO_Y_MPOS // value should be true or false #ifdef SERVO_Y_MPOS // value should be true or false
Y_Servo_Axis.set_use_mpos(SERVO_Y_MPOS); Y_Servo_Axis.set_use_mpos(SERVO_Y_MPOS);
#endif #endif
#endif #endif
// ======================== Z Axis =========================== // ======================== Z Axis ===========================
#ifdef SERVO_Z_PIN #ifdef SERVO_Z_PIN
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Z Servo range %4.3f to %4.3f", SERVO_Z_RANGE_MIN, SERVO_Z_RANGE_MAX); grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Z Servo range %4.3f to %4.3f", SERVO_Z_RANGE_MIN, SERVO_Z_RANGE_MAX);
Z_Servo_Axis.init(); Z_Servo_Axis.init();
Z_Servo_Axis.set_range(SERVO_Z_RANGE_MIN, SERVO_Z_RANGE_MAX); Z_Servo_Axis.set_range(SERVO_Z_RANGE_MIN, SERVO_Z_RANGE_MAX);
#ifdef SERVO_Z_HOMING_TYPE #ifdef SERVO_Z_HOMING_TYPE
Z_Servo_Axis.set_homing_type(SERVO_Z_HOMING_TYPE); Z_Servo_Axis.set_homing_type(SERVO_Z_HOMING_TYPE);
#endif #endif
#ifdef SERVO_Z_HOME_POS #ifdef SERVO_Z_HOME_POS
Z_Servo_Axis.set_homing_position(SERVO_Z_HOME_POS); Z_Servo_Axis.set_homing_position(SERVO_Z_HOME_POS);
#endif #endif
#ifdef SERVO_Z_MPOS // value should be true or false #ifdef SERVO_Z_MPOS // value should be true or false
Z_Servo_Axis.set_use_mpos(SERVO_Z_MPOS); Z_Servo_Axis.set_use_mpos(SERVO_Z_MPOS);
#endif #endif
#endif #endif
// ======================== A Axis =========================== // ======================== A Axis ===========================
#ifdef SERVO_A_PIN #ifdef SERVO_A_PIN
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "A Servo range %4.3f to %4.3f", SERVO_A_RANGE_MIN, SERVO_A_RANGE_MAX); grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "A Servo range %4.3f to %4.3f", SERVO_A_RANGE_MIN, SERVO_A_RANGE_MAX);
A_Servo_Axis.init(); A_Servo_Axis.init();
A_Servo_Axis.set_range(SERVO_A_RANGE_MIN, SERVO_A_RANGE_MAX); A_Servo_Axis.set_range(SERVO_A_RANGE_MIN, SERVO_A_RANGE_MAX);
#ifdef SERVO_A_HOMING_TYPE #ifdef SERVO_A_HOMING_TYPE
A_Servo_Axis.set_homing_type(SERVO_A_HOMING_TYPE); A_Servo_Axis.set_homing_type(SERVO_A_HOMING_TYPE);
#endif #endif
#ifdef SERVO_A_HOME_POS #ifdef SERVO_A_HOME_POS
A_Servo_Axis.set_homing_position(SERVO_A_HOME_POS); A_Servo_Axis.set_homing_position(SERVO_A_HOME_POS);
#endif #endif
#ifdef SERVO_A_MPOS // value should be true or false #ifdef SERVO_A_MPOS // value should be true or false
A_Servo_Axis.set_use_mpos(SERVO_A_MPOS); A_Servo_Axis.set_use_mpos(SERVO_A_MPOS);
#endif #endif
#endif #endif
// ======================== B Axis =========================== // ======================== B Axis ===========================
#ifdef SERVO_B_PIN #ifdef SERVO_B_PIN
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "B Servo range %4.3f to %4.3f", SERVO_B_RANGE_MIN, SERVO_B_RANGE_MAX); grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "B Servo range %4.3f to %4.3f", SERVO_B_RANGE_MIN, SERVO_B_RANGE_MAX);
B_Servo_Axis.init(); B_Servo_Axis.init();
B_Servo_Axis.set_range(SERVO_B_RANGE_MIN, SERVO_B_RANGE_MAX); B_Servo_Axis.set_range(SERVO_B_RANGE_MIN, SERVO_B_RANGE_MAX);
#ifdef SERVO_B_HOMING_TYPE #ifdef SERVO_B_HOMING_TYPE
B_Servo_Axis.set_homing_type(SERVO_B_HOMING_TYPE); B_Servo_Axis.set_homing_type(SERVO_B_HOMING_TYPE);
#endif #endif
#ifdef SERVO_B_HOME_POS #ifdef SERVO_B_HOME_POS
B_Servo_Axis.set_homing_position(SERVO_B_HOME_POS); B_Servo_Axis.set_homing_position(SERVO_B_HOME_POS);
#endif #endif
#ifdef SERVO_B_MPOS // value should be true or false #ifdef SERVO_B_MPOS // value should be true or false
B_Servo_Axis.set_use_mpos(SERVO_B_MPOS); B_Servo_Axis.set_use_mpos(SERVO_B_MPOS);
#endif #endif
#endif #endif
// ======================== C Axis =========================== // ======================== C Axis ===========================
#ifdef SERVO_C_PIN #ifdef SERVO_C_PIN
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "C Servo range %4.3f to %4.3f", SERVO_C_RANGE_MIN, SERVO_C_RANGE_MAX); grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "C Servo range %4.3f to %4.3f", SERVO_C_RANGE_MIN, SERVO_C_RANGE_MAX);
C_Servo_Axis.init(); C_Servo_Axis.init();
C_Servo_Axis.set_range(SERVO_C_RANGE_MIN, SERVO_C_RANGE_MAX); C_Servo_Axis.set_range(SERVO_C_RANGE_MIN, SERVO_C_RANGE_MAX);
#ifdef SERVO_C_HOMING_TYPE #ifdef SERVO_C_HOMING_TYPE
C_Servo_Axis.set_homing_type(SERVO_C_HOMING_TYPE); C_Servo_Axis.set_homing_type(SERVO_C_HOMING_TYPE);
#endif #endif
#ifdef SERVO_C_HOME_POS #ifdef SERVO_C_HOME_POS
C_Servo_Axis.set_homing_position(SERVO_C_HOME_POS); C_Servo_Axis.set_homing_position(SERVO_C_HOME_POS);
#endif #endif
#ifdef SERVO_C_MPOS // value should be true or false #ifdef SERVO_C_MPOS // value should be true or false
C_Servo_Axis.set_use_mpos(SERVO_C_MPOS); C_Servo_Axis.set_use_mpos(SERVO_C_MPOS);
#endif #endif
#endif #endif
// setup a task that will calculate the determine and set the servo positions // setup a task that will calculate the determine and set the servo positions
xTaskCreatePinnedToCore(servosSyncTask, // task xTaskCreatePinnedToCore(servosSyncTask, // task
"servosSyncTask", // name for task "servosSyncTask", // name for task
@@ -163,34 +157,34 @@ void servosSyncTask(void* pvParameters) {
const TickType_t xServoFrequency = SERVO_TIMER_INT_FREQ; // in ticks (typically ms) const TickType_t xServoFrequency = SERVO_TIMER_INT_FREQ; // in ticks (typically ms)
xLastWakeTime = xTaskGetTickCount(); // Initialise the xLastWakeTime variable with the current time. xLastWakeTime = xTaskGetTickCount(); // Initialise the xLastWakeTime variable with the current time.
while (true) { // don't ever return from this or the task dies while (true) { // don't ever return from this or the task dies
#ifdef SERVO_X_PIN #ifdef SERVO_X_PIN
X_Servo_Axis.set_location(); X_Servo_Axis.set_location();
#endif #endif
#ifdef SERVO_Y_PIN #ifdef SERVO_Y_PIN
Y_Servo_Axis.set_location(); Y_Servo_Axis.set_location();
#endif #endif
#ifdef SERVO_Z_PIN #ifdef SERVO_Z_PIN
Z_Servo_Axis.set_location(); Z_Servo_Axis.set_location();
#endif #endif
#ifdef SERVO_A_PIN #ifdef SERVO_A_PIN
A_Servo_Axis.set_location(); A_Servo_Axis.set_location();
#endif #endif
#ifdef SERVO_B_PIN #ifdef SERVO_B_PIN
B_Servo_Axis.set_location(); B_Servo_Axis.set_location();
#endif #endif
#ifdef SERVO_C_PIN #ifdef SERVO_C_PIN
C_Servo_Axis.set_location(); C_Servo_Axis.set_location();
#endif #endif
vTaskDelayUntil(&xLastWakeTime, xServoFrequency); vTaskDelayUntil(&xLastWakeTime, xServoFrequency);
} }
} }
// =============================== Class Stuff ================================= // // =============================== Class Stuff ================================= //
ServoAxis::ServoAxis(uint8_t axis, uint8_t pin_num, uint8_t channel_num) { // constructor ServoAxis::ServoAxis(uint8_t axis, uint8_t pin_num) { // constructor
_axis = axis; _axis = axis;
_pin_num = pin_num; _pin_num = pin_num;
_channel_num = channel_num; _channel_num = sys_get_next_PWM_chan_num();
_showError = true; // this will be used to show calibration error only once _showError = true; // this will be used to show calibration error only once
_use_mpos = true; // default is to use the machine position rather than work position _use_mpos = true; // default is to use the machine position rather than work position
} }

View File

@@ -36,7 +36,6 @@
2. In the machine definition file in Machines/, define servo pins and PWM channels like this .... 2. In the machine definition file in Machines/, define servo pins and PWM channels like this ....
#define SERVO_Y_PIN GPIO_NUM_14 #define SERVO_Y_PIN GPIO_NUM_14
#define SERVO_Y_CHANNEL_NUM 6
undefine any step and direction pins associated with that axis undefine any step and direction pins associated with that axis
@@ -93,7 +92,7 @@ void servosSyncTask(void* pvParameters);
class ServoAxis { class ServoAxis {
public: public:
ServoAxis(uint8_t axis, uint8_t pin_num, uint8_t channel_num); // constructor ServoAxis(uint8_t axis, uint8_t pin_num); // constructor
void init(); void init();
void set_location(); void set_location();
void disable(); // sets PWM to 0% duty cycle. Most servos can be manually moved in this state void disable(); // sets PWM to 0% duty cycle. Most servos can be manually moved in this state

View File

@@ -23,6 +23,8 @@
#ifdef USE_PEN_SOLENOID #ifdef USE_PEN_SOLENOID
int8_t solenoid_pwm_chan_num;
static TaskHandle_t solenoidSyncTaskHandle = 0; static TaskHandle_t solenoidSyncTaskHandle = 0;
// used to delay turn on // used to delay turn on
@@ -35,8 +37,9 @@ void solenoid_init() {
solenoid_pen_enable = false; // start delay has not completed yet. solenoid_pen_enable = false; // start delay has not completed yet.
solenoide_hold_count = 0; // initialize solenoide_hold_count = 0; // initialize
// setup PWM channel // setup PWM channel
ledcSetup(SOLENOID_CHANNEL_NUM, SOLENOID_PWM_FREQ, SOLENOID_PWM_RES_BITS); solenoid_pwm_chan_num = sys_get_next_PWM_chan_num();
ledcAttachPin(SOLENOID_PEN_PIN, SOLENOID_CHANNEL_NUM); ledcSetup(solenoid_pwm_chan_num, SOLENOID_PWM_FREQ, SOLENOID_PWM_RES_BITS);
ledcAttachPin(SOLENOID_PEN_PIN, solenoid_pwm_chan_num);
solenoid_disable(); // start it it off solenoid_disable(); // start it it off
// setup a task that will calculate the determine and set the servo position // setup a task that will calculate the determine and set the servo position
xTaskCreatePinnedToCore(solenoidSyncTask, // task xTaskCreatePinnedToCore(solenoidSyncTask, // task
@@ -51,7 +54,7 @@ void solenoid_init() {
// turn off the PWM (0 duty) // turn off the PWM (0 duty)
void solenoid_disable() { void solenoid_disable() {
ledcWrite(SOLENOID_CHANNEL_NUM, 0); ledcWrite(solenoid_pwm_chan_num, 0);
} }
// this is the task // this is the task
@@ -91,13 +94,13 @@ void calc_solenoid(float penZ) {
solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_HOLD; solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_HOLD;
} }
// skip setting value if it is unchanged // skip setting value if it is unchanged
if (ledcRead(SOLENOID_CHANNEL_NUM) == solenoid_pen_pulse_len) if (ledcRead(solenoid_pwm_chan_num) == solenoid_pen_pulse_len)
return; return;
// update the PWM value // update the PWM value
// ledcWrite appears to have issues with interrupts, so make this a critical section // ledcWrite appears to have issues with interrupts, so make this a critical section
portMUX_TYPE myMutex = portMUX_INITIALIZER_UNLOCKED; portMUX_TYPE myMutex = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL(&myMutex); portENTER_CRITICAL(&myMutex);
ledcWrite(SOLENOID_CHANNEL_NUM, solenoid_pen_pulse_len); ledcWrite(solenoid_pwm_chan_num, solenoid_pen_pulse_len);
portEXIT_CRITICAL(&myMutex); portEXIT_CRITICAL(&myMutex);
} }

View File

@@ -20,6 +20,8 @@
#include "grbl.h" #include "grbl.h"
int8_t spindle_pwm_chan_num;
#ifdef SPINDLE_PWM_PIN #ifdef SPINDLE_PWM_PIN
static float pwm_gradient; // Precalulated value to speed up rpm to PWM conversions. static float pwm_gradient; // Precalulated value to speed up rpm to PWM conversions.
uint32_t spindle_pwm_period; // how many counts in 1 period uint32_t spindle_pwm_period; // how many counts in 1 period
@@ -54,8 +56,9 @@ void spindle_init() {
pinMode(SPINDLE_DIR_PIN, OUTPUT); pinMode(SPINDLE_DIR_PIN, OUTPUT);
#endif #endif
// use the LED control feature to setup PWM https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/ledc.html // use the LED control feature to setup PWM https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/ledc.html
ledcSetup(SPINDLE_PWM_CHANNEL, (double)settings.spindle_pwm_freq, SPINDLE_PWM_BIT_PRECISION); // setup the channel spindle_pwm_chan_num - sys_get_next_PWM_chan_num();
ledcAttachPin(SPINDLE_PWM_PIN, SPINDLE_PWM_CHANNEL); // attach the PWM to the pin ledcSetup(spindle_pwm_chan_num, (double)settings.spindle_pwm_freq, SPINDLE_PWM_BIT_PRECISION); // setup the channel
ledcAttachPin(SPINDLE_PWM_PIN, spindle_pwm_chan_num); // attach the PWM to the pin
// Start with spindle off off // Start with spindle off off
spindle_stop(); spindle_stop();
#endif #endif
@@ -65,9 +68,9 @@ void spindle_stop() {
spindle_set_enable(false); spindle_set_enable(false);
#ifdef SPINDLE_PWM_PIN #ifdef SPINDLE_PWM_PIN
#ifndef INVERT_SPINDLE_PWM #ifndef INVERT_SPINDLE_PWM
grbl_analogWrite(SPINDLE_PWM_CHANNEL, spindle_pwm_off_value); grbl_analogWrite(spindle_pwm_chan_num, spindle_pwm_off_value);
#else #else
grbl_analogWrite(SPINDLE_PWM_CHANNEL, (1 << SPINDLE_PWM_BIT_PRECISION)); // TO DO...wrong for min_pwm grbl_analogWrite(spindle_pwm_chan_num, (1 << SPINDLE_PWM_BIT_PRECISION)); // TO DO...wrong for min_pwm
#endif #endif
#endif #endif
} }
@@ -77,7 +80,7 @@ uint8_t spindle_get_state() { // returns SPINDLE_STATE_DISABLE, SPINDLE_STATE_CW
#ifndef SPINDLE_PWM_PIN #ifndef SPINDLE_PWM_PIN
return (SPINDLE_STATE_DISABLE); return (SPINDLE_STATE_DISABLE);
#else #else
if (ledcRead(SPINDLE_PWM_CHANNEL) == 0) // Check the PWM value if (ledcRead(spindle_pwm_chan_num) == 0) // Check the PWM value
return (SPINDLE_STATE_DISABLE); return (SPINDLE_STATE_DISABLE);
else { else {
#ifdef SPINDLE_DIR_PIN #ifdef SPINDLE_DIR_PIN
@@ -103,9 +106,9 @@ void spindle_set_speed(uint32_t pwm_value) {
spindle_set_enable(pwm_value != 0); spindle_set_enable(pwm_value != 0);
#endif #endif
#ifndef INVERT_SPINDLE_PWM #ifndef INVERT_SPINDLE_PWM
grbl_analogWrite(SPINDLE_PWM_CHANNEL, pwm_value); grbl_analogWrite(spindle_pwm_chan_num, pwm_value);
#else #else
grbl_analogWrite(SPINDLE_PWM_CHANNEL, (1 << SPINDLE_PWM_BIT_PRECISION) - pwm_value); grbl_analogWrite(spindle_pwm_chan_num, (1 << SPINDLE_PWM_BIT_PRECISION) - pwm_value);
#endif #endif
#endif #endif
} }

View File

@@ -587,4 +587,14 @@ int8_t sys_get_next_RMT_chan_num() {
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_ERROR, "Error: out of RMT channels"); grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_ERROR, "Error: out of RMT channels");
return -1; return -1;
} }
}
int8_t sys_get_next_PWM_chan_num() {
static uint8_t next_PWM_chan_num = 0; // channels 0-7 are valid
if (next_PWM_chan_num < 8) // 7 is the max PWM channel number
return next_PWM_chan_num++;
else {
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_ERROR, "Error: out of PWM channels");
return -1;
}
} }

View File

@@ -229,5 +229,6 @@ void sys_io_control(uint8_t io_num_mask, bool turnOn);
// //
int8_t sys_get_next_RMT_chan_num(); int8_t sys_get_next_RMT_chan_num();
int8_t sys_get_next_PWM_chan_num();
#endif #endif