1
0
mirror of https://github.com/bdring/Grbl_Esp32.git synced 2025-09-02 19:02:35 +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

@@ -35,74 +35,66 @@
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(...)
} }
/* /*
@@ -120,226 +112,177 @@ bool user_defined_homing()
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

@@ -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

@@ -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

@@ -588,3 +588,13 @@ int8_t sys_get_next_RMT_chan_num() {
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