diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index f1f6594228..4f26a77cf6 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -4436,6 +4436,20 @@ #define FREEZE_STATE LOW // State of pin indicating freeze #endif +/** + * Adds realtime speed control using an external potentiometer and a free thermistor port + */ +//#define SPEED_DIAL_FEATURE +#if ENABLED(SPEED_DIAL_FEATURE) + #define SPEED_DIAL_PIN TEMP_BED_PIN + #define SPEED_DIAL_MIN_SPEED 10 + #define SPEED_DIAL_MAX_SPEED 100 + #define SPEED_DIAL_BOARD_RESISTOR 4700 + #define SPEED_DIAL_POT_RESISTOR 50000 + #define SPEED_DIAL_INVERT true + #define SPEED_DIAL_DIAL_SENSITIVITY -2 +#endif + /** * MAX7219 Debug Matrix * diff --git a/Marlin/src/feature/speed_dial.cpp b/Marlin/src/feature/speed_dial.cpp new file mode 100644 index 0000000000..7a2ca7a577 --- /dev/null +++ b/Marlin/src/feature/speed_dial.cpp @@ -0,0 +1,100 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program 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 + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * speed_dial.cpp - speed dial feature + */ + +#include "../MarlinCore.h" +#include "../HAL/shared/Delay.h" +#include "../lcd/marlinui.h" +#include "../gcode/gcode.h" +#include "../module/stepper.h" +#include "speed_dial.h" + +#if ENABLED(SPEED_DIAL_FEATURE) + +raw_adc_t SpeedDial::current_speed_dial_raw = HAL_ADC_RANGE; +uint8_t SpeedDial::current_speed_dial = 100; +uint8_t SpeedDial::next_value_change = SPEED_DIAL_DIAL_SENSITIVITY; + +SpeedDial speedDial; + +void SpeedDial::set(raw_adc_t value) { + current_speed_dial_raw = value; + + #define SPEED_DIAL_MULTIPLIER (SQRT(0x7FFFFFFF / SPEED_DIAL_BOARD_RESISTOR) / 100) + #define SPEED_DIAL_MULTIPLIER_FINAL (SPEED_DIAL_MULTIPLIER * 100) + #define SPEED_DIAL_SMOOTH_VALUE_TOTAL (SPEED_DIAL_SMOOTH_VALUE + 1) + + //get adc percentage + int32_t speed_dial_adc_percent = current_speed_dial_raw * SPEED_DIAL_MULTIPLIER_FINAL / HAL_ADC_RANGE; + if(speed_dial_adc_percent > SPEED_DIAL_MULTIPLIER_FINAL) speed_dial_adc_percent = SPEED_DIAL_MULTIPLIER_FINAL; + if(speed_dial_adc_percent < 0) speed_dial_adc_percent = 0; + + #if SPEED_DIAL_INVERT + speed_dial_adc_percent = SPEED_DIAL_MULTIPLIER_FINAL - speed_dial_adc_percent; + #endif + + //dial position percentage + int32_t speed_dial_percent = (speed_dial_adc_percent > 0 ? + ((SPEED_DIAL_BOARD_RESISTOR * SPEED_DIAL_MULTIPLIER_FINAL / speed_dial_adc_percent) - SPEED_DIAL_BOARD_RESISTOR) * SPEED_DIAL_MULTIPLIER_FINAL / SPEED_DIAL_POT_RESISTOR : + SPEED_DIAL_MULTIPLIER_FINAL); + if(speed_dial_percent > SPEED_DIAL_MULTIPLIER_FINAL) speed_dial_percent = SPEED_DIAL_MULTIPLIER_FINAL; + if(speed_dial_percent < 0) speed_dial_percent = 0; + + #if SPEED_DIAL_INVERT + speed_dial_percent = SPEED_DIAL_MULTIPLIER_FINAL - speed_dial_percent; + #endif + + //get actual speed value + int32_t speed_dial_value = (speed_dial_percent + (SPEED_DIAL_MULTIPLIER / 2)) * (SPEED_DIAL_MAX_SPEED - SPEED_DIAL_MIN_SPEED) / SPEED_DIAL_MULTIPLIER_FINAL + SPEED_DIAL_MIN_SPEED; + + //clamp speed value + if(speed_dial_value > SPEED_DIAL_MAX_SPEED) speed_dial_value = SPEED_DIAL_MAX_SPEED; + if(speed_dial_value < SPEED_DIAL_MIN_SPEED) speed_dial_value = SPEED_DIAL_MIN_SPEED; + + //store derived value + current_speed_dial = speed_dial_value; + + //update stepper speed as per dial sensitivity + if(SPEED_DIAL_DIAL_SENSITIVITY > 0) { + for(uint8_t i=0; i < SPEED_DIAL_DIAL_SENSITIVITY; i++) { + updateStepper(); + } + } else { + if(next_value_change) { + next_value_change--; + } else { + updateStepper(); + + next_value_change = SPEED_DIAL_DIAL_SENSITIVITY; + } + } +} + +void SpeedDial::updateStepper() { + if(current_speed_dial > stepper.current_speed_dial()) stepper.set_speed_dial(stepper.current_speed_dial() + 1); + if(current_speed_dial < stepper.current_speed_dial()) stepper.set_speed_dial(stepper.current_speed_dial() - 1); +} + +#endif diff --git a/Marlin/src/feature/speed_dial.h b/Marlin/src/feature/speed_dial.h new file mode 100644 index 0000000000..c55f456e6f --- /dev/null +++ b/Marlin/src/feature/speed_dial.h @@ -0,0 +1,48 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program 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 + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * speed_dial.h - speed dial feature + */ + +#include "../inc/MarlinConfig.h" + +#if ENABLED(SPEED_DIAL_FEATURE) + +class SpeedDial { + public: + static inline uint8_t current() { return current_speed_dial; } + static inline raw_adc_t raw() { return current_speed_dial_raw; } + static void set(raw_adc_t value); + + private: + static void updateStepper(); + + static raw_adc_t current_speed_dial_raw; + static uint8_t current_speed_dial; + static uint8_t next_value_change; +}; + +extern SpeedDial speedDial; + +#endif diff --git a/Marlin/src/gcode/temp/M105.cpp b/Marlin/src/gcode/temp/M105.cpp index 4de5ba8eef..863ade57b6 100644 --- a/Marlin/src/gcode/temp/M105.cpp +++ b/Marlin/src/gcode/temp/M105.cpp @@ -23,6 +23,10 @@ #include "../gcode.h" #include "../../module/temperature.h" +#if ENABLED(SPEED_DIAL_FEATURE) + #include "../../feature/speed_dial.h" +#endif + /** * M105: Read hot end and bed temperature */ @@ -41,7 +45,12 @@ void GcodeSuite::M105() { #else + #if ENABLED(SPEED_DIAL_FEATURE) + SERIAL_ECHOPGM(" T:", speedDial.current()); + SERIAL_ECHOLNPGM(" S@:", speedDial.raw()); + #else SERIAL_ECHOLNPGM(" T:0"); // Some hosts send M105 to test the serial connection + #endif #endif } diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index 2a10c83800..e86816e20a 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -203,6 +203,10 @@ uint32_t Stepper::acceleration_time, Stepper::deceleration_time; bool Stepper::frozen; // = false #endif +#if ENABLED(SPEED_DIAL_FEATURE) + uint8_t Stepper::speed_dial_value = 100; +#endif + // Delta error variables for the Bresenham line tracer xyze_long_t Stepper::delta_error{0}; xyze_long_t Stepper::advance_dividend{0}; @@ -2465,6 +2469,10 @@ void Stepper::isr() { acceleration_time += interval; deceleration_time = 0; // Reset since we're doing acceleration first. + #if ENABLED(SPEED_DIAL_FEATURE) + speed_dial_adjust_interval(interval); + #endif + // Apply Nonlinear Extrusion, if enabled calc_nonlinear_e(acc_step_rate << oversampling_factor); diff --git a/ini/features.ini b/ini/features.ini index 03a9bdbba8..89320e70ca 100644 --- a/ini/features.ini +++ b/ini/features.ini @@ -383,6 +383,7 @@ IS_SCARA = build_src_filter=+ + MORGAN_SCARA = build_src_filter=+ HAS_MICROSTEPS = build_src_filter=+ +SPEED_DIAL_FEATURE = build_src_filter=+ (ESP3D_)?WIFISUPPORT = esp32async/AsyncTCP@3.3.3, mathieucarbou/ESP Async WebServer@3.0.6 ESP3DLib=https://github.com/luc-github/ESP3DLib/archive/6d62f76c3f.zip arduinoWebSockets=links2004/WebSockets@2.3.4