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

Merge pull request #356 from bdring/Devt

Auto assigned PWM channels
This commit is contained in:
bdring
2020-03-22 20:41:01 +01:00
committed by GitHub
16 changed files with 354 additions and 414 deletions

View File

@@ -35,24 +35,21 @@
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"); grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Atari 1020 Solenoid");
// 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);
pinMode(SOLENOID_DIRECTION_PIN, OUTPUT); // this sets the direction of the solenoid current pinMode(SOLENOID_DIRECTION_PIN, OUTPUT); // this sets the direction of the solenoid current
pinMode(REED_SW_PIN, INPUT_PULLUP); // external pullup required pinMode(REED_SW_PIN, INPUT_PULLUP); // external pullup required
// setup a task that will calculate solenoid position // setup a task that will calculate solenoid position
xTaskCreatePinnedToCore(solenoidSyncTask, // task xTaskCreatePinnedToCore(solenoidSyncTask, // task
"solenoidSyncTask", // name for task "solenoidSyncTask", // name for task
@@ -74,21 +71,17 @@ void machine_init()
} }
// 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. xLastWakeTime = xTaskGetTickCount(); // Initialise the xLastWakeTime variable with the current time.
while (true) while (true) {
{ // don't ever return from this or the task dies // don't ever return from this or the task dies
memcpy(current_position, sys_position, sizeof(sys_position)); // get current position in step 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 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 calc_solenoid(m_pos[Z_AXIS]); // calculate kinematics and move the servos
vTaskDelayUntil(&xLastWakeTime, xSolenoidFrequency); vTaskDelayUntil(&xLastWakeTime, xSolenoidFrequency);
} }
} }
@@ -97,8 +90,7 @@ void solenoidSyncTask(void *pvParameters)
// 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;
@@ -120,23 +112,17 @@ 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) {
while (true) // this task will only last as long as it is homing
{ // this task will only last as long as it is homing if (atari_homing) {
if (atari_homing)
{
// must be in idle or alarm state // must be in idle or alarm state
if (sys.state == STATE_IDLE) if (sys.state == STATE_IDLE) {
{ switch (homing_phase) {
switch (homing_phase)
{
case HOMING_PHASE_FULL_APPROACH: // a full width move to insure it hits left end case HOMING_PHASE_FULL_APPROACH: // a full width move to insure it hits left end
inputBuffer.push("G90G0Z1\r"); // lift the pen 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 sprintf(gcode_line, "G91G0X%3.2f\r", -ATARI_PAPER_WIDTH + ATARI_HOME_POS - 3.0); // plus a little extra
@@ -145,26 +131,20 @@ void atari_home_task(void *pvParameters)
homing_phase = HOMING_PHASE_CHECK; homing_phase = HOMING_PHASE_CHECK;
break; break;
case HOMING_PHASE_CHECK: // check the limits switch case HOMING_PHASE_CHECK: // check the limits switch
if (digitalRead(REED_SW_PIN) == 0) if (digitalRead(REED_SW_PIN) == 0) {
{ // see if reed switch is grounded // see if reed switch is grounded
inputBuffer.push("G4P0.1\n"); // dramtic pause inputBuffer.push("G4P0.1\n"); // dramtic pause
sys_position[X_AXIS] = ATARI_HOME_POS * settings.steps_per_mm[X_AXIS]; sys_position[X_AXIS] = ATARI_HOME_POS * settings.steps_per_mm[X_AXIS];
sys_position[Y_AXIS] = 0.0; sys_position[Y_AXIS] = 0.0;
sys_position[Z_AXIS] = 1.0 * settings.steps_per_mm[Y_AXIS]; sys_position[Z_AXIS] = 1.0 * settings.steps_per_mm[Y_AXIS];
gc_sync_position(); gc_sync_position();
plan_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 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);
current_tool = 1; // local copy for reference...until actual M6 change current_tool = 1; // local copy for reference...until actual M6 change
gc_state.tool = current_tool; gc_state.tool = current_tool;
atari_homing = false; // done with homing sequence atari_homing = false; // done with homing sequence
} } else {
else
{
homing_phase = HOMING_PHASE_RETRACT; homing_phase = HOMING_PHASE_RETRACT;
homing_attempt++; homing_attempt++;
} }
@@ -182,9 +162,8 @@ void atari_home_task(void *pvParameters)
; // kills task ; // kills task
break; break;
} }
if (homing_attempt > ATARI_HOMING_ATTEMPTS) {
if (homing_attempt > ATARI_HOMING_ATTEMPTS) // try all positions plus 1
{ // try all positions plus 1
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Atari homing failed"); grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Atari homing failed");
inputBuffer.push("G90\r"); inputBuffer.push("G90\r");
atari_homing = false; atari_homing = false;
@@ -197,46 +176,35 @@ void atari_home_task(void *pvParameters)
} }
// 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 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 the state has not change, we only count down to the pull time
if (previousPenState == isPenUp) if (previousPenState == isPenUp) {
{ // if state is unchanged // if state is unchanged
if (solenoid_pull_count > 0) if (solenoid_pull_count > 0) {
{
solenoid_pull_count--; solenoid_pull_count--;
solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_PULL; // stay at full power while counting down solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_PULL; // stay at full power while counting down
} } else {
else
{
solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_HOLD; // pull in delay has expired so lower duty cycle solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_HOLD; // pull in delay has expired so lower duty cycle
} }
} } else {
else // pen direction has changed
{ // pen direction has changed
solenoid_pen_pulse_len = SOLENOID_PULSE_LEN_PULL; // go to full power 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_pull_count = SOLENOID_PULL_DURATION; // set the time to count down
} }
previousPenState = isPenUp; // save the prev state previousPenState = isPenUp; // save the prev state
digitalWrite(SOLENOID_DIRECTION_PIN, isPenUp); digitalWrite(SOLENOID_DIRECTION_PIN, isPenUp);
// 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);
} }
@@ -244,72 +212,50 @@ void calc_solenoid(float penZ)
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 protocol_buffer_synchronize(); // wait for all previous moves to complete
if ((new_tool < 1) || (new_tool > MAX_PEN_NUMBER)) {
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); 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) if (new_tool == current_tool)
return; return;
if (new_tool > current_tool) if (new_tool > current_tool)
{
move_count = BUMPS_PER_PEN_CHANGE * (new_tool - current_tool); move_count = BUMPS_PER_PEN_CHANGE * (new_tool - current_tool);
}
else else
{
move_count = BUMPS_PER_PEN_CHANGE * ((MAX_PEN_NUMBER - current_tool) + new_tool); 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 sprintf(gcode_line, "G0Z%3.2f\r", ATARI_TOOL_CHANGE_Z); // go to tool change height
inputBuffer.push(gcode_line); inputBuffer.push(gcode_line);
for (uint8_t i = 0; i < move_count; i++) for (uint8_t i = 0; i < move_count; i++) {
{
sprintf(gcode_line, "G0X%3.2f\r", ATARI_HOME_POS); // sprintf(gcode_line, "G0X%3.2f\r", ATARI_HOME_POS); //
inputBuffer.push(gcode_line); inputBuffer.push(gcode_line);
inputBuffer.push("G0X0\r"); inputBuffer.push("G0X0\r");
} }
current_tool = new_tool; current_tool = new_tool;
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Change to Pen#%d", current_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; gc_state.tool = current_tool + 1;
}
else else
{
gc_state.tool = 1; gc_state.tool = 1;
}
user_tool_change(gc_state.tool); 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");
@@ -318,7 +264,6 @@ void user_defined_macro(uint8_t index)
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
@@ -330,15 +275,13 @@ void user_defined_macro(uint8_t index)
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

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
@@ -58,19 +57,19 @@
// 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

@@ -59,7 +59,6 @@
#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
@@ -67,7 +66,6 @@
#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

@@ -48,7 +48,6 @@
#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

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

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