mirror of
https://github.com/bdring/Grbl_Esp32.git
synced 2025-09-02 10:53:01 +02:00
@@ -1,10 +1,10 @@
|
||||
/*
|
||||
atari_1020.cpp
|
||||
Part of Grbl_ESP32
|
||||
|
||||
|
||||
copyright (c) 2018 - Bart Dring This file was modified for use on the ESP32
|
||||
CPU. Do not use this with Grbl for atMega328P
|
||||
|
||||
|
||||
Grbl is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
@@ -19,9 +19,9 @@
|
||||
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
--------------------------------------------------------------
|
||||
|
||||
This contains all the special features required to control an
|
||||
Atari 1010 Pen Plotter
|
||||
|
||||
This contains all the special features required to control an
|
||||
Atari 1010 Pen Plotter
|
||||
*/
|
||||
|
||||
// This file is enabled by defining CUSTOM_CODE_FILENAME "atari_1020.cpp"
|
||||
@@ -35,311 +35,254 @@
|
||||
|
||||
static TaskHandle_t solenoidSyncTaskHandle = 0;
|
||||
static TaskHandle_t atariHomingTaskHandle = 0;
|
||||
int8_t solenoid_pwm_chan_num;
|
||||
uint16_t solenoid_pull_count;
|
||||
bool atari_homing = false;
|
||||
uint8_t homing_phase = HOMING_PHASE_FULL_APPROACH;
|
||||
uint8_t current_tool;
|
||||
|
||||
void machine_init()
|
||||
{
|
||||
solenoid_pull_count = 0; // initialize
|
||||
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Atari 1020 Solenoid");
|
||||
|
||||
// setup PWM channel
|
||||
ledcSetup(SOLENOID_CHANNEL_NUM, SOLENOID_PWM_FREQ, SOLENOID_PWM_RES_BITS);
|
||||
ledcAttachPin(SOLENOID_PEN_PIN, SOLENOID_CHANNEL_NUM);
|
||||
|
||||
pinMode(SOLENOID_DIRECTION_PIN, OUTPUT); // this sets the direction of the solenoid current
|
||||
pinMode(REED_SW_PIN, INPUT_PULLUP); // external pullup required
|
||||
|
||||
// setup a task that will calculate solenoid position
|
||||
xTaskCreatePinnedToCore(solenoidSyncTask, // task
|
||||
"solenoidSyncTask", // name for task
|
||||
4096, // size of task stack
|
||||
NULL, // parameters
|
||||
1, // priority
|
||||
&solenoidSyncTaskHandle,
|
||||
0 // core
|
||||
);
|
||||
// setup a task that will do the custom homing sequence
|
||||
xTaskCreatePinnedToCore(atari_home_task, // task
|
||||
"atari_home_task", // name for task
|
||||
4096, // size of task stack
|
||||
NULL, // parameters
|
||||
1, // priority
|
||||
&atariHomingTaskHandle,
|
||||
0 // core
|
||||
);
|
||||
void machine_init() {
|
||||
solenoid_pull_count = 0; // initialize
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Atari 1020 Solenoid");
|
||||
// setup PWM channel
|
||||
solenoid_pwm_chan_num = sys_get_next_PWM_chan_num();
|
||||
ledcSetup(solenoid_pwm_chan_num, SOLENOID_PWM_FREQ, SOLENOID_PWM_RES_BITS);
|
||||
ledcAttachPin(SOLENOID_PEN_PIN, solenoid_pwm_chan_num);
|
||||
pinMode(SOLENOID_DIRECTION_PIN, OUTPUT); // this sets the direction of the solenoid current
|
||||
pinMode(REED_SW_PIN, INPUT_PULLUP); // external pullup required
|
||||
// setup a task that will calculate solenoid position
|
||||
xTaskCreatePinnedToCore(solenoidSyncTask, // task
|
||||
"solenoidSyncTask", // name for task
|
||||
4096, // size of task stack
|
||||
NULL, // parameters
|
||||
1, // priority
|
||||
&solenoidSyncTaskHandle,
|
||||
0 // core
|
||||
);
|
||||
// setup a task that will do the custom homing sequence
|
||||
xTaskCreatePinnedToCore(atari_home_task, // task
|
||||
"atari_home_task", // name for task
|
||||
4096, // size of task stack
|
||||
NULL, // parameters
|
||||
1, // priority
|
||||
&atariHomingTaskHandle,
|
||||
0 // core
|
||||
);
|
||||
}
|
||||
|
||||
// this task tracks the Z position and sets the solenoid
|
||||
void solenoidSyncTask(void *pvParameters)
|
||||
{
|
||||
int32_t current_position[N_AXIS]; // copy of current location
|
||||
float m_pos[N_AXIS]; // machine position in mm
|
||||
TickType_t xLastWakeTime;
|
||||
const TickType_t xSolenoidFrequency = SOLENOID_TASK_FREQ; // in ticks (typically ms)
|
||||
|
||||
xLastWakeTime = xTaskGetTickCount(); // Initialise the xLastWakeTime variable with the current time.
|
||||
while (true)
|
||||
{ // don't ever return from this or the task dies
|
||||
|
||||
memcpy(current_position, sys_position, sizeof(sys_position)); // get current position in step
|
||||
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);
|
||||
}
|
||||
void solenoidSyncTask(void* pvParameters) {
|
||||
int32_t current_position[N_AXIS]; // copy of current location
|
||||
float m_pos[N_AXIS]; // machine position in mm
|
||||
TickType_t xLastWakeTime;
|
||||
const TickType_t xSolenoidFrequency = SOLENOID_TASK_FREQ; // in ticks (typically ms)
|
||||
xLastWakeTime = xTaskGetTickCount(); // Initialise the xLastWakeTime variable with the current time.
|
||||
while (true) {
|
||||
// don't ever return from this or the task dies
|
||||
memcpy(current_position, sys_position, sizeof(sys_position)); // get current position in step
|
||||
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
|
||||
// continue with regular homing after setup
|
||||
// return true if this completes homing
|
||||
|
||||
bool user_defined_homing()
|
||||
{
|
||||
// create and start a task to do the special homing
|
||||
homing_phase = HOMING_PHASE_FULL_APPROACH;
|
||||
atari_homing = true;
|
||||
return true; // this does it...skip the rest of mc_homing_cycle(...)
|
||||
bool user_defined_homing() {
|
||||
// create and start a task to do the special homing
|
||||
homing_phase = HOMING_PHASE_FULL_APPROACH;
|
||||
atari_homing = true;
|
||||
return true; // this does it...skip the rest of mc_homing_cycle(...)
|
||||
}
|
||||
|
||||
/*
|
||||
Do a custom homing routine.
|
||||
|
||||
|
||||
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
|
||||
2) Check for pen 1
|
||||
3) If fail Retract
|
||||
4) move to right end
|
||||
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?
|
||||
|
||||
*/
|
||||
void atari_home_task(void *pvParameters)
|
||||
{
|
||||
uint8_t homing_attempt = 0; // how many times have we tried to home
|
||||
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
|
||||
char gcode_line[20];
|
||||
|
||||
while (true)
|
||||
{ // this task will only last as long as it is homing
|
||||
|
||||
if (atari_homing)
|
||||
{
|
||||
// must be in idle or alarm state
|
||||
if (sys.state == STATE_IDLE)
|
||||
{
|
||||
switch (homing_phase)
|
||||
{
|
||||
case HOMING_PHASE_FULL_APPROACH: // a full width move to insure it hits left end
|
||||
inputBuffer.push("G90G0Z1\r"); // lift the pen
|
||||
sprintf(gcode_line, "G91G0X%3.2f\r", -ATARI_PAPER_WIDTH + ATARI_HOME_POS - 3.0); // plus a little extra
|
||||
inputBuffer.push(gcode_line);
|
||||
homing_attempt = 1;
|
||||
homing_phase = HOMING_PHASE_CHECK;
|
||||
break;
|
||||
case HOMING_PHASE_CHECK: // check the limits switch
|
||||
if (digitalRead(REED_SW_PIN) == 0)
|
||||
{ // see if reed switch is grounded
|
||||
inputBuffer.push("G4P0.1\n"); // dramtic pause
|
||||
|
||||
sys_position[X_AXIS] = ATARI_HOME_POS * settings.steps_per_mm[X_AXIS];
|
||||
sys_position[Y_AXIS] = 0.0;
|
||||
sys_position[Z_AXIS] = 1.0 * settings.steps_per_mm[Y_AXIS];
|
||||
|
||||
gc_sync_position();
|
||||
plan_sync_position();
|
||||
|
||||
sprintf(gcode_line, "G90G0X%3.2f\r", ATARI_PAPER_WIDTH); // alway return to right side to reduce home travel stalls
|
||||
inputBuffer.push(gcode_line);
|
||||
|
||||
current_tool = 1; // local copy for reference...until actual M6 change
|
||||
gc_state.tool = current_tool;
|
||||
atari_homing = false; // done with homing sequence
|
||||
}
|
||||
else
|
||||
{
|
||||
homing_phase = HOMING_PHASE_RETRACT;
|
||||
homing_attempt++;
|
||||
}
|
||||
break;
|
||||
case HOMING_PHASE_RETRACT:
|
||||
sprintf(gcode_line, "G0X%3.2f\r", -ATARI_HOME_POS);
|
||||
inputBuffer.push(gcode_line);
|
||||
sprintf(gcode_line, "G0X%3.2f\r", ATARI_HOME_POS);
|
||||
inputBuffer.push(gcode_line);
|
||||
homing_phase = HOMING_PHASE_CHECK;
|
||||
break;
|
||||
default:
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Homing phase error %d", homing_phase);
|
||||
atari_homing = false;
|
||||
; // kills task
|
||||
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);
|
||||
}
|
||||
void atari_home_task(void* pvParameters) {
|
||||
uint8_t homing_attempt = 0; // how many times have we tried to home
|
||||
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
|
||||
char gcode_line[20];
|
||||
while (true) {
|
||||
// this task will only last as long as it is homing
|
||||
if (atari_homing) {
|
||||
// must be in idle or alarm state
|
||||
if (sys.state == STATE_IDLE) {
|
||||
switch (homing_phase) {
|
||||
case HOMING_PHASE_FULL_APPROACH: // a full width move to insure it hits left end
|
||||
inputBuffer.push("G90G0Z1\r"); // lift the pen
|
||||
sprintf(gcode_line, "G91G0X%3.2f\r", -ATARI_PAPER_WIDTH + ATARI_HOME_POS - 3.0); // plus a little extra
|
||||
inputBuffer.push(gcode_line);
|
||||
homing_attempt = 1;
|
||||
homing_phase = HOMING_PHASE_CHECK;
|
||||
break;
|
||||
case HOMING_PHASE_CHECK: // check the limits switch
|
||||
if (digitalRead(REED_SW_PIN) == 0) {
|
||||
// see if reed switch is grounded
|
||||
inputBuffer.push("G4P0.1\n"); // dramtic pause
|
||||
sys_position[X_AXIS] = ATARI_HOME_POS * settings.steps_per_mm[X_AXIS];
|
||||
sys_position[Y_AXIS] = 0.0;
|
||||
sys_position[Z_AXIS] = 1.0 * settings.steps_per_mm[Y_AXIS];
|
||||
gc_sync_position();
|
||||
plan_sync_position();
|
||||
sprintf(gcode_line, "G90G0X%3.2f\r", ATARI_PAPER_WIDTH); // alway return to right side to reduce home travel stalls
|
||||
inputBuffer.push(gcode_line);
|
||||
current_tool = 1; // local copy for reference...until actual M6 change
|
||||
gc_state.tool = current_tool;
|
||||
atari_homing = false; // done with homing sequence
|
||||
} else {
|
||||
homing_phase = HOMING_PHASE_RETRACT;
|
||||
homing_attempt++;
|
||||
}
|
||||
break;
|
||||
case HOMING_PHASE_RETRACT:
|
||||
sprintf(gcode_line, "G0X%3.2f\r", -ATARI_HOME_POS);
|
||||
inputBuffer.push(gcode_line);
|
||||
sprintf(gcode_line, "G0X%3.2f\r", ATARI_HOME_POS);
|
||||
inputBuffer.push(gcode_line);
|
||||
homing_phase = HOMING_PHASE_CHECK;
|
||||
break;
|
||||
default:
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Homing phase error %d", homing_phase);
|
||||
atari_homing = false;
|
||||
; // kills task
|
||||
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
|
||||
void calc_solenoid(float penZ)
|
||||
{
|
||||
bool isPenUp;
|
||||
static bool previousPenState = false;
|
||||
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
|
||||
if (previousPenState == isPenUp)
|
||||
{ // if state is unchanged
|
||||
if (solenoid_pull_count > 0)
|
||||
{
|
||||
solenoid_pull_count--;
|
||||
solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_PULL; // stay at full power while counting down
|
||||
}
|
||||
else
|
||||
{
|
||||
solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_HOLD; // pull in delay has expired so lower duty cycle
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // pen direction has changed
|
||||
solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_PULL; // go to full power
|
||||
solenoid_pull_count = SOLENOID_PULL_DURATION; // set the time to count down
|
||||
}
|
||||
|
||||
previousPenState = isPenUp; // save the prev state
|
||||
|
||||
digitalWrite(SOLENOID_DIRECTION_PIN, isPenUp);
|
||||
|
||||
// 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);
|
||||
void calc_solenoid(float penZ) {
|
||||
bool isPenUp;
|
||||
static bool previousPenState = false;
|
||||
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
|
||||
if (previousPenState == isPenUp) {
|
||||
// if state is unchanged
|
||||
if (solenoid_pull_count > 0) {
|
||||
solenoid_pull_count--;
|
||||
solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_PULL; // stay at full power while counting down
|
||||
} else {
|
||||
solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_HOLD; // pull in delay has expired so lower duty cycle
|
||||
}
|
||||
} else {
|
||||
// pen direction has changed
|
||||
solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_PULL; // go to full power
|
||||
solenoid_pull_count = SOLENOID_PULL_DURATION; // set the time to count down
|
||||
}
|
||||
previousPenState = isPenUp; // save the prev state
|
||||
digitalWrite(SOLENOID_DIRECTION_PIN, isPenUp);
|
||||
// skip setting value if it is unchanged
|
||||
if (ledcRead(solenoid_pwm_chan_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_pwm_chan_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
|
||||
position change. Pen 1-4 is valid range.
|
||||
*/
|
||||
void user_tool_change(uint8_t new_tool)
|
||||
{
|
||||
uint8_t move_count;
|
||||
char gcode_line[20];
|
||||
|
||||
protocol_buffer_synchronize(); // wait for all previous moves to complete
|
||||
|
||||
if ((new_tool < 1) || (new_tool > MAX_PEN_NUMBER))
|
||||
{
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Requested Pen#%d is out of 1-4 range", new_tool);
|
||||
return;
|
||||
}
|
||||
|
||||
if (new_tool == current_tool)
|
||||
return;
|
||||
|
||||
if (new_tool > current_tool)
|
||||
{
|
||||
move_count = BUMPS_PER_PEN_CHANGE * (new_tool - current_tool);
|
||||
}
|
||||
else
|
||||
{
|
||||
move_count = BUMPS_PER_PEN_CHANGE * ((MAX_PEN_NUMBER - current_tool) + new_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);
|
||||
void user_tool_change(uint8_t new_tool) {
|
||||
uint8_t move_count;
|
||||
char gcode_line[20];
|
||||
protocol_buffer_synchronize(); // wait for all previous moves to complete
|
||||
if ((new_tool < 1) || (new_tool > MAX_PEN_NUMBER)) {
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Requested Pen#%d is out of 1-4 range", new_tool);
|
||||
return;
|
||||
}
|
||||
if (new_tool == current_tool)
|
||||
return;
|
||||
if (new_tool > current_tool)
|
||||
move_count = BUMPS_PER_PEN_CHANGE * (new_tool - current_tool);
|
||||
else
|
||||
move_count = BUMPS_PER_PEN_CHANGE * ((MAX_PEN_NUMBER - current_tool) + new_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....
|
||||
void atari_next_pen()
|
||||
{
|
||||
if (current_tool < MAX_PEN_NUMBER)
|
||||
{
|
||||
gc_state.tool = current_tool + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gc_state.tool = 1;
|
||||
}
|
||||
user_tool_change(gc_state.tool);
|
||||
void atari_next_pen() {
|
||||
if (current_tool < MAX_PEN_NUMBER)
|
||||
gc_state.tool = current_tool + 1;
|
||||
else
|
||||
gc_state.tool = 1;
|
||||
user_tool_change(gc_state.tool);
|
||||
}
|
||||
|
||||
// Polar coaster has macro buttons, this handles those button pushes.
|
||||
void user_defined_macro(uint8_t index)
|
||||
{
|
||||
char gcode_line[20];
|
||||
|
||||
switch (index)
|
||||
{
|
||||
void user_defined_macro(uint8_t index) {
|
||||
char gcode_line[20];
|
||||
switch (index) {
|
||||
#ifdef MACRO_BUTTON_0_PIN
|
||||
case CONTROL_PIN_INDEX_MACRO_0:
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Pen switch");
|
||||
inputBuffer.push("$H\r");
|
||||
break;
|
||||
case CONTROL_PIN_INDEX_MACRO_0:
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Pen switch");
|
||||
inputBuffer.push("$H\r");
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef MACRO_BUTTON_1_PIN
|
||||
case CONTROL_PIN_INDEX_MACRO_1:
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Color switch");
|
||||
atari_next_pen();
|
||||
sprintf(gcode_line, "G90G0X%3.2f\r", ATARI_PAPER_WIDTH); // alway return to right side to reduce home travel stalls
|
||||
inputBuffer.push(gcode_line);
|
||||
break;
|
||||
case CONTROL_PIN_INDEX_MACRO_1:
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Color switch");
|
||||
atari_next_pen();
|
||||
sprintf(gcode_line, "G90G0X%3.2f\r", ATARI_PAPER_WIDTH); // alway return to right side to reduce home travel stalls
|
||||
inputBuffer.push(gcode_line);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef MACRO_BUTTON_2_PIN
|
||||
case CONTROL_PIN_INDEX_MACRO_2:
|
||||
// feed out some paper and reset the Y 0
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Paper switch");
|
||||
inputBuffer.push("G0Y-25\r");
|
||||
inputBuffer.push("G4P0.1\r"); // sync...forces wait for planner to clear
|
||||
sys_position[Y_AXIS] = 0.0; // reset the Y position
|
||||
gc_sync_position();
|
||||
plan_sync_position();
|
||||
break;
|
||||
case CONTROL_PIN_INDEX_MACRO_2:
|
||||
// feed out some paper and reset the Y 0
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Paper switch");
|
||||
inputBuffer.push("G0Y-25\r");
|
||||
inputBuffer.push("G4P0.1\r"); // sync...forces wait for planner to clear
|
||||
sys_position[Y_AXIS] = 0.0; // reset the Y position
|
||||
gc_sync_position();
|
||||
plan_sync_position();
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Unknown Switch %d", index);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Unknown Switch %d", index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void user_m30()
|
||||
{
|
||||
char gcode_line[20];
|
||||
sprintf(gcode_line, "G90G0X%3.2f\r", ATARI_PAPER_WIDTH); //
|
||||
inputBuffer.push(gcode_line);
|
||||
void user_m30() {
|
||||
char gcode_line[20];
|
||||
sprintf(gcode_line, "G90G0X%3.2f\r", ATARI_PAPER_WIDTH); //
|
||||
inputBuffer.push(gcode_line);
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@
|
||||
#define CUSTOM_CODE_FILENAME "Custom/atari_1020.cpp"
|
||||
|
||||
#ifdef USE_RMT_STEPS
|
||||
#undef USE_RMT_STEPS
|
||||
#undef USE_RMT_STEPS
|
||||
#endif
|
||||
|
||||
#define USE_UNIPOLAR
|
||||
@@ -52,32 +52,31 @@
|
||||
|
||||
#define SOLENOID_DIRECTION_PIN GPIO_NUM_4
|
||||
#define SOLENOID_PEN_PIN GPIO_NUM_2
|
||||
#define SOLENOID_CHANNEL_NUM 6
|
||||
|
||||
#ifdef HOMING_CYCLE_0
|
||||
#undef HOMING_CYCLE_0
|
||||
#undef HOMING_CYCLE_0
|
||||
#endif
|
||||
#define HOMING_CYCLE_0 (1 << X_AXIS) // this 'bot only homes the X axis
|
||||
#ifdef HOMING_CYCLE_1
|
||||
#undef HOMING_CYCLE_1
|
||||
#undef HOMING_CYCLE_1
|
||||
#endif
|
||||
#ifdef HOMING_CYCLE_2
|
||||
#undef HOMING_CYCLE_2
|
||||
#undef HOMING_CYCLE_2
|
||||
#endif
|
||||
|
||||
#define REED_SW_PIN GPIO_NUM_17
|
||||
#define LIMIT_MASK 0
|
||||
|
||||
#ifdef IGNORE_CONTROL_PINS // maybe set in config.h
|
||||
#undef IGNORE_CONTROL_PINS
|
||||
#undef IGNORE_CONTROL_PINS
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_CONTROL_SW_DEBOUNCE
|
||||
#define ENABLE_CONTROL_SW_DEBOUNCE
|
||||
#define ENABLE_CONTROL_SW_DEBOUNCE
|
||||
#endif
|
||||
|
||||
#ifdef INVERT_CONTROL_PIN_MASK
|
||||
#undef INVERT_CONTROL_PIN_MASK
|
||||
#undef INVERT_CONTROL_PIN_MASK
|
||||
#endif
|
||||
#define INVERT_CONTROL_PIN_MASK B01110000
|
||||
|
||||
@@ -86,7 +85,7 @@
|
||||
#define MACRO_BUTTON_2_PIN GPIO_NUM_36 // Paper Switch
|
||||
|
||||
#ifdef DEFAULTS_GENERIC
|
||||
#undef DEFAULTS_GENERIC // undefine generic then define each default below
|
||||
#undef DEFAULTS_GENERIC // undefine generic then define each default below
|
||||
#endif
|
||||
#define DEFAULT_STEP_PULSE_MICROSECONDS 3
|
||||
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 200 // 200ms
|
||||
@@ -160,11 +159,11 @@
|
||||
#define USE_M30 // use the user defined end of program
|
||||
|
||||
#ifndef atari_h
|
||||
#define atari_h
|
||||
#define atari_h
|
||||
|
||||
void solenoid_disable();
|
||||
void solenoidSyncTask(void *pvParameters);
|
||||
void calc_solenoid(float penZ);
|
||||
void atari_home_task(void *pvParameters);
|
||||
void atari_next_pen();
|
||||
void solenoid_disable();
|
||||
void solenoidSyncTask(void* pvParameters);
|
||||
void calc_solenoid(float penZ);
|
||||
void atari_home_task(void* pvParameters);
|
||||
void atari_next_pen();
|
||||
#endif
|
||||
|
@@ -24,9 +24,8 @@
|
||||
|
||||
#define MACHINE_NAME "MACHINE_FOO_6X"
|
||||
|
||||
// Be sure to change to N_AXIS 6 in nuts_bolts.h
|
||||
#ifdef N_AXIS
|
||||
#undef N_AXIS
|
||||
#undef N_AXIS
|
||||
#endif
|
||||
#define N_AXIS 6
|
||||
|
||||
@@ -50,7 +49,6 @@
|
||||
// servos
|
||||
#define USE_SERVO_AXES
|
||||
#define SERVO_Z_PIN GPIO_NUM_22
|
||||
#define SERVO_Z_CHANNEL_NUM 6
|
||||
#define SERVO_Z_RANGE_MIN 0.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
|
||||
@@ -58,7 +56,6 @@
|
||||
#define SERVO_Z_MPOS false // will not use mpos, uses work coordinates
|
||||
|
||||
#define SERVO_C_PIN GPIO_NUM_2
|
||||
#define SERVO_C_CHANNEL_NUM 7
|
||||
#define SERVO_C_RANGE_MIN 0.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
|
||||
@@ -76,20 +73,20 @@
|
||||
#define STEPPERS_DISABLE_PIN GPIO_NUM_13
|
||||
|
||||
#ifdef HOMING_CYCLE_0 // undefine from config.h
|
||||
#undef HOMING_CYCLE_0
|
||||
#undef HOMING_CYCLE_0
|
||||
#endif
|
||||
//#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) |(1<<A_AXIS)|(1<<B_AXIS))
|
||||
|
||||
#ifdef HOMING_CYCLE_1 // undefine from config.h
|
||||
#undef HOMING_CYCLE_1
|
||||
#undef HOMING_CYCLE_1
|
||||
#endif
|
||||
//#define HOMING_CYCLE_1 (1<<A_AXIS)
|
||||
#define HOMING_CYCLE_1 ((1<<A_AXIS)|(1<<B_AXIS))
|
||||
|
||||
#ifdef HOMING_CYCLE_2 // undefine from config.h
|
||||
#undef HOMING_CYCLE_2
|
||||
#undef HOMING_CYCLE_2
|
||||
#endif
|
||||
/*
|
||||
#define HOMING_CYCLE_2 (1<<Y_AXIS)
|
||||
|
@@ -31,7 +31,7 @@
|
||||
#define Y_DIRECTION_PIN GPIO_NUM_25
|
||||
|
||||
#ifndef COREXY // maybe set in config.h
|
||||
#define COREXY
|
||||
#define COREXY
|
||||
#endif
|
||||
|
||||
#define STEPPERS_DISABLE_PIN GPIO_NUM_13
|
||||
@@ -41,11 +41,10 @@
|
||||
#define LIMIT_MASK B11
|
||||
|
||||
#ifndef USE_SERVO_AXES // maybe set in config.h
|
||||
#define USE_SERVO_AXES
|
||||
#define USE_SERVO_AXES
|
||||
#endif
|
||||
|
||||
#define SERVO_Z_PIN GPIO_NUM_27
|
||||
#define SERVO_Z_CHANNEL_NUM 5
|
||||
#define SERVO_Z_RANGE_MIN 0.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
|
||||
@@ -53,24 +52,24 @@
|
||||
#define SERVO_Z_MPOS false // will not use mpos, uses work coordinates
|
||||
|
||||
#ifndef IGNORE_CONTROL_PINS // maybe set in config.h
|
||||
#define IGNORE_CONTROL_PINS
|
||||
#define IGNORE_CONTROL_PINS
|
||||
#endif
|
||||
|
||||
// redefine some stuff from config.h
|
||||
#ifdef HOMING_CYCLE_0
|
||||
#undef HOMING_CYCLE_0
|
||||
#undef HOMING_CYCLE_0
|
||||
#endif
|
||||
|
||||
#define HOMING_CYCLE_0 (1<<Y_AXIS)
|
||||
|
||||
#ifdef HOMING_CYCLE_1
|
||||
#undef HOMING_CYCLE_1
|
||||
#undef HOMING_CYCLE_1
|
||||
#endif
|
||||
|
||||
#define HOMING_CYCLE_1 (1<<X_AXIS)
|
||||
|
||||
#ifdef HOMING_CYCLE_2
|
||||
#undef HOMING_CYCLE_2
|
||||
#undef HOMING_CYCLE_2
|
||||
#endif
|
||||
|
||||
#define SERVO_PEN_PIN GPIO_NUM_27
|
||||
|
@@ -41,10 +41,10 @@
|
||||
#define STEPPERS_DISABLE_PIN GPIO_NUM_13
|
||||
|
||||
#ifdef PEN_LASER_V1
|
||||
#define X_LIMIT_PIN GPIO_NUM_2
|
||||
#define X_LIMIT_PIN GPIO_NUM_2
|
||||
#endif
|
||||
#ifdef PEN_LASER_V2
|
||||
#define X_LIMIT_PIN GPIO_NUM_15
|
||||
#define X_LIMIT_PIN GPIO_NUM_15
|
||||
#endif
|
||||
#define Y_LIMIT_PIN GPIO_NUM_4
|
||||
#define LIMIT_MASK B11
|
||||
@@ -57,17 +57,15 @@
|
||||
//#define USING_SOLENOID // uncomment to use this feature
|
||||
|
||||
#ifdef USING_SERVO
|
||||
#define USE_SERVO_AXES
|
||||
#define SERVO_Z_PIN GPIO_NUM_27
|
||||
#define SERVO_Z_CHANNEL_NUM 3
|
||||
#define SERVO_Z_RANGE_MIN 0
|
||||
#define SERVO_Z_RANGE_MAX 10
|
||||
#define USE_SERVO_AXES
|
||||
#define SERVO_Z_PIN GPIO_NUM_27
|
||||
#define SERVO_Z_RANGE_MIN 0
|
||||
#define SERVO_Z_RANGE_MAX 10
|
||||
#endif
|
||||
|
||||
#ifdef USING_SOLENOID
|
||||
#define USE_PEN_SOLENOID
|
||||
#define SOLENOID_PEN_PIN GPIO_NUM_16
|
||||
#define SOLENOID_CHANNEL_NUM 6
|
||||
#define USE_PEN_SOLENOID
|
||||
#define SOLENOID_PEN_PIN GPIO_NUM_16
|
||||
#endif
|
||||
|
||||
// defaults
|
||||
|
@@ -44,11 +44,10 @@
|
||||
#define STEPPERS_DISABLE_PIN GPIO_NUM_17
|
||||
|
||||
#ifndef USE_SERVO_AXES // maybe set in config.h
|
||||
#define USE_SERVO_AXES
|
||||
#define USE_SERVO_AXES
|
||||
#endif
|
||||
|
||||
#define SERVO_Z_PIN GPIO_NUM_16
|
||||
#define SERVO_Z_CHANNEL_NUM 5
|
||||
#define SERVO_Z_RANGE_MIN 0.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
|
||||
@@ -59,20 +58,20 @@
|
||||
#define LIMIT_MASK B1
|
||||
|
||||
#ifdef IGNORE_CONTROL_PINS // maybe set in config.h
|
||||
#undef IGNORE_CONTROL_PINS
|
||||
#undef IGNORE_CONTROL_PINS
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_CONTROL_SW_DEBOUNCE
|
||||
#define ENABLE_CONTROL_SW_DEBOUNCE
|
||||
#define ENABLE_CONTROL_SW_DEBOUNCE
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_SW_DEBOUNCE_PERIOD
|
||||
#undef CONTROL_SW_DEBOUNCE_PERIOD
|
||||
#undef CONTROL_SW_DEBOUNCE_PERIOD
|
||||
#endif
|
||||
#define CONTROL_SW_DEBOUNCE_PERIOD 100 // really long debounce
|
||||
|
||||
#ifdef INVERT_CONTROL_PIN_MASK
|
||||
#undef INVERT_CONTROL_PIN_MASK
|
||||
#undef INVERT_CONTROL_PIN_MASK
|
||||
#endif
|
||||
#define INVERT_CONTROL_PIN_MASK B11111111
|
||||
|
||||
@@ -82,14 +81,14 @@
|
||||
|
||||
// redefine some stuff from config.h
|
||||
#ifdef HOMING_CYCLE_0
|
||||
#undef HOMING_CYCLE_0
|
||||
#undef HOMING_CYCLE_0
|
||||
#endif
|
||||
#define HOMING_CYCLE_0 (1<<X_AXIS) // this 'bot only homes the X axis
|
||||
#ifdef HOMING_CYCLE_1
|
||||
#undef HOMING_CYCLE_1
|
||||
#undef HOMING_CYCLE_1
|
||||
#endif
|
||||
#ifdef HOMING_CYCLE_2
|
||||
#undef HOMING_CYCLE_2
|
||||
#undef HOMING_CYCLE_2
|
||||
#endif
|
||||
|
||||
// ============= End CPU MAP ==================
|
||||
|
@@ -39,11 +39,11 @@
|
||||
#define STEPPERS_DISABLE_PIN GPIO_NUM_13
|
||||
|
||||
#ifdef PEN_LASER_V1
|
||||
#define X_LIMIT_PIN GPIO_NUM_2
|
||||
#define X_LIMIT_PIN GPIO_NUM_2
|
||||
#endif
|
||||
|
||||
#ifdef PEN_LASER_V2
|
||||
#define X_LIMIT_PIN GPIO_NUM_15
|
||||
#define X_LIMIT_PIN GPIO_NUM_15
|
||||
#endif
|
||||
|
||||
#define Y_LIMIT_PIN GPIO_NUM_4
|
||||
@@ -61,16 +61,14 @@
|
||||
#define SPINDLE_PWM_OFF_VALUE 0
|
||||
|
||||
#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
|
||||
|
||||
#define SERVO_Y_PIN GPIO_NUM_14
|
||||
#define SERVO_Y_CHANNEL_NUM 6
|
||||
#define SERVO_Y_RANGE_MIN 0.0
|
||||
#define SERVO_Y_RANGE_MAX 30.0
|
||||
|
||||
#define SERVO_Z_PIN GPIO_NUM_27
|
||||
#define SERVO_Z_CHANNEL_NUM 5
|
||||
#define SERVO_Z_RANGE_MIN 0.0
|
||||
#define SERVO_Z_RANGE_MAX 20.0
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
template.h
|
||||
Part of Grbl_ESP32
|
||||
template.h
|
||||
Part of Grbl_ESP32
|
||||
|
||||
Template for a machine configuration file.
|
||||
|
||||
@@ -135,7 +135,6 @@
|
||||
// #define USE_SERVO_AXES
|
||||
|
||||
// #define SERVO_Z_PIN GPIO_NUM_22
|
||||
// #define SERVO_Z_CHANNEL_NUM 6
|
||||
// #define SERVO_Z_RANGE_MIN 0.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
|
||||
|
@@ -4,7 +4,7 @@
|
||||
|
||||
Pin assignments for the TMC2130 Pen/Laser controller
|
||||
https://github.com/bdring/Grbl_ESP32_TMC2130_Plotter_Controller
|
||||
|
||||
|
||||
2018 - Bart Dring
|
||||
2020 - Mitch Bradley
|
||||
|
||||
@@ -28,11 +28,11 @@
|
||||
#define MACHINE_V2 // version 2 PCB
|
||||
|
||||
#ifdef MACHINE_V1
|
||||
#define MACHINE_NAME "ESP32_TMC2130_PEN V1"
|
||||
#define X_LIMIT_PIN GPIO_NUM_2
|
||||
#define MACHINE_NAME "ESP32_TMC2130_PEN V1"
|
||||
#define X_LIMIT_PIN GPIO_NUM_2
|
||||
#else
|
||||
#define MACHINE_NAME "ESP32_TMC2130_PEN V2"
|
||||
#define X_LIMIT_PIN GPIO_NUM_32
|
||||
#define MACHINE_NAME "ESP32_TMC2130_PEN V2"
|
||||
#define X_LIMIT_PIN GPIO_NUM_32
|
||||
#endif
|
||||
|
||||
#define USE_TRINAMIC // Using at least 1 trinamic driver
|
||||
@@ -59,7 +59,6 @@
|
||||
#endif
|
||||
|
||||
#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_MAX 5.0
|
||||
#define SERVO_Z_HOMING_TYPE SERVO_HOMING_TARGET // during homing it will instantly move to a target value
|
||||
|
@@ -6,7 +6,6 @@
|
||||
#endif
|
||||
|
||||
#define SPINDLE_PWM_MAX_VALUE ((1<<SPINDLE_PWM_BIT_PRECISION) - 1)
|
||||
#define SPINDLE_PWM_CHANNEL 0
|
||||
|
||||
// Grbl setting that are common to all machines
|
||||
// It should not be necessary to change anything herein
|
||||
|
@@ -29,122 +29,116 @@
|
||||
static TaskHandle_t servosSyncTaskHandle = 0;
|
||||
|
||||
#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
|
||||
#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
|
||||
#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
|
||||
|
||||
#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
|
||||
#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
|
||||
#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
|
||||
|
||||
void init_servos() {
|
||||
// ======================== 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);
|
||||
X_Servo_Axis.init();
|
||||
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);
|
||||
#endif
|
||||
#ifdef SERVO_X_HOME_POS
|
||||
#endif
|
||||
#ifdef SERVO_X_HOME_POS
|
||||
X_Servo_Axis.set_homing_position(SERVO_X_HOME_POS);
|
||||
#endif
|
||||
#ifdef SERVO_X_MPOS // value should be true or false
|
||||
#endif
|
||||
#ifdef SERVO_X_MPOS // value should be true or false
|
||||
X_Servo_Axis.set_use_mpos(SERVO_X_MPOS);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
// ======================== 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);
|
||||
Y_Servo_Axis.init();
|
||||
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);
|
||||
#endif
|
||||
#ifdef SERVO_Y_HOME_POS
|
||||
#endif
|
||||
#ifdef SERVO_Y_HOME_POS
|
||||
Y_Servo_Axis.set_homing_position(SERVO_Y_HOME_POS);
|
||||
#endif
|
||||
#ifdef SERVO_Y_MPOS // value should be true or false
|
||||
#endif
|
||||
#ifdef SERVO_Y_MPOS // value should be true or false
|
||||
Y_Servo_Axis.set_use_mpos(SERVO_Y_MPOS);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
// ======================== 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);
|
||||
Z_Servo_Axis.init();
|
||||
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);
|
||||
#endif
|
||||
#ifdef SERVO_Z_HOME_POS
|
||||
#endif
|
||||
#ifdef SERVO_Z_HOME_POS
|
||||
Z_Servo_Axis.set_homing_position(SERVO_Z_HOME_POS);
|
||||
#endif
|
||||
#ifdef SERVO_Z_MPOS // value should be true or false
|
||||
#endif
|
||||
#ifdef SERVO_Z_MPOS // value should be true or false
|
||||
Z_Servo_Axis.set_use_mpos(SERVO_Z_MPOS);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
// ======================== 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);
|
||||
A_Servo_Axis.init();
|
||||
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);
|
||||
#endif
|
||||
#ifdef SERVO_A_HOME_POS
|
||||
#endif
|
||||
#ifdef SERVO_A_HOME_POS
|
||||
A_Servo_Axis.set_homing_position(SERVO_A_HOME_POS);
|
||||
#endif
|
||||
#ifdef SERVO_A_MPOS // value should be true or false
|
||||
#endif
|
||||
#ifdef SERVO_A_MPOS // value should be true or false
|
||||
A_Servo_Axis.set_use_mpos(SERVO_A_MPOS);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
// ======================== 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);
|
||||
B_Servo_Axis.init();
|
||||
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);
|
||||
#endif
|
||||
#ifdef SERVO_B_HOME_POS
|
||||
#endif
|
||||
#ifdef SERVO_B_HOME_POS
|
||||
B_Servo_Axis.set_homing_position(SERVO_B_HOME_POS);
|
||||
#endif
|
||||
#ifdef SERVO_B_MPOS // value should be true or false
|
||||
#endif
|
||||
#ifdef SERVO_B_MPOS // value should be true or false
|
||||
B_Servo_Axis.set_use_mpos(SERVO_B_MPOS);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
// ======================== 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);
|
||||
C_Servo_Axis.init();
|
||||
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);
|
||||
#endif
|
||||
#ifdef SERVO_C_HOME_POS
|
||||
#endif
|
||||
#ifdef SERVO_C_HOME_POS
|
||||
C_Servo_Axis.set_homing_position(SERVO_C_HOME_POS);
|
||||
#endif
|
||||
#ifdef SERVO_C_MPOS // value should be true or false
|
||||
#endif
|
||||
#ifdef SERVO_C_MPOS // value should be true or false
|
||||
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
|
||||
xTaskCreatePinnedToCore(servosSyncTask, // 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)
|
||||
xLastWakeTime = xTaskGetTickCount(); // Initialise the xLastWakeTime variable with the current time.
|
||||
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();
|
||||
#endif
|
||||
#ifdef SERVO_Y_PIN
|
||||
#endif
|
||||
#ifdef SERVO_Y_PIN
|
||||
Y_Servo_Axis.set_location();
|
||||
#endif
|
||||
#ifdef SERVO_Z_PIN
|
||||
#endif
|
||||
#ifdef SERVO_Z_PIN
|
||||
Z_Servo_Axis.set_location();
|
||||
#endif
|
||||
#ifdef SERVO_A_PIN
|
||||
#endif
|
||||
#ifdef SERVO_A_PIN
|
||||
A_Servo_Axis.set_location();
|
||||
#endif
|
||||
#ifdef SERVO_B_PIN
|
||||
#endif
|
||||
#ifdef SERVO_B_PIN
|
||||
B_Servo_Axis.set_location();
|
||||
#endif
|
||||
#ifdef SERVO_C_PIN
|
||||
#endif
|
||||
#ifdef SERVO_C_PIN
|
||||
C_Servo_Axis.set_location();
|
||||
#endif
|
||||
#endif
|
||||
vTaskDelayUntil(&xLastWakeTime, xServoFrequency);
|
||||
}
|
||||
}
|
||||
|
||||
// =============================== 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;
|
||||
_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
|
||||
_use_mpos = true; // default is to use the machine position rather than work position
|
||||
}
|
||||
|
@@ -36,7 +36,6 @@
|
||||
|
||||
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_CHANNEL_NUM 6
|
||||
|
||||
undefine any step and direction pins associated with that axis
|
||||
|
||||
@@ -93,7 +92,7 @@ void servosSyncTask(void* pvParameters);
|
||||
|
||||
class ServoAxis {
|
||||
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 set_location();
|
||||
void disable(); // sets PWM to 0% duty cycle. Most servos can be manually moved in this state
|
||||
|
@@ -23,6 +23,8 @@
|
||||
|
||||
#ifdef USE_PEN_SOLENOID
|
||||
|
||||
int8_t solenoid_pwm_chan_num;
|
||||
|
||||
static TaskHandle_t solenoidSyncTaskHandle = 0;
|
||||
|
||||
// used to delay turn on
|
||||
@@ -35,8 +37,9 @@ void solenoid_init() {
|
||||
solenoid_pen_enable = false; // start delay has not completed yet.
|
||||
solenoide_hold_count = 0; // initialize
|
||||
// setup PWM channel
|
||||
ledcSetup(SOLENOID_CHANNEL_NUM, SOLENOID_PWM_FREQ, SOLENOID_PWM_RES_BITS);
|
||||
ledcAttachPin(SOLENOID_PEN_PIN, SOLENOID_CHANNEL_NUM);
|
||||
solenoid_pwm_chan_num = sys_get_next_PWM_chan_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
|
||||
// setup a task that will calculate the determine and set the servo position
|
||||
xTaskCreatePinnedToCore(solenoidSyncTask, // task
|
||||
@@ -51,7 +54,7 @@ void solenoid_init() {
|
||||
|
||||
// turn off the PWM (0 duty)
|
||||
void solenoid_disable() {
|
||||
ledcWrite(SOLENOID_CHANNEL_NUM, 0);
|
||||
ledcWrite(solenoid_pwm_chan_num, 0);
|
||||
}
|
||||
|
||||
// this is the task
|
||||
@@ -91,13 +94,13 @@ void calc_solenoid(float penZ) {
|
||||
solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_HOLD;
|
||||
}
|
||||
// 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;
|
||||
// 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);
|
||||
ledcWrite(solenoid_pwm_chan_num, solenoid_pen_pulse_len);
|
||||
portEXIT_CRITICAL(&myMutex);
|
||||
}
|
||||
|
||||
|
@@ -20,6 +20,8 @@
|
||||
|
||||
#include "grbl.h"
|
||||
|
||||
int8_t spindle_pwm_chan_num;
|
||||
|
||||
#ifdef SPINDLE_PWM_PIN
|
||||
static float pwm_gradient; // Precalulated value to speed up rpm to PWM conversions.
|
||||
uint32_t spindle_pwm_period; // how many counts in 1 period
|
||||
@@ -54,8 +56,9 @@ void spindle_init() {
|
||||
pinMode(SPINDLE_DIR_PIN, OUTPUT);
|
||||
#endif
|
||||
// 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
|
||||
ledcAttachPin(SPINDLE_PWM_PIN, SPINDLE_PWM_CHANNEL); // attach the PWM to the pin
|
||||
spindle_pwm_chan_num - sys_get_next_PWM_chan_num();
|
||||
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
|
||||
spindle_stop();
|
||||
#endif
|
||||
@@ -65,9 +68,9 @@ void spindle_stop() {
|
||||
spindle_set_enable(false);
|
||||
#ifdef SPINDLE_PWM_PIN
|
||||
#ifndef INVERT_SPINDLE_PWM
|
||||
grbl_analogWrite(SPINDLE_PWM_CHANNEL, spindle_pwm_off_value);
|
||||
grbl_analogWrite(spindle_pwm_chan_num, spindle_pwm_off_value);
|
||||
#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
|
||||
}
|
||||
@@ -77,7 +80,7 @@ uint8_t spindle_get_state() { // returns SPINDLE_STATE_DISABLE, SPINDLE_STATE_CW
|
||||
#ifndef SPINDLE_PWM_PIN
|
||||
return (SPINDLE_STATE_DISABLE);
|
||||
#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);
|
||||
else {
|
||||
#ifdef SPINDLE_DIR_PIN
|
||||
@@ -103,9 +106,9 @@ void spindle_set_speed(uint32_t pwm_value) {
|
||||
spindle_set_enable(pwm_value != 0);
|
||||
#endif
|
||||
#ifndef INVERT_SPINDLE_PWM
|
||||
grbl_analogWrite(SPINDLE_PWM_CHANNEL, pwm_value);
|
||||
grbl_analogWrite(spindle_pwm_chan_num, pwm_value);
|
||||
#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
|
||||
}
|
||||
|
@@ -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");
|
||||
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;
|
||||
}
|
||||
}
|
@@ -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_PWM_chan_num();
|
||||
|
||||
#endif
|
||||
#endif
|
Reference in New Issue
Block a user