MarlinUI support for up to 5 Material Presets (#18488)
- Add `I` preset parameter to `G26`, `M106`, `M140`, and `M190`. - Extend menu items to permit a string interpolation. - Keep material names in a list and interpolate in menu items. - Extend material presets to support up to 5 predefined materials. Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
		@@ -50,7 +50,12 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * M104: Set hot end temperature
 | 
			
		||||
 * M104: Set Hotend Temperature target and return immediately
 | 
			
		||||
 *
 | 
			
		||||
 * Parameters:
 | 
			
		||||
 *  I<preset> : Material Preset index (if material presets are defined)
 | 
			
		||||
 *  T<index>  : Tool index. If omitted, applies to the active tool
 | 
			
		||||
 *  S<target> : The target temperature in current units
 | 
			
		||||
 */
 | 
			
		||||
void GcodeSuite::M104() {
 | 
			
		||||
 | 
			
		||||
@@ -63,8 +68,25 @@ void GcodeSuite::M104() {
 | 
			
		||||
    if (target_extruder < 0) return;
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  if (parser.seenval('S')) {
 | 
			
		||||
    const int16_t temp = parser.value_celsius();
 | 
			
		||||
  bool got_temp = false;
 | 
			
		||||
  int16_t temp = 0;
 | 
			
		||||
 | 
			
		||||
  // Accept 'I' if temperature presets are defined
 | 
			
		||||
  #if PREHEAT_COUNT
 | 
			
		||||
    got_temp = parser.seenval('I');
 | 
			
		||||
    if (got_temp) {
 | 
			
		||||
      const uint8_t index = parser.value_byte();
 | 
			
		||||
      temp = ui.material_preset[_MIN(index, PREHEAT_COUNT - 1)].hotend_temp;
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  // If no 'I' get the temperature from 'S'
 | 
			
		||||
  if (!got_temp) {
 | 
			
		||||
    got_temp = parser.seenval('S');
 | 
			
		||||
    if (got_temp) temp = parser.value_celsius();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (got_temp) {
 | 
			
		||||
    #if ENABLED(SINGLENOZZLE_STANDBY_TEMP)
 | 
			
		||||
      singlenozzle_temp[target_extruder] = temp;
 | 
			
		||||
      if (target_extruder != active_extruder) return;
 | 
			
		||||
@@ -91,10 +113,25 @@ void GcodeSuite::M104() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * M109: Sxxx Wait for hotend(s) to reach temperature. Waits only when heating.
 | 
			
		||||
 *       Rxxx Wait for hotend(s) to reach temperature. Waits when heating and cooling.
 | 
			
		||||
 * M109: Set Hotend Temperature target and wait
 | 
			
		||||
 *
 | 
			
		||||
 * With PRINTJOB_TIMER_AUTOSTART also start the job timer on heating and stop it if turned off.
 | 
			
		||||
 * Parameters
 | 
			
		||||
 *  I<preset> : Material Preset index (if material presets are defined)
 | 
			
		||||
 *  T<index>  : Tool index. If omitted, applies to the active tool
 | 
			
		||||
 *  S<target> : The target temperature in current units. Wait for heating only.
 | 
			
		||||
 *  R<target> : The target temperature in current units. Wait for heating and cooling.
 | 
			
		||||
 *
 | 
			
		||||
 * With AUTOTEMP...
 | 
			
		||||
 *  F<factor> : Autotemp Scaling Factor. Set non-zero to enable Auto-temp.
 | 
			
		||||
 *  S<min>    : Minimum temperature, in current units.
 | 
			
		||||
 *  B<max>    : Maximum temperature, in current units.
 | 
			
		||||
 *
 | 
			
		||||
 * Examples
 | 
			
		||||
 *  M109 S100 : Set target to 100°. Wait until the hotend is at or above 100°.
 | 
			
		||||
 *  M109 R150 : Set target to 150°. Wait until the hotend gets close to 150°.
 | 
			
		||||
 *
 | 
			
		||||
 * With PRINTJOB_TIMER_AUTOSTART turning on heaters will start the print job timer
 | 
			
		||||
 *  (used by printingIsActive, etc.) and turning off heaters will stop the timer.
 | 
			
		||||
 */
 | 
			
		||||
void GcodeSuite::M109() {
 | 
			
		||||
 | 
			
		||||
@@ -107,10 +144,27 @@ void GcodeSuite::M109() {
 | 
			
		||||
    if (target_extruder < 0) return;
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  const bool no_wait_for_cooling = parser.seenval('S'),
 | 
			
		||||
             set_temp = no_wait_for_cooling || parser.seenval('R');
 | 
			
		||||
  if (set_temp) {
 | 
			
		||||
    const int16_t temp = parser.value_celsius();
 | 
			
		||||
  bool got_temp = false;
 | 
			
		||||
  int16_t temp = 0;
 | 
			
		||||
 | 
			
		||||
  // Accept 'I' if temperature presets are defined
 | 
			
		||||
  #if PREHEAT_COUNT
 | 
			
		||||
    got_temp = parser.seenval('I');
 | 
			
		||||
    if (got_temp) {
 | 
			
		||||
      const uint8_t index = parser.value_byte();
 | 
			
		||||
      temp = ui.material_preset[_MIN(index, PREHEAT_COUNT - 1)].hotend_temp;
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  // Get the temperature from 'S' or 'R'
 | 
			
		||||
  bool no_wait_for_cooling = false;
 | 
			
		||||
  if (!got_temp) {
 | 
			
		||||
    no_wait_for_cooling = parser.seenval('S');
 | 
			
		||||
    got_temp = no_wait_for_cooling || parser.seenval('R');
 | 
			
		||||
    if (got_temp) temp = int16_t(parser.value_celsius());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (got_temp) {
 | 
			
		||||
    #if ENABLED(SINGLENOZZLE_STANDBY_TEMP)
 | 
			
		||||
      singlenozzle_temp[target_extruder] = temp;
 | 
			
		||||
      if (target_extruder != active_extruder) return;
 | 
			
		||||
@@ -139,7 +193,7 @@ void GcodeSuite::M109() {
 | 
			
		||||
 | 
			
		||||
  TERN_(AUTOTEMP, planner.autotemp_M104_M109());
 | 
			
		||||
 | 
			
		||||
  if (set_temp)
 | 
			
		||||
  if (got_temp)
 | 
			
		||||
    (void)thermalManager.wait_for_hotend(target_extruder, no_wait_for_cooling);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,10 @@
 | 
			
		||||
#include "../../module/motion.h"
 | 
			
		||||
#include "../../module/temperature.h"
 | 
			
		||||
 | 
			
		||||
#if PREHEAT_COUNT
 | 
			
		||||
  #include "../../lcd/ultralcd.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ENABLED(SINGLENOZZLE)
 | 
			
		||||
  #define _ALT_P active_extruder
 | 
			
		||||
  #define _CNT_P EXTRUDERS
 | 
			
		||||
@@ -39,6 +43,7 @@
 | 
			
		||||
/**
 | 
			
		||||
 * M106: Set Fan Speed
 | 
			
		||||
 *
 | 
			
		||||
 *  I<index> Material Preset index (if material presets are defined)
 | 
			
		||||
 *  S<int>   Speed between 0-255
 | 
			
		||||
 *  P<index> Fan index, if more than one fan
 | 
			
		||||
 *
 | 
			
		||||
@@ -50,19 +55,32 @@
 | 
			
		||||
 *           3-255 = Set the speed for use with T2
 | 
			
		||||
 */
 | 
			
		||||
void GcodeSuite::M106() {
 | 
			
		||||
  const uint8_t p = parser.byteval('P', _ALT_P);
 | 
			
		||||
  const uint8_t pfan = parser.byteval('P', _ALT_P);
 | 
			
		||||
 | 
			
		||||
  if (p < _CNT_P) {
 | 
			
		||||
  if (pfan < _CNT_P) {
 | 
			
		||||
 | 
			
		||||
    #if ENABLED(EXTRA_FAN_SPEED)
 | 
			
		||||
      const uint16_t t = parser.intval('T');
 | 
			
		||||
      if (t > 0) return thermalManager.set_temp_fan_speed(p, t);
 | 
			
		||||
      if (t > 0) return thermalManager.set_temp_fan_speed(pfan, t);
 | 
			
		||||
    #endif
 | 
			
		||||
    uint16_t d = parser.seen('A') ? thermalManager.fan_speed[active_extruder] : 255;
 | 
			
		||||
    uint16_t s = parser.ushortval('S', d);
 | 
			
		||||
    NOMORE(s, 255U);
 | 
			
		||||
 | 
			
		||||
    thermalManager.set_fan_speed(p, s);
 | 
			
		||||
    const uint16_t dspeed = parser.seen('A') ? thermalManager.fan_speed[active_extruder] : 255;
 | 
			
		||||
 | 
			
		||||
    uint16_t speed = dspeed;
 | 
			
		||||
 | 
			
		||||
    // Accept 'I' if temperature presets are defined
 | 
			
		||||
    #if PREHEAT_COUNT
 | 
			
		||||
      const bool got_preset = parser.seenval('I');
 | 
			
		||||
      if (got_preset) speed = ui.material_preset[_MIN(parser.value_byte(), PREHEAT_COUNT - 1)].fan_speed;
 | 
			
		||||
    #else
 | 
			
		||||
      constexpr bool got_preset = false;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    if (!got_preset && parser.seenval('S'))
 | 
			
		||||
      speed = parser.value_ushort();
 | 
			
		||||
 | 
			
		||||
    // Set speed, with constraint
 | 
			
		||||
    thermalManager.set_fan_speed(pfan, speed);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -47,11 +47,33 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * M140: Set bed temperature
 | 
			
		||||
 *
 | 
			
		||||
 *  I<index>  : Preset index (if material presets are defined)
 | 
			
		||||
 *  S<target> : The target temperature in current units
 | 
			
		||||
 */
 | 
			
		||||
void GcodeSuite::M140() {
 | 
			
		||||
  if (DEBUGGING(DRYRUN)) return;
 | 
			
		||||
  if (parser.seenval('S')) {
 | 
			
		||||
    thermalManager.setTargetBed(parser.value_celsius());
 | 
			
		||||
 | 
			
		||||
  bool got_temp = false;
 | 
			
		||||
  int16_t temp = 0;
 | 
			
		||||
 | 
			
		||||
  // Accept 'I' if temperature presets are defined
 | 
			
		||||
  #if PREHEAT_COUNT
 | 
			
		||||
    got_temp = parser.seenval('I');
 | 
			
		||||
    if (got_temp) {
 | 
			
		||||
      const uint8_t index = parser.value_byte();
 | 
			
		||||
      temp = ui.material_preset[_MIN(index, PREHEAT_COUNT - 1)].bed_temp;
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  // If no 'I' get the temperature from 'S'
 | 
			
		||||
  if (!got_temp) {
 | 
			
		||||
    got_temp = parser.seenval('S');
 | 
			
		||||
    if (got_temp) temp = parser.value_celsius();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (got_temp) {
 | 
			
		||||
    thermalManager.setTargetBed(temp);
 | 
			
		||||
 | 
			
		||||
    #if ENABLED(PRINTJOB_TIMER_AUTOSTART)
 | 
			
		||||
      /**
 | 
			
		||||
@@ -65,20 +87,48 @@ void GcodeSuite::M140() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * M190: Sxxx Wait for bed current temp to reach target temp. Waits only when heating
 | 
			
		||||
 *       Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling
 | 
			
		||||
 * M190 - Set Bed Temperature target and wait
 | 
			
		||||
 *
 | 
			
		||||
 * With PRINTJOB_TIMER_AUTOSTART also start the job timer on heating.
 | 
			
		||||
 * Parameters:
 | 
			
		||||
 *  I<index>  : Preset index (if material presets are defined)
 | 
			
		||||
 *  S<target> : The target temperature in current units. Wait for heating only.
 | 
			
		||||
 *  R<target> : The target temperature in current units. Wait for heating and cooling.
 | 
			
		||||
 *
 | 
			
		||||
 * Examples:
 | 
			
		||||
 *  M190 S60 : Set target to 60°. Wait until the bed is at or above 60°.
 | 
			
		||||
 *  M190 R40 : Set target to 40°. Wait until the bed gets close to 40°.
 | 
			
		||||
 *
 | 
			
		||||
 * With PRINTJOB_TIMER_AUTOSTART turning on heaters will start the print job timer
 | 
			
		||||
 *  (used by printingIsActive, etc.) and turning off heaters will stop the timer.
 | 
			
		||||
 */
 | 
			
		||||
void GcodeSuite::M190() {
 | 
			
		||||
  if (DEBUGGING(DRYRUN)) return;
 | 
			
		||||
 | 
			
		||||
  const bool no_wait_for_cooling = parser.seenval('S');
 | 
			
		||||
  if (no_wait_for_cooling || parser.seenval('R')) {
 | 
			
		||||
    thermalManager.setTargetBed(parser.value_celsius());
 | 
			
		||||
    TERN_(PRINTJOB_TIMER_AUTOSTART, thermalManager.check_timer_autostart(true, false));
 | 
			
		||||
  bool got_temp = false;
 | 
			
		||||
  int16_t temp = 0;
 | 
			
		||||
 | 
			
		||||
  // Accept 'I' if temperature presets are defined
 | 
			
		||||
  #if PREHEAT_COUNT
 | 
			
		||||
    got_temp = parser.seenval('I');
 | 
			
		||||
    if (got_temp) {
 | 
			
		||||
      const uint8_t index = parser.value_byte();
 | 
			
		||||
      temp = ui.material_preset[_MIN(index, PREHEAT_COUNT - 1)].bed_temp;
 | 
			
		||||
    }
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  // Get the temperature from 'S' or 'R'
 | 
			
		||||
  bool no_wait_for_cooling = false;
 | 
			
		||||
  if (!got_temp) {
 | 
			
		||||
    no_wait_for_cooling = parser.seenval('S');
 | 
			
		||||
    got_temp = no_wait_for_cooling || parser.seenval('R');
 | 
			
		||||
    if (got_temp) temp = int16_t(parser.value_celsius());
 | 
			
		||||
  }
 | 
			
		||||
  else return;
 | 
			
		||||
 | 
			
		||||
  if (!got_temp) return;
 | 
			
		||||
 | 
			
		||||
  thermalManager.setTargetBed(temp);
 | 
			
		||||
 | 
			
		||||
  TERN_(PRINTJOB_TIMER_AUTOSTART, thermalManager.check_timer_autostart(true, false));
 | 
			
		||||
 | 
			
		||||
  ui.set_status_P(thermalManager.isHeatingBed() ? GET_TEXT(MSG_BED_HEATING) : GET_TEXT(MSG_BED_COOLING));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user