From 7a4cbdb8f5b25d995fadabdd5605ff400bd0231d Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Sat, 11 Jan 2020 12:30:54 -0600 Subject: [PATCH] Cleanup and further work on lasers --- g2core/board/gquintic/0_hardware.cpp | 7 +- g2core/board/gquintic/board_stepper.cpp | 6 + g2core/board/gquintic/board_stepper.h | 3 + g2core/board/gquintic/hardware.h | 12 +- .../device/laser_toolhead/laser_toolhead.cpp | 185 ++++++++++++++++++ g2core/device/laser_toolhead/laser_toolhead.h | 150 ++------------ g2core/spindle.h | 3 + 7 files changed, 230 insertions(+), 136 deletions(-) create mode 100644 g2core/device/laser_toolhead/laser_toolhead.cpp diff --git a/g2core/board/gquintic/0_hardware.cpp b/g2core/board/gquintic/0_hardware.cpp index dd237873..04e91a0f 100644 --- a/g2core/board/gquintic/0_hardware.cpp +++ b/g2core/board/gquintic/0_hardware.cpp @@ -88,7 +88,7 @@ SafetyManager *safety_manager = &sm; #include "esc_spindle.h" ESCSpindle esc_spindle {SPINDLE_PWM_NUMBER, SPINDLE_ENABLE_OUTPUT_NUMBER, SPINDLE_DIRECTION_OUTPUT_NUMBER, SPINDLE_SPEED_CHANGE_PER_MS}; - +#if HAS_LASER #ifndef LASER_ENABLE_OUTPUT_NUMBER #warning LASER_ENABLE_OUTPUT_NUMBER is defaulted to 7! #warning LASER_ENABLE_OUTPUT_NUMBER should be defined in settings or a board file! @@ -103,13 +103,18 @@ ESCSpindle esc_spindle {SPINDLE_PWM_NUMBER, SPINDLE_ENABLE_OUTPUT_NUMBER, SPINDL #include "laser_toolhead.h" LaserTool laser_tool {LASER_PWM_NUMBER, LASER_PWM_NUMBER}; +#endif ToolHead *toolhead_for_tool(uint8_t tool) { +#if !HAS_LASER + return &esc_spindle; +#else if (tool != 7) { return &esc_spindle; } else { return &laser_tool; } +#endif } /* diff --git a/g2core/board/gquintic/board_stepper.cpp b/g2core/board/gquintic/board_stepper.cpp index 57e99858..8b623108 100644 --- a/g2core/board/gquintic/board_stepper.cpp +++ b/g2core/board/gquintic/board_stepper.cpp @@ -90,11 +90,17 @@ HOT_DATA Trinamic2130 motor_6; Stepper* const Motors[MOTORS] = {&motor_1, &motor_2, &motor_3, &motor_4, &motor_5, &motor_6}; +#elif HAS_LASER +// laser_tool is defined over in hardware.cpp +extern LaserTool laser_tool; +LaserTool &motor_6 = laser_tool; +Stepper* const Motors[MOTORS] = {&motor_1, &motor_2, &motor_3, &motor_4, &motor_5, &laser_tool}; #else Stepper* const Motors[MOTORS] = {&motor_1, &motor_2, &motor_3, &motor_4, &motor_5}; #endif #endif // 'D' + #if (KINEMATICS == KINE_FOUR_CABLE) HOT_DATA encoder_0_t encoder_0{plex0, M1_ENCODER_INPUT_A, M1_ENCODER_INPUT_B, 1 << 0}; HOT_DATA encoder_1_t encoder_1{plex0, M2_ENCODER_INPUT_A, M2_ENCODER_INPUT_B, 1 << 1}; diff --git a/g2core/board/gquintic/board_stepper.h b/g2core/board/gquintic/board_stepper.h index e7c6974f..838bd69f 100644 --- a/g2core/board/gquintic/board_stepper.h +++ b/g2core/board/gquintic/board_stepper.h @@ -92,6 +92,9 @@ extern Trinamic2130 motor_6; +#elif HAS_LASER +#include "laser_toolhead.h" +extern LaserTool &motor_6; #endif #endif // 'D' diff --git a/g2core/board/gquintic/hardware.h b/g2core/board/gquintic/hardware.h index 42602d0c..1d975028 100644 --- a/g2core/board/gquintic/hardware.h +++ b/g2core/board/gquintic/hardware.h @@ -58,10 +58,18 @@ #define HAS_HOBBY_SERVO_MOTOR 0 #endif -#if QUINTIC_REVISION == 'C' or !HAS_HOBBY_SERVO_MOTOR +#ifndef HAS_LASER +#if HAS_HOBBY_SERVO_MOTOR +#error Can NOT have a laser and a hobby servo at the same time, sorry +#endif +#define HAS_LASER 0 +#endif + + +#if QUINTIC_REVISION == 'C' or (!HAS_HOBBY_SERVO_MOTOR && !HAS_LASER) #define MOTORS 5 // number of motors on the board - 5Trinamics OR 4 Trinamics + 1 servo #else -#define MOTORS 6 // number of motors on the board - 5 Trinamics + 1 servo +#define MOTORS 6 // number of motors on the board - 5 Trinamics + 1 servo or laser #endif #define PWMS 2 // number of PWM channels supported the hardware #define AXES 6 // axes to support -- must be 6 or 9 diff --git a/g2core/device/laser_toolhead/laser_toolhead.cpp b/g2core/device/laser_toolhead/laser_toolhead.cpp new file mode 100644 index 00000000..419baa63 --- /dev/null +++ b/g2core/device/laser_toolhead/laser_toolhead.cpp @@ -0,0 +1,185 @@ +/* + * laser_toolhead.cpp - toolhead driver for a laser, controlled by spindle commands + * This file is part of the g2core project + * + * Copyright (c) 2020 Robert Giseburt + * Copyright (c) 2020 Alden S. Hart, Jr. + * + * This file ("the software") is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 as published by the + * Free Software Foundation. You should have received a copy of the GNU General Public + * License, version 2 along with the software. If not, see . + * + * As a special exception, you may use this file as part of a software library without + * restriction. Specifically, if other files instantiate templates or use macros or + * inline functions from this file, or you compile this file and link it with other + * files to produce an executable, this file does not by itself cause the resulting + * executable to be covered by the GNU General Public License. This exception does not + * however invalidate any other reasons why the executable file might be covered by the + * GNU General Public License. + * + * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY + * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include "laser_toolhead.h" + +LaserTool::LaserTool(const uint8_t pwm_pin_number, const uint8_t enable_pin_number) + : pwm_output_num{pwm_pin_number}, + enable_output_num{enable_pin_number} {} + +void LaserTool::init() +{ + // TODO - ensure outputs are within range + set_pwm_output(pwm_output_num); + set_enable_output(enable_output_num); +} + +void LaserTool::pause() { + if (paused) { + return; + } + + paused = true; + this->complete_change(); +} + +void LaserTool::resume() { + if (!paused) { + return; + } + + paused = false; + this->complete_change(); +} + +bool LaserTool::ready_to_resume() { return paused && safety_manager->ok_to_spindle(); } +// bool LaserTool::busy() { +// // return true when not paused, on, and ramping up to speed +// if (paused || (direction == SPINDLE_OFF)) { +// return false; +// } +// return true; +// } + +float LaserTool::get_speed() { return speed; } + +spDirection LaserTool::get_direction() { return direction; } + +void LaserTool::stop() { + paused = false; + speed = 0; + direction = SPINDLE_OFF; + + this->complete_change(); +} + +// called from a command that was queued when the default set_speed and set_direction returned true +// ALSO called from the loader right before a move +// we are handed the gcode model to use +void LaserTool::engage(const GCodeState_t &gm) { + if ((direction == gm.spindle_direction) && fp_EQ(speed, gm.spindle_speed)) { + // nothing changed + return; + } + + // // special handling for reversals - we set the speed to zero and ramp up + // if ((gm.spindle_direction != direction) && (direction != SPINDLE_OFF) && (gm.spindle_direction != SPINDLE_OFF)) { + // speed_actual = 0; + // } + + speed = gm.spindle_speed; + direction = gm.spindle_direction; + + // handle the rest + this->complete_change(); +} + +bool LaserTool::is_on() { return (direction != SPINDLE_OFF); } + +// LaserTool-specific functions +void LaserTool::set_pwm_output(const uint8_t pwm_pin_number) { + if (pwm_pin_number == 0) { + pwm_output = nullptr; + } else { + pwm_output = d_out[pwm_pin_number - 1]; + pwm_output->setEnabled(IO_ENABLED); + // set the frequency on the output -- not here + // set the polarity on the output -- not here + } +} +void LaserTool::set_enable_output(const uint8_t enable_pin_number) { + if (enable_pin_number == 0) { + enable_output = nullptr; + } else { + enable_output = d_out[enable_pin_number - 1]; + enable_output->setEnabled(IO_ENABLED); + // set the polarity on the output -- not here + } +} + +void LaserTool::set_frequency(float new_frequency) +{ + if (pwm_output) { + pwm_output->setFrequency(new_frequency); + } +} +float LaserTool::get_frequency() +{ + if (pwm_output) { + return pwm_output->getFrequency(); + } + return 0.0; +} + +// Stepper functons + +void LaserTool::_enableImpl() { + enabled = true; +}; + +void LaserTool::_disableImpl() { + enabled = false; +}; + +void LaserTool::stepStart() { + if (!enabled) return; + +}; + +void LaserTool::stepEnd() { +}; + +void LaserTool::setDirection(uint8_t new_direction) { +}; + +void LaserTool::setPowerLevels(float active_pl, float idle_pl) { + ; // ignore this +}; + + +// Private functions + +void LaserTool::complete_change() { + // if the spindle is not on (or paused), make sure we stop it + if (paused || direction == SPINDLE_OFF) { + if (enable_output != nullptr) { + enable_output->setValue(false); + } + + return; + } else if (direction == SPINDLE_CW) { + if (enable_output != nullptr) { + enable_output->setValue(true); + } + } else if (direction == SPINDLE_CCW) { + if (enable_output != nullptr) { + enable_output->setValue(true); + } + } +} diff --git a/g2core/device/laser_toolhead/laser_toolhead.h b/g2core/device/laser_toolhead/laser_toolhead.h index 7987827d..bf375d7f 100644 --- a/g2core/device/laser_toolhead/laser_toolhead.h +++ b/g2core/device/laser_toolhead/laser_toolhead.h @@ -29,8 +29,10 @@ #ifndef LASER_TOOLHEAD_H_ONCE #define LASER_TOOLHEAD_H_ONCE +class LaserTool; // Need to forward declare since stepper.h may (eventually) include this file + #include "spindle.h" -#include "stepper.h" // for st_request_load_move +#include "stepper.h" // for Stepper and st_request_load_move #include "util.h" // for fp_NE #include "safety_manager.h" // for safety_manager @@ -46,7 +48,7 @@ // class declaration // note implementation is after -class LaserTool : public ToolHead { +class LaserTool : public ToolHead, virtual public Stepper { spDirection direction; // direction float speed; // S in RPM // float speed_actual; // actual speed (during speed ramping) @@ -62,9 +64,13 @@ class LaserTool : public ToolHead { uint8_t enable_output_num; gpioDigitalOutput *enable_output = nullptr; + // For "Stepper" enabled control + bool enabled = false; + void complete_change(); public: +// ToolHead functions ---- // constructor - provide it with the default output pins - 0 means no pin LaserTool(const uint8_t pwm_pin_number, const uint8_t enable_pin_number); @@ -129,137 +135,15 @@ class LaserTool : public ToolHead { // void set_phase_off(float new_phase_off) override { phase_off = new_phase_off; } // float get_phase_off() override { return phase_off; } + +// Stepper functions ---- + + void _enableImpl() override; + void _disableImpl() override; + void stepStart() override; + void stepEnd() override; + void setDirection(uint8_t new_direction) override; + void setPowerLevels(float active_pl, float idle_pl) override; }; -// method implementations follow - -LaserTool::LaserTool(const uint8_t pwm_pin_number, const uint8_t enable_pin_number) - : pwm_output_num{pwm_pin_number}, - enable_output_num{enable_pin_number} {} - -void LaserTool::init() -{ - // TODO - ensure outputs are within range - set_pwm_output(pwm_output_num); - set_enable_output(enable_output_num); -} - -void LaserTool::pause() { - if (paused) { - return; - } - - paused = true; - this->complete_change(); -} - -void LaserTool::resume() { - if (!paused) { - return; - } - - paused = false; - this->complete_change(); -} - -bool LaserTool::ready_to_resume() { return paused && safety_manager->ok_to_spindle(); } -// bool LaserTool::busy() { -// // return true when not paused, on, and ramping up to speed -// if (paused || (direction == SPINDLE_OFF)) { -// return false; -// } -// return true; -// } - -float LaserTool::get_speed() { return speed; } - -spDirection LaserTool::get_direction() { return direction; } - -void LaserTool::stop() { - paused = false; - speed = 0; - direction = SPINDLE_OFF; - - this->complete_change(); -} - -// called from a command that was queued when the default set_speed and set_direction returned true -// ALSO called from the loader right before a move -// we are handed the gcode model to use -void LaserTool::engage(const GCodeState_t &gm) { - if ((direction == gm.spindle_direction) && fp_EQ(speed, gm.spindle_speed)) { - // nothing changed - return; - } - - // // special handling for reversals - we set the speed to zero and ramp up - // if ((gm.spindle_direction != direction) && (direction != SPINDLE_OFF) && (gm.spindle_direction != SPINDLE_OFF)) { - // speed_actual = 0; - // } - - speed = gm.spindle_speed; - direction = gm.spindle_direction; - - // handle the rest - this->complete_change(); -} - -bool LaserTool::is_on() { return (direction != SPINDLE_OFF); } - -// LaserTool-specific functions -void LaserTool::set_pwm_output(const uint8_t pwm_pin_number) { - if (pwm_pin_number == 0) { - pwm_output = nullptr; - } else { - pwm_output = d_out[pwm_pin_number - 1]; - pwm_output->setEnabled(IO_ENABLED); - // set the frequency on the output -- not here - // set the polarity on the output -- not here - } -} -void LaserTool::set_enable_output(const uint8_t enable_pin_number) { - if (enable_pin_number == 0) { - enable_output = nullptr; - } else { - enable_output = d_out[enable_pin_number - 1]; - enable_output->setEnabled(IO_ENABLED); - // set the polarity on the output -- not here - } -} - -void LaserTool::set_frequency(float new_frequency) -{ - if (pwm_output) { - pwm_output->setFrequency(new_frequency); - } -} -float LaserTool::get_frequency() -{ - if (pwm_output) { - return pwm_output->getFrequency(); - } - return 0.0; -} - -// Private functions - -void LaserTool::complete_change() { - // if the spindle is not on (or paused), make sure we stop it - if (paused || direction == SPINDLE_OFF) { - if (enable_output != nullptr) { - enable_output->setValue(false); - } - - return; - } else if (direction == SPINDLE_CW) { - if (enable_output != nullptr) { - enable_output->setValue(true); - } - } else if (direction == SPINDLE_CCW) { - if (enable_output != nullptr) { - enable_output->setValue(true); - } - } -} - #endif // End of include guard: LASER_TOOLHEAD_H_ONCE diff --git a/g2core/spindle.h b/g2core/spindle.h index 15be7f19..b468a683 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -28,6 +28,9 @@ #ifndef SPINDLE_H_ONCE #define SPINDLE_H_ONCE +#include "error.h" // for stat_t +#include "config.h" // for configSubtable + enum spDirection { // how spindle controls are presented by the Gcode parser SPINDLE_OFF = 0, // M5 SPINDLE_CW = 1, // M3 and store CW to spindle.direction