Commit 832050e2 authored by nextime's avatar nextime

Merge remote-tracking branch 'upstream/dev' into dev

parents 637aa022 6c633f0e
......@@ -105,7 +105,7 @@
* M300 - Play beep sound S[frequency Hz] P[duration ms]
* M301 - Set PID parameters P I and D
* M302 - Allow cold extrudes
* M303 - PID relay autotune S<temperature> sets the target temperature (default target temperature = 150C). H<hotend> C<cycles>
* M303 - PID relay autotune S<temperature> sets the target temperature (default target temperature = 150C). H<hotend> C<cycles> U<Apply result>
* M304 - Set bed PID parameters P I and D or Water Cooling if L parameter
* M350 - Set microstepping mode.
* M351 - Toggle MS1 MS2 pins directly.
......
......@@ -52,9 +52,14 @@
//#define FIRMWARE_TEST
// Some particular clients re-start sending commands only after receiving a 'wait' when there is a bad serial-connection.
//#define NO_TIMEOUTS
//#define NO_TIMEOUTS 1000 // Milliseconds
// Uncomment to include more info in ok command
//#define ADVANCED_OK
// By default MarlinKimbra will send a busy status message to the host
// every couple of seconds when it can't accept commands.
// Enable this option if your host doesn't like keepalive messages.
//#define DISABLE_HOST_KEEPALIVE
/***********************************************************************/
......@@ -192,11 +197,16 @@
/***********************************************************************
************************* Temperature limits ***************************
***********************************************************************/
// Actual temperature must be close to target for this long before M109 returns success
// Hotend temperature must be close to target for this long before M109 returns success
#define TEMP_RESIDENCY_TIME 10 // (seconds)
#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one
#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early.
// Bed temperature must be close to target for this long before M190 returns success
#define TEMP_BED_RESIDENCY_TIME 0 // (seconds)
#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one
#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early.
// When temperature exceeds max temp, your heater will be switched off.
// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure!
// You should use MINTEMP for thermistor short/failure protection.
......
......@@ -57,7 +57,7 @@
//
// C, Y-axis
// |
// DELTA_ALPHA_CA=120° | DELTA_ALPHA_CB=12
// DELTA_ALPHA_CA=120° | DELTA_ALPHA_CB=120°
// |
// |______ X-axis
// / \
......@@ -423,4 +423,4 @@
#define HOTEND_OFFSET_Z {0.0, 0.0, 0.0, 0.0} // (in mm) for each hotend, offset of the hotend on the Z axis
/*****************************************************************************************/
#endif
\ No newline at end of file
#endif
......@@ -169,9 +169,10 @@
// Comment the following line to disable PID and enable bang-bang.
#define PIDTEMP
//#define PID_DEBUG // Sends debug data to the serial port.
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
//#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result.
//#define PID_DEBUG // Sends debug data to the serial port.
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
// If the temperature difference between the target temperature and the actual temperature
// is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
#define PID_FUNCTIONAL_RANGE 10 // degC
......@@ -1092,7 +1093,7 @@
//#define INVERT_CLICK_BUTTON // Option for invert encoder button logic
//#define INVERT_BACK_BUTTON // Option for invert back button logic if avaible
//#define INVERT_ROTARY_SWITCH // Option for invert rotary encoder
//#define INVERT_ROTARY_SWITCH // Option for reverses the encoder direction for navigating LCD menus.
#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly
#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiply steps moved x10 to quickly advance the value
#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiply steps moved x100 to really quickly advance the value
......
......@@ -45,7 +45,7 @@
* M666 XYZ endstop_adj (x3)
* M666 R delta_radius
* M666 D delta_diagonal_rod
* M666 H Z max_pos
* M666 H Z sw_endstop_max
* M666 ABCIJK tower_adj (x6)
* M666 UVW diagrod_adj (x3)
* M666 P XYZ XYZ probe_offset (x3)
......@@ -167,7 +167,7 @@ void Config_StoreSettings() {
EEPROM_WRITE_VAR(i, endstop_adj);
EEPROM_WRITE_VAR(i, delta_radius);
EEPROM_WRITE_VAR(i, delta_diagonal_rod);
EEPROM_WRITE_VAR(i, max_pos);
EEPROM_WRITE_VAR(i, sw_endstop_max);
EEPROM_WRITE_VAR(i, tower_adj);
EEPROM_WRITE_VAR(i, diagrod_adj);
EEPROM_WRITE_VAR(i, z_probe_offset);
......@@ -322,7 +322,7 @@ void Config_RetrieveSettings() {
EEPROM_READ_VAR(i, endstop_adj);
EEPROM_READ_VAR(i, delta_radius);
EEPROM_READ_VAR(i, delta_diagonal_rod);
EEPROM_READ_VAR(i, max_pos);
EEPROM_READ_VAR(i, sw_endstop_max);
EEPROM_READ_VAR(i, tower_adj);
EEPROM_READ_VAR(i, diagrod_adj);
EEPROM_READ_VAR(i, z_probe_offset);
......@@ -556,7 +556,6 @@ void Config_ResetDefault() {
diagrod_adj[0] = TOWER_A_DIAGROD_ADJ;
diagrod_adj[1] = TOWER_B_DIAGROD_ADJ;
diagrod_adj[2] = TOWER_C_DIAGROD_ADJ;
max_pos[2] = MANUAL_Z_HOME_POS;
z_probe_offset[0] = X_PROBE_OFFSET_FROM_EXTRUDER;
z_probe_offset[1] = Y_PROBE_OFFSET_FROM_EXTRUDER;
z_probe_offset[2] = Z_PROBE_OFFSET_FROM_EXTRUDER;
......@@ -762,7 +761,7 @@ void Config_ResetDefault() {
ECHO_MV(" W", diagrod_adj[2], 3);
ECHO_MV(" R", delta_radius);
ECHO_MV(" D", delta_diagonal_rod);
ECHO_EMV(" H", max_pos[2]);
ECHO_EMV(" H", sw_endstop_max[2]);
if (!forReplay) {
ECHO_LM(CFG, "Endstop Offsets:");
......
/**
* MK Firmware
* MK 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
......@@ -148,8 +148,8 @@
* M300 - Play beep sound S<frequency Hz> P<duration ms>
* M301 - Set PID parameters P I D and C
* M302 - Allow cold extrudes, or set the minimum extrude S<temperature>.
* M303 - PID relay autotune S<temperature> sets the target temperature (default target temperature = 150C). H<hotend> C<cycles>
* M304 - Set bed PID parameters P I and D or Water cooling if L parameter
* M303 - PID relay autotune S<temperature> sets the target temperature (default target temperature = 150C). H<hotend> C<cycles> U<Apply result>
* M304 - Set bed PID parameters P I and D or Water cooling if L parameter
* M350 - Set microstepping mode.
* M351 - Toggle MS1 MS2 pins directly.
* M380 - Activate solenoid on active extruder
......
......@@ -54,6 +54,7 @@
#include "Configuration_Store.h"
#include "module/language/language.h"
#include "module/stopwatch/stopwatch.h"
#include "module/MK_Main.h"
#include "module/motion/planner.h"
#include "module/motion/stepper_indirection.h"
......
/*
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 <http://www.gnu.org/licenses/>.
*/
// **************************************************************************
//
// Description: *** HAL for Arduino ***
//
// **************************************************************************
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* This is the main Hardware Abstraction Layer (HAL).
* To make the firmware work with different processors and toolchains,
* all hardware related code should be packed into the hal files.
*
* 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 <http://www.gnu.org/licenses/>.
*
*
* Description: *** HAL for Arduino ***
*
* Contributors:
* Copyright (c) 2014 Bob Cousins bobcousins42@googlemail.com
* Nico Tonnhofer wurstnase.reprap@gmail.com
*
* Copyright (c) 2015 - 2016 Alberto Cotronei @MagoKimbra
*
* ARDUINO_ARCH_ARM
*/
// --------------------------------------------------------------------------
// Includes
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* This is the main Hardware Abstraction Layer (HAL).
* To make the firmware work with different processors and toolchains,
......@@ -19,6 +41,12 @@
*
* Description: *** HAL for Arduino ***
*
* Contributors:
* Copyright (c) 2014 Bob Cousins bobcousins42@googlemail.com
* Nico Tonnhofer wurstnase.reprap@gmail.com
*
* Copyright (c) 2015 - 2016 Alberto Cotronei @MagoKimbra
*
* ARDUINO_ARCH_ARM
*/
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/*
This code contributed by Triffid_Hunter and modified by Kliment
why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
......
This source diff could not be displayed because it is too large. You can view the blob instead.
// Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware.
// License: GPL
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef MK_H
#define MK_H
......@@ -9,16 +28,17 @@
void get_command();
void idle(bool ignore_stepper_queue = false);
void idle(
#if ENABLED(FILAMENTCHANGEENABLE)
bool no_stepper_sleep=false // pass true to keep steppers from disabling on timeout
#endif
);
void manage_inactivity(bool ignore_stepper_queue = false);
void FlushSerialRequestResend();
void ok_to_send();
bool setTargetedExtruder(int code);
bool setTargetedHotend(int code);
#if MECH(DELTA)
float probe_bed(float x, float y);
void set_delta_constants();
......@@ -28,7 +48,6 @@ bool setTargetedHotend(int code);
void calibration_report();
void bed_probe_all();
void set_delta_constants();
void save_carriage_positions(int position_num);
void calculate_delta(float cartesian[3]);
void adjust_delta(float cartesian[3]);
void adj_endstops();
......@@ -51,7 +70,13 @@ bool setTargetedHotend(int code);
void calculate_delta(float cartesian[3]);
void calculate_SCARA_forward_Transform(float f_scara[3]);
#endif
void prepare_move();
void prepare_move(
#if MECH(DELTA)
const bool delta_probe = false
#endif
);
void kill(const char *);
void Stop();
......@@ -63,25 +88,26 @@ void Stop();
* Debug flags - with repetier
*/
enum DebugFlags {
DEBUG_ECHO = _BV(0),
DEBUG_INFO = _BV(1),
DEBUG_ERRORS = _BV(2),
DEBUG_DRYRUN = _BV(3),
DEBUG_COMMUNICATION = _BV(4),
DEBUG_DEBUG = _BV(5)
DEBUG_NONE = 0,
DEBUG_ECHO = _BV(0), ///< Echo commands in order as they are processed
DEBUG_INFO = _BV(1), ///< Print messages for code that has debug output
DEBUG_ERRORS = _BV(2), ///< Not implemented
DEBUG_DRYRUN = _BV(3), ///< Ignore temperature setting
DEBUG_COMMUNICATION = _BV(4), ///< Not implemented
DEBUG_DEBUG = _BV(5) ///< Print Debug
};
extern uint8_t mk_debug_flags;
void clamp_to_software_endstops(float target[3]);
extern uint8_t debugLevel;
extern bool Running;
inline bool IsRunning() { return Running; }
inline bool IsStopped() { return !Running; }
extern bool Printing;
bool enqueuecommand(const char *cmd); //put a single ASCII command at the end of the current buffer or return false when it is full
void enqueuecommands_P(const char *cmd); //put one or many ASCII commands at the end of the current buffer, read from flash
bool enqueue_and_echo_command(const char* cmd, bool say_ok = false); // put a single ASCII command at the end of the current buffer or return false when it is full
void enqueue_and_echo_command_now(const char* cmd); // enqueue now, only return when the command has been enqueued
void enqueue_and_echo_commands_P(const char* cmd); // put one or many ASCII commands at the end of the current buffer, read from flash
void prepare_arc_move(char isclockwise);
void clamp_to_software_endstops(float target[3]);
......@@ -108,11 +134,11 @@ extern float current_position[NUM_AXIS];
extern float destination[NUM_AXIS];
extern float home_offset[3];
extern float hotend_offset[3][HOTENDS];
extern float min_pos[3];
extern float max_pos[3];
extern float sw_endstop_min[3];
extern float sw_endstop_max[3];
extern bool axis_known_position[3];
extern bool axis_homed[3];
extern float zprobe_zoffset;
extern uint8_t axis_known_position;
extern uint8_t axis_was_homed;
#if HEATER_USES_AD595
extern float ad595_offset[HOTENDS];
......@@ -140,11 +166,15 @@ extern double printer_usage_filament;
extern float extrude_min_temp;
#endif
#if ENABLED(HOST_KEEPALIVE_FEATURE)
extern uint8_t host_keepalive_interval;
#endif
extern int fanSpeed;
#if ENABLED(BARICUDA)
extern int ValvePressure;
extern int EtoPPressure;
extern int baricuda_valve_pressure;
extern int baricuda_e_to_p_pressure;
#endif
#if ENABLED(FAN_SOFT_PWM)
......@@ -203,8 +233,8 @@ extern int fanSpeed;
extern bool config_readed;
#endif
extern millis_t print_job_start_ms;
extern millis_t print_job_stop_ms;
// Print job timer
extern Stopwatch print_job_timer;
// Handling multiple extruders pins
extern uint8_t active_extruder;
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* blinkm.cpp - Library for controlling a BlinkM over i2c
* Created by Tim Koster, August 21 2013.
......
/*
blinkm.h
Library header file for BlinkM library
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* blinkm.h
* Library header file for BlinkM library
*/
#ifndef BLINKM_H
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef COMMUNICATION_H
#define COMMUNICATION_H
#define START "start" // start for host
#define OK "ok " // ok answer for host
#define ER "Error: " // error for host
#define WT "Wait" // wait for host
#define DB "Echo: " // message for user
#define DEB "Debug: " // message for debug
#define CFG "Config: " // config for host
#define INFO "Info: " // info for host
#define RESEND "Resend: " // resend for host
#define WARNING "Warning: " // warning for host
#define OK "ok" // ok answer for host
#define ER "Error:" // error for host
#define WT "wait" // wait for host
#define DB "Echo:" // message for user
#define DEB "Debug:" // message for debug
#define CFG "Config:" // config for host
#define INFO "Info:" // info for host
#define BUSY "busy:" // buys for host
#define RESEND "Resend:" // resend for host
#define WARNING "Warning:" // warning for host
#define TNAN "NAN" // NAN for host
#define TINF "INF" // INF for host
#define PAUSE "//action:pause" // command for host that support action
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* Conditionals.h
* Defines that depend on configuration but are not editable.
*/
#ifndef CONDITIONALS_H
#define CONDITIONALS_H
#if ENABLED(MAKRPANEL)
#define DOGLCD
#define DEFAULT_LCD_CONTRAST 17
#define ULTIPANEL
#define NEWPANEL
#endif
#if ENABLED(miniVIKI) || ENABLED(VIKI2) || ENABLED(ELB_FULL_GRAPHIC_CONTROLLER)
#define ULTRA_LCD //general LCD support, also 16x2
#define DOGLCD // Support for SPI LCD 128x64 (Controller ST7565R graphic Display Family)
#define ULTIMAKERCONTROLLER //as available from the Ultimaker online store.
#if ENABLED(miniVIKI)
#define DEFAULT_LCD_CONTRAST 95
#elif ENABLED(VIKI2)
#define DEFAULT_LCD_CONTRAST 40
#elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER)
#define DEFAULT_LCD_CONTRAST 110
#define U8GLIB_LM6059_AF
#endif
#define ENCODER_PULSES_PER_STEP 4
#define ENCODER_STEPS_PER_MENU_ITEM 1
#endif
// Generic support for SSD1306 OLED based LCDs.
#if ENABLED(U8GLIB_SSD1306)
#define ULTRA_LCD //general LCD support, also 16x2
#define DOGLCD // Support for I2C LCD 128x64 (Controller SSD1306 graphic Display Family)
#endif
#if ENABLED(PANEL_ONE)
#define ULTIMAKERCONTROLLER
#endif
#if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER)
#define DOGLCD
#define U8GLIB_ST7920
#define REPRAP_DISCOUNT_SMART_CONTROLLER
#endif
#if ENABLED(SPARK_FULL_GRAPHICS)
#define ENCODER_PULSES_PER_STEP 2
#define ENCODER_STEPS_PER_MENU_ITEM 1
#define DOGLCD
#define U8GLIB_ST7920
#define REPRAP_DISCOUNT_SMART_CONTROLLER
#endif
#if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER)
#if DISABLED(SDSUPPORT)
#define SDSUPPORT
#endif
#endif
#if ENABLED(ULTIMAKERCONTROLLER) || ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) || ENABLED(G3D_PANEL) || ENABLED(RIGIDBOT_PANEL)
#define ULTIPANEL
#define NEWPANEL
#endif
#if ENABLED(RADDS_DISPLAY)
#define ENCODER_PULSES_PER_STEP 2
#define ENCODER_STEPS_PER_MENU_ITEM 1
#define ULTIPANEL
#define NEWPANEL
#endif
#if ENABLED(REPRAPWORLD_KEYPAD)
#define ULTIPANEL
#define NEWPANEL
#endif
#if ENABLED(RA_CONTROL_PANEL)
#define LCD_I2C_TYPE_PCA8574
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
#define ULTIPANEL
#define NEWPANEL
#endif
#if ENABLED(MINIPANEL)
#define DOGLCD
#define ULTIPANEL
#define NEWPANEL
#define DEFAULT_LCD_CONTRAST 17
#endif
#define CONDITIONALS_H
#if ENABLED(MAKRPANEL)
#define DOGLCD
#define DEFAULT_LCD_CONTRAST 17
#define ULTIPANEL
#define NEWPANEL
#endif
#if ENABLED(miniVIKI) || ENABLED(VIKI2) || ENABLED(ELB_FULL_GRAPHIC_CONTROLLER)
#define ULTRA_LCD //general LCD support, also 16x2
#define DOGLCD // Support for SPI LCD 128x64 (Controller ST7565R graphic Display Family)
#define ULTIMAKERCONTROLLER //as available from the Ultimaker online store.
#if ENABLED(miniVIKI)
#define DEFAULT_LCD_CONTRAST 95
#elif ENABLED(VIKI2)
#define DEFAULT_LCD_CONTRAST 40
#elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER)
#define DEFAULT_LCD_CONTRAST 110
#define U8GLIB_LM6059_AF
#endif
/**
* I2C PANELS
*/
#if ENABLED(LCD_I2C_SAINSMART_YWROBOT)
// This uses the LiquidCrystal_I2C library ( https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home )
// Make sure it is placed in the Arduino libraries directory.
#define LCD_I2C_TYPE_PCF8575
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
#define ULTIPANEL
#define NEWPANEL
#endif
// PANELOLU2 LCD with status LEDs, separate encoder and click inputs
#if ENABLED(LCD_I2C_PANELOLU2)
#define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD
#if DISABLED(ENCODER_PULSES_PER_STEP)
#define ENCODER_PULSES_PER_STEP 4
#endif
#if DISABLED(ENCODER_STEPS_PER_MENU_ITEM)
#define ENCODER_STEPS_PER_MENU_ITEM 1
#endif
#if ENABLED(LCD_USE_I2C_BUZZER)
#define LCD_FEEDBACK_FREQUENCY_HZ 1000
#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100
// Generic support for SSD1306 OLED based LCDs.
#if ENABLED(U8GLIB_SSD1306)
#define ULTRA_LCD //general LCD support, also 16x2
#define DOGLCD // Support for I2C LCD 128x64 (Controller SSD1306 graphic Display Family)
#endif
#define ULTIPANEL
#define NEWPANEL
#endif
// Panucatt VIKI LCD with status LEDs, integrated click & L/R/U/P buttons, separate encoder inputs
#if ENABLED(LCD_I2C_VIKI)
// This uses the LiquidTWI2 library v1.2.3 or later ( https://github.com/lincomatic/LiquidTWI2 )
// Make sure the LiquidTWI2 directory is placed in the Arduino or Sketchbook libraries subdirectory.
// Note: The pause/stop/resume LCD button pin should be connected to the Arduino
// BTN_ENC pin (or set BTN_ENC to -1 if not used)
#define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD (requires LiquidTWI2 v1.2.3 or later)
#define ULTIPANEL
#define NEWPANEL
#endif
#if ENABLED(PANEL_ONE)
#define ULTIMAKERCONTROLLER
#endif
// Shift register panels
// ---------------------
// 2 wire Non-latching LCD SR from:
// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection
#if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER)
#define DOGLCD
#define U8GLIB_ST7920
#define REPRAP_DISCOUNT_SMART_CONTROLLER
#endif
#if ENABLED(SAV_3DLCD)
#define SR_LCD_2W_NL // Non latching 2 wire shiftregister
#define ULTIPANEL
#define NEWPANEL
#endif
#if ENABLED(SPARK_FULL_GRAPHICS)
#define ENCODER_PULSES_PER_STEP 2
#define ENCODER_STEPS_PER_MENU_ITEM 1
#if ENABLED(DOGLCD) // Change number of lines to match the DOG graphic display
#if DISABLED(LCD_WIDTH)
#define LCD_WIDTH 22
#endif
#if DISABLED(LCD_HEIGHT)
#define LCD_HEIGHT 5
#define DOGLCD
#define U8GLIB_ST7920
#define REPRAP_DISCOUNT_SMART_CONTROLLER
#endif
#endif
#if ENABLED(ULTIPANEL)
#define NEWPANEL //enable this if you have a click-encoder panel
#define ULTRA_LCD
#if DISABLED(LCD_WIDTH)
#define LCD_WIDTH 20
#endif
#if DISABLED(LCD_HEIGHT)
#define LCD_HEIGHT 4
#endif
#else //no panel but just LCD
#if ENABLED(ULTRA_LCD)
#if DISABLED(LCD_WIDTH)
#define LCD_WIDTH 16
#if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER)
#if DISABLED(SDSUPPORT)
#define SDSUPPORT
#endif
#if DISABLED(LCD_HEIGHT)
#define LCD_HEIGHT 2
#endif
#endif
#endif
#if ENABLED(DOGLCD)
/* Custom characters defined in font font_6x10_marlin_symbols */
// \x00 intentionally skipped to avoid problems in strings
#define LCD_STR_REFRESH "\x01"
#define LCD_STR_FOLDER "\x02"
#define LCD_STR_ARROW_RIGHT "\x03"
#define LCD_STR_UPLEVEL "\x04"
#define LCD_STR_CLOCK "\x05"
#define LCD_STR_FEEDRATE "\x06"
#define LCD_STR_BEDTEMP "\x07"
#define LCD_STR_THERMOMETER "\x08"
#define LCD_STR_DEGREE "\x09"
#define LCD_STR_SPECIAL_MAX '\x09'
// Maximum here is 0x1f because 0x20 is ' ' (space) and the normal charsets begin.
// Better stay below 0x10 because DISPLAY_CHARSET_HD44780_WESTERN begins here.
#else
/* Custom characters defined in the first 8 characters of the LCD */
#define LCD_STR_BEDTEMP "\x00" // this will have 'unexpected' results when used in a string!
#define LCD_STR_DEGREE "\x01"
#define LCD_STR_THERMOMETER "\x02"
#define LCD_STR_UPLEVEL "\x03"
#define LCD_STR_REFRESH "\x04"
#define LCD_STR_FOLDER "\x05"
#define LCD_STR_FEEDRATE "\x06"
#define LCD_STR_CLOCK "\x07"
#define LCD_STR_ARROW_RIGHT ">" /* from the default character set */
#endif
/**
* Default LCD contrast for dogm-like LCD displays
*/
#if ENABLED(DOGLCD) && DISABLED(DEFAULT_LCD_CONTRAST)
#define DEFAULT_LCD_CONTRAST 32
#endif
#if ENABLED(DOGLCD)
#define HAS_LCD_CONTRAST
#if ENABLED(U8GLIB_ST7920)
#undef HAS_LCD_CONTRAST
#endif
#if ENABLED(U8GLIB_SSD1306)
#undef HAS_LCD_CONTRAST
#if ENABLED(ULTIMAKERCONTROLLER) || ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) || ENABLED(G3D_PANEL) || ENABLED(RIGIDBOT_PANEL)
#define ULTIPANEL
#define NEWPANEL
#endif
#endif
#include "pins.h"
#if ENABLED(RADDS_DISPLAY)
#define ENCODER_PULSES_PER_STEP 2
#define ENCODER_STEPS_PER_MENU_ITEM 1
/**
* SAM3X8E
*/
#ifdef __SAM3X8E__
#ifdef FAST_PWM_FAN
#undef FAST_PWM_FAN
#define ULTIPANEL
#define NEWPANEL
#endif
#ifdef M100_FREE_MEMORY_WATCHER
#undef M100_FREE_MEMORY_WATCHER
#if ENABLED(REPRAPWORLD_KEYPAD)
#define ULTIPANEL
#define NEWPANEL
#endif
#endif
/**
* DONDOLO
*/
#if ENABLED(DONDOLO)
#undef SINGLENOZZLE
#undef ADVANCE
#undef DRIVER_EXTRUDERS
#define DRIVER_EXTRUDERS 1
#endif
/**
* SINGLENOZZLE
*/
#if ENABLED(SINGLENOZZLE)
#undef HOTENDS
#define HOTENDS 1
#undef TEMP_SENSOR_1_AS_REDUNDANT
#else
#undef HOTENDS
#define HOTENDS EXTRUDERS
#endif
#if ENABLED(RA_CONTROL_PANEL)
#define LCD_I2C_TYPE_PCA8574
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
#define ULTIPANEL
#define NEWPANEL
#endif
/**
* DRIVER_EXTRUDERS
*/
#if DISABLED(MKR4) && DISABLED(NPR2) && DISABLED(DONDOLO) && DISABLED(COLOR_MIXING_EXTRUDER)
#undef DRIVER_EXTRUDERS
#define DRIVER_EXTRUDERS EXTRUDERS // This defines the number of Driver extruder
#endif
#if ENABLED(MINIPANEL)
#define DOGLCD
#define ULTIPANEL
#define NEWPANEL
#define DEFAULT_LCD_CONTRAST 17
#endif
#ifndef __SAM3X8E__
#ifndef USBCON
#define HardwareSerial_h // trick to disable the standard HWserial
/**
* I2C PANELS
*/
#if ENABLED(LCD_I2C_SAINSMART_YWROBOT)
// This uses the LiquidCrystal_I2C library ( https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home )
// Make sure it is placed in the Arduino libraries directory.
#define LCD_I2C_TYPE_PCF8575
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
#define ULTIPANEL
#define NEWPANEL
#endif
#endif
/**
* ENDSTOPPULLUPS
*/
#if ENABLED(ENDSTOPPULLUPS)
#define ENDSTOPPULLUP_XMIN
#define ENDSTOPPULLUP_YMIN
#define ENDSTOPPULLUP_ZMIN
#define ENDSTOPPULLUP_Z2MIN
#define ENDSTOPPULLUP_XMAX
#define ENDSTOPPULLUP_YMAX
#define ENDSTOPPULLUP_ZMAX
#define ENDSTOPPULLUP_Z2MAX
#define ENDSTOPPULLUP_ZPROBE
#define ENDSTOPPULLUP_EMIN
#endif
// PANELOLU2 LCD with status LEDs, separate encoder and click inputs
#if ENABLED(LCD_I2C_PANELOLU2)
#define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD
/**
* ENDSTOP LOGICAL
*/
#if MB(ALLIGATOR)
#define X_MIN_ENDSTOP_INVERTING !X_MIN_ENDSTOP_LOGIC
#define Y_MIN_ENDSTOP_INVERTING !Y_MIN_ENDSTOP_LOGIC
#define Z_MIN_ENDSTOP_INVERTING !Z_MIN_ENDSTOP_LOGIC
#define Z2_MIN_ENDSTOP_INVERTING !Z2_MIN_ENDSTOP_LOGIC
#define E_MIN_ENDSTOP_INVERTING !E_MIN_ENDSTOP_LOGIC
#define X_MAX_ENDSTOP_INVERTING !X_MAX_ENDSTOP_LOGIC
#define Y_MAX_ENDSTOP_INVERTING !Y_MAX_ENDSTOP_LOGIC
#define Z_MAX_ENDSTOP_INVERTING !Z_MAX_ENDSTOP_LOGIC
#define Z2_MAX_ENDSTOP_INVERTING !Z2_MAX_ENDSTOP_LOGIC
#define Z_PROBE_ENDSTOP_INVERTING !Z_PROBE_ENDSTOP_LOGIC
#undef ENDSTOPPULLUP_XMIN
#undef ENDSTOPPULLUP_YMIN
#undef ENDSTOPPULLUP_ZMIN
#undef ENDSTOPPULLUP_Z2MIN
#undef ENDSTOPPULLUP_XMAX
#undef ENDSTOPPULLUP_YMAX
#undef ENDSTOPPULLUP_ZMAX
#undef ENDSTOPPULLUP_Z2MAX
#undef ENDSTOPPULLUP_ZPROBE
#undef ENDSTOPPULLUP_EMIN
#else
#define X_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_LOGIC
#define Y_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_LOGIC
#define Z_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_LOGIC
#define Z2_MIN_ENDSTOP_INVERTING Z2_MIN_ENDSTOP_LOGIC
#define E_MIN_ENDSTOP_INVERTING E_MIN_ENDSTOP_LOGIC
#define X_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_LOGIC
#define Y_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_LOGIC
#define Z_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_LOGIC
#define Z2_MAX_ENDSTOP_INVERTING Z2_MAX_ENDSTOP_LOGIC
#define Z_PROBE_ENDSTOP_INVERTING Z_PROBE_ENDSTOP_LOGIC
#endif
#if DISABLED(ENCODER_PULSES_PER_STEP)
#define ENCODER_PULSES_PER_STEP 4
#endif
/**
* Firmware Test
*/
#if ENABLED(FIRMWARE_TEST)
#undef BAUDRATE
#define BAUDRATE 115200 // Baudrate setting to 115200 because serial monitor arduino function at max 115200 baudrate.
#endif
#if DISABLED(ENCODER_STEPS_PER_MENU_ITEM)
#define ENCODER_STEPS_PER_MENU_ITEM 1
#endif
/**
* Axis lengths
*/
#define X_MAX_LENGTH (X_MAX_POS - (X_MIN_POS))
#define Y_MAX_LENGTH (Y_MAX_POS - (Y_MIN_POS))
#define Z_MAX_LENGTH (Z_MAX_POS - (Z_MIN_POS))
#if ENABLED(LCD_USE_I2C_BUZZER)
#define LCD_FEEDBACK_FREQUENCY_HZ 1000
#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100
#endif
/**
* SCARA
*/
#if MECH(SCARA)
#undef SLOWDOWN
#define QUICK_HOME //SCARA needs Quickhome
#endif
#define ULTIPANEL
#define NEWPANEL
#endif
/**
* DELTA
*/
#if MECH(DELTA)
#undef SLOWDOWN //DELTA not needs SLOWDOWN
#define AUTOLEVEL_GRID_MULTI 1/AUTOLEVEL_GRID
// DELTA must have same valour for 3 axis endstop hits
#define X_HOME_BUMP_MM XYZ_HOME_BUMP_MM
#define Y_HOME_BUMP_MM XYZ_HOME_BUMP_MM
#define Z_HOME_BUMP_MM XYZ_HOME_BUMP_MM
#define HOMING_BUMP_DIVISOR {XYZ_BUMP_DIVISOR, XYZ_BUMP_DIVISOR, XYZ_BUMP_DIVISOR}
// Effective horizontal distance bridged by diagonal push rods.
#define DEFAULT_DELTA_RADIUS (DELTA_SMOOTH_ROD_OFFSET - DELTA_EFFECTOR_OFFSET - DELTA_CARRIAGE_OFFSET)
#define LEFT_PROBE_BED_POSITION -DELTA_PROBABLE_RADIUS
#define RIGHT_PROBE_BED_POSITION DELTA_PROBABLE_RADIUS
#define FRONT_PROBE_BED_POSITION -DELTA_PROBABLE_RADIUS
#define BACK_PROBE_BED_POSITION DELTA_PROBABLE_RADIUS
// Radius for probe
#define DELTA_PROBABLE_RADIUS DELTA_PRINTABLE_RADIUS - 5
#endif
/**
* AUTOSET LOCATIONS OF LIMIT SWITCHES
*/
#if ENABLED(MANUAL_HOME_POSITIONS) // Use manual limit switch locations
#define X_HOME_POS MANUAL_X_HOME_POS
#define Y_HOME_POS MANUAL_Y_HOME_POS
#define Z_HOME_POS MANUAL_Z_HOME_POS
#else //!MANUAL_HOME_POSITIONS – Use home switch positions based on homing direction and travel limits
#if ENABLED(BED_CENTER_AT_0_0)
#define X_HOME_POS (X_MAX_LENGTH) * (X_HOME_DIR) * 0.5
#define Y_HOME_POS (Y_MAX_LENGTH) * (Y_HOME_DIR) * 0.5
#else
#define X_HOME_POS (X_HOME_DIR < 0 ? X_MIN_POS : X_MAX_POS)
#define Y_HOME_POS (Y_HOME_DIR < 0 ? Y_MIN_POS : Y_MAX_POS)
// Panucatt VIKI LCD with status LEDs, integrated click & L/R/U/P buttons, separate encoder inputs
#if ENABLED(LCD_I2C_VIKI)
// This uses the LiquidTWI2 library v1.2.3 or later ( https://github.com/lincomatic/LiquidTWI2 )
// Make sure the LiquidTWI2 directory is placed in the Arduino or Sketchbook libraries subdirectory.
// Note: The pause/stop/resume LCD button pin should be connected to the Arduino
// BTN_ENC pin (or set BTN_ENC to -1 if not used)
#define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD (requires LiquidTWI2 v1.2.3 or later)
#define ULTIPANEL
#define NEWPANEL
#endif
#define Z_HOME_POS (Z_HOME_DIR < 0 ? Z_MIN_POS : Z_MAX_POS)
#endif //!MANUAL_HOME_POSITIONS
/**
* Auto Bed Leveling
*/
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
// Boundaries for probing based on set limits
#define MIN_PROBE_X (max(X_MIN_POS, X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER))
#define MAX_PROBE_X (min(X_MAX_POS, X_MAX_POS + X_PROBE_OFFSET_FROM_EXTRUDER))
#define MIN_PROBE_Y (max(Y_MIN_POS, Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER))
#define MAX_PROBE_Y (min(Y_MAX_POS, Y_MAX_POS + Y_PROBE_OFFSET_FROM_EXTRUDER))
// Shift register panels
// ---------------------
// 2 wire Non-latching LCD SR from:
// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection
// Make sure probing points are reachable
#if LEFT_PROBE_BED_POSITION < MIN_PROBE_X
#undef LEFT_PROBE_BED_POSITION
#define LEFT_PROBE_BED_POSITION MIN_PROBE_X
#endif
#if RIGHT_PROBE_BED_POSITION > MAX_PROBE_X
#undef RIGHT_PROBE_BED_POSITION
#define RIGHT_PROBE_BED_POSITION MAX_PROBE_X
#endif
#if FRONT_PROBE_BED_POSITION < MIN_PROBE_Y
#undef FRONT_PROBE_BED_POSITION
#define FRONT_PROBE_BED_POSITION MIN_PROBE_Y
#endif
#if BACK_PROBE_BED_POSITION > MAX_PROBE_Y
#undef BACK_PROBE_BED_POSITION
#define BACK_PROBE_BED_POSITION MAX_PROBE_Y
#if ENABLED(SAV_3DLCD)
#define SR_LCD_2W_NL // Non latching 2 wire shiftregister
#define ULTIPANEL
#define NEWPANEL
#endif
// Z_RAISE_AFTER_PROBING is not for all probes. Be sure that it is zero in that cases
#if DISABLED(ENABLE_SERVOS) && DISABLED(Z_PROBE_SLED)
#undef Z_RAISE_AFTER_PROBING
#define Z_RAISE_AFTER_PROBING 0
#if ENABLED(DOGLCD) // Change number of lines to match the DOG graphic display
#if DISABLED(LCD_WIDTH)
#define LCD_WIDTH 22
#endif
#if DISABLED(LCD_HEIGHT)
#define LCD_HEIGHT 5
#endif
#endif
#endif
/**
* Sled Options
*/
#if ENABLED(Z_PROBE_SLED)
#define Z_SAFE_HOMING
#endif
#if ENABLED(ULTIPANEL)
#define NEWPANEL //enable this if you have a click-encoder panel
#define ULTRA_LCD
#if DISABLED(LCD_WIDTH)
#define LCD_WIDTH 20
#endif
#if DISABLED(LCD_HEIGHT)
#define LCD_HEIGHT 4
#endif
#else //no panel but just LCD
#if ENABLED(ULTRA_LCD)
#if DISABLED(LCD_WIDTH)
#define LCD_WIDTH 16
#endif
#if DISABLED(LCD_HEIGHT)
#define LCD_HEIGHT 2
#endif
#endif
#endif
/**
* MAX_STEP_FREQUENCY differs for TOSHIBA OR ARDUINO DUE OR ARDUINO MEGA
*/
#ifdef __SAM3X8E__
#if ENABLED(CONFIG_STEPPERS_TOSHIBA)
#define MAX_STEP_FREQUENCY 150000 // Max step frequency for Toshiba Stepper Controllers
#define DOUBLE_STEP_FREQUENCY MAX_STEP_FREQUENCY
#if ENABLED(DOGLCD)
/* Custom characters defined in font font_6x10_marlin_symbols */
// \x00 intentionally skipped to avoid problems in strings
#define LCD_STR_REFRESH "\x01"
#define LCD_STR_FOLDER "\x02"
#define LCD_STR_ARROW_RIGHT "\x03"
#define LCD_STR_UPLEVEL "\x04"
#define LCD_STR_CLOCK "\x05"
#define LCD_STR_FEEDRATE "\x06"
#define LCD_STR_BEDTEMP "\x07"
#define LCD_STR_THERMOMETER "\x08"
#define LCD_STR_DEGREE "\x09"
#define LCD_STR_SPECIAL_MAX '\x09'
// Maximum here is 0x1f because 0x20 is ' ' (space) and the normal charsets begin.
// Better stay below 0x10 because DISPLAY_CHARSET_HD44780_WESTERN begins here.
#else
#define MAX_STEP_FREQUENCY 320000 // Max step frequency for the Due is approx. 330kHz
#define DOUBLE_STEP_FREQUENCY 90000 // 96kHz is close to maximum for an Arduino Due
/* Custom characters defined in the first 8 characters of the LCD */
#define LCD_STR_BEDTEMP "\x00" // this will have 'unexpected' results when used in a string!
#define LCD_STR_DEGREE "\x01"
#define LCD_STR_THERMOMETER "\x02"
#define LCD_STR_UPLEVEL "\x03"
#define LCD_STR_REFRESH "\x04"
#define LCD_STR_FOLDER "\x05"
#define LCD_STR_FEEDRATE "\x06"
#define LCD_STR_CLOCK "\x07"
#define LCD_STR_ARROW_RIGHT ">" /* from the default character set */
#endif
/**
* Default LCD contrast for dogm-like LCD displays
*/
#if ENABLED(DOGLCD) && DISABLED(DEFAULT_LCD_CONTRAST)
#define DEFAULT_LCD_CONTRAST 32
#endif
#if ENABLED(DOGLCD)
#define HAS_LCD_CONTRAST
#if ENABLED(U8GLIB_ST7920)
#undef HAS_LCD_CONTRAST
#endif
#if ENABLED(U8GLIB_SSD1306)
#undef HAS_LCD_CONTRAST
#endif
#endif
#else
#if ENABLED(CONFIG_STEPPERS_TOSHIBA)
#define MAX_STEP_FREQUENCY 10000 // Max step frequency for Toshiba Stepper Controllers
#define DOUBLE_STEP_FREQUENCY MAX_STEP_FREQUENCY
#else
#define MAX_STEP_FREQUENCY 40000 // Max step frequency for Arduino mega
#define DOUBLE_STEP_FREQUENCY 10000
#endif
#endif
// MS1 MS2 Stepper Driver Microstepping mode table
#define MICROSTEP1 LOW,LOW
#define MICROSTEP2 HIGH,LOW
#define MICROSTEP4 LOW,HIGH
#define MICROSTEP8 HIGH,HIGH
#if MB(ALLIGATOR)
#define MICROSTEP16 LOW,LOW
#define MICROSTEP32 HIGH,HIGH
#else
#define MICROSTEP16 HIGH,HIGH
#endif
/**
* Advance calculated values
*/
#if ENABLED(ADVANCE)
#define EXTRUSION_AREA (0.25 * (D_FILAMENT) * (D_FILAMENT) * M_PI)
#define STEPS_PER_CUBIC_MM_E (axis_steps_per_unit[E_AXIS + active_extruder] / EXTRUSION_AREA)
#endif
#include "pins.h"
/**
* SD DETECT
*
*/
#if ENABLED(SD_DISABLED_DETECT)
#undef SD_DETECT_PIN
#define SD_DETECT_PIN -1
#endif
#if ENABLED(ULTIPANEL) && DISABLED(ELB_FULL_GRAPHIC_CONTROLLER)
#undef SD_DETECT_INVERTED
#endif
/**
* SAM3X8E
*/
#ifdef __SAM3X8E__
#ifdef FAST_PWM_FAN
#undef FAST_PWM_FAN
#endif
#ifdef M100_FREE_MEMORY_WATCHER
#undef M100_FREE_MEMORY_WATCHER
#endif
#endif
/**
* DONDOLO
*/
#if ENABLED(DONDOLO)
#undef SINGLENOZZLE
#undef ADVANCE
#undef DRIVER_EXTRUDERS
#define DRIVER_EXTRUDERS 1
#endif
/**
* SINGLENOZZLE
*/
#if ENABLED(SINGLENOZZLE)
#undef HOTENDS
#define HOTENDS 1
#undef TEMP_SENSOR_1_AS_REDUNDANT
#else
#undef HOTENDS
#define HOTENDS EXTRUDERS
#endif
/**
* Power Signal Control Definitions
* By default use Normal definition
*/
#if DISABLED(POWER_SUPPLY)
#define POWER_SUPPLY 0
#endif
#if (POWER_SUPPLY == 1) // 1 = ATX
#define PS_ON_AWAKE LOW
#define PS_ON_ASLEEP HIGH
#elif (POWER_SUPPLY == 2) // 2 = X-Box 360 203W
#define PS_ON_AWAKE HIGH
#define PS_ON_ASLEEP LOW
#endif
#define HAS_POWER_SWITCH (POWER_SUPPLY > 0 && PIN_EXISTS(PS_ON))
/**
* DRIVER_EXTRUDERS
*/
#if DISABLED(MKR4) && DISABLED(NPR2) && DISABLED(DONDOLO) && DISABLED(COLOR_MIXING_EXTRUDER)
#undef DRIVER_EXTRUDERS
#define DRIVER_EXTRUDERS EXTRUDERS // This defines the number of Driver extruder
#endif
/**
* Temp Sensor defines
*/
#if TEMP_SENSOR_0 == -2
#define HEATER_0_USES_MAX6675
#elif TEMP_SENSOR_0 == -1
#define HEATER_0_USES_AD595
#elif TEMP_SENSOR_0 == 0
#undef HEATER_0_MINTEMP
#undef HEATER_0_MAXTEMP
#elif TEMP_SENSOR_0 > 0
#define THERMISTORHEATER_0 TEMP_SENSOR_0
#define HEATER_0_USES_THERMISTOR
#endif
#if TEMP_SENSOR_1 == -1
#define HEATER_1_USES_AD595
#elif TEMP_SENSOR_1 == 0
#undef HEATER_1_MINTEMP
#undef HEATER_1_MAXTEMP
#elif TEMP_SENSOR_1 > 0
#define THERMISTORHEATER_1 TEMP_SENSOR_1
#define HEATER_1_USES_THERMISTOR
#endif
#if TEMP_SENSOR_2 == -1
#define HEATER_2_USES_AD595
#elif TEMP_SENSOR_2 == 0
#undef HEATER_2_MINTEMP
#undef HEATER_2_MAXTEMP
#elif TEMP_SENSOR_2 > 0
#define THERMISTORHEATER_2 TEMP_SENSOR_2
#define HEATER_2_USES_THERMISTOR
#endif
#if TEMP_SENSOR_3 == -1
#define HEATER_3_USES_AD595
#elif TEMP_SENSOR_3 == 0
#undef HEATER_3_MINTEMP
#undef HEATER_3_MAXTEMP
#elif TEMP_SENSOR_3 > 0
#define THERMISTORHEATER_3 TEMP_SENSOR_3
#define HEATER_3_USES_THERMISTOR
#endif
#if TEMP_SENSOR_BED == -1
#define BED_USES_AD595
#elif TEMP_SENSOR_BED == 0
#undef BED_MINTEMP
#undef BED_MAXTEMP
#elif TEMP_SENSOR_BED > 0
#define THERMISTORBED TEMP_SENSOR_BED
#define BED_USES_THERMISTOR
#endif
#define HEATER_USES_AD595 (ENABLED(HEATER_0_USES_AD595) || ENABLED(HEATER_1_USES_AD595) || ENABLED(HEATER_2_USES_AD595) || ENABLED(HEATER_3_USES_AD595))
#ifndef __SAM3X8E__
#ifndef USBCON
#define HardwareSerial_h // trick to disable the standard HWserial
#endif
#endif
/**
* ARRAY_BY_EXTRUDERS based on EXTRUDERS
*/
#if EXTRUDERS > 9
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1, v1, v1, v1, v1, v1, v1, v1, v1 }
#elif EXTRUDERS > 8
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1, v1, v1, v1, v1, v1, v1, v1 }
#elif EXTRUDERS > 7
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1, v1, v1, v1, v1, v1, v1 }
#elif EXTRUDERS > 6
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1, v1, v1, v1, v1, v1 }
#elif EXTRUDERS > 5
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1, v1, v1, v1, v1 }
#elif EXTRUDERS > 4
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1, v1, v1, v1 }
#elif EXTRUDERS > 3
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1, v1, v1 }
#elif EXTRUDERS > 2
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1, v1 }
#elif EXTRUDERS > 1
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1 }
#else
#define ARRAY_BY_EXTRUDERS(v1) { v1 }
#endif
/**
* ENDSTOPPULLUPS
*/
#if ENABLED(ENDSTOPPULLUPS)
#define ENDSTOPPULLUP_XMIN
#define ENDSTOPPULLUP_YMIN
#define ENDSTOPPULLUP_ZMIN
#define ENDSTOPPULLUP_Z2MIN
#define ENDSTOPPULLUP_XMAX
#define ENDSTOPPULLUP_YMAX
#define ENDSTOPPULLUP_ZMAX
#define ENDSTOPPULLUP_Z2MAX
#define ENDSTOPPULLUP_ZPROBE
#define ENDSTOPPULLUP_EMIN
#endif
/**
* ENDSTOP LOGICAL
*/
#if MB(ALLIGATOR)
#define X_MIN_ENDSTOP_INVERTING !X_MIN_ENDSTOP_LOGIC
#define Y_MIN_ENDSTOP_INVERTING !Y_MIN_ENDSTOP_LOGIC
#define Z_MIN_ENDSTOP_INVERTING !Z_MIN_ENDSTOP_LOGIC
#define Z2_MIN_ENDSTOP_INVERTING !Z2_MIN_ENDSTOP_LOGIC
#define E_MIN_ENDSTOP_INVERTING !E_MIN_ENDSTOP_LOGIC
#define X_MAX_ENDSTOP_INVERTING !X_MAX_ENDSTOP_LOGIC
#define Y_MAX_ENDSTOP_INVERTING !Y_MAX_ENDSTOP_LOGIC
#define Z_MAX_ENDSTOP_INVERTING !Z_MAX_ENDSTOP_LOGIC
#define Z2_MAX_ENDSTOP_INVERTING !Z2_MAX_ENDSTOP_LOGIC
#define Z_PROBE_ENDSTOP_INVERTING !Z_PROBE_ENDSTOP_LOGIC
#undef ENDSTOPPULLUP_XMIN
#undef ENDSTOPPULLUP_YMIN
#undef ENDSTOPPULLUP_ZMIN
#undef ENDSTOPPULLUP_Z2MIN
#undef ENDSTOPPULLUP_XMAX
#undef ENDSTOPPULLUP_YMAX
#undef ENDSTOPPULLUP_ZMAX
#undef ENDSTOPPULLUP_Z2MAX
#undef ENDSTOPPULLUP_ZPROBE
#undef ENDSTOPPULLUP_EMIN
#else
#define X_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_LOGIC
#define Y_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_LOGIC
#define Z_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_LOGIC
#define Z2_MIN_ENDSTOP_INVERTING Z2_MIN_ENDSTOP_LOGIC
#define E_MIN_ENDSTOP_INVERTING E_MIN_ENDSTOP_LOGIC
#define X_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_LOGIC
#define Y_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_LOGIC
#define Z_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_LOGIC
#define Z2_MAX_ENDSTOP_INVERTING Z2_MAX_ENDSTOP_LOGIC
#define Z_PROBE_ENDSTOP_INVERTING Z_PROBE_ENDSTOP_LOGIC
#endif
/**
* Firmware Test
*/
#if ENABLED(FIRMWARE_TEST)
#undef BAUDRATE
#define BAUDRATE 115200 // Baudrate setting to 115200 because serial monitor arduino function at max 115200 baudrate.
#endif
/**
* Axis lengths
*/
#define X_MAX_LENGTH (X_MAX_POS - (X_MIN_POS))
#define Y_MAX_LENGTH (Y_MAX_POS - (Y_MIN_POS))
#define Z_MAX_LENGTH (Z_MAX_POS - (Z_MIN_POS))
/**
* SCARA
*/
#if MECH(SCARA)
#undef SLOWDOWN
#define QUICK_HOME //SCARA needs Quickhome
#endif
/**
* DELTA
*/
#if MECH(DELTA)
#undef SLOWDOWN //DELTA not needs SLOWDOWN
#define AUTOLEVEL_GRID_MULTI 1/AUTOLEVEL_GRID
// DELTA must have same valour for 3 axis endstop hits
#define X_HOME_BUMP_MM XYZ_HOME_BUMP_MM
#define Y_HOME_BUMP_MM XYZ_HOME_BUMP_MM
#define Z_HOME_BUMP_MM XYZ_HOME_BUMP_MM
#define HOMING_BUMP_DIVISOR {XYZ_BUMP_DIVISOR, XYZ_BUMP_DIVISOR, XYZ_BUMP_DIVISOR}
// Effective horizontal distance bridged by diagonal push rods.
#define DEFAULT_DELTA_RADIUS (DELTA_SMOOTH_ROD_OFFSET - DELTA_EFFECTOR_OFFSET - DELTA_CARRIAGE_OFFSET)
#define LEFT_PROBE_BED_POSITION -DELTA_PROBABLE_RADIUS
#define RIGHT_PROBE_BED_POSITION DELTA_PROBABLE_RADIUS
#define FRONT_PROBE_BED_POSITION -DELTA_PROBABLE_RADIUS
#define BACK_PROBE_BED_POSITION DELTA_PROBABLE_RADIUS
// Radius for probe
#define DELTA_PROBABLE_RADIUS DELTA_PRINTABLE_RADIUS - 5
#endif
/**
* AUTOSET LOCATIONS OF LIMIT SWITCHES
*/
#if ENABLED(MANUAL_HOME_POSITIONS) // Use manual limit switch locations
#define X_HOME_POS MANUAL_X_HOME_POS
#define Y_HOME_POS MANUAL_Y_HOME_POS
#define Z_HOME_POS MANUAL_Z_HOME_POS
#else //!MANUAL_HOME_POSITIONS – Use home switch positions based on homing direction and travel limits
#if ENABLED(BED_CENTER_AT_0_0)
#define X_HOME_POS (X_MAX_LENGTH) * (X_HOME_DIR) * 0.5
#define Y_HOME_POS (Y_MAX_LENGTH) * (Y_HOME_DIR) * 0.5
#else
#define X_HOME_POS (X_HOME_DIR < 0 ? X_MIN_POS : X_MAX_POS)
#define Y_HOME_POS (Y_HOME_DIR < 0 ? Y_MIN_POS : Y_MAX_POS)
#endif
#define Z_HOME_POS (Z_HOME_DIR < 0 ? Z_MIN_POS : Z_MAX_POS)
#endif //!MANUAL_HOME_POSITIONS
/**
* Auto Bed Leveling
*/
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
// Boundaries for probing based on set limits
#define MIN_PROBE_X (max(X_MIN_POS, X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER))
#define MAX_PROBE_X (min(X_MAX_POS, X_MAX_POS + X_PROBE_OFFSET_FROM_EXTRUDER))
#define MIN_PROBE_Y (max(Y_MIN_POS, Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER))
#define MAX_PROBE_Y (min(Y_MAX_POS, Y_MAX_POS + Y_PROBE_OFFSET_FROM_EXTRUDER))
// Make sure probing points are reachable
#if LEFT_PROBE_BED_POSITION < MIN_PROBE_X
#undef LEFT_PROBE_BED_POSITION
#define LEFT_PROBE_BED_POSITION MIN_PROBE_X
#endif
#if RIGHT_PROBE_BED_POSITION > MAX_PROBE_X
#undef RIGHT_PROBE_BED_POSITION
#define RIGHT_PROBE_BED_POSITION MAX_PROBE_X
#endif
#if FRONT_PROBE_BED_POSITION < MIN_PROBE_Y
#undef FRONT_PROBE_BED_POSITION
#define FRONT_PROBE_BED_POSITION MIN_PROBE_Y
#endif
#if BACK_PROBE_BED_POSITION > MAX_PROBE_Y
#undef BACK_PROBE_BED_POSITION
#define BACK_PROBE_BED_POSITION MAX_PROBE_Y
#endif
/**
* ARRAY_BY_HOTENDS based on HOTENDS
*/
#if HOTENDS > 3
#define ARRAY_BY_HOTENDS(v1, v2, v3, v4) { v1, v2, v3, v4 }
#elif HOTENDS > 2
#define ARRAY_BY_HOTENDS(v1, v2, v3, v4) { v1, v2, v3 }
#elif HOTENDS > 1
#define ARRAY_BY_HOTENDS(v1, v2, v3, v4) { v1, v2 }
#else
#define ARRAY_BY_HOTENDS(v1, v2, v3, v4) { v1 }
#endif
#define ARRAY_BY_HOTENDS1(v1) ARRAY_BY_HOTENDS(v1, v1, v1, v1)
// Z_RAISE_AFTER_PROBING is not for all probes. Be sure that it is zero in that cases
#if DISABLED(ENABLE_SERVOS) && DISABLED(Z_PROBE_SLED)
#undef Z_RAISE_AFTER_PROBING
#define Z_RAISE_AFTER_PROBING 0
#endif
#endif
/**
* Shorthand for pin tests, used wherever needed
*/
#define HAS_TEMP_0 (PIN_EXISTS(TEMP_0) && TEMP_SENSOR_0 != 0 && TEMP_SENSOR_0 != -2)
#define HAS_TEMP_1 (PIN_EXISTS(TEMP_1) && TEMP_SENSOR_1 != 0)
#define HAS_TEMP_2 (PIN_EXISTS(TEMP_2) && TEMP_SENSOR_2 != 0)
#define HAS_TEMP_3 (PIN_EXISTS(TEMP_3) && TEMP_SENSOR_3 != 0)
#define HAS_TEMP_BED (PIN_EXISTS(TEMP_BED) && TEMP_SENSOR_BED != 0)
#define HAS_HEATER_0 (PIN_EXISTS(HEATER_0))
#define HAS_HEATER_1 (PIN_EXISTS(HEATER_1))
#define HAS_HEATER_2 (PIN_EXISTS(HEATER_2))
#define HAS_HEATER_3 (PIN_EXISTS(HEATER_3))
#define HAS_HEATER_BED (PIN_EXISTS(HEATER_BED))
#define HAS_AUTO_FAN_0 (ENABLED(EXTRUDER_AUTO_FAN) && PIN_EXISTS(EXTRUDER_0_AUTO_FAN))
#define HAS_AUTO_FAN_1 (ENABLED(EXTRUDER_AUTO_FAN) && PIN_EXISTS(EXTRUDER_1_AUTO_FAN))
#define HAS_AUTO_FAN_2 (ENABLED(EXTRUDER_AUTO_FAN) && PIN_EXISTS(EXTRUDER_2_AUTO_FAN))
#define HAS_AUTO_FAN_3 (ENABLED(EXTRUDER_AUTO_FAN) && PIN_EXISTS(EXTRUDER_3_AUTO_FAN))
#define HAS_AUTO_FAN (HAS_AUTO_FAN_0 || HAS_AUTO_FAN_1 || HAS_AUTO_FAN_2 || HAS_AUTO_FAN_3)
#define HAS_FAN (PIN_EXISTS(FAN))
#define HAS_CONTROLLERFAN (ENABLED(CONTROLLERFAN) && PIN_EXISTS(CONTROLLERFAN))
#define HAS_SERVO_0 (PIN_EXISTS(SERVO0))
#define HAS_SERVO_1 (PIN_EXISTS(SERVO1))
#define HAS_SERVO_2 (PIN_EXISTS(SERVO2))
#define HAS_SERVO_3 (PIN_EXISTS(SERVO3))
#define HAS_SERVOS ((ENABLED(ENABLE_SERVOS) && NUM_SERVOS > 0) && (HAS_SERVO_0 || HAS_SERVO_1 || HAS_SERVO_2 || HAS_SERVO_3))
#define HAS_FILAMENT_SENSOR (ENABLED(FILAMENT_SENSOR) && PIN_EXISTS(FILWIDTH))
#define HAS_POWER_CONSUMPTION_SENSOR (ENABLED(POWER_CONSUMPTION) && PIN_EXISTS(POWER_CONSUMPTION))
#define HAS_Z_PROBE_SLED (ENABLED(Z_PROBE_SLED) && PIN_EXISTS(SLED_PIN))
#define HAS_FILRUNOUT (ENABLED(FILAMENT_RUNOUT_SENSOR) && PIN_EXISTS(FILRUNOUT))
#define HAS_HOME (PIN_EXISTS(HOME))
#define HAS_KILL (PIN_EXISTS(KILL))
#define HAS_SUICIDE (PIN_EXISTS(SUICIDE))
#define HAS_CHDK (ENABLED(CHDK) && PIN_EXISTS(CHDK))
#define HAS_PHOTOGRAPH (ENABLED(PHOTOGRAPH) && PIN_EXISTS(PHOTOGRAPH))
#define HAS_X_MIN (PIN_EXISTS(X_MIN))
#define HAS_X_MAX (PIN_EXISTS(X_MAX))
#define HAS_Y_MIN (PIN_EXISTS(Y_MIN))
#define HAS_Y_MAX (PIN_EXISTS(Y_MAX))
#define HAS_Z_MIN (PIN_EXISTS(Z_MIN))
#define HAS_Z_MAX (PIN_EXISTS(Z_MAX))
#define HAS_Z2_MIN (PIN_EXISTS(Z2_MIN))
#define HAS_Z2_MAX (PIN_EXISTS(Z2_MAX))
#define HAS_Z_PROBE (ENABLED(Z_PROBE_ENDSTOP) && PIN_EXISTS(Z_PROBE))
#define HAS_E_MIN (PIN_EXISTS(E_MIN))
#define HAS_SOLENOID_1 (PIN_EXISTS(SOL1))
#define HAS_SOLENOID_2 (PIN_EXISTS(SOL2))
#define HAS_SOLENOID_3 (PIN_EXISTS(SOL3))
#define HAS_MICROSTEPS (ENABLED(USE_MICROSTEPS) && PIN_EXISTS(X_MS1))
#define HAS_MICROSTEPS_E0 (ENABLED(USE_MICROSTEPS) && PIN_EXISTS(E0_MS1))
#define HAS_MICROSTEPS_E1 (ENABLED(USE_MICROSTEPS) && PIN_EXISTS(E1_MS1))
#define HAS_MICROSTEPS_E2 (ENABLED(USE_MICROSTEPS) && PIN_EXISTS(E2_MS1))
#define HAS_STEPPER_RESET (PIN_EXISTS(STEPPER_RESET))
#define HAS_X_ENABLE (PIN_EXISTS(X_ENABLE))
#define HAS_X2_ENABLE (PIN_EXISTS(X2_ENABLE))
#define HAS_Y_ENABLE (PIN_EXISTS(Y_ENABLE))
#define HAS_Y2_ENABLE (PIN_EXISTS(Y2_ENABLE))
#define HAS_Z_ENABLE (PIN_EXISTS(Z_ENABLE))
#define HAS_Z2_ENABLE (PIN_EXISTS(Z2_ENABLE))
#define HAS_E0_ENABLE (PIN_EXISTS(E0_ENABLE))
#define HAS_E1_ENABLE (PIN_EXISTS(E1_ENABLE))
#define HAS_E2_ENABLE (PIN_EXISTS(E2_ENABLE))
#define HAS_E3_ENABLE (PIN_EXISTS(E3_ENABLE))
#define HAS_E4_ENABLE (PIN_EXISTS(E4_ENABLE))
#define HAS_E5_ENABLE (PIN_EXISTS(E5_ENABLE))
#define HAS_X_DIR (PIN_EXISTS(X_DIR))
#define HAS_X2_DIR (PIN_EXISTS(X2_DIR))
#define HAS_Y_DIR (PIN_EXISTS(Y_DIR))
#define HAS_Y2_DIR (PIN_EXISTS(Y2_DIR))
#define HAS_Z_DIR (PIN_EXISTS(Z_DIR))
#define HAS_Z2_DIR (PIN_EXISTS(Z2_DIR))
#define HAS_E0_DIR (PIN_EXISTS(E0_DIR))
#define HAS_E1_DIR (PIN_EXISTS(E1_DIR))
#define HAS_E2_DIR (PIN_EXISTS(E2_DIR))
#define HAS_E3_DIR (PIN_EXISTS(E3_DIR))
#define HAS_E4_DIR (PIN_EXISTS(E4_DIR))
#define HAS_E5_DIR (PIN_EXISTS(E5_DIR))
#define HAS_X_STEP (PIN_EXISTS(X_STEP))
#define HAS_X2_STEP (PIN_EXISTS(X2_STEP))
#define HAS_Y_STEP (PIN_EXISTS(Y_STEP))
#define HAS_Y2_STEP (PIN_EXISTS(Y2_STEP))
#define HAS_Z_STEP (PIN_EXISTS(Z_STEP))
#define HAS_Z2_STEP (PIN_EXISTS(Z2_STEP))
#define HAS_E0_STEP (PIN_EXISTS(E0_STEP))
#define HAS_E1_STEP (PIN_EXISTS(E1_STEP))
#define HAS_E2_STEP (PIN_EXISTS(E2_STEP))
#define HAS_E3_STEP (PIN_EXISTS(E3_STEP))
#define HAS_E4_STEP (PIN_EXISTS(E4_STEP))
#define HAS_E5_STEP (PIN_EXISTS(E5_STEP))
#define HAS_E0E1 (PIN_EXISTS(E0E1_CHOICE))
#define HAS_E0E2 (PIN_EXISTS(E0E2_CHOICE))
#define HAS_E0E3 (PIN_EXISTS(E0E3_CHOICE))
#define HAS_E0E4 (PIN_EXISTS(E0E4_CHOICE))
#define HAS_E0E5 (PIN_EXISTS(E0E5_CHOICE))
#define HAS_E1E3 (PIN_EXISTS(E1E3_CHOICE))
#define HAS_BTN_BACK (PIN_EXISTS(BTN_BACK))
#define HAS_POWER_SWITCH (POWER_SUPPLY > 0 && PIN_EXISTS(PS_ON))
#define HAS_MOTOR_CURRENT_PWM_XY (PIN_EXISTS(MOTOR_CURRENT_PWM_XY))
#define HAS_SDSUPPORT (ENABLED(SDSUPPORT))
#define HAS_DIGIPOTSS (PIN_EXISTS(DIGIPOTSS))
/**
* Sled Options
*/
#if ENABLED(Z_PROBE_SLED)
#define Z_SAFE_HOMING
#endif
/**
* Shorthand for filament sensor and power sensor for ultralcd.cpp, dogm_lcd_implementation.h, ultralcd_implementation_hitachi_HD44780.h
*/
#define HAS_LCD_FILAMENT_SENSOR (HAS_FILAMENT_SENSOR && ENABLED(FILAMENT_LCD_DISPLAY))
#define HAS_LCD_POWER_SENSOR (HAS_POWER_CONSUMPTION_SENSOR && ENABLED(POWER_CONSUMPTION_LCD_DISPLAY))
/**
* Avoid double-negatives for enabling features
*/
#if DISABLED(DISABLE_HOST_KEEPALIVE)
#define HOST_KEEPALIVE_FEATURE
#define DEFAULT_KEEPALIVE_INTERVAL 2
#endif
/**
* Helper Macros for heaters and extruder fan and rele
*/
#if ENABLED(INVERTED_HEATER_PINS)
#define WRITE_HEATER(pin, value) WRITE(pin, !value)
#else
#define WRITE_HEATER(pin, value) WRITE(pin, value)
#endif
#define WRITE_HEATER_0P(v) WRITE_HEATER(HEATER_0_PIN, v)
#if HOTENDS > 1 || ENABLED(HEATERS_PARALLEL)
#define WRITE_HEATER_1(v) WRITE_HEATER(HEATER_1_PIN, v)
#if HOTENDS > 2
#define WRITE_HEATER_2(v) WRITE_HEATER(HEATER_2_PIN, v)
#if HOTENDS > 3
#define WRITE_HEATER_3(v) WRITE_HEATER(HEATER_3_PIN, v)
#endif
#endif
#endif
#if ENABLED(HEATERS_PARALLEL)
#define WRITE_HEATER_0(v) { WRITE_HEATER_0P(v); WRITE_HEATER_1(v); }
#else
#define WRITE_HEATER_0(v) WRITE_HEATER_0P(v)
#endif
#if HAS(HEATER_BED)
#if ENABLED(INVERTED_BED_PINS)
#define WRITE_HEATER_BED(v) WRITE(HEATER_BED_PIN,!v)
/**
* MAX_STEP_FREQUENCY differs for TOSHIBA OR ARDUINO DUE OR ARDUINO MEGA
*/
#ifdef __SAM3X8E__
#if ENABLED(CONFIG_STEPPERS_TOSHIBA)
#define MAX_STEP_FREQUENCY 150000 // Max step frequency for Toshiba Stepper Controllers
#define DOUBLE_STEP_FREQUENCY MAX_STEP_FREQUENCY
#else
#define MAX_STEP_FREQUENCY 320000 // Max step frequency for the Due is approx. 330kHz
#define DOUBLE_STEP_FREQUENCY 90000 // 96kHz is close to maximum for an Arduino Due
#endif
#else
#define WRITE_HEATER_BED(v) WRITE(HEATER_BED_PIN,v)
#if ENABLED(CONFIG_STEPPERS_TOSHIBA)
#define MAX_STEP_FREQUENCY 10000 // Max step frequency for Toshiba Stepper Controllers
#define DOUBLE_STEP_FREQUENCY MAX_STEP_FREQUENCY
#else
#define MAX_STEP_FREQUENCY 40000 // Max step frequency for Arduino mega
#define DOUBLE_STEP_FREQUENCY 10000
#endif
#endif
#endif
#if HAS(FAN)
// MS1 MS2 Stepper Driver Microstepping mode table
#define MICROSTEP1 LOW,LOW
#define MICROSTEP2 HIGH,LOW
#define MICROSTEP4 LOW,HIGH
#define MICROSTEP8 HIGH,HIGH
#if MB(ALLIGATOR)
#define MICROSTEP16 LOW,LOW
#define MICROSTEP32 HIGH,HIGH
#else
#define MICROSTEP16 HIGH,HIGH
#endif
/**
* Advance calculated values
*/
#if ENABLED(ADVANCE)
#define EXTRUSION_AREA (0.25 * (D_FILAMENT) * (D_FILAMENT) * M_PI)
#define STEPS_PER_CUBIC_MM_E (axis_steps_per_unit[E_AXIS + active_extruder] / EXTRUSION_AREA)
#endif
/**
* SD DETECT
*
*/
#if ENABLED(SD_DISABLED_DETECT)
#undef SD_DETECT_PIN
#define SD_DETECT_PIN -1
#endif
#if ENABLED(ULTIPANEL) && DISABLED(ELB_FULL_GRAPHIC_CONTROLLER)
#undef SD_DETECT_INVERTED
#endif
/**
* Power Signal Control Definitions
* By default use Normal definition
*/
#if DISABLED(POWER_SUPPLY)
#define POWER_SUPPLY 0
#endif
#if (POWER_SUPPLY == 1) // 1 = ATX
#define PS_ON_AWAKE LOW
#define PS_ON_ASLEEP HIGH
#elif (POWER_SUPPLY == 2) // 2 = X-Box 360 203W
#define PS_ON_AWAKE HIGH
#define PS_ON_ASLEEP LOW
#endif
#define HAS_POWER_SWITCH (POWER_SUPPLY > 0 && PIN_EXISTS(PS_ON))
/**
* Temp Sensor defines
*/
#if TEMP_SENSOR_0 == -2
#define HEATER_0_USES_MAX6675
#elif TEMP_SENSOR_0 == -1
#define HEATER_0_USES_AD595
#elif TEMP_SENSOR_0 == 0
#undef HEATER_0_MINTEMP
#undef HEATER_0_MAXTEMP
#elif TEMP_SENSOR_0 > 0
#define THERMISTORHEATER_0 TEMP_SENSOR_0
#define HEATER_0_USES_THERMISTOR
#endif
#if TEMP_SENSOR_1 == -1
#define HEATER_1_USES_AD595
#elif TEMP_SENSOR_1 == 0
#undef HEATER_1_MINTEMP
#undef HEATER_1_MAXTEMP
#elif TEMP_SENSOR_1 > 0
#define THERMISTORHEATER_1 TEMP_SENSOR_1
#define HEATER_1_USES_THERMISTOR
#endif
#if TEMP_SENSOR_2 == -1
#define HEATER_2_USES_AD595
#elif TEMP_SENSOR_2 == 0
#undef HEATER_2_MINTEMP
#undef HEATER_2_MAXTEMP
#elif TEMP_SENSOR_2 > 0
#define THERMISTORHEATER_2 TEMP_SENSOR_2
#define HEATER_2_USES_THERMISTOR
#endif
#if TEMP_SENSOR_3 == -1
#define HEATER_3_USES_AD595
#elif TEMP_SENSOR_3 == 0
#undef HEATER_3_MINTEMP
#undef HEATER_3_MAXTEMP
#elif TEMP_SENSOR_3 > 0
#define THERMISTORHEATER_3 TEMP_SENSOR_3
#define HEATER_3_USES_THERMISTOR
#endif
#if TEMP_SENSOR_BED == -1
#define BED_USES_AD595
#elif TEMP_SENSOR_BED == 0
#undef BED_MINTEMP
#undef BED_MAXTEMP
#elif TEMP_SENSOR_BED > 0
#define THERMISTORBED TEMP_SENSOR_BED
#define BED_USES_THERMISTOR
#endif
#define HEATER_USES_AD595 (ENABLED(HEATER_0_USES_AD595) || ENABLED(HEATER_1_USES_AD595) || ENABLED(HEATER_2_USES_AD595) || ENABLED(HEATER_3_USES_AD595))
/**
* Flags for PID handling
*/
#define HAS_PID_HEATING (ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED))
#define HAS_PID_FOR_BOTH (ENABLED(PIDTEMP) && ENABLED(PIDTEMPBED))
/**
* ARRAY_BY_EXTRUDERS based on EXTRUDERS
*/
#if EXTRUDERS > 9
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1, v1, v1, v1, v1, v1, v1, v1, v1 }
#elif EXTRUDERS > 8
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1, v1, v1, v1, v1, v1, v1, v1 }
#elif EXTRUDERS > 7
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1, v1, v1, v1, v1, v1, v1 }
#elif EXTRUDERS > 6
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1, v1, v1, v1, v1, v1 }
#elif EXTRUDERS > 5
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1, v1, v1, v1, v1 }
#elif EXTRUDERS > 4
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1, v1, v1, v1 }
#elif EXTRUDERS > 3
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1, v1, v1 }
#elif EXTRUDERS > 2
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1, v1 }
#elif EXTRUDERS > 1
#define ARRAY_BY_EXTRUDERS(v1) { v1, v1 }
#else
#define ARRAY_BY_EXTRUDERS(v1) { v1 }
#endif
/**
* ARRAY_BY_HOTENDS based on HOTENDS
*/
#if HOTENDS > 3
#define ARRAY_BY_HOTENDS(v1, v2, v3, v4) { v1, v2, v3, v4 }
#elif HOTENDS > 2
#define ARRAY_BY_HOTENDS(v1, v2, v3, v4) { v1, v2, v3 }
#elif HOTENDS > 1
#define ARRAY_BY_HOTENDS(v1, v2, v3, v4) { v1, v2 }
#else
#define ARRAY_BY_HOTENDS(v1, v2, v3, v4) { v1 }
#endif
#define ARRAY_BY_HOTENDS1(v1) ARRAY_BY_HOTENDS(v1, v1, v1, v1)
/**
* Shorthand for pin tests, used wherever needed
*/
#define HAS_TEMP_0 (PIN_EXISTS(TEMP_0) && TEMP_SENSOR_0 != 0 && TEMP_SENSOR_0 != -2)
#define HAS_TEMP_1 (PIN_EXISTS(TEMP_1) && TEMP_SENSOR_1 != 0)
#define HAS_TEMP_2 (PIN_EXISTS(TEMP_2) && TEMP_SENSOR_2 != 0)
#define HAS_TEMP_3 (PIN_EXISTS(TEMP_3) && TEMP_SENSOR_3 != 0)
#define HAS_TEMP_BED (PIN_EXISTS(TEMP_BED) && TEMP_SENSOR_BED != 0)
#define HAS_HEATER_0 (PIN_EXISTS(HEATER_0))
#define HAS_HEATER_1 (PIN_EXISTS(HEATER_1))
#define HAS_HEATER_2 (PIN_EXISTS(HEATER_2))
#define HAS_HEATER_3 (PIN_EXISTS(HEATER_3))
#define HAS_HEATER_BED (PIN_EXISTS(HEATER_BED))
#define HAS_AUTO_FAN_0 (ENABLED(EXTRUDER_AUTO_FAN) && PIN_EXISTS(EXTRUDER_0_AUTO_FAN))
#define HAS_AUTO_FAN_1 (ENABLED(EXTRUDER_AUTO_FAN) && PIN_EXISTS(EXTRUDER_1_AUTO_FAN))
#define HAS_AUTO_FAN_2 (ENABLED(EXTRUDER_AUTO_FAN) && PIN_EXISTS(EXTRUDER_2_AUTO_FAN))
#define HAS_AUTO_FAN_3 (ENABLED(EXTRUDER_AUTO_FAN) && PIN_EXISTS(EXTRUDER_3_AUTO_FAN))
#define HAS_AUTO_FAN (HAS_AUTO_FAN_0 || HAS_AUTO_FAN_1 || HAS_AUTO_FAN_2 || HAS_AUTO_FAN_3)
#define HAS_FAN (PIN_EXISTS(FAN))
#define HAS_CONTROLLERFAN (ENABLED(CONTROLLERFAN) && PIN_EXISTS(CONTROLLERFAN))
#define HAS_SERVO_0 (PIN_EXISTS(SERVO0))
#define HAS_SERVO_1 (PIN_EXISTS(SERVO1))
#define HAS_SERVO_2 (PIN_EXISTS(SERVO2))
#define HAS_SERVO_3 (PIN_EXISTS(SERVO3))
#define HAS_SERVOS ((ENABLED(ENABLE_SERVOS) && NUM_SERVOS > 0) && (HAS_SERVO_0 || HAS_SERVO_1 || HAS_SERVO_2 || HAS_SERVO_3))
#define HAS_FILAMENT_SENSOR (ENABLED(FILAMENT_SENSOR) && PIN_EXISTS(FILWIDTH))
#define HAS_POWER_CONSUMPTION_SENSOR (ENABLED(POWER_CONSUMPTION) && PIN_EXISTS(POWER_CONSUMPTION))
#define HAS_Z_PROBE_SLED (ENABLED(Z_PROBE_SLED) && PIN_EXISTS(SLED_PIN))
#define HAS_FILRUNOUT (ENABLED(FILAMENT_RUNOUT_SENSOR) && PIN_EXISTS(FILRUNOUT))
#define HAS_HOME (PIN_EXISTS(HOME))
#define HAS_KILL (PIN_EXISTS(KILL))
#define HAS_SUICIDE (PIN_EXISTS(SUICIDE))
#define HAS_CHDK (ENABLED(CHDK) && PIN_EXISTS(CHDK))
#define HAS_PHOTOGRAPH (ENABLED(PHOTOGRAPH) && PIN_EXISTS(PHOTOGRAPH))
#define HAS_X_MIN (PIN_EXISTS(X_MIN))
#define HAS_X_MAX (PIN_EXISTS(X_MAX))
#define HAS_Y_MIN (PIN_EXISTS(Y_MIN))
#define HAS_Y_MAX (PIN_EXISTS(Y_MAX))
#define HAS_Z_MIN (PIN_EXISTS(Z_MIN))
#define HAS_Z_MAX (PIN_EXISTS(Z_MAX))
#define HAS_Z2_MIN (PIN_EXISTS(Z2_MIN))
#define HAS_Z2_MAX (PIN_EXISTS(Z2_MAX))
#define HAS_Z_PROBE (ENABLED(Z_PROBE_ENDSTOP) && PIN_EXISTS(Z_PROBE))
#define HAS_E_MIN (PIN_EXISTS(E_MIN))
#define HAS_SOLENOID_1 (PIN_EXISTS(SOL1))
#define HAS_SOLENOID_2 (PIN_EXISTS(SOL2))
#define HAS_SOLENOID_3 (PIN_EXISTS(SOL3))
#define HAS_MICROSTEPS (ENABLED(USE_MICROSTEPS) && PIN_EXISTS(X_MS1))
#define HAS_MICROSTEPS_E0 (ENABLED(USE_MICROSTEPS) && PIN_EXISTS(E0_MS1))
#define HAS_MICROSTEPS_E1 (ENABLED(USE_MICROSTEPS) && PIN_EXISTS(E1_MS1))
#define HAS_MICROSTEPS_E2 (ENABLED(USE_MICROSTEPS) && PIN_EXISTS(E2_MS1))
#define HAS_STEPPER_RESET (PIN_EXISTS(STEPPER_RESET))
#define HAS_X_ENABLE (PIN_EXISTS(X_ENABLE))
#define HAS_X2_ENABLE (PIN_EXISTS(X2_ENABLE))
#define HAS_Y_ENABLE (PIN_EXISTS(Y_ENABLE))
#define HAS_Y2_ENABLE (PIN_EXISTS(Y2_ENABLE))
#define HAS_Z_ENABLE (PIN_EXISTS(Z_ENABLE))
#define HAS_Z2_ENABLE (PIN_EXISTS(Z2_ENABLE))
#define HAS_E0_ENABLE (PIN_EXISTS(E0_ENABLE))
#define HAS_E1_ENABLE (PIN_EXISTS(E1_ENABLE))
#define HAS_E2_ENABLE (PIN_EXISTS(E2_ENABLE))
#define HAS_E3_ENABLE (PIN_EXISTS(E3_ENABLE))
#define HAS_E4_ENABLE (PIN_EXISTS(E4_ENABLE))
#define HAS_E5_ENABLE (PIN_EXISTS(E5_ENABLE))
#define HAS_X_DIR (PIN_EXISTS(X_DIR))
#define HAS_X2_DIR (PIN_EXISTS(X2_DIR))
#define HAS_Y_DIR (PIN_EXISTS(Y_DIR))
#define HAS_Y2_DIR (PIN_EXISTS(Y2_DIR))
#define HAS_Z_DIR (PIN_EXISTS(Z_DIR))
#define HAS_Z2_DIR (PIN_EXISTS(Z2_DIR))
#define HAS_E0_DIR (PIN_EXISTS(E0_DIR))
#define HAS_E1_DIR (PIN_EXISTS(E1_DIR))
#define HAS_E2_DIR (PIN_EXISTS(E2_DIR))
#define HAS_E3_DIR (PIN_EXISTS(E3_DIR))
#define HAS_E4_DIR (PIN_EXISTS(E4_DIR))
#define HAS_E5_DIR (PIN_EXISTS(E5_DIR))
#define HAS_X_STEP (PIN_EXISTS(X_STEP))
#define HAS_X2_STEP (PIN_EXISTS(X2_STEP))
#define HAS_Y_STEP (PIN_EXISTS(Y_STEP))
#define HAS_Y2_STEP (PIN_EXISTS(Y2_STEP))
#define HAS_Z_STEP (PIN_EXISTS(Z_STEP))
#define HAS_Z2_STEP (PIN_EXISTS(Z2_STEP))
#define HAS_E0_STEP (PIN_EXISTS(E0_STEP))
#define HAS_E1_STEP (PIN_EXISTS(E1_STEP))
#define HAS_E2_STEP (PIN_EXISTS(E2_STEP))
#define HAS_E3_STEP (PIN_EXISTS(E3_STEP))
#define HAS_E4_STEP (PIN_EXISTS(E4_STEP))
#define HAS_E5_STEP (PIN_EXISTS(E5_STEP))
#define HAS_E0E1 (PIN_EXISTS(E0E1_CHOICE))
#define HAS_E0E2 (PIN_EXISTS(E0E2_CHOICE))
#define HAS_E0E3 (PIN_EXISTS(E0E3_CHOICE))
#define HAS_E0E4 (PIN_EXISTS(E0E4_CHOICE))
#define HAS_E0E5 (PIN_EXISTS(E0E5_CHOICE))
#define HAS_E1E3 (PIN_EXISTS(E1E3_CHOICE))
#define HAS_BTN_BACK (PIN_EXISTS(BTN_BACK))
#define HAS_POWER_SWITCH (POWER_SUPPLY > 0 && PIN_EXISTS(PS_ON))
#define HAS_MOTOR_CURRENT_PWM_XY (PIN_EXISTS(MOTOR_CURRENT_PWM_XY))
#define HAS_SDSUPPORT (ENABLED(SDSUPPORT))
#define HAS_DIGIPOTSS (PIN_EXISTS(DIGIPOTSS))
/**
* Shorthand for filament sensor and power sensor for ultralcd.cpp, dogm_lcd_implementation.h, ultralcd_implementation_hitachi_HD44780.h
*/
#define HAS_LCD_FILAMENT_SENSOR (HAS_FILAMENT_SENSOR && ENABLED(FILAMENT_LCD_DISPLAY))
#define HAS_LCD_POWER_SENSOR (HAS_POWER_CONSUMPTION_SENSOR && ENABLED(POWER_CONSUMPTION_LCD_DISPLAY))
/**
* Helper Macros for heaters and extruder fan and rele
*/
#if ENABLED(INVERTED_HEATER_PINS)
#define WRITE_FAN(v) WRITE(FAN_PIN, !v)
#define WRITE_HEATER(pin, value) WRITE(pin, !value)
#else
#define WRITE_FAN(v) WRITE(FAN_PIN, v)
#define WRITE_HEATER(pin, value) WRITE(pin, value)
#endif
#define WRITE_HEATER_0P(v) WRITE_HEATER(HEATER_0_PIN, v)
#if HOTENDS > 1 || ENABLED(HEATERS_PARALLEL)
#define WRITE_HEATER_1(v) WRITE_HEATER(HEATER_1_PIN, v)
#if HOTENDS > 2
#define WRITE_HEATER_2(v) WRITE_HEATER(HEATER_2_PIN, v)
#if HOTENDS > 3
#define WRITE_HEATER_3(v) WRITE_HEATER(HEATER_3_PIN, v)
#endif
#endif
#endif
#endif
#if ENABLED(MKR4)
#if ENABLED(INVERTED_RELE_PINS)
#define WRITE_RELE(pin, value) WRITE(pin, !value)
#define OUT_WRITE_RELE(pin, value) OUT_WRITE(pin, !value)
#if ENABLED(HEATERS_PARALLEL)
#define WRITE_HEATER_0(v) { WRITE_HEATER_0P(v); WRITE_HEATER_1(v); }
#else
#define WRITE_RELE(pin, value) WRITE(pin, value)
#define OUT_WRITE_RELE(pin, value) OUT_WRITE(pin, value)
#endif
#endif
/**
* Buzzer
*/
#define HAS_BUZZER (PIN_EXISTS(BEEPER) || ENABLED(LCD_USE_I2C_BUZZER))
/**
* Servos
*/
#if HAS(SERVOS)
#ifndef X_ENDSTOP_SERVO_NR
#define X_ENDSTOP_SERVO_NR -1
#endif
#ifndef Y_ENDSTOP_SERVO_NR
#define Y_ENDSTOP_SERVO_NR -1
#define WRITE_HEATER_0(v) WRITE_HEATER_0P(v)
#endif
#ifndef Z_ENDSTOP_SERVO_NR
#define Z_ENDSTOP_SERVO_NR -1
#if HAS(HEATER_BED)
#if ENABLED(INVERTED_BED_PINS)
#define WRITE_HEATER_BED(v) WRITE(HEATER_BED_PIN,!v)
#else
#define WRITE_HEATER_BED(v) WRITE(HEATER_BED_PIN,v)
#endif
#endif
#ifndef SERVO_DEACTIVATION_DELAY
#define SERVO_DEACTIVATION_DELAY 300
#if HAS(FAN)
#if ENABLED(INVERTED_HEATER_PINS)
#define WRITE_FAN(v) WRITE(FAN_PIN, !v)
#else
#define WRITE_FAN(v) WRITE(FAN_PIN, v)
#endif
#endif
#if X_ENDSTOP_SERVO_NR >= 0 || Y_ENDSTOP_SERVO_NR >= 0 || Z_ENDSTOP_SERVO_NR >= 0
#define HAS_SERVO_ENDSTOPS true
#define SERVO_ENDSTOP_IDS { X_ENDSTOP_SERVO_NR, Y_ENDSTOP_SERVO_NR, Z_ENDSTOP_SERVO_NR }
#if ENABLED(MKR4)
#if ENABLED(INVERTED_RELE_PINS)
#define WRITE_RELE(pin, value) WRITE(pin, !value)
#define OUT_WRITE_RELE(pin, value) OUT_WRITE(pin, !value)
#else
#define WRITE_RELE(pin, value) WRITE(pin, value)
#define OUT_WRITE_RELE(pin, value) OUT_WRITE(pin, value)
#endif
#endif
#endif
/**
* Buzzer
*/
#define HAS_BUZZER (PIN_EXISTS(BEEPER) || ENABLED(LCD_USE_I2C_BUZZER))
/**
* The axis order in all axis related arrays is X, Y, Z, E
*/
#define NUM_AXIS 4
/**
* Servos
*/
#if HAS(SERVOS)
#ifndef X_ENDSTOP_SERVO_NR
#define X_ENDSTOP_SERVO_NR -1
#endif
#ifndef Y_ENDSTOP_SERVO_NR
#define Y_ENDSTOP_SERVO_NR -1
#endif
#ifndef Z_ENDSTOP_SERVO_NR
#define Z_ENDSTOP_SERVO_NR -1
#endif
#ifndef SERVO_DEACTIVATION_DELAY
#define SERVO_DEACTIVATION_DELAY 300
#endif
#if X_ENDSTOP_SERVO_NR >= 0 || Y_ENDSTOP_SERVO_NR >= 0 || Z_ENDSTOP_SERVO_NR >= 0
#define HAS_SERVO_ENDSTOPS true
#define SERVO_ENDSTOP_IDS { X_ENDSTOP_SERVO_NR, Y_ENDSTOP_SERVO_NR, Z_ENDSTOP_SERVO_NR }
#endif
#endif
/**
* The axis order in all axis related arrays is X, Y, Z, E
*/
#define NUM_AXIS 4
#endif //CONDITIONALS_H
/**
* Tools for firmware test
* By MagoKimbra
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "../../base.h"
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef FIRMWARE_TEST_H
#define FIRMWARE_TEST_H
void FirmwareTest();
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef LANGUAGE_H
#define LANGUAGE_H
......@@ -28,9 +50,6 @@
// 18 Japanese utf
// 19 Chinese
#define STRINGIFY_(n) #n
#define STRINGIFY(n) STRINGIFY_(n)
#define PROTOCOL_VERSION "2.0"
#if MB(ULTIMAKER)|| MB(ULTIMAKER_OLD)|| MB(ULTIMAIN_2)
......@@ -101,13 +120,16 @@
#define SERIAL_COUNT_X " Count X: "
#define SERIAL_ERR_KILLED "Printer halted. kill() called!"
#define SERIAL_ERR_STOPPED "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"
#define SERIAL_BUSY_PROCESSING "processing"
#define SERIAL_BUSY_PAUSED_FOR_USER "paused for user"
#define SERIAL_BUSY_PAUSED_FOR_INPUT "paused for input"
#define SERIAL_UNKNOWN_COMMAND "Unknown command: \""
#define SERIAL_ACTIVE_DRIVER "Active Driver: "
#define SERIAL_ACTIVE_EXTRUDER "Active Extruder: "
#define SERIAL_ACTIVE_COLOR "Active Color: "
#define MSG_COUNT_X " Count X:"
#define MSG_COUNT_A " Count A:"
#define MSG_COUNT_ALPHA " Count Alpha:"
#define SERIAL_COUNT_X " Count X:"
#define SERIAL_COUNT_A " Count A:"
#define SERIAL_COUNT_ALPHA " Count Alpha:"
#define SERIAL_X_MIN "x_min: "
#define SERIAL_X_MAX "x_max: "
#define SERIAL_Y_MIN "y_min: "
......@@ -155,6 +177,7 @@
#define SERIAL_ENDSTOPS_HIT "endstops hit: "
#define SERIAL_ERR_COLD_EXTRUDE_STOP "cold extrusion prevented"
#define SERIAL_ERR_LONG_EXTRUDE_STOP "too long extrusion prevented"
#define SERIAL_MICROSTEP_MS1_MS2 "MS1,MS2 Pins"
#define SERIAL_MICROSTEP_X "X:"
#define SERIAL_MICROSTEP_Y "Y:"
......@@ -178,14 +201,14 @@
#define SERIAL_KU " Ku: "
#define SERIAL_TU " Tu: "
#define SERIAL_CLASSIC_PID " Classic PID "
#define SERIAL_KP "Kp: "
#define SERIAL_KP " Kp: "
#define SERIAL_KI " Ki: "
#define SERIAL_KD " Kd: "
#define SERIAL_B "B:"
#define SERIAL_T "T:"
#define SERIAL_AT "@"
#define SERIAL_BAT "B@:"
#define SERIAL_W "W:"
#define SERIAL_T " T:"
#define SERIAL_B " B:"
#define SERIAL_AT " @"
#define SERIAL_BAT " B@:"
#define SERIAL_W " W:"
#define SERIAL_PID_AUTOTUNE_FINISHED SERIAL_PID_AUTOTUNE " finished! Put the last Kp, Ki and Kd constants from above into Configuration.h or send command M500 for save in EEPROM the new value!"
#define SERIAL_PID_DEBUG " PID_DEBUG "
#define SERIAL_PID_DEBUG_INPUT ": Input "
......@@ -212,11 +235,14 @@
#define SERIAL_ENDSTOP_PROBE " PROBE="
// Debug
#define SERIAL_DEBUG_ECHO "DEBUG ECHO ENABLED"
#define SERIAL_DEBUG_INFO "DEBUG INFO ENABLED"
#define SERIAL_DEBUG_ERRORS "DEBUG ERRORS ENABLED"
#define SERIAL_DEBUG_DRYRUN "DEBUG DRYRUN ENABLED"
#define SERIAL_DEBUG "DEBUG ENABLED"
#define SERIAL_DEBUG_PREFIX "DEBUG:"
#define SERIAL_DEBUG_OFF "off"
#define SERIAL_DEBUG_ECHO "ECHO"
#define SERIAL_DEBUG_INFO "INFO"
#define SERIAL_DEBUG_ERRORS "ERRORS"
#define SERIAL_DEBUG_DRYRUN "DRYRUN"
#define SERIAL_DEBUG_COMMUNICATION "COMMUNICATION"
#define SERIAL_DEBUG_DEBUG "DEBUG"
//other
#define SERIAL_ERR_HOMING_DIV "The Homing Bump Feedrate Divisor cannot be less than 1"
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "../../base.h"
#if HAS(BUZZER)
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef BUZZER_H
#define BUZZER_H
......
// BitMap for splashscreen
// Generated with: http://www.digole.com/tools/PicturetoC_Hex_converter.php
// Please note that using the high-res version takes 402Bytes of PROGMEM.
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* BitMap for splashscreen
* Generated with: http://www.digole.com/tools/PicturetoC_Hex_converter.php
* Please note that using the high-res version takes 402Bytes of PROGMEM.
*/
#define START_BMPHIGH
#if ENABLED(SHOW_BOOTSCREEN)
......
/*
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
Fontname: -Misc-Fixed-Medium-R-Normal--9-90-75-75-C-60-ISO10646-1
Copyright: Public domain font. Share and enjoy.
Capital A Height: 6, '1' Height: 6
......
/*
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
Fontname: HD44780_C v1.2
Copyright: A. Hardtung, public domain
Capital A Height: 7, '1' Height: 7
......
/*
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
Fontname: HD44780_J
Copyright: A. Hardtung, public domain
Capital A Height: 7, '1' Height: 7
Calculated Max Values w= 6 h=10 x= 2 y= 8 dx= 6 dy= 0 ascent= 8 len= 8
Calculated Max Values w= 6 h=10 x= 2 y= 5 dx= 6 dy= 0 ascent= 8 len= 8
Font Bounding box w= 6 h= 9 x= 0 y=-2
Calculated Min Values x= 0 y=-2 dx= 0 dy= 0
Pure Font ascent = 7 descent=-1
......@@ -10,9 +32,9 @@
Max Font ascent = 8 descent=-2
*/
#include <U8glib.h>
const u8g_fntpgm_uint8_t HD44780_J_5x7[2491] U8G_SECTION(".progmem.HD44780_J_5x7") = {
const u8g_fntpgm_uint8_t HD44780_J_5x7[2492] U8G_SECTION(".progmem.HD44780_J_5x7") = {
0, 6, 9, 0, 254, 7, 1, 145, 3, 34, 32, 255, 255, 8, 254, 7,
255, 0, 0, 0, 6, 0, 8, 1, 7, 7, 6, 2, 0, 128, 128, 128,
255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128,
128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6,
0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32,
120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32,
......@@ -84,19 +106,19 @@ const u8g_fntpgm_uint8_t HD44780_J_5x7[2491] U8G_SECTION(".progmem.HD44780_J_5x7
128, 64, 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128,
128, 3, 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 5,
5, 6, 0, 1, 32, 16, 248, 16, 32, 5, 5, 5, 6, 0, 1, 32,
64, 248, 64, 32, 0, 0, 0, 6, 0, 8, 0, 0, 0, 6, 0, 8,
0, 0, 0, 6, 0, 8, 0, 0, 0, 6, 0, 8, 0, 0, 0, 6,
0, 8, 0, 0, 0, 6, 0, 8, 0, 0, 0, 6, 0, 8, 0, 0,
0, 6, 0, 8, 0, 0, 0, 6, 0, 8, 0, 0, 0, 6, 0, 8,
0, 0, 0, 6, 0, 8, 0, 0, 0, 6, 0, 8, 0, 0, 0, 6,
0, 8, 0, 0, 0, 6, 0, 8, 0, 0, 0, 6, 0, 8, 0, 0,
0, 6, 0, 8, 0, 0, 0, 6, 0, 8, 0, 0, 0, 6, 0, 8,
0, 0, 0, 6, 0, 8, 0, 0, 0, 6, 0, 8, 0, 0, 0, 6,
0, 8, 0, 0, 0, 6, 0, 8, 0, 0, 0, 6, 0, 8, 0, 0,
0, 6, 0, 8, 0, 0, 0, 6, 0, 8, 0, 0, 0, 6, 0, 8,
0, 0, 0, 6, 0, 8, 0, 0, 0, 6, 0, 8, 0, 0, 0, 6,
0, 8, 0, 0, 0, 6, 0, 8, 0, 0, 0, 6, 0, 8, 0, 0,
0, 6, 0, 8, 0, 0, 0, 6, 0, 8, 3, 3, 3, 6, 0, 0,
64, 248, 64, 32, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0,
0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6,
0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0,
0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6,
0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0,
0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6,
0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0,
0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6,
0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 3, 3, 3, 6, 0, 0,
224, 160, 224, 3, 4, 4, 6, 2, 3, 224, 128, 128, 128, 3, 4, 4,
6, 0, 0, 32, 32, 32, 224, 3, 3, 3, 6, 0, 0, 128, 64, 32,
2, 2, 2, 6, 1, 2, 192, 192, 5, 6, 6, 6, 0, 0, 248, 8,
......@@ -106,7 +128,7 @@ const u8g_fntpgm_uint8_t HD44780_J_5x7[2491] U8G_SECTION(".progmem.HD44780_J_5x7
5, 5, 6, 0, 0, 16, 248, 48, 80, 144, 5, 5, 5, 6, 0, 0,
64, 248, 72, 80, 64, 5, 4, 4, 6, 0, 0, 112, 16, 16, 248, 4,
5, 5, 6, 0, 0, 240, 16, 240, 16, 240, 5, 4, 4, 6, 0, 0,
168, 168, 8, 48, 5, 1, 1, 6, 0, 4, 248, 5, 7, 7, 6, 0,
168, 168, 8, 48, 5, 1, 1, 6, 0, 3, 248, 5, 7, 7, 6, 0,
0, 248, 8, 40, 48, 32, 32, 64, 5, 7, 7, 6, 0, 0, 8, 16,
32, 96, 160, 32, 32, 5, 7, 7, 6, 0, 0, 32, 248, 136, 136, 8,
16, 32, 5, 6, 6, 6, 0, 0, 248, 32, 32, 32, 32, 248, 5, 7,
......@@ -124,47 +146,47 @@ const u8g_fntpgm_uint8_t HD44780_J_5x7[2491] U8G_SECTION(".progmem.HD44780_J_5x7
6, 0, 0, 112, 0, 248, 32, 32, 32, 64, 3, 7, 7, 6, 1, 0,
128, 128, 128, 192, 160, 128, 128, 5, 7, 7, 6, 0, 0, 32, 32, 248,
32, 32, 64, 128, 5, 6, 6, 6, 0, 0, 112, 0, 0, 0, 0, 248,
5, 6, 6, 6, 0, 0, 248, 8, 80, 32, 80, 128, 5, 6, 6, 6,
0, 1, 32, 248, 16, 32, 112, 168, 3, 7, 7, 6, 1, 0, 32, 32,
32, 32, 32, 64, 128, 5, 6, 6, 6, 0, 0, 32, 16, 136, 136, 136,
136, 5, 7, 7, 6, 0, 0, 128, 128, 248, 128, 128, 128, 120, 5, 6,
6, 6, 0, 0, 248, 8, 8, 8, 16, 96, 5, 5, 5, 6, 0, 1,
64, 160, 16, 8, 8, 5, 7, 7, 6, 0, 0, 32, 248, 32, 32, 168,
168, 32, 5, 6, 6, 6, 0, 0, 248, 8, 8, 80, 32, 16, 4, 6,
6, 6, 1, 0, 224, 0, 224, 0, 224, 16, 5, 6, 6, 6, 0, 0,
32, 64, 128, 136, 248, 8, 5, 6, 6, 6, 0, 0, 8, 8, 80, 32,
80, 128, 5, 6, 6, 6, 0, 0, 248, 64, 248, 64, 64, 56, 5, 7,
7, 6, 0, 0, 64, 64, 248, 72, 80, 64, 64, 5, 7, 7, 6, 0,
0, 112, 16, 16, 16, 16, 16, 248, 5, 6, 6, 6, 0, 0, 248, 8,
248, 8, 8, 248, 5, 7, 7, 6, 0, 0, 112, 0, 248, 8, 8, 16,
32, 4, 7, 7, 6, 0, 0, 144, 144, 144, 144, 16, 32, 64, 5, 6,
6, 6, 0, 0, 32, 160, 160, 168, 168, 176, 5, 7, 7, 6, 0, 0,
128, 128, 128, 136, 144, 160, 192, 5, 6, 6, 6, 0, 0, 248, 136, 136,
136, 136, 248, 5, 6, 6, 6, 0, 0, 248, 136, 136, 8, 16, 32, 5,
6, 6, 6, 0, 0, 192, 0, 8, 8, 16, 224, 4, 3, 3, 6, 0,
4, 32, 144, 64, 3, 3, 3, 6, 0, 4, 224, 160, 224, 5, 5, 5,
6, 0, 1, 72, 168, 144, 144, 104, 5, 7, 7, 6, 0, 0, 80, 0,
112, 8, 120, 136, 120, 4, 8, 8, 6, 1, 255, 96, 144, 144, 224, 144,
144, 224, 128, 5, 5, 5, 6, 0, 0, 112, 128, 96, 136, 112, 5, 6,
6, 6, 0, 255, 136, 136, 152, 232, 136, 128, 5, 5, 5, 6, 0, 0,
120, 160, 144, 136, 112, 5, 7, 7, 6, 0, 254, 48, 72, 136, 136, 240,
128, 128, 5, 8, 8, 6, 0, 254, 120, 136, 136, 136, 120, 8, 8, 112,
5, 5, 5, 6, 0, 1, 56, 32, 32, 160, 64, 4, 3, 3, 6, 0,
3, 16, 208, 16, 4, 8, 8, 6, 0, 255, 16, 0, 48, 16, 16, 16,
144, 96, 3, 3, 3, 6, 0, 4, 160, 64, 160, 5, 7, 7, 6, 0,
0, 32, 112, 160, 160, 168, 112, 32, 5, 7, 7, 6, 0, 0, 64, 64,
224, 64, 224, 64, 120, 5, 7, 7, 6, 0, 0, 112, 0, 176, 200, 136,
136, 136, 5, 7, 7, 6, 0, 0, 80, 0, 112, 136, 136, 136, 112, 5,
7, 7, 6, 0, 255, 176, 200, 136, 136, 240, 128, 128, 5, 7, 7, 6,
0, 255, 104, 152, 136, 136, 120, 8, 8, 5, 6, 6, 6, 0, 0, 112,
136, 248, 136, 136, 112, 5, 3, 3, 6, 0, 2, 88, 168, 208, 5, 5,
5, 6, 0, 0, 112, 136, 136, 80, 216, 5, 7, 7, 6, 0, 0, 80,
0, 136, 136, 136, 152, 104, 5, 7, 7, 6, 0, 0, 248, 128, 64, 32,
64, 128, 248, 5, 5, 5, 6, 0, 0, 248, 80, 80, 80, 152, 5, 7,
7, 6, 0, 0, 248, 0, 136, 80, 32, 80, 136, 5, 7, 7, 6, 0,
255, 136, 136, 136, 136, 120, 8, 112, 5, 6, 6, 6, 0, 1, 8, 240,
32, 248, 32, 32, 5, 5, 5, 6, 0, 0, 248, 64, 120, 72, 136, 5,
5, 5, 6, 0, 0, 248, 168, 248, 136, 136, 5, 5, 5, 6, 0, 1,
32, 0, 248, 0, 32, 0, 0, 0, 6, 0, 8, 6, 10, 10, 6, 0,
254, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252
5, 6, 6, 6, 0, 0, 248, 8, 80, 32, 80, 128, 5, 7, 7, 6,
0, 0, 32, 248, 16, 32, 112, 168, 32, 3, 7, 7, 6, 1, 0, 32,
32, 32, 32, 32, 64, 128, 5, 6, 6, 6, 0, 0, 32, 16, 136, 136,
136, 136, 5, 7, 7, 6, 0, 0, 128, 128, 248, 128, 128, 128, 120, 5,
6, 6, 6, 0, 0, 248, 8, 8, 8, 16, 96, 5, 5, 5, 6, 0,
1, 64, 160, 16, 8, 8, 5, 7, 7, 6, 0, 0, 32, 248, 32, 32,
168, 168, 32, 5, 6, 6, 6, 0, 0, 248, 8, 8, 80, 32, 16, 4,
6, 6, 6, 1, 0, 224, 0, 224, 0, 224, 16, 5, 6, 6, 6, 0,
0, 32, 64, 128, 136, 248, 8, 5, 6, 6, 6, 0, 0, 8, 8, 80,
32, 80, 128, 5, 6, 6, 6, 0, 0, 248, 64, 248, 64, 64, 56, 5,
7, 7, 6, 0, 0, 64, 64, 248, 72, 80, 64, 64, 5, 7, 7, 6,
0, 0, 112, 16, 16, 16, 16, 16, 248, 5, 6, 6, 6, 0, 0, 248,
8, 248, 8, 8, 248, 5, 7, 7, 6, 0, 0, 112, 0, 248, 8, 8,
16, 32, 4, 7, 7, 6, 0, 0, 144, 144, 144, 144, 16, 32, 64, 5,
6, 6, 6, 0, 0, 32, 160, 160, 168, 168, 176, 5, 7, 7, 6, 0,
0, 128, 128, 128, 136, 144, 160, 192, 5, 6, 6, 6, 0, 0, 248, 136,
136, 136, 136, 248, 5, 6, 6, 6, 0, 0, 248, 136, 136, 8, 16, 32,
5, 6, 6, 6, 0, 0, 192, 0, 8, 8, 16, 224, 4, 3, 3, 6,
0, 4, 32, 144, 64, 3, 3, 3, 6, 0, 4, 224, 160, 224, 5, 5,
5, 6, 0, 1, 72, 168, 144, 144, 104, 5, 7, 7, 6, 0, 0, 80,
0, 112, 8, 120, 136, 120, 4, 8, 8, 6, 1, 255, 96, 144, 144, 224,
144, 144, 224, 128, 5, 5, 5, 6, 0, 0, 112, 128, 96, 136, 112, 5,
6, 6, 6, 0, 255, 136, 136, 152, 232, 136, 128, 5, 5, 5, 6, 0,
0, 120, 160, 144, 136, 112, 5, 7, 7, 6, 0, 254, 48, 72, 136, 136,
240, 128, 128, 5, 8, 8, 6, 0, 254, 120, 136, 136, 136, 120, 8, 8,
112, 5, 5, 5, 6, 0, 1, 56, 32, 32, 160, 64, 4, 3, 3, 6,
0, 3, 16, 208, 16, 4, 8, 8, 6, 0, 255, 16, 0, 48, 16, 16,
16, 144, 96, 3, 3, 3, 6, 0, 4, 160, 64, 160, 5, 7, 7, 6,
0, 0, 32, 112, 160, 160, 168, 112, 32, 5, 7, 7, 6, 0, 0, 64,
64, 224, 64, 224, 64, 120, 5, 7, 7, 6, 0, 0, 112, 0, 176, 200,
136, 136, 136, 5, 7, 7, 6, 0, 0, 80, 0, 112, 136, 136, 136, 112,
5, 7, 7, 6, 0, 255, 176, 200, 136, 136, 240, 128, 128, 5, 7, 7,
6, 0, 255, 104, 152, 136, 136, 120, 8, 8, 5, 6, 6, 6, 0, 0,
112, 136, 248, 136, 136, 112, 5, 3, 3, 6, 0, 2, 88, 168, 208, 5,
5, 5, 6, 0, 0, 112, 136, 136, 80, 216, 5, 7, 7, 6, 0, 0,
80, 0, 136, 136, 136, 152, 104, 5, 7, 7, 6, 0, 0, 248, 128, 64,
32, 64, 128, 248, 5, 5, 5, 6, 0, 0, 248, 80, 80, 80, 152, 5,
7, 7, 6, 0, 0, 248, 0, 136, 80, 32, 80, 136, 5, 7, 7, 6,
0, 255, 136, 136, 136, 136, 120, 8, 112, 5, 6, 6, 6, 0, 0, 8,
240, 32, 248, 32, 32, 5, 5, 5, 6, 0, 0, 248, 64, 120, 72, 136,
5, 5, 5, 6, 0, 0, 248, 168, 248, 136, 136, 5, 5, 5, 6, 0,
1, 32, 0, 248, 0, 32, 0, 0, 0, 6, 0, 0, 6, 10, 10, 6,
0, 254, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252
};
/*
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
Fontname: HD44780_W
Copyright: A.Hardtung, public domain
Capital A Height: 7, '1' Height: 7
......
/*
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
Fontname: ISO10646-1
Copyright: A.Hardtung, public domain
Capital A Height: 7, '1' Height: 7
......
/*
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
Fontname: ISO10646_5_Cyrillic
Copyright: A. Hardtung, public domain
Capital A Height: 7, '1' Height: 7
......
/*
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
Fontname: ISO10646_Kana
Copyright: A. Hardtung, public domain
Capital A Height: 7, '1' Height: 7
Calculated Max Values w= 5 h= 9 x= 2 y= 5 dx= 6 dy= 0 ascent= 8 len= 9
Calculated Max Values w= 5 h= 8 x= 2 y= 5 dx= 6 dy= 0 ascent= 8 len= 8
Font Bounding box w= 6 h= 9 x= 0 y=-2
Calculated Min Values x= 0 y=-1 dx= 0 dy= 0
Pure Font ascent = 7 descent=-1
......@@ -10,7 +32,7 @@
Max Font ascent = 8 descent=-1
*/
#include <U8glib.h>
const u8g_fntpgm_uint8_t ISO10646_Kana_5x7[2549] U8G_SECTION(".progmem.ISO10646_Kana_5x7") = {
const u8g_fntpgm_uint8_t ISO10646_Kana_5x7[2482] U8G_SECTION(".progmem.ISO10646_Kana_5x7") = {
0, 6, 9, 0, 254, 7, 1, 145, 3, 32, 32, 255, 255, 8, 255, 7,
255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128,
128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6,
......@@ -95,80 +117,76 @@ const u8g_fntpgm_uint8_t ISO10646_Kana_5x7[2549] U8G_SECTION(".progmem.ISO10646_
0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0,
0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6,
0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 5, 3, 3, 6, 0, 2,
248, 0, 248, 5, 6, 6, 6, 0, 0, 248, 8, 40, 48, 32, 64, 5,
7, 7, 6, 0, 0, 248, 8, 40, 48, 32, 32, 64, 4, 5, 5, 6,
0, 0, 16, 32, 96, 160, 32, 5, 7, 7, 6, 0, 0, 8, 16, 32,
96, 160, 32, 32, 5, 5, 5, 6, 0, 0, 32, 248, 136, 8, 48, 5,
7, 7, 6, 0, 0, 32, 248, 136, 136, 8, 16, 32, 5, 4, 4, 6,
0, 0, 248, 32, 32, 248, 5, 6, 6, 6, 0, 0, 248, 32, 32, 32,
32, 248, 5, 5, 5, 6, 0, 0, 16, 248, 48, 80, 144, 5, 7, 7,
6, 0, 0, 16, 248, 16, 48, 80, 144, 16, 5, 5, 5, 6, 0, 0,
64, 248, 72, 80, 64, 5, 7, 7, 6, 0, 0, 40, 0, 64, 248, 72,
80, 64, 5, 7, 7, 6, 0, 0, 32, 248, 32, 248, 32, 32, 32, 5,
8, 8, 6, 0, 0, 40, 0, 32, 248, 32, 248, 32, 32, 4, 6, 6,
6, 0, 0, 64, 112, 144, 16, 16, 32, 5, 8, 8, 6, 0, 0, 40,
0, 64, 112, 144, 16, 16, 32, 5, 6, 6, 6, 0, 0, 64, 120, 144,
16, 16, 32, 5, 8, 8, 6, 0, 0, 40, 0, 64, 120, 144, 16, 16,
32, 5, 5, 5, 6, 0, 0, 248, 8, 8, 8, 248, 5, 7, 7, 6,
0, 0, 40, 0, 248, 8, 8, 8, 248, 5, 7, 7, 6, 0, 255, 80,
248, 80, 80, 16, 32, 64, 5, 9, 9, 6, 0, 255, 40, 0, 80, 248,
80, 80, 16, 32, 64, 5, 6, 6, 6, 0, 0, 192, 8, 200, 8, 16,
224, 5, 8, 8, 6, 0, 0, 40, 0, 192, 8, 200, 8, 16, 224, 5,
6, 6, 6, 0, 0, 248, 8, 16, 32, 80, 136, 5, 8, 8, 6, 0,
0, 40, 0, 248, 8, 16, 32, 80, 136, 5, 6, 6, 6, 0, 0, 64,
248, 72, 80, 64, 120, 5, 8, 8, 6, 0, 0, 40, 0, 64, 248, 72,
80, 64, 120, 4, 4, 4, 6, 0, 1, 16, 208, 16, 224, 5, 7, 7,
6, 0, 0, 40, 0, 8, 200, 8, 16, 224, 5, 7, 7, 6, 0, 255,
32, 120, 136, 40, 16, 40, 64, 5, 9, 9, 6, 0, 255, 40, 0, 32,
120, 136, 40, 16, 40, 64, 5, 6, 6, 6, 0, 0, 240, 32, 248, 32,
64, 128, 5, 8, 8, 6, 0, 0, 40, 0, 240, 32, 248, 32, 64, 128,
4, 5, 5, 6, 0, 1, 192, 16, 208, 16, 224, 5, 6, 6, 6, 0,
0, 192, 8, 200, 8, 16, 224, 5, 8, 8, 6, 0, 0, 40, 0, 192,
8, 200, 8, 16, 224, 5, 6, 6, 6, 0, 0, 112, 0, 248, 32, 32,
64, 5, 8, 8, 6, 0, 0, 40, 0, 112, 0, 248, 32, 32, 64, 3,
7, 7, 6, 1, 0, 128, 128, 128, 192, 160, 128, 128, 4, 8, 8, 6,
1, 0, 80, 0, 128, 128, 192, 160, 128, 128, 5, 7, 7, 6, 0, 0,
32, 32, 248, 32, 32, 64, 128, 5, 6, 6, 6, 0, 0, 112, 0, 0,
0, 0, 248, 5, 6, 6, 6, 0, 0, 248, 8, 80, 32, 80, 128, 5,
7, 7, 6, 0, 255, 32, 248, 8, 16, 32, 112, 168, 3, 7, 7, 6,
1, 0, 32, 32, 32, 32, 32, 64, 128, 5, 5, 5, 6, 0, 0, 16,
136, 136, 136, 136, 5, 7, 7, 6, 0, 0, 40, 0, 16, 136, 136, 136,
136, 5, 8, 8, 6, 0, 0, 24, 24, 0, 16, 136, 136, 136, 136, 5,
7, 7, 6, 0, 0, 128, 128, 248, 128, 128, 128, 120, 5, 8, 8, 6,
0, 0, 40, 128, 128, 248, 128, 128, 128, 120, 5, 8, 8, 6, 0, 0,
24, 152, 128, 248, 128, 128, 128, 120, 5, 6, 6, 6, 0, 0, 248, 8,
8, 8, 16, 96, 5, 8, 8, 6, 0, 0, 40, 0, 248, 8, 8, 8,
16, 96, 5, 8, 8, 6, 0, 0, 24, 24, 248, 8, 8, 8, 16, 96,
5, 5, 5, 6, 0, 1, 64, 160, 16, 8, 8, 5, 7, 7, 6, 0,
1, 40, 0, 64, 160, 16, 8, 8, 5, 7, 7, 6, 0, 1, 24, 24,
64, 160, 16, 8, 8, 5, 6, 6, 6, 0, 0, 32, 248, 32, 32, 168,
168, 5, 8, 8, 6, 0, 0, 40, 0, 32, 248, 32, 32, 168, 168, 5,
8, 8, 6, 0, 0, 24, 24, 32, 248, 32, 32, 168, 168, 5, 6, 6,
6, 0, 0, 248, 8, 8, 80, 32, 16, 4, 6, 6, 6, 1, 0, 224,
0, 224, 0, 224, 16, 5, 6, 6, 6, 0, 0, 32, 64, 128, 144, 248,
8, 5, 6, 6, 6, 0, 0, 8, 8, 80, 32, 80, 128, 5, 6, 6,
6, 0, 0, 120, 32, 248, 32, 32, 56, 5, 7, 7, 6, 0, 0, 64,
64, 248, 72, 80, 64, 64, 5, 7, 7, 6, 0, 0, 64, 248, 72, 80,
64, 64, 64, 5, 5, 5, 6, 0, 0, 112, 16, 16, 16, 248, 5, 7,
7, 6, 0, 0, 112, 16, 16, 16, 16, 16, 248, 4, 5, 5, 6, 1,
0, 240, 16, 240, 16, 240, 5, 7, 7, 6, 0, 0, 248, 8, 8, 248,
8, 8, 248, 5, 6, 6, 6, 0, 0, 112, 0, 248, 8, 16, 32, 3,
6, 6, 6, 1, 0, 160, 160, 160, 160, 32, 64, 5, 6, 6, 6, 0,
0, 80, 80, 80, 80, 88, 144, 4, 6, 6, 6, 1, 0, 128, 128, 128,
144, 160, 192, 5, 6, 6, 6, 0, 0, 248, 136, 136, 136, 248, 136, 5,
5, 5, 6, 0, 0, 248, 136, 8, 16, 96, 5, 6, 6, 6, 0, 0,
248, 136, 8, 8, 16, 96, 5, 6, 6, 6, 0, 0, 16, 248, 80, 80,
248, 16, 5, 6, 6, 6, 0, 0, 248, 8, 80, 96, 64, 248, 5, 6,
6, 6, 0, 0, 248, 8, 248, 8, 16, 32, 5, 6, 6, 6, 0, 0,
128, 64, 8, 8, 16, 224, 5, 8, 8, 6, 0, 0, 40, 0, 32, 248,
136, 8, 24, 32, 5, 6, 6, 6, 0, 0, 64, 248, 72, 72, 136, 144,
4, 5, 5, 6, 1, 0, 128, 240, 160, 32, 32, 5, 8, 8, 6, 0,
0, 40, 0, 248, 136, 8, 8, 16, 96, 5, 8, 8, 6, 0, 0, 40,
0, 16, 248, 80, 80, 248, 16, 5, 7, 7, 6, 0, 0, 40, 0, 248,
16, 32, 32, 248, 5, 8, 8, 6, 0, 0, 40, 0, 248, 8, 248, 8,
16, 32, 2, 2, 2, 6, 2, 2, 192, 192, 5, 1, 1, 6, 0, 3,
248, 5, 5, 5, 6, 0, 1, 128, 64, 32, 16, 8, 5, 6, 6, 6,
0, 1, 40, 128, 64, 32, 16, 8, 5, 7, 7, 6, 0, 0, 248, 8,
8, 8, 8, 8, 8
0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 5, 3, 3, 6, 0, 1,
248, 0, 248, 4, 4, 4, 6, 0, 0, 240, 16, 96, 64, 5, 6, 6,
6, 0, 0, 248, 8, 40, 48, 32, 64, 3, 4, 4, 6, 1, 0, 32,
64, 192, 64, 4, 6, 6, 6, 0, 0, 16, 32, 96, 160, 32, 32, 4,
4, 4, 6, 0, 0, 32, 240, 144, 32, 5, 6, 6, 6, 0, 0, 32,
248, 136, 8, 16, 32, 3, 4, 4, 6, 1, 0, 224, 64, 64, 224, 5,
5, 5, 6, 0, 0, 248, 32, 32, 32, 248, 4, 4, 4, 6, 0, 0,
32, 240, 96, 160, 5, 6, 6, 6, 0, 0, 16, 248, 48, 80, 144, 16,
5, 6, 6, 6, 0, 0, 64, 248, 72, 72, 72, 144, 5, 8, 8, 6,
0, 0, 40, 0, 64, 248, 72, 72, 72, 144, 5, 6, 6, 6, 0, 0,
32, 248, 32, 248, 32, 32, 5, 8, 8, 6, 0, 0, 40, 0, 32, 248,
32, 248, 32, 32, 4, 5, 5, 6, 0, 0, 112, 144, 16, 32, 192, 5,
7, 7, 6, 0, 0, 40, 0, 112, 144, 16, 32, 192, 5, 6, 6, 6,
0, 0, 64, 120, 144, 16, 16, 32, 5, 8, 8, 6, 0, 0, 40, 0,
64, 120, 144, 16, 16, 32, 5, 5, 5, 6, 0, 0, 248, 8, 8, 8,
248, 5, 7, 7, 6, 0, 0, 40, 0, 248, 8, 8, 8, 248, 5, 6,
6, 6, 0, 0, 80, 248, 80, 16, 32, 64, 5, 8, 8, 6, 0, 0,
40, 0, 80, 248, 80, 16, 32, 64, 5, 5, 5, 6, 0, 0, 192, 8,
200, 16, 224, 5, 7, 7, 6, 0, 0, 40, 0, 192, 8, 200, 16, 224,
5, 5, 5, 6, 0, 0, 248, 16, 32, 80, 136, 5, 7, 7, 6, 0,
0, 40, 0, 248, 16, 32, 80, 136, 5, 6, 6, 6, 0, 0, 64, 248,
72, 80, 64, 56, 5, 8, 8, 6, 0, 0, 40, 0, 64, 248, 72, 80,
64, 56, 5, 5, 5, 6, 0, 0, 136, 136, 72, 16, 96, 5, 7, 7,
6, 0, 0, 40, 0, 136, 136, 72, 16, 96, 5, 5, 5, 6, 0, 0,
120, 72, 168, 16, 96, 5, 7, 7, 6, 0, 0, 40, 0, 120, 72, 168,
16, 96, 5, 6, 6, 6, 0, 0, 16, 224, 32, 248, 32, 64, 5, 8,
8, 6, 0, 0, 40, 0, 16, 224, 32, 248, 32, 64, 5, 4, 4, 6,
0, 0, 168, 168, 8, 48, 5, 5, 5, 6, 0, 0, 168, 168, 8, 16,
32, 5, 7, 7, 6, 0, 0, 40, 0, 168, 168, 8, 16, 32, 5, 6,
6, 6, 0, 0, 112, 0, 248, 32, 32, 64, 5, 8, 8, 6, 0, 0,
40, 0, 112, 0, 248, 32, 32, 64, 3, 6, 6, 6, 1, 0, 128, 128,
192, 160, 128, 128, 4, 8, 8, 6, 1, 0, 80, 0, 128, 128, 192, 160,
128, 128, 5, 6, 6, 6, 0, 0, 32, 248, 32, 32, 64, 128, 5, 5,
5, 6, 0, 0, 112, 0, 0, 0, 248, 5, 5, 5, 6, 0, 0, 248,
8, 80, 32, 208, 5, 6, 6, 6, 0, 0, 32, 248, 16, 32, 112, 168,
3, 6, 6, 6, 1, 0, 32, 32, 32, 32, 64, 128, 5, 5, 5, 6,
0, 0, 16, 136, 136, 136, 136, 5, 7, 7, 6, 0, 0, 40, 0, 16,
136, 136, 136, 136, 5, 8, 8, 6, 0, 0, 24, 24, 0, 16, 136, 136,
136, 136, 5, 6, 6, 6, 0, 0, 128, 128, 248, 128, 128, 120, 5, 7,
7, 6, 0, 0, 40, 128, 128, 248, 128, 128, 120, 5, 7, 7, 6, 0,
0, 24, 152, 128, 248, 128, 128, 120, 5, 5, 5, 6, 0, 0, 248, 8,
8, 16, 96, 5, 7, 7, 6, 0, 0, 40, 0, 248, 8, 8, 16, 96,
5, 8, 8, 6, 0, 0, 24, 24, 0, 248, 8, 8, 16, 96, 5, 4,
4, 6, 0, 1, 64, 160, 16, 8, 5, 6, 6, 6, 0, 1, 40, 0,
64, 160, 16, 8, 5, 6, 6, 6, 0, 1, 24, 24, 64, 160, 16, 8,
5, 6, 6, 6, 0, 0, 32, 248, 32, 168, 168, 32, 5, 8, 8, 6,
0, 0, 40, 0, 32, 248, 32, 168, 168, 32, 5, 8, 8, 6, 0, 0,
24, 24, 32, 248, 32, 168, 168, 32, 5, 5, 5, 6, 0, 0, 248, 8,
80, 32, 16, 4, 5, 5, 6, 1, 0, 224, 0, 224, 0, 240, 5, 5,
5, 6, 0, 0, 32, 64, 136, 248, 8, 5, 5, 5, 6, 0, 0, 8,
40, 16, 40, 192, 5, 5, 5, 6, 0, 0, 248, 64, 248, 64, 56, 5,
4, 4, 6, 0, 0, 64, 248, 80, 64, 5, 6, 6, 6, 0, 0, 64,
248, 72, 80, 64, 64, 4, 4, 4, 6, 0, 0, 96, 32, 32, 240, 5,
5, 5, 6, 0, 0, 112, 16, 16, 16, 248, 4, 5, 5, 6, 0, 0,
240, 16, 240, 16, 240, 5, 5, 5, 6, 0, 0, 248, 8, 248, 8, 248,
5, 6, 6, 6, 0, 0, 112, 0, 248, 8, 16, 32, 4, 6, 6, 6,
0, 0, 144, 144, 144, 144, 16, 32, 5, 5, 5, 6, 0, 0, 32, 160,
168, 168, 176, 4, 5, 5, 6, 0, 0, 128, 128, 144, 160, 192, 5, 5,
5, 6, 0, 0, 248, 136, 136, 136, 248, 4, 4, 4, 6, 0, 0, 240,
144, 16, 32, 5, 5, 5, 6, 0, 0, 248, 136, 8, 16, 32, 5, 6,
6, 6, 0, 0, 16, 248, 80, 80, 248, 16, 5, 5, 5, 6, 0, 0,
248, 8, 48, 32, 248, 5, 5, 5, 6, 0, 0, 248, 8, 248, 8, 48,
5, 5, 5, 6, 0, 0, 192, 8, 8, 16, 224, 5, 8, 8, 6, 0,
0, 40, 0, 32, 248, 136, 8, 16, 32, 4, 4, 4, 6, 0, 0, 64,
240, 80, 160, 4, 4, 4, 6, 0, 0, 64, 240, 32, 64, 5, 7, 7,
6, 0, 0, 40, 0, 248, 136, 8, 16, 96, 5, 8, 8, 6, 0, 0,
40, 0, 16, 248, 80, 80, 248, 16, 5, 7, 7, 6, 0, 0, 40, 0,
248, 8, 48, 32, 248, 5, 7, 7, 6, 0, 0, 40, 0, 248, 8, 248,
8, 48, 2, 2, 2, 6, 2, 2, 192, 192, 5, 1, 1, 6, 0, 2,
248, 5, 4, 4, 6, 0, 1, 128, 96, 16, 8, 5, 5, 5, 6, 0,
1, 40, 128, 96, 16, 8, 5, 6, 6, 6, 0, 0, 248, 8, 8, 8,
8, 8
};
/*
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
Fontname: Marlin_symbols
Copyright: Created with Fony 1.4.7
Capital A Height: 0, '1' Height: 0
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* dogm_lcd_implementation.h
*
......@@ -7,7 +29,7 @@
*
* With the use of:
* u8glib by Oliver Kraus
* http://code.google.com/p/u8glib/
* https://github.com/olikraus/U8glib_Arduino
* License: http://opensource.org/licenses/BSD-3-Clause
*/
......@@ -177,7 +199,7 @@ char lcd_print(char c) {
return charset_mapper(c);
}
char lcd_print(char* str) {
char lcd_print(const char* str) {
char c;
int i = 0;
char n = 0;
......@@ -232,14 +254,14 @@ static void lcd_implementation_init() {
#endif
#if ENABLED(SHOW_BOOTSCREEN)
int offx = (u8g.getWidth() - START_BMPWIDTH) / 2;
int offx = (u8g.getWidth() - (START_BMPWIDTH)) / 2;
#if ENABLED(START_BMPHIGH)
int offy = 0;
#else
int offy = DOG_CHAR_HEIGHT;
#endif
int txt1X = (u8g.getWidth() - (sizeof(STRING_SPLASH_LINE1) - 1) * DOG_CHAR_WIDTH) / 2;
int txt1X = (u8g.getWidth() - (sizeof(STRING_SPLASH_LINE1) - 1) * (DOG_CHAR_WIDTH)) / 2;
u8g.firstPage();
do {
......@@ -247,11 +269,11 @@ static void lcd_implementation_init() {
u8g.drawBitmapP(offx, offy, START_BMPBYTEWIDTH, START_BMPHEIGHT, start_bmp);
lcd_setFont(FONT_MENU);
#if DISABLED(STRING_SPLASH_LINE2)
u8g.drawStr(txt1X, u8g.getHeight() - DOG_CHAR_HEIGHT, STRING_SPLASH_LINE1);
u8g.drawStr(txt1X, u8g.getHeight() - (DOG_CHAR_HEIGHT), STRING_SPLASH_LINE1);
#else
int txt2X = (u8g.getWidth() - (sizeof(STRING_SPLASH_LINE2) - 1) * DOG_CHAR_WIDTH) / 2;
u8g.drawStr(txt1X, u8g.getHeight() - DOG_CHAR_HEIGHT * 3 / 2, STRING_SPLASH_LINE1);
u8g.drawStr(txt2X, u8g.getHeight() - DOG_CHAR_HEIGHT * 1 / 2, STRING_SPLASH_LINE2);
int txt2X = (u8g.getWidth() - (sizeof(STRING_SPLASH_LINE2) - 1) * (DOG_CHAR_WIDTH)) / 2;
u8g.drawStr(txt1X, u8g.getHeight() - (DOG_CHAR_HEIGHT) * 3 / 2, STRING_SPLASH_LINE1);
u8g.drawStr(txt2X, u8g.getHeight() - (DOG_CHAR_HEIGHT) * 1 / 2, STRING_SPLASH_LINE2);
#endif
}
} while (u8g.nextPage());
......@@ -265,8 +287,20 @@ static void lcd_implementation_init() {
static void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
static void _draw_heater_status(int x, int heater) {
bool isBed = heater < 0;
FORCE_INLINE void _draw_centered_temp(int temp, int x, int y) {
int degsize = 6 * (temp >= 100 ? 3 : temp >= 10 ? 2 : 1); // number's pixel width
u8g.setPrintPos(x - (18 - degsize) / 2, y); // move left if shorter
lcd_print(itostr3(temp));
lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
}
FORCE_INLINE void _draw_heater_status(int x, int heater) {
#if HAS(TEMP_BED)
bool isBed = heater < 0;
#else
const bool isBed = false;
#endif
int y = 17 + (isBed ? 1 : 0);
lcd_setFont(FONT_STATUSMENU);
......@@ -319,6 +353,21 @@ static void _draw_heater_status(int x, int heater) {
#endif
}
FORCE_INLINE void _draw_axis_label(AxisEnum axis, const char *pstr, bool blink) {
if (blink)
lcd_printPGM(pstr);
else {
if (!axis_homed[axis])
lcd_printPGM(PSTR("?"));
else {
if (!axis_known_position[axis])
lcd_printPGM(PSTR(" "));
else
lcd_printPGM(pstr);
}
}
}
static void lcd_implementation_status_screen() {
u8g.setColorIndex(1); // black on white
......@@ -345,29 +394,30 @@ static void lcd_implementation_status_screen() {
u8g.drawBitmapP(9, 1, STATUS_SCREENBYTEWIDTH, STATUS_SCREENHEIGHT, (blink % 2) && fanSpeed ? status_screen0_bmp : status_screen1_bmp);
#endif
// Status Menu Font for SD info, Heater status, Fan, XYZ
lcd_setFont(FONT_STATUSMENU);
#if ENABLED(SDSUPPORT)
// SD Card Symbol
u8g.drawBox(42, 42 - TALL_FONT_CORRECTION, 8, 7);
u8g.drawBox(50, 44 - TALL_FONT_CORRECTION, 2, 5);
u8g.drawFrame(42, 49 - TALL_FONT_CORRECTION, 10, 4);
u8g.drawPixel(50, 43 - TALL_FONT_CORRECTION);
u8g.drawBox(42, 42 - (TALL_FONT_CORRECTION), 8, 7);
u8g.drawBox(50, 44 - (TALL_FONT_CORRECTION), 2, 5);
u8g.drawFrame(42, 49 - (TALL_FONT_CORRECTION), 10, 4);
u8g.drawPixel(50, 43 - (TALL_FONT_CORRECTION));
// Progress bar frame
u8g.drawFrame(54, 49, 73, 4 - TALL_FONT_CORRECTION);
u8g.drawFrame(54, 49, 73, 4 - (TALL_FONT_CORRECTION));
// SD Card Progress bar and clock
lcd_setFont(FONT_STATUSMENU);
if (IS_SD_PRINTING) {
// Progress bar solid part
u8g.drawBox(55, 50, (unsigned int)(71.f * card.percentDone() / 100.f), 2 - TALL_FONT_CORRECTION);
u8g.drawBox(55, 50, (unsigned int)(71.f * card.percentDone() / 100.f), 2 - (TALL_FONT_CORRECTION));
}
u8g.setPrintPos(53, 47);
if (print_job_start_ms != 0) {
uint16_t time = print_job_timer.duration() / 60;
if (time != 0) {
#if HAS(LCD_POWER_SENSOR)
if (millis() < print_millis + 1000) {
uint16_t time = (millis() - print_job_start_ms) / 60000;
uint16_t end_time = (time * (100 - card.percentDone())) / card.percentDone();
lcd_print('S');
lcd_print(itostr2(time/60));
......@@ -380,9 +430,9 @@ static void lcd_implementation_status_screen() {
u8g.print('E--:--');
else if (end_time > 0) {
u8g.print('E');
u8g.print(itostr2(end_time / 60));
u8g.print(itostr2(end_time/60));
u8g.print(':');
u8g.print(itostr2(end_time %60));
u8g.print(itostr2(end_time%60));
}
}
else {
......@@ -390,12 +440,11 @@ static void lcd_implementation_status_screen() {
lcd_print((char*)"Wh");
}
#else
uint16_t time = (millis() - print_job_start_ms) / 60000;
uint16_t end_time = (time * (100 - card.percentDone())) / card.percentDone();
lcd_print('S');
lcd_print(itostr2(time / 60));
lcd_print(itostr2(time/60));
lcd_print(':');
lcd_print(itostr2(time %60));
lcd_print(itostr2(time%60));
u8g.setPrintPos(90, 47);
......@@ -403,9 +452,9 @@ static void lcd_implementation_status_screen() {
lcd_printPGM(PSTR("E--:--"));
else if (end_time > 0) {
u8g.print('E');
u8g.print(itostr2(end_time / 60));
u8g.print(itostr2(end_time/60));
u8g.print(':');
u8g.print(itostr2(end_time %60));
u8g.print(itostr2(end_time%60));
}
#endif
}
......@@ -417,14 +466,16 @@ static void lcd_implementation_status_screen() {
#endif
#if DISABLED(LASER)
// Hotends
// Hotends
for (int i = 0; i < HOTENDS; i++) _draw_heater_status(6 + i * 25, i);
// Heatbed
if (HOTENDS < 4) _draw_heater_status(81, -1);
// Heated bed
#if HOTENDS < 4 && HAS(TEMP_BED)
_draw_heater_status(81, -1);
#endif
#endif // DISABLED LASER
// Fan
lcd_setFont(FONT_STATUSMENU);
u8g.setPrintPos(104, 27);
#if HAS(FAN)
int per = ((fanSpeed + 1) * 100) / 256;
......@@ -432,17 +483,13 @@ static void lcd_implementation_status_screen() {
lcd_print(itostr3(per));
lcd_print('%');
}
else
#endif
{
lcd_printPGM(PSTR("---"));
}
// Print XYZ Coordinates
// If the axis was not homed, show "---"
// If the position is untrusted, show "?"
// X, Y, Z-Coordinates
// Before homing the axis letters are blinking 'X' <-> '?'.
// When axis is homed but axis_known_position is false the axis letters are blinking 'X' <-> ' '.
// When everything is ok you see a constant 'X'.
#define XYZ_BASELINE 38
lcd_setFont(FONT_STATUSMENU);
#if ENABLED(USE_SMALL_INFOFONT)
u8g.drawBox(0, 30, LCD_PIXEL_WIDTH, 10);
......@@ -452,54 +499,40 @@ static void lcd_implementation_status_screen() {
u8g.setColorIndex(0); // white on black
u8g.setPrintPos(2, XYZ_BASELINE);
lcd_print(TEST(axis_known_position, X_AXIS) || !TEST(axis_was_homed, X_AXIS) ? 'X' : '?');
u8g.drawPixel(8, XYZ_BASELINE - 5);
u8g.drawPixel(8, XYZ_BASELINE - 3);
_draw_axis_label(X_AXIS, PSTR(MSG_X), blink);
u8g.setPrintPos(10, XYZ_BASELINE);
if (TEST(axis_was_homed, X_AXIS))
lcd_print(ftostr31ns(current_position[X_AXIS]));
else
lcd_printPGM(PSTR("---"));
lcd_print(ftostr4sign(current_position[X_AXIS]));
u8g.setPrintPos(43, XYZ_BASELINE);
lcd_print(TEST(axis_known_position, Y_AXIS) || !TEST(axis_was_homed, Y_AXIS) ? 'Y' : '?');
u8g.drawPixel(49, XYZ_BASELINE - 5);
u8g.drawPixel(49, XYZ_BASELINE - 3);
_draw_axis_label(Y_AXIS, PSTR(MSG_Y), blink);
u8g.setPrintPos(51, XYZ_BASELINE);
if (TEST(axis_was_homed, Y_AXIS))
lcd_print(ftostr31ns(current_position[Y_AXIS]));
else
lcd_printPGM(PSTR("---"));
lcd_print(ftostr4sign(current_position[Y_AXIS]));
u8g.setPrintPos(83, XYZ_BASELINE);
lcd_print(TEST(axis_known_position, Z_AXIS) || !TEST(axis_was_homed, Z_AXIS) ? 'Z' : '?');
u8g.drawPixel(89, XYZ_BASELINE - 5);
u8g.drawPixel(89, XYZ_BASELINE - 3);
_draw_axis_label(Z_AXIS, PSTR(MSG_Z), blink);
u8g.setPrintPos(91, XYZ_BASELINE);
if (TEST(axis_was_homed, Z_AXIS))
lcd_print(ftostr32sp(current_position[Z_AXIS]));
else
lcd_printPGM(PSTR("---.--"));
lcd_print(ftostr32sp(current_position[Z_AXIS] + 0.00001));
u8g.setColorIndex(1); // black on white
// Feedrate
lcd_setFont(FONT_MENU);
u8g.setPrintPos(3, 49);
lcd_print(LCD_STR_FEEDRATE[0]);
lcd_setFont(FONT_STATUSMENU);
u8g.setPrintPos(12, 49);
lcd_print(itostr3(feedrate_multiplier));
lcd_print('%');
// Status line
lcd_setFont(FONT_STATUSMENU);
#if ENABLED(USE_SMALL_INFOFONT)
u8g.setPrintPos(0, 62);
#else
u8g.setPrintPos(0, 63);
#endif
#if HAS(LCD_FILAMENT_SENSOR) || HAS(LCD_POWER_SENSOR)
if (millis() < previous_lcd_status_ms + 5000) //Display both Status message line and Filament display on the last line
if (PENDING(millis(), previous_lcd_status_ms + 5000UL)) { //Display both Status message line and Filament display on the last line
lcd_print(lcd_status_message);
#if HAS(LCD_POWER_SENSOR)
#if HAS(LCD_FILAMENT_SENSOR)
......@@ -532,13 +565,13 @@ static void lcd_implementation_status_screen() {
static void lcd_implementation_mark_as_selected(uint8_t row, bool isSelected) {
if (isSelected) {
u8g.setColorIndex(1); // black on white
u8g.drawBox(0, row * DOG_CHAR_HEIGHT + 3 - TALL_FONT_CORRECTION, LCD_PIXEL_WIDTH, DOG_CHAR_HEIGHT);
u8g.drawBox(0, row * (DOG_CHAR_HEIGHT) + 3 - (TALL_FONT_CORRECTION), LCD_PIXEL_WIDTH, DOG_CHAR_HEIGHT);
u8g.setColorIndex(0); // following text must be white on black
}
else {
u8g.setColorIndex(1); // unmarked text is black on white
}
u8g.setPrintPos(START_ROW * DOG_CHAR_WIDTH, (row + 1) * DOG_CHAR_HEIGHT);
u8g.setPrintPos((START_ROW) * (DOG_CHAR_WIDTH), (row + 1) * (DOG_CHAR_HEIGHT));
}
static void lcd_implementation_drawmenu_generic(bool isSelected, uint8_t row, const char* pstr, char pre_char, char post_char) {
......@@ -552,7 +585,7 @@ static void lcd_implementation_drawmenu_generic(bool isSelected, uint8_t row, co
pstr++;
}
while (n--) lcd_print(' ');
u8g.setPrintPos(LCD_PIXEL_WIDTH - DOG_CHAR_WIDTH, (row + 1) * DOG_CHAR_HEIGHT);
u8g.setPrintPos(LCD_PIXEL_WIDTH - (DOG_CHAR_WIDTH), (row + 1) * (DOG_CHAR_HEIGHT));
lcd_print(post_char);
lcd_print(' ');
}
......@@ -570,7 +603,7 @@ static void _drawmenu_setting_edit_generic(bool isSelected, uint8_t row, const c
}
lcd_print(':');
while (n--) lcd_print(' ');
u8g.setPrintPos(LCD_PIXEL_WIDTH - DOG_CHAR_WIDTH * vallen, (row + 1) * DOG_CHAR_HEIGHT);
u8g.setPrintPos(LCD_PIXEL_WIDTH - (DOG_CHAR_WIDTH) * vallen, (row + 1) * (DOG_CHAR_HEIGHT));
if (pgm) lcd_printPGM(data); else lcd_print((char*)data);
}
......@@ -617,14 +650,16 @@ void lcd_implementation_drawedit(const char* pstr, char* value) {
if (lcd_strlen_P(pstr) > LCD_WIDTH - 2 - vallen) rows = 2;
const float kHalfChar = DOG_CHAR_HEIGHT_EDIT / 2;
const float kHalfChar = (DOG_CHAR_HEIGHT_EDIT) / 2;
float rowHeight = u8g.getHeight() / (rows + 1); // 1/(rows+1) = 1/2 or 1/3
u8g.setPrintPos(0, rowHeight + kHalfChar);
lcd_printPGM(pstr);
lcd_print(':');
u8g.setPrintPos((lcd_width - 1 - vallen) * char_width, rows * rowHeight + kHalfChar);
lcd_print(value);
if (value != NULL) {
lcd_print(':');
u8g.setPrintPos((lcd_width - 1 - vallen) * char_width, rows * rowHeight + kHalfChar);
lcd_print(value);
}
}
#if ENABLED(SDSUPPORT)
......@@ -647,7 +682,7 @@ void lcd_implementation_drawedit(const char* pstr, char* value) {
#endif //SDSUPPORT
#define lcd_implementation_drawmenu_back(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])
#define lcd_implementation_drawmenu_back(sel, row, pstr) lcd_implementation_drawmenu_generic(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])
#define lcd_implementation_drawmenu_submenu(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0])
#define lcd_implementation_drawmenu_gcode(sel, row, pstr, gcode) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ')
#define lcd_implementation_drawmenu_function(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ')
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "../../base.h"
#include "ultralcd.h"
#if ENABLED(ULTRA_LCD)
#include "ultralcd.h"
/**
* INVERT_ROTARY_SWITCH
*
* To reverse the menu direction we need a general way to reverse
* the direction of the encoder everywhere. So encoderDirection is
* added to allow the encoder to go the other way.
*
* This behavior is limited to scrolling Menus and SD card listings,
* and is disabled in other contexts.
*/
#if ENABLED(INVERT_ROTARY_SWITCH)
int8_t encoderDirection = 1;
#define ENCODER_DIRECTION_NORMAL() (encoderDirection = 1)
#define ENCODER_DIRECTION_MENUS() (encoderDirection = -1)
#else
#define ENCODER_DIRECTION_NORMAL() ;
#define ENCODER_DIRECTION_MENUS() ;
#endif
int8_t encoderDiff; // updated from interrupt context and added to encoderPosition every LCD update
......@@ -94,12 +134,15 @@ static void lcd_status_screen();
static void lcd_control_temperature_preheat_gum_settings_menu();
#endif
static void lcd_control_motion_menu();
#if DISABLED(LASER)
static void lcd_control_volumetric_menu();
#endif
#if HAS(LCD_CONTRAST)
static void lcd_set_contrast();
#endif
#if ENABLED(FWRETRACT)
static void lcd_control_retract_menu();
#endif
......@@ -109,10 +152,10 @@ static void lcd_status_screen();
#elif !MECH(DELTA) && DISABLED(Z_SAFE_HOMING) && Z_HOME_DIR < 0
static void lcd_level_bed();
static void config_lcd_level_bed();
#endif // DELTA
#endif // !DELTA
/* Different types of actions that can be used in menu items. */
static void menu_action_back(menuFunc_t data);
static void menu_action_back();
static void menu_action_submenu(menuFunc_t data);
static void menu_action_gcode(const char* pgcode);
static void menu_action_function(menuFunc_t data);
......@@ -166,7 +209,8 @@ static void lcd_status_screen();
* START_MENU generates the init code for a menu function
*/
#if ENABLED(BTN_BACK) && BTN_BACK > 0
#define START_MENU(last_menu) do { \
#define START_MENU() do { \
ENCODER_DIRECTION_MENUS(); \
encoderRateMultiplierEnabled = false; \
if (encoderPosition > 0x8000) encoderPosition = 0; \
uint8_t encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM; \
......@@ -176,12 +220,13 @@ static void lcd_status_screen();
bool wasBackClicked = LCD_BACK_CLICKED; \
if (wasBackClicked) { \
lcd_quick_feedback(); \
menu_action_back( last_menu ); \
menu_action_back(); \
return; } \
for (uint8_t _drawLineNr = 0; _drawLineNr < LCD_HEIGHT; _drawLineNr++, _lineNr++) { \
_menuItemNr = 0;
#else
#define START_MENU(last_menu) do { \
#define START_MENU() do { \
ENCODER_DIRECTION_MENUS(); \
encoderRateMultiplierEnabled = false; \
if (encoderPosition > 0x8000) encoderPosition = 0; \
uint8_t encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM; \
......@@ -199,9 +244,9 @@ static void lcd_status_screen();
* menu_action_[type](arg3...)
*
* Examples:
* MENU_ITEM(back, MSG_WATCH, lcd_status_screen)
* lcd_implementation_drawmenu_back(sel, row, PSTR(MSG_WATCH), lcd_status_screen)
* menu_action_back(lcd_status_screen)
* MENU_ITEM(back, MSG_WATCH)
* lcd_implementation_drawmenu_back(sel, row, PSTR(MSG_WATCH))
* menu_action_back()
*
* MENU_ITEM(function, MSG_PAUSE_PRINT, lcd_sdcard_pause)
* lcd_implementation_drawmenu_function(sel, row, PSTR(MSG_PAUSE_PRINT), lcd_sdcard_pause)
......@@ -213,19 +258,25 @@ static void lcd_status_screen();
* menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedrate_multiplier, 10, 999)
*
*/
#define MENU_ITEM(type, label, args...) do { \
#define _MENU_ITEM_PART_1(type, label, args...) \
if (_menuItemNr == _lineNr) { \
itemSelected = encoderLine == _menuItemNr; \
if (lcdDrawUpdate) \
lcd_implementation_drawmenu_ ## type(itemSelected, _drawLineNr, PSTR(label), ## args); \
if (wasClicked && itemSelected) { \
lcd_quick_feedback(); \
lcd_quick_feedback()
#define _MENU_ITEM_PART_2(type, args...) \
menu_action_ ## type(args); \
return; \
} \
} \
_menuItemNr++; \
} while(0)
_menuItemNr++
#define MENU_ITEM(type, label, args...) do { \
_MENU_ITEM_PART_1(type, label, ## args); \
_MENU_ITEM_PART_2(type, ## args); \
} while(0)
#if ENABLED(ENCODER_RATE_MULTIPLIER)
......@@ -235,21 +286,13 @@ static void lcd_status_screen();
* MENU_MULTIPLIER_ITEM generates drawing and handling code for a multiplier menu item
*/
#define MENU_MULTIPLIER_ITEM(type, label, args...) do { \
if (_menuItemNr == _lineNr) { \
itemSelected = encoderLine == _menuItemNr; \
if (lcdDrawUpdate) \
lcd_implementation_drawmenu_ ## type(itemSelected, _drawLineNr, PSTR(label), ## args); \
if (wasClicked && itemSelected) { \
lcd_quick_feedback(); \
encoderRateMultiplierEnabled = true; \
lastEncoderMovementMillis = 0; \
menu_action_ ## type(args); \
return; \
} \
} \
_menuItemNr++; \
} while(0)
#endif //ENCODER_RATE_MULTIPLIER
_MENU_ITEM_PART_1(type, label, ## args); \
encoderRateMultiplierEnabled = true; \
lastEncoderMovementMillis = 0; \
_MENU_ITEM_PART_2(type, ## args); \
} while(0)
#endif // ENCODER_RATE_MULTIPLIER
#define MENU_ITEM_DUMMY() do { _menuItemNr++; } while(0)
#define MENU_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label), ## args)
......@@ -257,13 +300,13 @@ static void lcd_status_screen();
#if ENABLED(ENCODER_RATE_MULTIPLIER)
#define MENU_MULTIPLIER_ITEM_EDIT(type, label, args...) MENU_MULTIPLIER_ITEM(setting_edit_ ## type, label, PSTR(label), ## args)
#define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_MULTIPLIER_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args)
#else //!ENCODER_RATE_MULTIPLIER
#else // !ENCODER_RATE_MULTIPLIER
#define MENU_MULTIPLIER_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label), ## args)
#define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args)
#endif //!ENCODER_RATE_MULTIPLIER
#endif // !ENCODER_RATE_MULTIPLIER
#define END_MENU() \
if (encoderLine >= _menuItemNr) { encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1; encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM; }\
if (encoderLine >= currentMenuViewOffset + LCD_HEIGHT) { currentMenuViewOffset = encoderLine - LCD_HEIGHT + 1; lcdDrawUpdate = 1; _lineNr = currentMenuViewOffset - 1; _drawLineNr = -1; } \
if (encoderLine >= _menuItemNr) { encoderPosition = _menuItemNr * (ENCODER_STEPS_PER_MENU_ITEM) - 1; encoderLine = _menuItemNr - 1; }\
if (encoderLine >= currentMenuViewOffset + LCD_HEIGHT) { currentMenuViewOffset = encoderLine - (LCD_HEIGHT) + 1; lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; _lineNr = currentMenuViewOffset - 1; _drawLineNr = -1; } \
} } while(0)
/** Used variables to keep track of the menu */
......@@ -285,16 +328,34 @@ static void lcd_status_screen();
#endif // ULTIPANEL
typedef struct {
menuFunc_t menu_function;
#if ENABLED(ULTIPANEL)
uint32_t encoder_position;
#endif
} menuPosition;
menuFunc_t currentMenu = lcd_status_screen; /* function pointer to the currently active menu */
menuPosition menu_history[10];
uint8_t menu_history_depth = 0;
millis_t next_lcd_update_ms;
uint8_t lcd_status_update_delay;
bool ignore_click = false;
bool wait_for_unclick;
uint8_t lcdDrawUpdate = 2; /* Set to none-zero when the LCD needs to draw, decreased after every draw. Set to 2 in LCD routines so the LCD gets at least 1 full redraw (first redraw is partial) */
bool defer_return_to_status = false;
enum LCDViewAction {
LCDVIEW_NONE,
LCDVIEW_REDRAW_NOW,
LCDVIEW_CALL_REDRAW_NEXT,
LCDVIEW_CLEAR_CALL_REDRAW,
LCDVIEW_CALL_NO_REDRAW
};
uint8_t lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; // Set when the LCD needs to draw, decrements after every draw. Set to 2 in LCD routines so the LCD gets at least 1 full redraw (first redraw is partial)
//prevMenu and prevEncoderPosition are used to store the previous menu location when editing settings.
menuFunc_t prevMenu = NULL;
uint16_t prevEncoderPosition;
//Variables used when editing values.
const char* editLabel;
void* editValue;
......@@ -306,21 +367,52 @@ float raw_Ki, raw_Kd;
/**
* General function to go directly to a menu
* Remembers the previous position
*/
static void lcd_goto_menu(menuFunc_t menu, const bool feedback = false, const uint32_t encoder = 0) {
if (currentMenu != menu) {
currentMenu = menu;
lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW;
#if ENABLED(NEWPANEL)
encoderPosition = encoder;
if (feedback) lcd_quick_feedback();
#endif
// For LCD_PROGRESS_BAR re-initialize the custom characters
if (menu == lcd_status_screen) {
defer_return_to_status = false;
menu_history_depth = 0;
}
#if ENABLED(LCD_PROGRESS_BAR)
// For LCD_PROGRESS_BAR re-initialize the custom characters
lcd_set_custom_characters(menu == lcd_status_screen);
#endif
}
}
static void lcd_return_to_status() { lcd_goto_menu(lcd_status_screen); }
inline void lcd_save_previous_menu() {
if (menu_history_depth < COUNT(menu_history)) {
menu_history[menu_history_depth].menu_function = currentMenu;
#if ENABLED(ULTIPANEL)
menu_history[menu_history_depth].encoder_position = encoderPosition;
#endif
++menu_history_depth;
}
}
static void lcd_goto_previous_menu(bool feedback = false) {
if (menu_history_depth > 0) {
--menu_history_depth;
lcd_goto_menu(menu_history[menu_history_depth].menu_function, feedback
#if ENABLED(ULTIPANEL)
, menu_history[menu_history_depth].encoder_position
#endif
);
}
else
lcd_return_to_status();
}
/**
*
* "Info Screen"
......@@ -329,12 +421,13 @@ static void lcd_goto_menu(menuFunc_t menu, const bool feedback = false, const ui
*/
static void lcd_status_screen() {
ENCODER_DIRECTION_NORMAL();
encoderRateMultiplierEnabled = false;
#if ENABLED(LCD_PROGRESS_BAR)
millis_t ms = millis();
#if DISABLED(PROGRESS_MSG_ONCE)
if (ms > progress_bar_ms + PROGRESS_BAR_MSG_TIME + PROGRESS_BAR_BAR_TIME) {
if (ELAPSED(ms, progress_bar_ms + PROGRESS_BAR_MSG_TIME + PROGRESS_BAR_BAR_TIME)) {
progress_bar_ms = ms;
}
#endif
......@@ -412,24 +505,24 @@ static void lcd_status_screen() {
}
#if ENABLED(ULTIPANEL_FEEDMULTIPLY)
int new_frm = feedrate_multiplier + (int32_t)encoderPosition;
// Dead zone at 100% feedrate
if ((feedrate_multiplier < 100 && (feedrate_multiplier + int(encoderPosition)) > 100) ||
(feedrate_multiplier > 100 && (feedrate_multiplier + int(encoderPosition)) < 100)) {
encoderPosition = 0;
if ((feedrate_multiplier < 100 && new_frm > 100) || (feedrate_multiplier > 100 && new_frm < 100)) {
feedrate_multiplier = 100;
encoderPosition = 0;
}
if (feedrate_multiplier == 100) {
if (int(encoderPosition) > ENCODER_FEEDRATE_DEADZONE) {
feedrate_multiplier += int(encoderPosition) - ENCODER_FEEDRATE_DEADZONE;
else if (feedrate_multiplier == 100) {
if ((int32_t)encoderPosition > ENCODER_FEEDRATE_DEADZONE) {
feedrate_multiplier += (int32_t)encoderPosition - (ENCODER_FEEDRATE_DEADZONE);
encoderPosition = 0;
}
else if (int(encoderPosition) < -ENCODER_FEEDRATE_DEADZONE) {
feedrate_multiplier += int(encoderPosition) + ENCODER_FEEDRATE_DEADZONE;
else if ((int32_t)encoderPosition < -(ENCODER_FEEDRATE_DEADZONE)) {
feedrate_multiplier += (int32_t)encoderPosition + ENCODER_FEEDRATE_DEADZONE;
encoderPosition = 0;
}
}
else {
feedrate_multiplier += int(encoderPosition);
feedrate_multiplier = new_frm;
encoderPosition = 0;
}
#endif // ULTIPANEL_FEEDMULTIPLY
......@@ -441,7 +534,14 @@ static void lcd_status_screen() {
#if ENABLED(ULTIPANEL)
static void lcd_return_to_status() { lcd_goto_menu(lcd_status_screen); }
inline void line_to_current(AxisEnum axis) {
#if MECH(DELTA)
calculate_delta(current_position);
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], manual_feedrate[axis]/60, active_extruder, active_driver);
#else
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[axis]/60, active_extruder, active_driver);
#endif
}
#if ENABLED(SDSUPPORT)
......@@ -467,678 +567,729 @@ static void lcd_return_to_status() { lcd_goto_menu(lcd_status_screen); }
*/
static void lcd_main_menu() {
START_MENU(lcd_status_screen);
MENU_ITEM(back, MSG_WATCH, lcd_status_screen);
#if ENABLED(LASER)
if (!(movesplanned() || IS_SD_PRINTING)) {
MENU_ITEM(submenu, "Laser Functions", lcd_laser_menu);
}
#endif
if (movesplanned() || IS_SD_PRINTING) {
MENU_ITEM(submenu, MSG_TUNE, lcd_tune_menu);
}
else {
MENU_ITEM(submenu, MSG_PREPARE, lcd_prepare_menu);
#if MECH(DELTA)
MENU_ITEM(submenu, MSG_DELTA_CALIBRATE, lcd_delta_calibrate_menu);
#endif
}
MENU_ITEM(submenu, MSG_CONTROL, lcd_control_menu);
MENU_ITEM(submenu, MSG_STATS, lcd_stats_menu);
#if ENABLED(SDSUPPORT)
if (card.cardOK) {
if (card.isFileOpen()) {
if (card.sdprinting)
MENU_ITEM(function, MSG_PAUSE_PRINT, lcd_sdcard_pause);
else
MENU_ITEM(function, MSG_RESUME_PRINT, lcd_sdcard_resume);
MENU_ITEM(function, MSG_STOP_PRINT, lcd_sdcard_stop);
}
else {
MENU_ITEM(submenu, MSG_CARD_MENU, lcd_sdcard_menu);
#if !PIN_EXISTS(SD_DETECT)
MENU_ITEM(gcode, MSG_CNG_SDCARD, PSTR("M21")); // SD-card changed by user
#endif
}
}
else {
MENU_ITEM(submenu, MSG_NO_CARD, lcd_sdcard_menu);
#if !PIN_EXISTS(SD_DETECT)
MENU_ITEM(gcode, MSG_INIT_SDCARD, PSTR("M21")); // Manually initialize the SD-card via user interface
#endif
}
#endif // SDSUPPORT
START_MENU();
MENU_ITEM(back, MSG_WATCH);
#if ENABLED(LASER)
if (!(movesplanned() || IS_SD_PRINTING)) {
MENU_ITEM(submenu, "Laser Functions", lcd_laser_menu);
}
#endif
if (movesplanned() || IS_SD_PRINTING) {
MENU_ITEM(submenu, MSG_TUNE, lcd_tune_menu);
}
else {
MENU_ITEM(submenu, MSG_PREPARE, lcd_prepare_menu);
#if MECH(DELTA)
MENU_ITEM(submenu, MSG_DELTA_CALIBRATE, lcd_delta_calibrate_menu);
#endif
}
MENU_ITEM(submenu, MSG_CONTROL, lcd_control_menu);
MENU_ITEM(submenu, MSG_STATS, lcd_stats_menu);
END_MENU();
#if ENABLED(SDSUPPORT)
if (card.cardOK) {
if (card.isFileOpen()) {
if (card.sdprinting)
MENU_ITEM(function, MSG_PAUSE_PRINT, lcd_sdcard_pause);
else
MENU_ITEM(function, MSG_RESUME_PRINT, lcd_sdcard_resume);
MENU_ITEM(function, MSG_STOP_PRINT, lcd_sdcard_stop);
}
else {
MENU_ITEM(submenu, MSG_CARD_MENU, lcd_sdcard_menu);
#if !PIN_EXISTS(SD_DETECT)
MENU_ITEM(gcode, MSG_CNG_SDCARD, PSTR("M21")); // SD-card changed by user
#endif
}
}
else {
MENU_ITEM(submenu, MSG_NO_CARD, lcd_sdcard_menu);
#if !PIN_EXISTS(SD_DETECT)
MENU_ITEM(gcode, MSG_INIT_SDCARD, PSTR("M21")); // Manually initialize the SD-card via user interface
#endif
}
#endif // SDSUPPORT
END_MENU();
}
#if ENABLED(SDSUPPORT) && ENABLED(MENU_ADDAUTOSTART)
static void lcd_autostart_sd() {
card.checkautostart(true);
}
static void lcd_autostart_sd() {
card.checkautostart(true);
}
#endif
/**
* Set the home offset based on the current_position
*/
*
* "Tune" submenu items
*
*/
/**
* Set the home offset based on the current_position
*/
void lcd_set_home_offsets() {
// M428 Command
enqueuecommands_P(PSTR("M428"));
lcd_return_to_status();
// M428 Command
enqueue_and_echo_commands_P(PSTR("M428"));
lcd_return_to_status();
}
#if ENABLED(BABYSTEPPING)
static void _lcd_babystep(int axis, const char* msg) {
if (encoderPosition != 0) {
babystepsTodo[axis] += BABYSTEP_MULTIPLICATOR * (int)encoderPosition;
encoderPosition = 0;
lcdDrawUpdate = 1;
}
if (lcdDrawUpdate) lcd_implementation_drawedit(msg, (char*)"");
if (LCD_CLICKED) lcd_goto_menu(lcd_tune_menu);
}
static void lcd_babystep_x() { _lcd_babystep(X_AXIS, PSTR(MSG_BABYSTEPPING_X)); }
static void lcd_babystep_y() { _lcd_babystep(Y_AXIS, PSTR(MSG_BABYSTEPPING_Y)); }
static void lcd_babystep_z() { _lcd_babystep(Z_AXIS, PSTR(MSG_BABYSTEPPING_Z)); }
int babysteps_done = 0;
static void _lcd_babystep(const int axis, const char* msg) {
ENCODER_DIRECTION_NORMAL();
if (encoderPosition) {
int distance = (int32_t)encoderPosition * BABYSTEP_MULTIPLICATOR;
encoderPosition = 0;
lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
#if MECH(COREXY) || MECH(COREYX)|| MECH(COREXZ) || MECH(COREZX)
#if ENABLED(BABYSTEP_XY)
switch(axis) {
case X_AXIS: // X on CoreXY, Core YX, CoreXZ and CoreZZ
babystepsTodo[A_AXIS] += distance * 2;
babystepsTodo[CORE_AXIS_2] += distance * 2;
break;
case CORE_AXIS_2: // Y on CoreXY and CoreYX, Z on CoreXZ and CoreZX
babystepsTodo[A_AXIS] += distance * 2;
babystepsTodo[CORE_AXIS_2] -= distance * 2;
break;
case CORE_AXIS_3: // Z on CoreXY and CoreYX, Y on CoreXZ and CoreZX
babystepsTodo[CORE_AXIS_3] += distance;
break;
}
#elif MECH(COREXZ) || MECH(COREZX)
babystepsTodo[A_AXIS] += distance * 2;
babystepsTodo[C_AXIS] -= distance * 2;
#else
babystepsTodo[Z_AXIS] += distance;
#endif
#else
babystepsTodo[axis] += distance;
#endif
babysteps_done += distance;
}
if (lcdDrawUpdate) lcd_implementation_drawedit(msg, itostr3sign(babysteps_done));
if (LCD_CLICKED) lcd_goto_previous_menu(true);
}
#if ENABLED(BABYSTEP_XY)
static void _lcd_babystep_x() { _lcd_babystep(X_AXIS, PSTR(MSG_BABYSTEPPING_X)); }
static void _lcd_babystep_y() { _lcd_babystep(Y_AXIS, PSTR(MSG_BABYSTEPPING_Y)); }
static void lcd_babystep_x() { babysteps_done = 0; lcd_goto_menu(_lcd_babystep_x); }
static void lcd_babystep_y() { babysteps_done = 0; lcd_goto_menu(_lcd_babystep_y); }
#endif
static void _lcd_babystep_z() { _lcd_babystep(Z_AXIS, PSTR(MSG_BABYSTEPPING_Z)); }
static void lcd_babystep_z() { babysteps_done = 0; lcd_goto_menu(_lcd_babystep_z); }
#endif // BABYSTEPPING
static void lcd_tune_fixstep() {
#if MECH(DELTA)
enqueuecommands_P(PSTR("G28 B"));
#else
enqueuecommands_P(PSTR("G28 X Y B"));
#endif
#if MECH(DELTA)
enqueue_and_echo_commands_P(PSTR("G28 B"));
#else
enqueue_and_echo_commands_P(PSTR("G28 X Y B"));
#endif
}
/**
* Watch temperature callbacks
*/
* Watch temperature callbacks
*/
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
#if TEMP_SENSOR_0 != 0
void watch_temp_callback_E0() { start_watching_heater(0); }
#endif
#if HOTENDS > 1 && TEMP_SENSOR_1 != 0
void watch_temp_callback_E1() { start_watching_heater(1); }
#endif
#if HOTENDS > 2 && TEMP_SENSOR_2 != 0
void watch_temp_callback_E2() { start_watching_heater(2); }
#endif
#if HOTENDS > 3 && TEMP_SENSOR_3 != 0
void watch_temp_callback_E3() { start_watching_heater(3); }
#endif
#if TEMP_SENSOR_0 != 0
void watch_temp_callback_E0() { start_watching_heater(0); }
#endif
#if HOTENDS > 1 && TEMP_SENSOR_1 != 0
void watch_temp_callback_E1() { start_watching_heater(1); }
#endif
#if HOTENDS > 2 && TEMP_SENSOR_2 != 0
void watch_temp_callback_E2() { start_watching_heater(2); }
#endif
#if HOTENDS > 3 && TEMP_SENSOR_3 != 0
void watch_temp_callback_E3() { start_watching_heater(3); }
#endif
#else
#if TEMP_SENSOR_0 != 0
void watch_temp_callback_E0() {}
#endif
#if HOTENDS > 1 && TEMP_SENSOR_1 != 0
void watch_temp_callback_E1() {}
#endif
#if HOTENDS > 2 && TEMP_SENSOR_2 != 0
void watch_temp_callback_E2() {}
#endif
#if HOTENDS > 3 && TEMP_SENSOR_3 != 0
void watch_temp_callback_E3() {}
#endif
#if TEMP_SENSOR_0 != 0
void watch_temp_callback_E0() {}
#endif
#if HOTENDS > 1 && TEMP_SENSOR_1 != 0
void watch_temp_callback_E1() {}
#endif
#if HOTENDS > 2 && TEMP_SENSOR_2 != 0
void watch_temp_callback_E2() {}
#endif
#if HOTENDS > 3 && TEMP_SENSOR_3 != 0
void watch_temp_callback_E3() {}
#endif
#endif // !THERMAL_PROTECTION_HOTENDS
/**
*
* "Tune" submenu
*
*/
*
* "Tune" submenu
*
*/
static void lcd_tune_menu() {
START_MENU(lcd_main_menu);
//
// ^ Main
//
MENU_ITEM(back, MSG_MAIN, lcd_main_menu);
START_MENU();
//
// Speed:
//
MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_multiplier, 10, 999);
//
// ^ Main
//
MENU_ITEM(back, MSG_MAIN);
//
// Laser:
//
#if ENABLED(LASER)
MENU_ITEM_EDIT(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP - 15);
#endif
//
// Speed:
//
MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_multiplier, 10, 999);
//
// Nozzle:
//
#if HOTENDS == 1
#if TEMP_SENSOR_0 != 0
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP - 15, watch_temp_callback_E0);
#endif
#else // HOTENDS > 1
#if TEMP_SENSOR_0 != 0
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE " 0", &target_temperature[0], 0, HEATER_0_MAXTEMP - 15, watch_temp_callback_E0);
#endif
#if TEMP_SENSOR_1 != 0
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE " 1", &target_temperature[1], 0, HEATER_1_MAXTEMP - 15, watch_temp_callback_E1);
#endif
#if HOTENDS > 2
#if TEMP_SENSOR_2 != 0
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE " 2", &target_temperature[2], 0, HEATER_2_MAXTEMP - 15, watch_temp_callback_E2);
#endif
#if HOTENDS > 3
#if TEMP_SENSOR_3 != 0
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE " 3", &target_temperature[3], 0, HEATER_3_MAXTEMP - 15, watch_temp_callback_E3);
#endif
#endif // HOTENDS > 3
#endif // HOTENDS > 2
#endif // HOTENDS > 1
//
// Laser:
//
#if ENABLED(LASER)
MENU_ITEM_EDIT(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP - 15);
#endif
//
// Bed:
//
#if TEMP_SENSOR_BED != 0
MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_BED, &target_temperature_bed, 0, BED_MAXTEMP - 15);
#endif
//
// Nozzle:
//
#if HOTENDS == 1
#if TEMP_SENSOR_0 != 0
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP - 15, watch_temp_callback_E0);
#endif
#else // HOTENDS > 1
#if TEMP_SENSOR_0 != 0
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE " 0", &target_temperature[0], 0, HEATER_0_MAXTEMP - 15, watch_temp_callback_E0);
#endif
#if TEMP_SENSOR_1 != 0
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE " 1", &target_temperature[1], 0, HEATER_1_MAXTEMP - 15, watch_temp_callback_E1);
#endif
#if HOTENDS > 2
#if TEMP_SENSOR_2 != 0
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE " 2", &target_temperature[2], 0, HEATER_2_MAXTEMP - 15, watch_temp_callback_E2);
#endif
#if HOTENDS > 3
#if TEMP_SENSOR_3 != 0
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, MSG_NOZZLE " 3", &target_temperature[3], 0, HEATER_3_MAXTEMP - 15, watch_temp_callback_E3);
#endif
#endif // HOTENDS > 3
#endif // HOTENDS > 2
#endif // HOTENDS > 1
//
// Fan Speed:
//
MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED, &fanSpeed, 0, 255);
//
// Bed:
//
#if TEMP_SENSOR_BED != 0
MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_BED, &target_temperature_bed, 0, BED_MAXTEMP - 15);
#endif
//
// Flow:
// Flow 1:
// Flow 2:
// Flow 3:
// Flow 4:
//
#if EXTRUDERS == 1
MENU_ITEM_EDIT(int3, MSG_FLOW, &extruder_multiplier[0], 10, 999);
#else // EXTRUDERS > 1
MENU_ITEM_EDIT(int3, MSG_FLOW, &extruder_multiplier[active_extruder], 10, 999);
MENU_ITEM_EDIT(int3, MSG_FLOW " 0", &extruder_multiplier[0], 10, 999);
MENU_ITEM_EDIT(int3, MSG_FLOW " 1", &extruder_multiplier[1], 10, 999);
#if EXTRUDERS > 2
MENU_ITEM_EDIT(int3, MSG_FLOW " 2", &extruder_multiplier[2], 10, 999);
#if EXTRUDERS > 3
MENU_ITEM_EDIT(int3, MSG_FLOW " 3", &extruder_multiplier[3], 10, 999);
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
#endif // EXTRUDERS > 1
//
// Fan Speed:
//
MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED, &fanSpeed, 0, 255);
//
// Flow:
// Flow 1:
// Flow 2:
// Flow 3:
// Flow 4:
//
#if EXTRUDERS == 1
MENU_ITEM_EDIT(int3, MSG_FLOW, &extruder_multiplier[0], 10, 999);
#else // EXTRUDERS > 1
MENU_ITEM_EDIT(int3, MSG_FLOW, &extruder_multiplier[active_extruder], 10, 999);
MENU_ITEM_EDIT(int3, MSG_FLOW " 0", &extruder_multiplier[0], 10, 999);
MENU_ITEM_EDIT(int3, MSG_FLOW " 1", &extruder_multiplier[1], 10, 999);
#if EXTRUDERS > 2
MENU_ITEM_EDIT(int3, MSG_FLOW " 2", &extruder_multiplier[2], 10, 999);
#if EXTRUDERS > 3
MENU_ITEM_EDIT(int3, MSG_FLOW " 3", &extruder_multiplier[3], 10, 999);
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
#endif // EXTRUDERS > 1
//
// Babystep X:
// Babystep Y:
// Babystep Z:
//
#if ENABLED(BABYSTEPPING)
#if ENABLED(BABYSTEP_XY)
MENU_ITEM(submenu, MSG_BABYSTEP_X, lcd_babystep_x);
MENU_ITEM(submenu, MSG_BABYSTEP_Y, lcd_babystep_y);
#endif // BABYSTEP_XY
MENU_ITEM(submenu, MSG_BABYSTEP_Z, lcd_babystep_z);
#endif
//
// Babystep X:
// Babystep Y:
// Babystep Z:
//
#if ENABLED(BABYSTEPPING)
#if ENABLED(BABYSTEP_XY)
MENU_ITEM(submenu, MSG_BABYSTEP_X, lcd_babystep_x);
MENU_ITEM(submenu, MSG_BABYSTEP_Y, lcd_babystep_y);
#endif // BABYSTEP_XY
MENU_ITEM(submenu, MSG_BABYSTEP_Z, lcd_babystep_z);
#endif
MENU_ITEM(function, MSG_FIX_LOSE_STEPS, lcd_tune_fixstep);
MENU_ITEM(function, MSG_FIX_LOSE_STEPS, lcd_tune_fixstep);
//
// Change filament
//
#if ENABLED(FILAMENTCHANGEENABLE)
MENU_ITEM(gcode, MSG_FILAMENTCHANGE, PSTR("M600"));
#endif
//
// Change filament
//
#if ENABLED(FILAMENTCHANGEENABLE)
MENU_ITEM(gcode, MSG_FILAMENTCHANGE, PSTR("M600"));
#endif
END_MENU();
END_MENU();
}
#if ENABLED(EASY_LOAD)
static void lcd_extrude(float length, float feedrate) {
current_position[E_AXIS] += length;
#if MECH(DELTA)
calculate_delta(current_position);
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], feedrate, active_extruder, active_driver);
#else
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate, active_extruder, active_driver);
#endif
}
static void lcd_purge() { lcd_extrude(LCD_PURGE_LENGTH, LCD_PURGE_FEEDRATE); }
static void lcd_retract() { lcd_extrude(-LCD_RETRACT_LENGTH, LCD_RETRACT_FEEDRATE); }
static void lcd_easy_load() {
allow_lengthy_extrude_once = true;
lcd_extrude(BOWDEN_LENGTH, LCD_LOAD_FEEDRATE);
lcd_return_to_status();
}
static void lcd_easy_unload() {
allow_lengthy_extrude_once = true;
lcd_extrude(-BOWDEN_LENGTH, LCD_UNLOAD_FEEDRATE);
lcd_return_to_status();
}
static void lcd_extrude(float length, float feedrate) {
current_position[E_AXIS] += length;
#if MECH(DELTA)
calculate_delta(current_position);
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], feedrate, active_extruder, active_driver);
#else
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate, active_extruder, active_driver);
#endif
}
static void lcd_purge() { lcd_extrude(LCD_PURGE_LENGTH, LCD_PURGE_FEEDRATE); }
static void lcd_retract() { lcd_extrude(-LCD_RETRACT_LENGTH, LCD_RETRACT_FEEDRATE); }
static void lcd_easy_load() {
allow_lengthy_extrude_once = true;
lcd_extrude(BOWDEN_LENGTH, LCD_LOAD_FEEDRATE);
lcd_return_to_status();
}
static void lcd_easy_unload() {
allow_lengthy_extrude_once = true;
lcd_extrude(-BOWDEN_LENGTH, LCD_UNLOAD_FEEDRATE);
lcd_return_to_status();
}
#endif // EASY_LOAD
void _lcd_preheat(int endnum, const float temph, const float tempb, const int fan) {
if (temph > 0) setTargetHotend(temph, endnum);
#if TEMP_SENSOR_BED != 0
setTargetBed(tempb);
#endif
fanSpeed = fan;
lcd_return_to_status();
if (temph > 0) setTargetHotend(temph, endnum);
#if TEMP_SENSOR_BED != 0
setTargetBed(tempb);
#else
UNUSED(tempb);
#endif
fanSpeed = fan;
lcd_return_to_status();
}
#if TEMP_SENSOR_0 != 0
void lcd_preheat_pla0() { _lcd_preheat(0, plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed); }
void lcd_preheat_abs0() { _lcd_preheat(0, absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed); }
void lcd_preheat_gum0() { _lcd_preheat(0, gumPreheatHotendTemp, gumPreheatHPBTemp, gumPreheatFanSpeed); }
void lcd_preheat_pla0() { _lcd_preheat(0, plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed); }
void lcd_preheat_abs0() { _lcd_preheat(0, absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed); }
void lcd_preheat_gum0() { _lcd_preheat(0, gumPreheatHotendTemp, gumPreheatHPBTemp, gumPreheatFanSpeed); }
#endif
#if HOTENDS > 1
void lcd_preheat_pla1() { _lcd_preheat(1, plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed); }
void lcd_preheat_abs1() { _lcd_preheat(1, absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed); }
void lcd_preheat_gum1() { _lcd_preheat(1, gumPreheatHotendTemp, gumPreheatHPBTemp, gumPreheatFanSpeed); }
#if HOTENDS > 2
void lcd_preheat_pla2() { _lcd_preheat(2, plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed); }
void lcd_preheat_abs2() { _lcd_preheat(2, absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed); }
void lcd_preheat_gum2() { _lcd_preheat(2, gumPreheatHotendTemp, gumPreheatHPBTemp, gumPreheatFanSpeed); }
#if HOTENDS > 3
void lcd_preheat_pla3() { _lcd_preheat(3, plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed); }
void lcd_preheat_abs3() { _lcd_preheat(3, absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed); }
void lcd_preheat_gum3() { _lcd_preheat(3, gumPreheatHotendTemp, gumPreheatHPBTemp, gumPreheatFanSpeed); }
#endif
#endif
void lcd_preheat_pla1() { _lcd_preheat(1, plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed); }
void lcd_preheat_abs1() { _lcd_preheat(1, absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed); }
void lcd_preheat_gum1() { _lcd_preheat(1, gumPreheatHotendTemp, gumPreheatHPBTemp, gumPreheatFanSpeed); }
#if HOTENDS > 2
void lcd_preheat_pla2() { _lcd_preheat(2, plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed); }
void lcd_preheat_abs2() { _lcd_preheat(2, absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed); }
void lcd_preheat_gum2() { _lcd_preheat(2, gumPreheatHotendTemp, gumPreheatHPBTemp, gumPreheatFanSpeed); }
#if HOTENDS > 3
void lcd_preheat_pla3() { _lcd_preheat(3, plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed); }
void lcd_preheat_abs3() { _lcd_preheat(3, absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed); }
void lcd_preheat_gum3() { _lcd_preheat(3, gumPreheatHotendTemp, gumPreheatHPBTemp, gumPreheatFanSpeed); }
#endif
#endif
void lcd_preheat_pla0123() {
setTargetHotend0(plaPreheatHotendTemp);
setTargetHotend1(plaPreheatHotendTemp);
setTargetHotend2(plaPreheatHotendTemp);
_lcd_preheat(3, plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed);
}
void lcd_preheat_abs0123() {
setTargetHotend0(absPreheatHotendTemp);
setTargetHotend1(absPreheatHotendTemp);
setTargetHotend2(absPreheatHotendTemp);
_lcd_preheat(3, absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed);
}
void lcd_preheat_gum0123() {
setTargetHotend0(gumPreheatHotendTemp);
setTargetHotend1(gumPreheatHotendTemp);
setTargetHotend2(gumPreheatHotendTemp);
_lcd_preheat(3, gumPreheatHotendTemp, gumPreheatHPBTemp, gumPreheatFanSpeed);
}
void lcd_preheat_pla0123() {
setTargetHotend0(plaPreheatHotendTemp);
setTargetHotend1(plaPreheatHotendTemp);
setTargetHotend2(plaPreheatHotendTemp);
_lcd_preheat(3, plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed);
}
void lcd_preheat_abs0123() {
setTargetHotend0(absPreheatHotendTemp);
setTargetHotend1(absPreheatHotendTemp);
setTargetHotend2(absPreheatHotendTemp);
_lcd_preheat(3, absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed);
}
void lcd_preheat_gum0123() {
setTargetHotend0(gumPreheatHotendTemp);
setTargetHotend1(gumPreheatHotendTemp);
setTargetHotend2(gumPreheatHotendTemp);
_lcd_preheat(3, gumPreheatHotendTemp, gumPreheatHPBTemp, gumPreheatFanSpeed);
}
#endif // HOTENDS > 1
#if TEMP_SENSOR_BED != 0
void lcd_preheat_pla_bedonly() { _lcd_preheat(0, 0, plaPreheatHPBTemp, plaPreheatFanSpeed); }
void lcd_preheat_abs_bedonly() { _lcd_preheat(0, 0, absPreheatHPBTemp, absPreheatFanSpeed); }
void lcd_preheat_gum_bedonly() { _lcd_preheat(0, 0, gumPreheatHPBTemp, gumPreheatFanSpeed); }
void lcd_preheat_pla_bedonly() { _lcd_preheat(0, 0, plaPreheatHPBTemp, plaPreheatFanSpeed); }
void lcd_preheat_abs_bedonly() { _lcd_preheat(0, 0, absPreheatHPBTemp, absPreheatFanSpeed); }
void lcd_preheat_gum_bedonly() { _lcd_preheat(0, 0, gumPreheatHPBTemp, gumPreheatFanSpeed); }
#endif
#if TEMP_SENSOR_0 != 0 && (TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_3 != 0 || TEMP_SENSOR_BED != 0)
static void lcd_preheat_pla_menu() {
START_MENU(lcd_prepare_menu);
MENU_ITEM(back, MSG_PREPARE, lcd_prepare_menu);
#if HOTENDS == 1
MENU_ITEM(function, MSG_PREHEAT_PLA, lcd_preheat_pla0);
#else
MENU_ITEM(function, MSG_PREHEAT_PLA " 0", lcd_preheat_pla0);
MENU_ITEM(function, MSG_PREHEAT_PLA " 1", lcd_preheat_pla1);
#if HOTENDS > 2
MENU_ITEM(function, MSG_PREHEAT_PLA " 2", lcd_preheat_pla2);
#if HOTENDS > 3
MENU_ITEM(function, MSG_PREHEAT_PLA " 3", lcd_preheat_pla3);
#endif
#endif
MENU_ITEM(function, MSG_PREHEAT_PLA_ALL, lcd_preheat_pla0123);
#endif
#if TEMP_SENSOR_BED != 0
MENU_ITEM(function, MSG_PREHEAT_PLA_BEDONLY, lcd_preheat_pla_bedonly);
#endif
END_MENU();
}
static void lcd_preheat_abs_menu() {
START_MENU(lcd_prepare_menu);
MENU_ITEM(back, MSG_TEMPERATURE, lcd_prepare_menu);
#if HOTENDS == 1
MENU_ITEM(function, MSG_PREHEAT_ABS, lcd_preheat_abs0);
#else
MENU_ITEM(function, MSG_PREHEAT_ABS " 0", lcd_preheat_abs0);
MENU_ITEM(function, MSG_PREHEAT_ABS " 1", lcd_preheat_abs1);
#if HOTENDS > 2
MENU_ITEM(function, MSG_PREHEAT_ABS " 2", lcd_preheat_abs2);
#if HOTENDS > 3
MENU_ITEM(function, MSG_PREHEAT_ABS " 3", lcd_preheat_abs3);
#endif
#endif
MENU_ITEM(function, MSG_PREHEAT_ABS_ALL, lcd_preheat_abs0123);
#endif
#if TEMP_SENSOR_BED != 0
MENU_ITEM(function, MSG_PREHEAT_ABS_BEDONLY, lcd_preheat_abs_bedonly);
#endif
END_MENU();
}
static void lcd_preheat_gum_menu() {
START_MENU(lcd_prepare_menu);
MENU_ITEM(back, MSG_TEMPERATURE, lcd_prepare_menu);
#if HOTENDS == 1
MENU_ITEM(function, MSG_PREHEAT_GUM, lcd_preheat_gum0);
#else
MENU_ITEM(function, MSG_PREHEAT_GUM " 0", lcd_preheat_gum0);
MENU_ITEM(function, MSG_PREHEAT_GUM " 1", lcd_preheat_gum1);
#if HOTENDS > 2
MENU_ITEM(function, MSG_PREHEAT_GUM " 2", lcd_preheat_gum2);
#if HOTENDS > 3
MENU_ITEM(function, MSG_PREHEAT_GUM " 3", lcd_preheat_gum3);
#endif
#endif
MENU_ITEM(function, MSG_PREHEAT_GUM_ALL, lcd_preheat_gum0123);
#endif
#if TEMP_SENSOR_BED != 0
MENU_ITEM(function, MSG_PREHEAT_GUM_BEDONLY, lcd_preheat_gum_bedonly);
#endif
END_MENU();
}
static void lcd_preheat_pla_menu() {
START_MENU();
MENU_ITEM(back, MSG_PREPARE);
#if HOTENDS == 1
MENU_ITEM(function, MSG_PREHEAT_PLA, lcd_preheat_pla0);
#else
MENU_ITEM(function, MSG_PREHEAT_PLA " 0", lcd_preheat_pla0);
MENU_ITEM(function, MSG_PREHEAT_PLA " 1", lcd_preheat_pla1);
#if HOTENDS > 2
MENU_ITEM(function, MSG_PREHEAT_PLA " 2", lcd_preheat_pla2);
#if HOTENDS > 3
MENU_ITEM(function, MSG_PREHEAT_PLA " 3", lcd_preheat_pla3);
#endif
#endif
MENU_ITEM(function, MSG_PREHEAT_PLA_ALL, lcd_preheat_pla0123);
#endif
#if TEMP_SENSOR_BED != 0
MENU_ITEM(function, MSG_PREHEAT_PLA_BEDONLY, lcd_preheat_pla_bedonly);
#endif
END_MENU();
}
static void lcd_preheat_abs_menu() {
START_MENU();
MENU_ITEM(back, MSG_TEMPERATURE);
#if HOTENDS == 1
MENU_ITEM(function, MSG_PREHEAT_ABS, lcd_preheat_abs0);
#else
MENU_ITEM(function, MSG_PREHEAT_ABS " 0", lcd_preheat_abs0);
MENU_ITEM(function, MSG_PREHEAT_ABS " 1", lcd_preheat_abs1);
#if HOTENDS > 2
MENU_ITEM(function, MSG_PREHEAT_ABS " 2", lcd_preheat_abs2);
#if HOTENDS > 3
MENU_ITEM(function, MSG_PREHEAT_ABS " 3", lcd_preheat_abs3);
#endif
#endif
MENU_ITEM(function, MSG_PREHEAT_ABS_ALL, lcd_preheat_abs0123);
#endif
#if TEMP_SENSOR_BED != 0
MENU_ITEM(function, MSG_PREHEAT_ABS_BEDONLY, lcd_preheat_abs_bedonly);
#endif
END_MENU();
}
static void lcd_preheat_gum_menu() {
START_MENU();
MENU_ITEM(back, MSG_TEMPERATURE);
#if HOTENDS == 1
MENU_ITEM(function, MSG_PREHEAT_GUM, lcd_preheat_gum0);
#else
MENU_ITEM(function, MSG_PREHEAT_GUM " 0", lcd_preheat_gum0);
MENU_ITEM(function, MSG_PREHEAT_GUM " 1", lcd_preheat_gum1);
#if HOTENDS > 2
MENU_ITEM(function, MSG_PREHEAT_GUM " 2", lcd_preheat_gum2);
#if HOTENDS > 3
MENU_ITEM(function, MSG_PREHEAT_GUM " 3", lcd_preheat_gum3);
#endif
#endif
MENU_ITEM(function, MSG_PREHEAT_GUM_ALL, lcd_preheat_gum0123);
#endif
#if TEMP_SENSOR_BED != 0
MENU_ITEM(function, MSG_PREHEAT_GUM_BEDONLY, lcd_preheat_gum_bedonly);
#endif
END_MENU();
}
#endif // TEMP_SENSOR_0 && (TEMP_SENSOR_1 || TEMP_SENSOR_2 || TEMP_SENSOR_3 || TEMP_SENSOR_BED)
void lcd_cooldown() {
disable_all_heaters();
fanSpeed = 0;
lcd_return_to_status();
disable_all_heaters();
fanSpeed = 0;
lcd_return_to_status();
}
/**
*
* "Prepare" submenu
*
*/
*
* "Prepare" submenu
*
*/
static void lcd_prepare_menu() {
START_MENU(lcd_main_menu);
//
// ^ Main
//
MENU_ITEM(back, MSG_MAIN, lcd_main_menu);
//
// Auto Home
//
#if ENABLED(LASER)
MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28 X Y F2000"));
#else
MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28"));
#endif
//
// Set Home Offsets
//
MENU_ITEM(function, MSG_SET_HOME_OFFSETS, lcd_set_home_offsets);
//MENU_ITEM(gcode, MSG_SET_ORIGIN, PSTR("G92 X0 Y0 Z0"));
//
// Level Bed
//
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
if (axis_known_position & (_BV(X_AXIS)|_BV(Y_AXIS)) == (_BV(X_AXIS)|_BV(Y_AXIS)))
MENU_ITEM(gcode, MSG_LEVEL_BED, PSTR("G29"));
#elif !MECH(DELTA) && DISABLED(Z_SAFE_HOMING) && Z_HOME_DIR < 0
MENU_ITEM(submenu, MSG_MBL_SETTING, config_lcd_level_bed);
#endif
START_MENU();
//
// Move Axis
//
MENU_ITEM(submenu, MSG_MOVE_AXIS, lcd_move_menu);
//
// ^ Main
//
MENU_ITEM(back, MSG_MAIN);
//
// Disable Steppers
//
MENU_ITEM(gcode, MSG_DISABLE_STEPPERS, PSTR("M84"));
//
// Auto Home
//
#if ENABLED(LASER)
MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28 X Y F2000"));
#else
MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28"));
#endif
//
// Preheat PLA
// Preheat ABS
// Preheat GUM
//
#if TEMP_SENSOR_0 != 0 && DISABLED(LASER)
#if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_3 != 0 || TEMP_SENSOR_BED != 0
MENU_ITEM(submenu, MSG_PREHEAT_PLA, lcd_preheat_pla_menu);
MENU_ITEM(submenu, MSG_PREHEAT_ABS, lcd_preheat_abs_menu);
MENU_ITEM(submenu, MSG_PREHEAT_GUM, lcd_preheat_gum_menu);
#else
MENU_ITEM(function, MSG_PREHEAT_PLA, lcd_preheat_pla0);
MENU_ITEM(function, MSG_PREHEAT_ABS, lcd_preheat_abs0);
MENU_ITEM(function, MSG_PREHEAT_GUM, lcd_preheat_gum0);
#endif
#endif
//
// Set Home Offsets
//
MENU_ITEM(function, MSG_SET_HOME_OFFSETS, lcd_set_home_offsets);
//MENU_ITEM(gcode, MSG_SET_ORIGIN, PSTR("G92 X0 Y0 Z0"));
//
// Level Bed
//
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
MENU_ITEM(gcode, MSG_LEVEL_BED,
axis_homed[X_AXIS] && axis_homed[Y_AXIS] ? PSTR("G29") : PSTR("G28\nG29")
);
#elif !MECH(DELTA) && DISABLED(Z_SAFE_HOMING) && Z_HOME_DIR < 0
MENU_ITEM(submenu, MSG_MBL_SETTING, config_lcd_level_bed);
#endif
//
// Easy Load
//
#if ENABLED(EASY_LOAD)
MENU_ITEM(function, MSG_E_BOWDEN_LENGTH, lcd_easy_load);
MENU_ITEM(function, MSG_R_BOWDEN_LENGTH, lcd_easy_unload);
MENU_ITEM(function, MSG_PURGE_XMM, lcd_purge);
MENU_ITEM(function, MSG_RETRACT_XMM, lcd_retract);
#endif // EASY_LOAD
//
// Move Axis
//
MENU_ITEM(submenu, MSG_MOVE_AXIS, lcd_move_menu);
//
// Disable Steppers
//
MENU_ITEM(gcode, MSG_DISABLE_STEPPERS, PSTR("M84"));
//
// Preheat PLA
// Preheat ABS
// Preheat GUM
//
#if TEMP_SENSOR_0 != 0 && DISABLED(LASER)
#if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_3 != 0 || TEMP_SENSOR_BED != 0
MENU_ITEM(submenu, MSG_PREHEAT_PLA, lcd_preheat_pla_menu);
MENU_ITEM(submenu, MSG_PREHEAT_ABS, lcd_preheat_abs_menu);
MENU_ITEM(submenu, MSG_PREHEAT_GUM, lcd_preheat_gum_menu);
#else
MENU_ITEM(function, MSG_PREHEAT_PLA, lcd_preheat_pla0);
MENU_ITEM(function, MSG_PREHEAT_ABS, lcd_preheat_abs0);
MENU_ITEM(function, MSG_PREHEAT_GUM, lcd_preheat_gum0);
#endif
#endif
//
// LASER BEAM
//
#if ENABLED(LASERBEAM)
MENU_ITEM_EDIT(int3, MSG_LASER, &laser_ttl_modulation, 0, 255);
if(laser_ttl_modulation == 0) {
WRITE(LASER_PWR_PIN, LOW);
}
else {
WRITE(LASER_PWR_PIN, HIGH);
}
#endif
//
// Easy Load
//
#if ENABLED(EASY_LOAD)
MENU_ITEM(function, MSG_E_BOWDEN_LENGTH, lcd_easy_load);
MENU_ITEM(function, MSG_R_BOWDEN_LENGTH, lcd_easy_unload);
MENU_ITEM(function, MSG_PURGE_XMM, lcd_purge);
MENU_ITEM(function, MSG_RETRACT_XMM, lcd_retract);
#endif // EASY_LOAD
//
// Cooldown
//
MENU_ITEM(function, MSG_COOLDOWN, lcd_cooldown);
//
// LASER BEAM
//
#if ENABLED(LASERBEAM)
MENU_ITEM_EDIT(int3, MSG_LASER, &laser_ttl_modulation, 0, 255);
if(laser_ttl_modulation == 0) {
WRITE(LASER_PWR_PIN, LOW);
}
else {
WRITE(LASER_PWR_PIN, HIGH);
}
#endif
//
// Switch power on/off
//
#if HAS(POWER_SWITCH)
if (powersupply)
MENU_ITEM(gcode, MSG_SWITCH_PS_OFF, PSTR("M81"));
else
MENU_ITEM(gcode, MSG_SWITCH_PS_ON, PSTR("M80"));
#endif
//
// Cooldown
//
MENU_ITEM(function, MSG_COOLDOWN, lcd_cooldown);
//
// Switch power on/off
//
#if HAS(POWER_SWITCH)
if (powersupply)
MENU_ITEM(gcode, MSG_SWITCH_PS_OFF, PSTR("M81"));
else
MENU_ITEM(gcode, MSG_SWITCH_PS_ON, PSTR("M80"));
#endif
//
// Autostart
//
#if ENABLED(SDSUPPORT) && ENABLED(MENU_ADDAUTOSTART)
MENU_ITEM(function, MSG_AUTOSTART, lcd_autostart_sd);
#endif
//
// Autostart
//
#if ENABLED(SDSUPPORT) && ENABLED(MENU_ADDAUTOSTART)
MENU_ITEM(function, MSG_AUTOSTART, lcd_autostart_sd);
#endif
END_MENU();
END_MENU();
}
#if MECH(DELTA)
static void lcd_delta_calibrate_menu() {
START_MENU(lcd_main_menu);
MENU_ITEM(back, MSG_MAIN, lcd_main_menu);
MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28"));
MENU_ITEM(gcode, MSG_DELTA_CALIBRATE_X, PSTR("G0 F8000 X-77.94 Y-45 Z0"));
MENU_ITEM(gcode, MSG_DELTA_CALIBRATE_Y, PSTR("G0 F8000 X77.94 Y-45 Z0"));
MENU_ITEM(gcode, MSG_DELTA_CALIBRATE_Z, PSTR("G0 F8000 X0 Y90 Z0"));
MENU_ITEM(gcode, MSG_DELTA_CALIBRATE_CENTER, PSTR("G0 F8000 X0 Y0 Z0"));
END_MENU();
}
static void lcd_delta_calibrate_menu() {
START_MENU();
MENU_ITEM(back, MSG_MAIN);
MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28"));
MENU_ITEM(gcode, MSG_DELTA_CALIBRATE_X, PSTR("G0 F8000 X-77.94 Y-45 Z0"));
MENU_ITEM(gcode, MSG_DELTA_CALIBRATE_Y, PSTR("G0 F8000 X77.94 Y-45 Z0"));
MENU_ITEM(gcode, MSG_DELTA_CALIBRATE_Z, PSTR("G0 F8000 X0 Y90 Z0"));
MENU_ITEM(gcode, MSG_DELTA_CALIBRATE_CENTER, PSTR("G0 F8000 X0 Y0 Z0"));
END_MENU();
}
#endif // DELTA
inline void line_to_current(float feedrate) {
#if MECH(DELTA)
calculate_delta(current_position);
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], feedrate/60, active_extruder, active_driver);
#else
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate/60, active_extruder, active_driver);
#endif
}
/**
*
* "Prepare" > "Move Axis" submenu
*
*/
*
* "Prepare" > "Move Axis" submenu
*
*/
float move_menu_scale;
static void lcd_move_menu_axis();
static void _lcd_move(const char* name, AxisEnum axis, int min, int max) {
if (encoderPosition != 0) {
refresh_cmd_timeout();
current_position[axis] += float((int)encoderPosition) * move_menu_scale;
if (SOFTWARE_MIN_ENDSTOPS) NOLESS(current_position[axis], min);
if (SOFTWARE_MAX_ENDSTOPS) NOMORE(current_position[axis], max);
encoderPosition = 0;
line_to_current(manual_feedrate[axis]);
lcdDrawUpdate = 1;
}
if (lcdDrawUpdate) lcd_implementation_drawedit(name, ftostr31(current_position[axis]));
if (LCD_CLICKED) lcd_goto_menu(lcd_move_menu_axis);
ENCODER_DIRECTION_NORMAL();
if (encoderPosition != 0) {
refresh_cmd_timeout();
current_position[axis] += float((int)encoderPosition) * move_menu_scale;
if (SOFTWARE_MIN_ENDSTOPS) NOLESS(current_position[axis], min);
if (SOFTWARE_MAX_ENDSTOPS) NOMORE(current_position[axis], max);
encoderPosition = 0;
line_to_current(axis);
lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
}
encoderPosition = 0;
if (lcdDrawUpdate) lcd_implementation_drawedit(name, ftostr31(current_position[axis]));
if (LCD_CLICKED) lcd_goto_previous_menu(true);
}
#if MECH(DELTA)
static float delta_clip_radius_2 = DELTA_PRINTABLE_RADIUS * DELTA_PRINTABLE_RADIUS;
static int delta_clip( float a ) { return sqrt(delta_clip_radius_2 - a * a); }
static void lcd_move_x() { int clip = delta_clip(current_position[Y_AXIS]); _lcd_move(PSTR(MSG_MOVE_X), X_AXIS, max(X_MIN_POS, -clip), min(X_MAX_POS, clip)); }
static void lcd_move_y() { int clip = delta_clip(current_position[X_AXIS]); _lcd_move(PSTR(MSG_MOVE_X), X_AXIS, max(X_MIN_POS, -clip), min(X_MAX_POS, clip)); }
static float delta_clip_radius_2 = DELTA_PRINTABLE_RADIUS * DELTA_PRINTABLE_RADIUS;
static int delta_clip( float a ) { return sqrt(delta_clip_radius_2 - a * a); }
static void lcd_move_x() { int clip = delta_clip(current_position[Y_AXIS]); _lcd_move(PSTR(MSG_MOVE_X), X_AXIS, max(X_MIN_POS, -clip), min(X_MAX_POS, clip)); }
static void lcd_move_y() { int clip = delta_clip(current_position[X_AXIS]); _lcd_move(PSTR(MSG_MOVE_X), X_AXIS, max(X_MIN_POS, -clip), min(X_MAX_POS, clip)); }
#else
static void lcd_move_x() { _lcd_move(PSTR(MSG_MOVE_X), X_AXIS, X_MIN_POS, X_MAX_POS); }
static void lcd_move_y() { _lcd_move(PSTR(MSG_MOVE_Y), Y_AXIS, Y_MIN_POS, Y_MAX_POS); }
static void lcd_move_x() { _lcd_move(PSTR(MSG_MOVE_X), X_AXIS, X_MIN_POS, X_MAX_POS); }
static void lcd_move_y() { _lcd_move(PSTR(MSG_MOVE_Y), Y_AXIS, Y_MIN_POS, Y_MAX_POS); }
#endif
static void lcd_move_z() { _lcd_move(PSTR(MSG_MOVE_Z), Z_AXIS, Z_MIN_POS, Z_MAX_POS); }
static void lcd_move_e(
#if EXTRUDERS > 1
uint8_t e
#endif
#if EXTRUDERS > 1
uint8_t e
#endif
) {
#if EXTRUDERS > 1
unsigned short original_active_extruder = active_extruder;
active_extruder = e;
#endif
if (encoderPosition != 0) {
#if ENABLED(IDLE_OOZING_PREVENT)
IDLE_OOZING_retract(false);
#endif
current_position[E_AXIS] += float((int)encoderPosition) * move_menu_scale;
encoderPosition = 0;
line_to_current(manual_feedrate[E_AXIS]);
lcdDrawUpdate = 1;
}
if (lcdDrawUpdate) {
PGM_P pos_label;
#if EXTRUDERS == 1
pos_label = PSTR(MSG_MOVE_E);
#else
switch (e) {
case 0: pos_label = PSTR(MSG_MOVE_E "0"); break;
case 1: pos_label = PSTR(MSG_MOVE_E "1"); break;
#if EXTRUDERS > 2
case 2: pos_label = PSTR(MSG_MOVE_E "2"); break;
#if EXTRUDERS > 3
case 3: pos_label = PSTR(MSG_MOVE_E "3"); break;
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
}
#endif // EXTRUDERS > 1
lcd_implementation_drawedit(pos_label, ftostr31(current_position[E_AXIS]));
}
if (LCD_CLICKED) lcd_goto_menu(lcd_move_menu_axis);
#if EXTRUDERS > 1
active_extruder = original_active_extruder;
#endif
ENCODER_DIRECTION_NORMAL();
#if EXTRUDERS > 1
unsigned short original_active_extruder = active_extruder;
active_extruder = e;
#endif
if (encoderPosition != 0) {
#if ENABLED(IDLE_OOZING_PREVENT)
IDLE_OOZING_retract(false);
#endif
current_position[E_AXIS] += float((int)encoderPosition) * move_menu_scale;
line_to_current(E_AXIS);
lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
}
encoderPosition = 0;
if (lcdDrawUpdate) {
PGM_P pos_label;
#if EXTRUDERS == 1
pos_label = PSTR(MSG_MOVE_E);
#else
switch (e) {
case 0: pos_label = PSTR(MSG_MOVE_E "0"); break;
case 1: pos_label = PSTR(MSG_MOVE_E "1"); break;
#if EXTRUDERS > 2
case 2: pos_label = PSTR(MSG_MOVE_E "2"); break;
#if EXTRUDERS > 3
case 3: pos_label = PSTR(MSG_MOVE_E "3"); break;
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
}
#endif // EXTRUDERS > 1
lcd_implementation_drawedit(pos_label, ftostr31(current_position[E_AXIS]));
}
if (LCD_CLICKED) lcd_goto_previous_menu(true);
#if EXTRUDERS > 1
active_extruder = original_active_extruder;
#endif
}
#if EXTRUDERS > 1
static void lcd_move_e0() { lcd_move_e(0); }
static void lcd_move_e1() { lcd_move_e(1); }
#if EXTRUDERS > 2
static void lcd_move_e2() { lcd_move_e(2); }
#if EXTRUDERS > 3
static void lcd_move_e3() { lcd_move_e(3); }
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
static void lcd_move_e0() { lcd_move_e(0); }
static void lcd_move_e1() { lcd_move_e(1); }
#if EXTRUDERS > 2
static void lcd_move_e2() { lcd_move_e(2); }
#if EXTRUDERS > 3
static void lcd_move_e3() { lcd_move_e(3); }
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
#endif // EXTRUDERS > 1
/**
*
* "Prepare" > "Move Xmm" > "Move XYZ" submenu
*
*/
*
* "Prepare" > "Move Xmm" > "Move XYZ" submenu
*
*/
#if MECH(DELTA) || MECH(SCARA)
#define _MOVE_XYZ_ALLOWED (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS])
#else
#define _MOVE_XYZ_ALLOWED true
#endif
static void lcd_move_menu_axis() {
START_MENU(lcd_move_menu);
MENU_ITEM(back, MSG_MOVE_AXIS, lcd_move_menu);
MENU_ITEM(submenu, MSG_MOVE_X, lcd_move_x);
MENU_ITEM(submenu, MSG_MOVE_Y, lcd_move_y);
MENU_ITEM(submenu, MSG_MOVE_Z, lcd_move_z);
if (move_menu_scale < 10.0) {
#if EXTRUDERS == 1
MENU_ITEM(submenu, MSG_MOVE_E, lcd_move_e);
#else
MENU_ITEM(submenu, MSG_MOVE_E "0", lcd_move_e0);
MENU_ITEM(submenu, MSG_MOVE_E "1", lcd_move_e1);
#if EXTRUDERS > 2
MENU_ITEM(submenu, MSG_MOVE_E "2", lcd_move_e2);
#if EXTRUDERS > 3
MENU_ITEM(submenu, MSG_MOVE_E "3", lcd_move_e3);
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
#endif // EXTRUDERS > 1
}
END_MENU();
START_MENU();
MENU_ITEM(back, MSG_MOVE_AXIS);
if (_MOVE_XYZ_ALLOWED) {
MENU_ITEM(submenu, MSG_MOVE_X, lcd_move_x);
MENU_ITEM(submenu, MSG_MOVE_Y, lcd_move_y);
MENU_ITEM(submenu, MSG_MOVE_Z, lcd_move_z);
}
if (move_menu_scale < 10.0) {
#if EXTRUDERS == 1
MENU_ITEM(submenu, MSG_MOVE_E, lcd_move_e);
#else
MENU_ITEM(submenu, MSG_MOVE_E "0", lcd_move_e0);
MENU_ITEM(submenu, MSG_MOVE_E "1", lcd_move_e1);
#if EXTRUDERS > 2
MENU_ITEM(submenu, MSG_MOVE_E "2", lcd_move_e2);
#if EXTRUDERS > 3
MENU_ITEM(submenu, MSG_MOVE_E "3", lcd_move_e3);
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
#endif // EXTRUDERS > 1
}
END_MENU();
}
static void lcd_move_menu_10mm() {
move_menu_scale = 10.0;
lcd_move_menu_axis();
move_menu_scale = 10.0;
lcd_move_menu_axis();
}
static void lcd_move_menu_1mm() {
move_menu_scale = 1.0;
lcd_move_menu_axis();
move_menu_scale = 1.0;
lcd_move_menu_axis();
}
static void lcd_move_menu_01mm() {
move_menu_scale = 0.1;
lcd_move_menu_axis();
move_menu_scale = 0.1;
lcd_move_menu_axis();
}
/**
*
* "Prepare" > "Move Axis" submenu
*
*/
*
* "Prepare" > "Move Axis" submenu
*
*/
static void lcd_move_menu() {
START_MENU(lcd_prepare_menu);
MENU_ITEM(back, MSG_MOTION, lcd_prepare_menu);
MENU_ITEM(submenu, MSG_MOVE_10MM, lcd_move_menu_10mm);
MENU_ITEM(submenu, MSG_MOVE_1MM, lcd_move_menu_1mm);
MENU_ITEM(submenu, MSG_MOVE_01MM, lcd_move_menu_01mm);
// TODO:X,Y,Z,E
END_MENU();
START_MENU();
MENU_ITEM(back, MSG_PREPARE);
if (_MOVE_XYZ_ALLOWED)
MENU_ITEM(submenu, MSG_MOVE_10MM, lcd_move_menu_10mm);
MENU_ITEM(submenu, MSG_MOVE_1MM, lcd_move_menu_1mm);
MENU_ITEM(submenu, MSG_MOVE_01MM, lcd_move_menu_01mm);
// TODO:X,Y,Z,E
END_MENU();
}
/**
*
* "Control" submenu
*
*/
*
* "Control" submenu
*
*/
static void lcd_control_menu() {
START_MENU(lcd_main_menu);
MENU_ITEM(back, MSG_MAIN, lcd_main_menu);
START_MENU();
MENU_ITEM(back, MSG_MAIN);
#if DISABLED(LASER)
MENU_ITEM(submenu, MSG_TEMPERATURE, lcd_control_temperature_menu);
#endif
......@@ -1193,6 +1344,33 @@ static void lcd_stats_menu() {
*
*/
#if ENABLED(PID_AUTOTUNE_MENU)
#if ENABLED(PIDTEMP)
int autotune_temp[HOTENDS] = { 150 };
const int heater_maxtemp[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP);
#endif
#if ENABLED(PIDTEMPBED)
int autotune_temp_bed = 70;
#endif
static void _lcd_autotune(int h) {
char cmd[30];
sprintf_P(cmd, PSTR("M303 U1 H%i S%i"), h,
#if HAS_PID_FOR_BOTH
h < 0 ? autotune_temp_bed : autotune_temp[h]
#elif ENABLED(PIDTEMPBED)
autotune_temp_bed
#else
autotune_temp[h]
#endif
);
enqueue_and_echo_command(cmd);
}
#endif //PID_AUTOTUNE_MENU
#if ENABLED(PIDTEMP)
// Helpers for editing PID Ki & Kd values
......@@ -1205,16 +1383,25 @@ static void lcd_stats_menu() {
PID_PARAM(Kd, h) = scalePID_d(raw_Kd);
updatePID();
}
#define COPY_AND_SCALE(hindex) \
#define _PIDTEMP_BASE_FUNCTIONS(hindex) \
void copy_and_scalePID_i_H ## hindex() { copy_and_scalePID_i(hindex); } \
void copy_and_scalePID_d_H ## hindex() { copy_and_scalePID_d(hindex); }
COPY_AND_SCALE(0);
#if ENABLED(PID_AUTOTUNE_MENU)
#define _PIDTEMP_FUNCTIONS(hindex) \
_PIDTEMP_BASE_FUNCTIONS(hindex); \
void lcd_autotune_callback_H ## hindex() { _lcd_autotune(hindex); }
#else
#define _PIDTEMP_FUNCTIONS(hindex) _PIDTEMP_BASE_FUNCTIONS(hindex)
#endif
_PIDTEMP_FUNCTIONS(0);
#if HOTENDS > 1
COPY_AND_SCALE(1);
_PIDTEMP_FUNCTIONS(1);
#if HOTENDS > 2
COPY_AND_SCALE(2);
_PIDTEMP_FUNCTIONS(2);
#if HOTENDS > 3
COPY_AND_SCALE(3);
_PIDTEMP_FUNCTIONS(3);
#endif // HOTENDS > 3
#endif // HOTENDS > 2
#endif // HOTENDS > 1
......@@ -1228,12 +1415,12 @@ static void lcd_stats_menu() {
*/
#if DISABLED(LASER)
static void lcd_control_temperature_menu() {
START_MENU(lcd_control_menu);
START_MENU();
//
// ^ Control
//
MENU_ITEM(back, MSG_CONTROL, lcd_control_menu);
MENU_ITEM(back, MSG_CONTROL);
//
// Nozzle:
......@@ -1284,40 +1471,43 @@ static void lcd_control_temperature_menu() {
#endif
//
// PID-P, PID-I, PID-D
// PID-P, PID-I, PID-D, PID-C, PID Autotune
// PID-P H1, PID-I H1, PID-D H1, PID-C H1, PID Autotune H1
// PID-P H2, PID-I H2, PID-D H2, PID-C H2, PID Autotune H2
// PID-P H3, PID-I H3, PID-D H3, PID-C H3, PID Autotune H3
// PID-P H4, PID-I H4, PID-D H4, PID-C H4, PID Autotune H4
//
#if ENABLED(PIDTEMP)
// set up temp variables - undo the default scaling
raw_Ki = unscalePID_i(PID_PARAM(Ki, 0));
raw_Kd = unscalePID_d(PID_PARAM(Kd, 0));
MENU_ITEM_EDIT(float52, MSG_PID_P, &PID_PARAM(Kp,0), 1, 9990);
// i is typically a small value so allows values below 1
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I, &raw_Ki, 0.01, 9990, copy_and_scalePID_i_H0);
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D, &raw_Kd, 1, 9990, copy_and_scalePID_d_H0);
#define _PID_BASE_MENU_ITEMS(HLABEL, hindex) \
raw_Ki = unscalePID_i(PID_PARAM(Ki, hindex)); \
raw_Kd = unscalePID_d(PID_PARAM(Kd, hindex)); \
MENU_ITEM_EDIT(float52, MSG_PID_P HLABEL, &PID_PARAM(Kp, hindex), 1, 9990); \
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I HLABEL, &raw_Ki, 0.01, 9990, copy_and_scalePID_i_H ## hindex); \
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D HLABEL, &raw_Kd, 1, 9990, copy_and_scalePID_d_H ## hindex)
#if ENABLED(PID_ADD_EXTRUSION_RATE)
#define _PID_MENU_ITEMS(HLABEL, hindex) \
_PID_BASE_MENU_ITEMS(HLABEL, hindex); \
MENU_ITEM_EDIT(float3, MSG_PID_C HLABEL, &PID_PARAM(Kc, hindex), 1, 9990)
#else
#define _PID_MENU_ITEMS(HLABEL, hindex) _PID_BASE_MENU_ITEMS(HLABEL, hindex)
#endif
#if ENABLED(PID_AUTOTUNE_MENU)
#define PID_MENU_ITEMS(HLABEL, hindex) \
_PID_MENU_ITEMS(HLABEL, hindex); \
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(int3, SERIAL_PID_AUTOTUNE HLABEL, &autotune_temp[hindex], 150, heater_maxtemp[hindex] - 15, lcd_autotune_callback_H ## hindex)
#else
#define PID_MENU_ITEMS(HLABEL, hindex) _PID_MENU_ITEMS(HLABEL, hindex)
#endif
PID_MENU_ITEMS("", 0);
#if HOTENDS > 1
// set up temp variables - undo the default scaling
raw_Ki = unscalePID_i(PID_PARAM(Ki, 1));
raw_Kd = unscalePID_d(PID_PARAM(Kd, 1));
MENU_ITEM_EDIT(float52, MSG_PID_P MSG_H1, &PID_PARAM(Kp,1), 1, 9990);
// i is typically a small value so allows values below 1
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I MSG_H1, &raw_Ki, 0.01, 9990, copy_and_scalePID_i_H1);
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D MSG_H1, &raw_Kd, 1, 9990, copy_and_scalePID_d_H1);
PID_MENU_ITEMS(MSG_H1, 1);
#if HOTENDS > 2
// set up temp variables - undo the default scaling
raw_Ki = unscalePID_i(PID_PARAM(Ki, 2));
raw_Kd = unscalePID_d(PID_PARAM(Kd, 2));
MENU_ITEM_EDIT(float52, MSG_PID_P MSG_H2, &PID_PARAM(Kp,2), 1, 9990);
// i is typically a small value so allows values below 1
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I MSG_H2, &raw_Ki, 0.01, 9990, copy_and_scalePID_i_H2);
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D MSG_H2, &raw_Kd, 1, 9990, copy_and_scalePID_d_H2);
PID_MENU_ITEMS(MSG_H2, 2);
#if HOTENDS > 3
// set up temp variables - undo the default scaling
raw_Ki = unscalePID_i(PID_PARAM(Ki, 3));
raw_Kd = unscalePID_d(PID_PARAM(Kd, 3));
MENU_ITEM_EDIT(float52, MSG_PID_P MSG_H3, &PID_PARAM(Kp,3), 1, 9990);
// i is typically a small value so allows values below 1
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I MSG_H3, &raw_Ki, 0.01, 9990, copy_and_scalePID_i_H3);
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D MSG_H3, &raw_Kd, 1, 9990, copy_and_scalePID_d_H3);
PID_MENU_ITEMS(MSG_H3, 3);
#endif // HOTENDS > 3
#endif // HOTENDS > 2
#endif // HOTENDS > 1
......@@ -1358,8 +1548,8 @@ static void lcd_control_temperature_menu() {
*/
#if DISABLED(LASER)
static void lcd_control_temperature_preheat_pla_settings_menu() {
START_MENU(lcd_control_temperature_menu);
MENU_ITEM(back, MSG_TEMPERATURE, lcd_control_temperature_menu);
START_MENU();
MENU_ITEM(back, MSG_TEMPERATURE);
MENU_ITEM_EDIT(int3, MSG_FAN_SPEED, &plaPreheatFanSpeed, 0, 255);
#if TEMP_SENSOR_0 != 0
MENU_ITEM_EDIT(int3, MSG_NOZZLE, &plaPreheatHotendTemp, HEATER_0_MINTEMP, HEATER_0_MAXTEMP - 15);
......@@ -1381,8 +1571,8 @@ static void lcd_control_temperature_preheat_pla_settings_menu() {
*/
#if DISABLED(LASER)
static void lcd_control_temperature_preheat_abs_settings_menu() {
START_MENU(lcd_control_temperature_menu);
MENU_ITEM(back, MSG_TEMPERATURE, lcd_control_temperature_menu);
START_MENU();
MENU_ITEM(back, MSG_TEMPERATURE);
MENU_ITEM_EDIT(int3, MSG_FAN_SPEED, &absPreheatFanSpeed, 0, 255);
#if TEMP_SENSOR_0 != 0
MENU_ITEM_EDIT(int3, MSG_NOZZLE, &absPreheatHotendTemp, HEATER_0_MINTEMP, HEATER_0_MAXTEMP - 15);
......@@ -1403,8 +1593,8 @@ static void lcd_control_temperature_preheat_abs_settings_menu() {
*/
#if DISABLED(LASER)
static void lcd_control_temperature_preheat_gum_settings_menu() {
START_MENU(lcd_control_temperature_menu);
MENU_ITEM(back, MSG_TEMPERATURE, lcd_control_temperature_menu);
START_MENU();
MENU_ITEM(back, MSG_TEMPERATURE);
MENU_ITEM_EDIT(int3, MSG_FAN_SPEED, &gumPreheatFanSpeed, 0, 255);
#if TEMP_SENSOR_0 != 0
MENU_ITEM_EDIT(int3, MSG_NOZZLE, &gumPreheatHotendTemp, HEATER_0_MINTEMP, HEATER_0_MAXTEMP - 15);
......@@ -1424,8 +1614,8 @@ static void lcd_control_temperature_preheat_gum_settings_menu() {
*
*/
static void lcd_control_motion_menu() {
START_MENU(lcd_control_menu);
MENU_ITEM(back, MSG_CONTROL, lcd_control_menu);
START_MENU();
MENU_ITEM(back, MSG_CONTROL);
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
MENU_ITEM_EDIT(float32, MSG_ZPROBE_ZOFFSET, &zprobe_zoffset, -50, 50);
#endif
......@@ -1490,8 +1680,8 @@ static void lcd_control_motion_menu() {
*/
#if DISABLED(LASER)
static void lcd_control_volumetric_menu() {
START_MENU(lcd_control_menu);
MENU_ITEM(back, MSG_CONTROL, lcd_control_menu);
START_MENU();
MENU_ITEM(back, MSG_CONTROL);
MENU_ITEM_EDIT_CALLBACK(bool, MSG_VOLUMETRIC_ENABLED, &volumetric_enabled, calculate_volumetric_multipliers);
......@@ -1521,6 +1711,7 @@ static void lcd_control_volumetric_menu() {
*/
#if HAS(LCD_CONTRAST)
static void lcd_set_contrast() {
ENCODER_DIRECTION_NORMAL();
if (encoderPosition != 0) {
#if ENABLED(U8GLIB_LM6059_AF)
lcd_contrast += encoderPosition;
......@@ -1540,7 +1731,7 @@ static void lcd_control_volumetric_menu() {
lcd_implementation_drawedit(PSTR(MSG_CONTRAST), itostr2(lcd_contrast));
#endif
}
if (LCD_CLICKED) lcd_goto_menu(lcd_control_menu);
if (LCD_CLICKED) lcd_goto_previous_menu(true);
}
#endif // HAS(LCD_CONTRAST)
......@@ -1551,8 +1742,8 @@ static void lcd_control_volumetric_menu() {
*/
#if ENABLED(FWRETRACT)
static void lcd_control_retract_menu() {
START_MENU(lcd_control_menu);
MENU_ITEM(back, MSG_CONTROL, lcd_control_menu);
START_MENU();
MENU_ITEM(back, MSG_CONTROL);
MENU_ITEM_EDIT(bool, MSG_AUTORETRACT, &autoretract_enabled);
MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT, &retract_length, 0, 100);
#if EXTRUDERS > 1
......@@ -1712,8 +1903,8 @@ static void laser_set_focus(float f_length) {
void lcd_sdcard_menu() {
if (lcdDrawUpdate == 0 && LCD_CLICKED == 0) return; // nothing to do (so don't thrash the SD card)
uint16_t fileCnt = card.getnrfilenames();
START_MENU(lcd_main_menu);
MENU_ITEM(back, MSG_MAIN, lcd_main_menu);
START_MENU();
MENU_ITEM(back, MSG_MAIN);
card.getWorkDirName();
if (fullName[0] == '/') {
#if !PIN_EXISTS(SD_DETECT)
......@@ -1750,9 +1941,31 @@ static void laser_set_focus(float f_length) {
*
* Functions for editing single values
*
* The "menu_edit_type" macro generates the functions needed to edit a numerical value.
*
* For example, menu_edit_type(int, int3, itostr3, 1) expands into these functions:
*
* bool _menu_edit_int3();
* void menu_edit_int3(); // edit int (interactively)
* void menu_edit_callback_int3(); // edit int (interactively) with callback on completion
* static void _menu_action_setting_edit_int3(const char* pstr, int* ptr, int minValue, int maxValue);
* static void menu_action_setting_edit_int3(const char* pstr, int* ptr, int minValue, int maxValue);
* static void menu_action_setting_edit_callback_int3(const char* pstr, int* ptr, int minValue, int maxValue, menuFunc_t callback); // edit int with callback
*
* You can then use one of the menu macros to present the edit interface:
* MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_multiplier, 10, 999)
*
* This expands into a more primitive menu item:
* MENU_ITEM(setting_edit_int3, MSG_SPEED, PSTR(MSG_SPEED), &feedrate_multiplier, 10, 999)
*
*
* Also: MENU_MULTIPLIER_ITEM_EDIT, MENU_ITEM_EDIT_CALLBACK, and MENU_MULTIPLIER_ITEM_EDIT_CALLBACK
*
* menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedrate_multiplier, 10, 999)
*/
#define menu_edit_type(_type, _name, _strFunc, scale) \
bool _menu_edit_ ## _name () { \
ENCODER_DIRECTION_NORMAL(); \
bool isClicked = LCD_CLICKED; \
if ((int32_t)encoderPosition < 0) encoderPosition = 0; \
if ((int32_t)encoderPosition > maxEditValue) encoderPosition = maxEditValue; \
......@@ -1760,18 +1973,16 @@ static void laser_set_focus(float f_length) {
lcd_implementation_drawedit(editLabel, _strFunc(((_type)((int32_t)encoderPosition + minEditValue)) / scale)); \
if (isClicked) { \
*((_type*)editValue) = ((_type)((int32_t)encoderPosition + minEditValue)) / scale; \
lcd_goto_menu(prevMenu, prevEncoderPosition); \
lcd_goto_previous_menu(true); \
} \
return isClicked; \
} \
void menu_edit_ ## _name () { _menu_edit_ ## _name(); } \
void menu_edit_callback_ ## _name () { if (_menu_edit_ ## _name ()) (*callbackFunc)(); } \
static void _menu_action_setting_edit_ ## _name (const char* pstr, _type* ptr, _type minValue, _type maxValue) { \
prevMenu = currentMenu; \
prevEncoderPosition = encoderPosition; \
lcd_save_previous_menu(); \
\
lcdDrawUpdate = 2; \
currentMenu = menu_edit_ ## _name; \
lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; \
\
editLabel = pstr; \
editValue = ptr; \
......@@ -1834,7 +2045,7 @@ menu_edit_type(unsigned long, long5, ftostr5, 0.01)
lcd_move_y();
}
static void reprapworld_keypad_move_home() {
enqueuecommands_P((PSTR("G28"))); // move all axis home
enqueue_and_echo_commands_P((PSTR("G28"))); // move all axis home
}
#endif // REPRAPWORLD_KEYPAD
......@@ -1884,9 +2095,9 @@ void lcd_quick_feedback() {
* Menu actions
*
*/
static void menu_action_back(menuFunc_t func) { lcd_goto_menu(func); }
static void menu_action_submenu(menuFunc_t func) { lcd_goto_menu(func); }
static void menu_action_gcode(const char* pgcode) { enqueuecommands_P(pgcode); }
static void menu_action_back() { lcd_goto_previous_menu(); }
static void menu_action_submenu(menuFunc_t func) { lcd_save_previous_menu(); lcd_goto_menu(func); }
static void menu_action_gcode(const char* pgcode) { enqueue_and_echo_commands_P(pgcode); }
static void menu_action_function(menuFunc_t func) { (*func)(); }
#if ENABLED(SDSUPPORT)
......@@ -1896,8 +2107,8 @@ static void menu_action_function(menuFunc_t func) { (*func)(); }
char* c;
sprintf_P(cmd, PSTR("M23 %s"), longFilename);
for (c = &cmd[4]; *c; c++) *c = tolower(*c);
enqueuecommand(cmd);
enqueuecommands_P(PSTR("M24"));
enqueue_and_echo_command(cmd);
enqueue_and_echo_commands_P(PSTR("M24"));
lcd_return_to_status();
}
......@@ -1922,13 +2133,17 @@ void lcd_init() {
lcd_implementation_init();
#if ENABLED(NEWPANEL)
#if BUTTON_EXISTS(EN1)
SET_INPUT(BTN_EN1);
PULLUP(BTN_EN1, HIGH);
#endif
SET_INPUT(BTN_EN1);
SET_INPUT(BTN_EN2);
PULLUP(BTN_EN1, HIGH);
PULLUP(BTN_EN2, HIGH);
#if BUTTON_EXISTS(EN2)
SET_INPUT(BTN_EN2);
PULLUP(BTN_EN2, HIGH);
#endif
#if BTN_ENC > 0
#if BUTTON_EXISTS(ENC)
SET_INPUT(BTN_ENC);
PULLUP(BTN_ENC, HIGH);
#endif
......@@ -1941,6 +2156,13 @@ void lcd_init() {
WRITE(SHIFT_LD, HIGH);
#endif
#ifdef RIGIDBOT_PANEL
SET_INPUT(BTN_UP);
SET_INPUT(BTN_DWN);
SET_INPUT(BTN_LFT);
SET_INPUT(BTN_RT);
#endif
#else // Not NEWPANEL
#if ENABLED(SR_LCD_2W_NL) // Non latching 2 wire shift register
......@@ -1975,7 +2197,7 @@ void lcd_init() {
#endif
}
int lcd_strlen(char* s) {
int lcd_strlen(const char* s) {
int i = 0, j = 0;
while (s[i]) {
if ((s[i] & 0xc0) != 0x80) j++;
......@@ -1993,6 +2215,17 @@ int lcd_strlen_P(const char* s) {
return j;
}
bool lcd_blink() {
static uint8_t blink = 0;
static millis_t next_blink_ms = 0;
millis_t ms = millis();
if (ELAPSED(ms, next_blink_ms)) {
blink ^= 0xFF;
next_blink_ms = ms + 1000 - LCD_UPDATE_INTERVAL / 2;
}
return blink != 0;
}
/**
* Update the LCD, read encoder buttons, etc.
* - Read button states
......@@ -2017,7 +2250,7 @@ void lcd_update() {
bool sd_status = IS_SD_INSERTED;
if (sd_status != lcd_sd_status && lcd_detected()) {
lcdDrawUpdate = 2;
lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW;
lcd_implementation_init( // to maybe revive the LCD if static electricity killed it.
#if ENABLED(LCD_PROGRESS_BAR)
currentMenu == lcd_status_screen
......@@ -2039,7 +2272,13 @@ void lcd_update() {
#endif // SDSUPPORT && SD_DETECT_PIN
millis_t ms = millis();
if (ms > next_lcd_update_ms) {
if (ELAPSED(ms, next_lcd_update_ms)) {
next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL;
#if ENABLED(LCD_HAS_STATUS_INDICATORS)
lcd_implementation_update_indicators();
#endif
#if ENABLED(LCD_HAS_SLOW_BUTTONS)
slow_buttons = lcd_implementation_read_slow_buttons(); // buttons which take too long to read in interrupt context
......@@ -2048,13 +2287,22 @@ void lcd_update() {
#if ENABLED(ULTIPANEL)
#if ENABLED(REPRAPWORLD_KEYPAD)
if (REPRAPWORLD_KEYPAD_MOVE_Z_UP) reprapworld_keypad_move_z_up();
if (REPRAPWORLD_KEYPAD_MOVE_Z_DOWN) reprapworld_keypad_move_z_down();
if (REPRAPWORLD_KEYPAD_MOVE_X_LEFT) reprapworld_keypad_move_x_left();
if (REPRAPWORLD_KEYPAD_MOVE_X_RIGHT) reprapworld_keypad_move_x_right();
if (REPRAPWORLD_KEYPAD_MOVE_Y_DOWN) reprapworld_keypad_move_y_down();
if (REPRAPWORLD_KEYPAD_MOVE_Y_UP) reprapworld_keypad_move_y_up();
if (REPRAPWORLD_KEYPAD_MOVE_HOME) reprapworld_keypad_move_home();
#if MECH(DELTA) || MECH(SCARA)
#define _KEYPAD_MOVE_ALLOWED (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS])
#else
#define _KEYPAD_MOVE_ALLOWED true
#endif
if (REPRAPWORLD_KEYPAD_MOVE_HOME) reprapworld_keypad_move_home();
if (_KEYPAD_MOVE_ALLOWED) {
if (REPRAPWORLD_KEYPAD_MOVE_Z_UP) reprapworld_keypad_move_z_up();
if (REPRAPWORLD_KEYPAD_MOVE_Z_DOWN) reprapworld_keypad_move_z_down();
if (REPRAPWORLD_KEYPAD_MOVE_X_LEFT) reprapworld_keypad_move_x_left();
if (REPRAPWORLD_KEYPAD_MOVE_X_RIGHT) reprapworld_keypad_move_x_right();
if (REPRAPWORLD_KEYPAD_MOVE_Y_DOWN) reprapworld_keypad_move_y_down();
if (REPRAPWORLD_KEYPAD_MOVE_Y_UP) reprapworld_keypad_move_y_up();
}
#endif
bool encoderPastThreshold = (abs(encoderDiff) >= ENCODER_PULSES_PER_STEP);
......@@ -2091,59 +2339,70 @@ void lcd_update() {
encoderDiff = 0;
}
return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS;
lcdDrawUpdate = 1;
lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
}
#endif //ULTIPANEL
#endif // ULTIPANEL
if (currentMenu == lcd_status_screen) {
if (!lcd_status_update_delay) {
lcdDrawUpdate = 1;
lcd_status_update_delay = 10; /* redraw the main screen every second. This is easier then trying keep track of all things that change on the screen */
}
else {
lcd_status_update_delay--;
// Simply redraw the Info Screen 10 times a second
if (currentMenu == lcd_status_screen && !(++lcd_status_update_delay % 10))
lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
if (lcdDrawUpdate) {
switch (lcdDrawUpdate) {
case LCDVIEW_CALL_NO_REDRAW:
lcdDrawUpdate = LCDVIEW_NONE;
break;
case LCDVIEW_CLEAR_CALL_REDRAW: // set by handlers, then altered after (rarely occurs here)
case LCDVIEW_CALL_REDRAW_NEXT: // set by handlers, then altered after (never occurs here?)
lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
case LCDVIEW_REDRAW_NOW: // set above, or by a handler through LCDVIEW_CALL_REDRAW_NEXT
case LCDVIEW_NONE:
break;
}
}
#if ENABLED(DOGLCD) // Changes due to different driver architecture of the DOGM display
if (lcdDrawUpdate) {
blink++; // Variable for fan animation and alive dot
#if ENABLED(DOGLCD) // Changes due to different driver architecture of the DOGM display
static int8_t dot_color = 0;
dot_color = 1 - dot_color;
u8g.firstPage();
do {
lcd_setFont(FONT_MENU);
u8g.setPrintPos(125, 0);
if (blink % 2) u8g.setColorIndex(1); else u8g.setColorIndex(0); // Set color for the alive dot
u8g.setColorIndex(dot_color); // Set color for the alive dot
u8g.drawPixel(127, 63); // draw alive dot
u8g.setColorIndex(1); // black on white
(*currentMenu)();
} while(u8g.nextPage());
}
#else
if (lcdDrawUpdate)
} while (u8g.nextPage());
#else
(*currentMenu)();
#endif
#if ENABLED(LCD_HAS_STATUS_INDICATORS)
lcd_implementation_update_indicators();
#endif
#endif
}
#if ENABLED(ULTIPANEL)
// Return to Status Screen after a timeout
if (currentMenu != lcd_status_screen &&
if (currentMenu == lcd_status_screen || defer_return_to_status
#if !MECH(DELTA) && DISABLED(Z_SAFE_HOMING) && Z_HOME_DIR < 0
currentMenu != lcd_level_bed &&
|| currentMenu == lcd_level_bed
#endif
millis() > return_to_status_ms
) {
)
return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS;
else if (ELAPSED(ms, return_to_status_ms))
lcd_return_to_status();
lcdDrawUpdate = 2;
}
#endif // ULTIPANEL
if (lcdDrawUpdate == 2) lcd_implementation_clear();
if (lcdDrawUpdate) lcdDrawUpdate--;
next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL;
switch (lcdDrawUpdate) {
case LCDVIEW_CLEAR_CALL_REDRAW:
lcd_implementation_clear();
case LCDVIEW_CALL_REDRAW_NEXT:
lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
break;
case LCDVIEW_REDRAW_NOW:
lcdDrawUpdate = LCDVIEW_NONE;
break;
case LCDVIEW_NONE:
break;
}
}
}
......@@ -2153,13 +2412,17 @@ void lcd_ignore_click(bool b) {
}
void lcd_finishstatus(bool persist = false) {
#if !(ENABLED(LCD_PROGRESS_BAR) && (PROGRESS_MSG_EXPIRE > 0))
UNUSED(persist);
#endif
#if ENABLED(LCD_PROGRESS_BAR)
progress_bar_ms = millis();
#if PROGRESS_MSG_EXPIRE > 0
expire_status_ms = persist ? 0 : progress_bar_ms + PROGRESS_MSG_EXPIRE;
#endif
#endif
lcdDrawUpdate = 2;
lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW;
#if HAS(LCD_FILAMENT_SENSOR) || HAS(LCD_POWER_SENSOR)
previous_lcd_status_ms = millis(); //get status message to show up for a while
......@@ -2221,13 +2484,26 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; }
* These values are independent of which pins are used for EN_A and EN_B indications
* The rotary encoder part is also independent to the chipset used for the LCD
*/
#if ENABLED(EN_A) && ENABLED(EN_B)
#if defined(EN_A) && defined(EN_B)
#define encrot0 0
#define encrot1 2
#define encrot2 3
#define encrot3 1
#endif
#define GET_BUTTON_STATES(DST) \
uint8_t new_##DST = 0; \
WRITE(SHIFT_LD, LOW); \
WRITE(SHIFT_LD, HIGH); \
for (int8_t i = 0; i < 8; i++) { \
new_##DST >>= 1; \
if (READ(SHIFT_OUT)) SBI(new_##DST, 7); \
WRITE(SHIFT_CLK, HIGH); \
WRITE(SHIFT_CLK, LOW); \
} \
DST = ~new_##DST; //invert it, because a pressed switch produces a logical 0
/**
* Read encoder buttons from the hardware registers
* Warning: This function is called from interrupt context!
......@@ -2235,73 +2511,68 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; }
void lcd_buttons_update() {
#if ENABLED(NEWPANEL)
uint8_t newbutton = 0;
#if ENABLED(INVERT_ROTARY_SWITCH)
if (READ(BTN_EN1) == 0) newbutton |= EN_B;
if (READ(BTN_EN2) == 0) newbutton |= EN_A;
#else
if (READ(BTN_EN1) == 0) newbutton |= EN_A;
if (READ(BTN_EN2) == 0) newbutton |= EN_B;
#if BUTTON_EXISTS(EN1)
if (BUTTON_PRESSED(EN1)) newbutton |= EN_A;
#endif
#if BTN_ENC > 0
millis_t ms = millis();
if (ms > next_button_update_ms && READ(BTN_ENC) == 0) newbutton |= EN_C;
#if ENABLED(BTN_BACK) && BTN_BACK > 0
if (ms > next_button_update_ms && READ(BTN_BACK) == 0) newbutton |= EN_D;
#endif
#if BUTTON_EXISTS(EN2)
if (BUTTON_PRESSED(EN2)) newbutton |= EN_B;
#endif
#if ENABLED(RIGIDBOT_PANEL) || BUTTON_EXISTS(ENC)
millis_t now = millis();
#endif
#if ENABLED(RIGIDBOT_PANEL)
if (ELAPSED(now, next_button_update_ms)) {
if (BUTTON_PRESSED(UP)) {
encoderDiff = -(ENCODER_STEPS_PER_MENU_ITEM);
next_button_update_ms = now + 300;
}
else if (BUTTON_PRESSED(DWN)) {
encoderDiff = ENCODER_STEPS_PER_MENU_ITEM;
next_button_update_ms = now + 300;
}
else if (BUTTON_PRESSED(LFT)) {
encoderDiff = -(ENCODER_PULSES_PER_STEP);
next_button_update_ms = now + 300;
}
else if (BUTTON_PRESSED(RT)) {
encoderDiff = ENCODER_PULSES_PER_STEP;
next_button_update_ms = now + 300;
}
}
#endif
#if BUTTON_EXISTS(ENC)
if (ELAPSED(now, next_button_update_ms) && BUTTON_PRESSED(ENC)) newbutton |= EN_C;
#endif
buttons = newbutton;
#if ENABLED(LCD_HAS_SLOW_BUTTONS)
buttons |= slow_buttons;
#endif
#if ENABLED(REPRAPWORLD_KEYPAD)
// for the reprapworld_keypad
uint8_t newbutton_reprapworld_keypad = 0;
WRITE(SHIFT_LD, LOW);
WRITE(SHIFT_LD, HIGH);
for (uint8_t i = 0; i < 8; i++) {
newbutton_reprapworld_keypad >>= 1;
if (READ(SHIFT_OUT)) BITSET(newbutton_reprapworld_keypad, 7);
WRITE(SHIFT_CLK, HIGH);
WRITE(SHIFT_CLK, LOW);
}
buttons_reprapworld_keypad = ~newbutton_reprapworld_keypad; //invert it, because a pressed switch produces a logical 0
GET_BUTTON_STATES(buttons_reprapworld_keypad);
#endif
#else //read it from the shift register
uint8_t newbutton = 0;
WRITE(SHIFT_LD, LOW);
WRITE(SHIFT_LD, HIGH);
unsigned char tmp_buttons = 0;
for (uint8_t i = 0; i < 8; i++) {
newbutton >>= 1;
if (READ(SHIFT_OUT)) BITSET(newbutton, 7);
WRITE(SHIFT_CLK, HIGH);
WRITE(SHIFT_CLK, LOW);
}
buttons = ~newbutton; //invert it, because a pressed switch produces a logical 0
GET_BUTTON_STATES(buttons);
#endif //!NEWPANEL
#if ENABLED(INVERT_ROTARY_SWITCH)
#define ENCODER_DIFF_CW (encoderDiff += encoderDirection)
#define ENCODER_DIFF_CCW (encoderDiff -= encoderDirection)
#else
#define ENCODER_DIFF_CW (encoderDiff++)
#define ENCODER_DIFF_CCW (encoderDiff--)
#endif
#define ENCODER_SPIN(_E1, _E2) switch (lastEncoderBits) { case _E1: ENCODER_DIFF_CW; break; case _E2: ENCODER_DIFF_CCW; }
//manage encoder rotation
uint8_t enc = 0;
if (buttons & EN_A) enc |= B01;
if (buttons & EN_B) enc |= B10;
if (enc != lastEncoderBits) {
switch (enc) {
case encrot0:
if (lastEncoderBits == encrot3) encoderDiff++;
else if (lastEncoderBits == encrot1) encoderDiff--;
break;
case encrot1:
if (lastEncoderBits == encrot0) encoderDiff++;
else if (lastEncoderBits == encrot2) encoderDiff--;
break;
case encrot2:
if (lastEncoderBits == encrot1) encoderDiff++;
else if (lastEncoderBits == encrot3) encoderDiff--;
break;
case encrot3:
if (lastEncoderBits == encrot2) encoderDiff++;
else if (lastEncoderBits == encrot0) encoderDiff--;
break;
case encrot0: ENCODER_SPIN(encrot3, encrot1); break;
case encrot1: ENCODER_SPIN(encrot0, encrot2); break;
case encrot2: ENCODER_SPIN(encrot1, encrot3); break;
case encrot3: ENCODER_SPIN(encrot2, encrot0); break;
}
}
lastEncoderBits = enc;
......@@ -2662,7 +2933,7 @@ char* ftostr52(const float& x) {
LCD_Printpos(0, 0); lcd_printPGM(PSTR(MSG_MBL_6));
LCD_Printpos(0, 1); lcd_printPGM(PSTR(" "));
HAL::delayMilliseconds(5000);
enqueuecommands_P(PSTR("G28"));
enqueue_and_echo_commands_P(PSTR("G28"));
lcd_goto_menu(lcd_prepare_menu);
}
break;
......@@ -2671,7 +2942,7 @@ char* ftostr52(const float& x) {
static void config_lcd_level_bed() {
ECHO_EM(MSG_MBL_SETTING);
enqueuecommands_P(PSTR("G28 M"));
enqueue_and_echo_commands_P(PSTR("G28 M"));
pageShowInfo = 0;
lcd_goto_menu(lcd_level_bed);
}
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTRALCD_H
#define ULTRALCD_H
......@@ -6,7 +28,10 @@
#include "buzzer.h"
#endif
int lcd_strlen(char* s);
#define BUTTON_EXISTS(BN) (defined(BTN_## BN) && BTN_## BN >= 0)
#define BUTTON_PRESSED(BN) !READ(BTN_## BN)
int lcd_strlen(const char* s);
int lcd_strlen_P(const char* s);
void lcd_update();
void lcd_init();
......@@ -42,10 +67,7 @@
#if ENABLED(ULTIPANEL)
void lcd_buttons_update();
extern volatile uint8_t buttons; //the last checked buttons in a bit array.
#if ENABLED(REPRAPWORLD_KEYPAD)
extern volatile uint8_t buttons_reprapworld_keypad; // to store the keypad shift register values
#endif
extern volatile uint8_t buttons; // the last checked buttons in a bit array.
#else
FORCE_INLINE void lcd_buttons_update() {}
#endif
......@@ -67,18 +89,54 @@
#endif
void lcd_quick_feedback(); // Audible feedback for a button click - could also be visual
bool lcd_clicked();
void lcd_ignore_click(bool b=true);
void lcd_ignore_click(bool b = true);
bool lcd_blink();
#if ENABLED(ULTIPANEL) && ENABLED(REPRAPWORLD_KEYPAD)
#define REPRAPWORLD_BTN_OFFSET 0 // bit offset into buttons for shift register values
#define BLEN_REPRAPWORLD_KEYPAD_F3 0
#define BLEN_REPRAPWORLD_KEYPAD_F2 1
#define BLEN_REPRAPWORLD_KEYPAD_F1 2
#define BLEN_REPRAPWORLD_KEYPAD_DOWN 3
#define BLEN_REPRAPWORLD_KEYPAD_RIGHT 4
#define BLEN_REPRAPWORLD_KEYPAD_MIDDLE 5
#define BLEN_REPRAPWORLD_KEYPAD_UP 6
#define BLEN_REPRAPWORLD_KEYPAD_LEFT 7
#define EN_REPRAPWORLD_KEYPAD_F3 (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_F3))
#define EN_REPRAPWORLD_KEYPAD_F2 (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_F2))
#define EN_REPRAPWORLD_KEYPAD_F1 (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_F1))
#define EN_REPRAPWORLD_KEYPAD_DOWN (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_DOWN))
#define EN_REPRAPWORLD_KEYPAD_RIGHT (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_RIGHT))
#define EN_REPRAPWORLD_KEYPAD_MIDDLE (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_MIDDLE))
#define EN_REPRAPWORLD_KEYPAD_UP (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_UP))
#define EN_REPRAPWORLD_KEYPAD_LEFT (_BV(REPRAPWORLD_BTN_OFFSET + BLEN_REPRAPWORLD_KEYPAD_LEFT))
#define REPRAPWORLD_KEYPAD_MOVE_Z_DOWN (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_F3)
#define REPRAPWORLD_KEYPAD_MOVE_Z_UP (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_F2)
#define REPRAPWORLD_KEYPAD_MOVE_Y_DOWN (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_DOWN)
#define REPRAPWORLD_KEYPAD_MOVE_X_RIGHT (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_RIGHT)
#define REPRAPWORLD_KEYPAD_MOVE_HOME (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_MIDDLE)
#define REPRAPWORLD_KEYPAD_MOVE_Y_UP (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_UP)
#define REPRAPWORLD_KEYPAD_MOVE_X_LEFT (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_LEFT)
#endif // ULTIPANEL && REPRAPWORLD_KEYPAD
#if ENABLED(NEWPANEL)
#define EN_C (_BV(BLEN_C))
#define EN_B (_BV(BLEN_B))
#define EN_A (_BV(BLEN_A))
#if ENABLED(INVERT_CLICK_BUTTON)
#define LCD_CLICKED !(buttons&EN_C)
#if ENABLED(REPRAPWORLD_KEYPAD)
#define LCD_CLICKED ((buttons&EN_C) || (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_F1))
#else
#define LCD_CLICKED (buttons&EN_C)
#if ENABLED(INVERT_CLICK_BUTTON)
#define LCD_CLICKED !(buttons&EN_C)
#else
#define LCD_CLICKED (buttons&EN_C)
#endif
#endif
#if ENABLED(BTN_BACK) && BTN_BACK > 0
#define EN_D (_BV(BLEN_D))
#if ENABLED(INVERT_BACK_BUTTON)
......@@ -87,30 +145,10 @@
#define LCD_BACK_CLICKED (buttons&EN_D)
#endif
#endif
#if ENABLED(REPRAPWORLD_KEYPAD)
#define EN_REPRAPWORLD_KEYPAD_F3 (_BV(BLEN_REPRAPWORLD_KEYPAD_F3))
#define EN_REPRAPWORLD_KEYPAD_F2 (_BV(BLEN_REPRAPWORLD_KEYPAD_F2))
#define EN_REPRAPWORLD_KEYPAD_F1 (_BV(BLEN_REPRAPWORLD_KEYPAD_F1))
#define EN_REPRAPWORLD_KEYPAD_UP (_BV(BLEN_REPRAPWORLD_KEYPAD_UP))
#define EN_REPRAPWORLD_KEYPAD_RIGHT (_BV(BLEN_REPRAPWORLD_KEYPAD_RIGHT))
#define EN_REPRAPWORLD_KEYPAD_MIDDLE (_BV(BLEN_REPRAPWORLD_KEYPAD_MIDDLE))
#define EN_REPRAPWORLD_KEYPAD_DOWN (_BV(BLEN_REPRAPWORLD_KEYPAD_DOWN))
#define EN_REPRAPWORLD_KEYPAD_LEFT (_BV(BLEN_REPRAPWORLD_KEYPAD_LEFT))
#if ENABLED(INVERT_CLICK_BUTTON)
#define LCD_CLICKED !((buttons&EN_C) || (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_F1))
#else
#define LCD_CLICKED ((buttons&EN_C) || (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_F1))
#endif
#define REPRAPWORLD_KEYPAD_MOVE_Z_UP (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_F2)
#define REPRAPWORLD_KEYPAD_MOVE_Z_DOWN (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_F3)
#define REPRAPWORLD_KEYPAD_MOVE_X_LEFT (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_LEFT)
#define REPRAPWORLD_KEYPAD_MOVE_X_RIGHT (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_RIGHT)
#define REPRAPWORLD_KEYPAD_MOVE_Y_DOWN (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_DOWN)
#define REPRAPWORLD_KEYPAD_MOVE_Y_UP (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_UP)
#define REPRAPWORLD_KEYPAD_MOVE_HOME (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_MIDDLE)
#endif //REPRAPWORLD_KEYPAD
#else
//atomic, do not change
#else // !NEWPANEL
// atomic, do not change
#define B_LE (_BV(BL_LE))
#define B_UP (_BV(BL_UP))
#define B_MI (_BV(BL_MI))
......@@ -120,9 +158,9 @@
#define EN_B (_BV(BLEN_B))
#define EN_A (_BV(BLEN_A))
#define LCD_CLICKED (buttons&(B_MI|B_ST))
#define LCD_CLICKED ((buttons&B_MI)||(buttons&B_ST))
#endif//NEWPANEL
#endif // NEWPANEL
char* itostr2(const uint8_t& x);
char* itostr31(const int& xx);
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTRALCD_IMPLEMENTATION_HITACHI_HD44780_H
#define ULTRALCD_IMPLEMENTATION_HITACHI_HD44780_H
......@@ -553,6 +575,21 @@ unsigned lcd_print(char c) { return charset_mapper(c); }
}
#endif // SHOW_BOOTSCREEN
FORCE_INLINE void _draw_axis_label(AxisEnum axis, const char *pstr, bool blink) {
if (blink)
lcd_printPGM(pstr);
else {
if (!axis_homed[axis])
lcd_printPGM(PSTR("?"));
else {
if (!axis_known_position[axis])
lcd_printPGM(PSTR(" "));
else
lcd_printPGM(pstr);
}
}
}
/*
Possible status screens:
16x2 |000/000 B000/000|
......@@ -646,6 +683,8 @@ static void lcd_implementation_status_screen() {
#if LCD_HEIGHT > 2
bool blink = lcd_blink();
#if LCD_WIDTH < 20
#if ENABLED(SDSUPPORT)
......@@ -662,12 +701,6 @@ static void lcd_implementation_status_screen() {
lcd.setCursor(0, 1);
//
// Print XYZ Coordinates
// If the axis was not homed, show "---"
// If the position is untrusted, show "?"
//
#if HOTENDS > 1 && TEMP_SENSOR_BED != 0
// If we both have a 2nd hotend and a heated bed,
......@@ -676,29 +709,25 @@ static void lcd_implementation_status_screen() {
LCD_TEMP(degBed(), degTargetBed(), LCD_STR_BEDTEMP[0]);
#else
// Before homing the axis letters are blinking 'X' <-> '?'.
// When axis is homed but axis_known_position is false the axis letters are blinking 'X' <-> ' '.
// When everything is ok you see a constant 'X'.
lcd.print(TEST(axis_known_position, X_AXIS) || !TEST(axis_was_homed, X_AXIS) ? 'X' : '?');
if (TEST(axis_was_homed, X_AXIS))
lcd.print(ftostr4sign(current_position[X_AXIS]));
else
lcd_printPGM(PSTR(" ---"));
_draw_axis_label(X_AXIS, PSTR(MSG_X), blink);
lcd.print(ftostr4sign(current_position[X_AXIS]));
lcd_printPGM(TEST(axis_known_position, Y_AXIS) || !TEST(axis_was_homed, Y_AXIS) ? PSTR(" Y") : PSTR(" ?"));
if (TEST(axis_was_homed, Y_AXIS))
lcd.print(ftostr4sign(current_position[Y_AXIS]));
else
lcd_printPGM(PSTR(" ---"));
lcd_printPGM(PSTR(" "));
_draw_axis_label(Y_AXIS, PSTR(MSG_Y), blink);
lcd.print(ftostr4sign(current_position[Y_AXIS]));
#endif // HOTENDS > 1 || TEMP_SENSOR_BED != 0
#endif // LCD_WIDTH >= 20
lcd.setCursor(LCD_WIDTH - 8, 1);
lcd_printPGM(TEST(axis_known_position, Z_AXIS) || !TEST(axis_was_homed, Z_AXIS) ? PSTR("Z ") : PSTR("? "));
if (TEST(axis_was_homed, Z_AXIS))
lcd.print(ftostr32sp(current_position[Z_AXIS] + 0.00001));
else
lcd_printPGM(PSTR("---.--"));
_draw_axis_label(Z_AXIS, PSTR(MSG_Z), blink);
lcd.print(ftostr32sp(current_position[Z_AXIS] + 0.00001));
#endif // LCD_HEIGHT > 2
......@@ -726,11 +755,11 @@ static void lcd_implementation_status_screen() {
#endif // LCD_WIDTH > 19 && SDSUPPORT
lcd.setCursor(LCD_WIDTH - 6, 2);
if(print_job_start_ms != 0) {
uint16_t time = print_job_timer.duration() / 60;
if(time != 0) {
#if HAS(LCD_POWER_SENSOR)
if (millis() < print_millis + 1000) {
lcd.print(LCD_STR_CLOCK[0]);
uint16_t time = millis()/60000 - print_job_start_ms/60000;
lcd.print(itostr2(time/60));
lcd.print(':');
lcd.print(itostr2(time%60));
......@@ -741,7 +770,6 @@ static void lcd_implementation_status_screen() {
}
#else
lcd.print(LCD_STR_CLOCK[0]);
uint16_t time = millis()/60000 - print_job_start_ms/60000;
lcd.print(itostr2(time/60));
lcd.print(':');
lcd.print(itostr2(time%60));
......@@ -786,12 +814,12 @@ static void lcd_implementation_status_screen() {
//Display both Status message line and Filament display on the last line
#if HAS(LCD_FILAMENT_SENSOR) || HAS(LCD_POWER_SENSOR)
if (millis() >= previous_lcd_status_ms + 5000) {
if (millis() >= previous_lcd_status_ms + 5000UL) {
lcd_print(lcd_status_message);
}
#if HAS(LCD_POWER_SENSOR)
#if HAS(LCD_FILAMENT_SENSOR)
else if (millis() < message_millis + 10000)
else if (millis() < message_millis + 10000UL)
#else
else
#endif
......@@ -808,7 +836,7 @@ static void lcd_implementation_status_screen() {
lcd_printPGM(PSTR("Dia "));
lcd.print(ftostr12ns(filament_width_meas));
lcd_printPGM(PSTR(" V"));
lcd.print(itostr3(100.0*volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]));
lcd.print(itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]));
lcd.print('%');
return;
}
......@@ -879,17 +907,20 @@ static void lcd_implementation_drawmenu_setting_edit_generic_P(bool sel, uint8_t
#define lcd_implementation_drawmenu_setting_edit_callback_long5(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr5(*(data)))
#define lcd_implementation_drawmenu_setting_edit_callback_bool(sel, row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
void lcd_implementation_drawedit(const char* pstr, char* value) {
void lcd_implementation_drawedit(const char* pstr, const char* value = NULL) {
lcd.setCursor(1, 1);
lcd_printPGM(pstr);
lcd.print(':');
lcd.setCursor(LCD_WIDTH - lcd_strlen(value), 1);
lcd_print(value);
if (value != NULL) {
lcd.print(':');
lcd.setCursor(LCD_WIDTH - lcd_strlen(value), 1);
lcd_print(value);
}
}
#if ENABLED(SDSUPPORT)
static void lcd_implementation_drawmenu_sd(bool sel, uint8_t row, const char* pstr, const char* longFilename, uint8_t concat, char post_char) {
UNUSED(pstr);
char c;
uint8_t n = LCD_WIDTH - concat;
lcd.setCursor(0, row);
......@@ -912,7 +943,7 @@ void lcd_implementation_drawedit(const char* pstr, char* value) {
#endif // SDSUPPORT
#define lcd_implementation_drawmenu_back(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])
#define lcd_implementation_drawmenu_back(sel, row, pstr) lcd_implementation_drawmenu_generic(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])
#define lcd_implementation_drawmenu_submenu(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0])
#define lcd_implementation_drawmenu_gcode(sel, row, pstr, gcode) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ')
#define lcd_implementation_drawmenu_function(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ')
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULCDST7920_H
#define ULCDST7920_H
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef MACROS_H
#define MACROS_H
......@@ -25,11 +47,13 @@
// Macros to support option testing
#define ENABLED defined
#define DISABLED !defined
#define PIN_EXISTS(PN) (defined(PN##_PIN) && PN##_PIN >= 0)
#define HAS(FE) (HAS_##FE)
#define HASNT(FE) (!(HAS_##FE))
// Macros to contrain values
#define NUMERIC(a) ((a) >= '0' && '9' >= (a))
#define NUMERIC_SIGNED(a) (NUMERIC(a) || (a) == '-')
#define NOLESS(v,n) do{ if (v < n) v = n; }while(0)
#define NOMORE(v,n) do{ if (v > n) v = n; }while(0)
#define COUNT(a) (sizeof(a)/sizeof(*a))
......@@ -37,4 +61,19 @@
// Function macro
#define FORCE_INLINE __attribute__((always_inline)) inline
// Macro for debugging
#define DEBUGGING(F) (mk_debug_flags & (DEBUG_## F))
// Macro for String
#define STRINGIFY_(n) #n
#define STRINGIFY(n) STRINGIFY_(n)
// Macro for varie
#define PIN_EXISTS(PN) (defined(PN##_PIN) && PN##_PIN >= 0)
#define PENDING(NOW,SOON) ((long)(NOW-(SOON))<0)
#define ELAPSED(NOW,SOON) (!PENDING(NOW,SOON))
#define NOOP do{}while(0)
#endif //__MACROS_H
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef MECHANICS_H
#define MECHANICS_H
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* cartesian_correction.cpp
* A class that manages hysteresis by inserting extra plan_buffer_line when necessary
* A class that manages ZWobble
*
* Copyright (c) 2016 MagoKimbra
* Copyright (c) 2013 Francesco Santini
* Copyright (c) 2012 Neil James Martin
* Copyright (c) 2013 Francesco Santini
* Copyright (c) 2016 MagoKimbra
*
* Grbl is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -242,7 +264,7 @@
//===========================================================================
void ZWobble::setSample(float zRod, float zActual) {
if (debugLevel & DEBUG_DEBUG) {
if (DEBUGGING(DEBUG)) {
ECHO_SMV(DB, "New sample Rod: ", zRod);
ECHO_EMV(" Act: ", zActual);
}
......@@ -446,7 +468,7 @@
if (originZ < ZWOBBLE_MIN_Z || targetZ < ZWOBBLE_MIN_Z) return;
if (debugLevel & DEBUG_DEBUG) {
if (DEBUGGING(DEBUG)) {
ECHO_SMV(DB, "Origin: ", originZ);
ECHO_MV(" Target: ", targetZ);
}
......@@ -461,18 +483,18 @@
else
originZRod = findZRod(originZ);
if (debugLevel & DEBUG_DEBUG)
if (DEBUGGING(DEBUG))
ECHO_MV(" Origin rod: ", originZRod);
float targetZRod = findZRod(targetZ);
if (debugLevel & DEBUG_DEBUG)
if (DEBUGGING(DEBUG))
ECHO_MV(" Target Rod: ", targetZRod);
// difference in steps between the correct movement (originZRod->targetZRod) and the planned movement
long stepDiff = lround((targetZRod - originZRod) * axis_steps_per_unit[Z_AXIS]) - (lround(targetZ * axis_steps_per_unit[Z_AXIS]) - position[Z_AXIS]);
if (debugLevel & DEBUG_DEBUG)
if (DEBUGGING(DEBUG))
ECHO_EMV(" stepDiff: ", stepDiff);
lastZ = targetZ;
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* cartesian_correction.h
* A class that manages hysteresis by inserting extra plan_buffer_line when necessary
* A class that manages ZWobble
*
* Copyright (c) 2016 MagoKimbra
* Copyright (c) 2013 Francesco Santini
* Copyright (c) 2012 Neil James Martin
* Copyright (c) 2013 Francesco Santini
* Copyright (c) 2016 MagoKimbra
*
* Grbl is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......
/**
* MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* planner.cpp - Buffer movement commands and manage the acceleration profile plan
* Part of Grbl
......@@ -151,8 +173,8 @@ FORCE_INLINE float intersection_distance(float initial_rate, float final_rate, f
// Calculates trapezoid parameters so that the entry- and exit-speed is compensated by the provided factors.
void calculate_trapezoid_for_block(block_t* block, float entry_factor, float exit_factor) {
unsigned long initial_rate = ceil(block->nominal_rate * entry_factor); // (step/min)
unsigned long final_rate = ceil(block->nominal_rate * exit_factor); // (step/min)
unsigned long initial_rate = ceil(block->nominal_rate * entry_factor),
final_rate = ceil(block->nominal_rate * exit_factor); // (steps per second)
// Limit minimal step rate (Otherwise the timer will overflow.)
NOLESS(initial_rate, 120);
......@@ -510,12 +532,13 @@ float junction_deviation = 0.1;
// The target position of the tool in absolute steps
// Calculate target position in absolute steps
//this should be done after the wait, because otherwise a M92 code within the gcode disrupts this calculation somehow
int32_t target[NUM_AXIS];
target[X_AXIS] = lround(x * axis_steps_per_unit[X_AXIS]);
target[Y_AXIS] = lround(y * axis_steps_per_unit[Y_AXIS]);
target[Z_AXIS] = lround(z * axis_steps_per_unit[Z_AXIS]);
target[E_AXIS] = lround(e * axis_steps_per_unit[E_AXIS + extruder]);
// this should be done after the wait, because otherwise a M92 code within the gcode disrupts this calculation somehow
int32_t target[NUM_AXIS] = {
lround(x * axis_steps_per_unit[X_AXIS]),
lround(y * axis_steps_per_unit[Y_AXIS]),
lround(z * axis_steps_per_unit[Z_AXIS]),
lround(e * axis_steps_per_unit[E_AXIS + extruder])
};
// If changing extruder have to recalculate current position based on
// the steps-per-mm value for the new extruder.
......@@ -552,8 +575,8 @@ float junction_deviation = 0.1;
if (extruder != 1)
#endif
{
if (degHotend(extruder) < extrude_min_temp && !(debugLevel & DEBUG_DRYRUN)) {
position[E_AXIS] = target[E_AXIS]; //behave as if the move really took place, but ignore E part
if (degHotend(extruder) < extrude_min_temp && !(DEBUGGING(DRYRUN))) {
position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part
de = 0; // no difference
ECHO_LM(ER, SERIAL_ERR_COLD_EXTRUDE_STOP);
}
......@@ -645,10 +668,10 @@ float junction_deviation = 0.1;
if (dc < 0) SBI(dirb, C_AXIS); // Motor B direction
#else
if (dx < 0) SBI(dirb, X_AXIS);
if (dy < 0) SBI(dirb, Y_AXIS);
if (dy < 0) SBI(dirb, Y_AXIS);
if (dz < 0) SBI(dirb, Z_AXIS);
#endif
if (de < 0) SBI(dirb, E_AXIS);
if (de < 0) SBI(dirb, E_AXIS);
block->direction_bits = dirb;
block->active_driver = driver;
......@@ -1014,7 +1037,7 @@ float junction_deviation = 0.1;
// Compute and limit the acceleration rate for the trapezoid generator.
float steps_per_mm = block->step_event_count / block->millimeters;
long bsx = block->steps[X_AXIS], bsy = block->steps[Y_AXIS], bsz = block->steps[Z_AXIS], bse = block->steps[E_AXIS];
unsigned long bsx = block->steps[X_AXIS], bsy = block->steps[Y_AXIS], bsz = block->steps[Z_AXIS], bse = block->steps[E_AXIS];
if (bsx == 0 && bsy == 0 && bsz == 0) {
block->acceleration_st = ceil(retract_acceleration[extruder] * steps_per_mm); // convert to: acceleration steps/sec^2
}
......@@ -1029,11 +1052,12 @@ float junction_deviation = 0.1;
xsteps = axis_steps_per_sqr_second[X_AXIS],
ysteps = axis_steps_per_sqr_second[Y_AXIS],
zsteps = axis_steps_per_sqr_second[Z_AXIS],
esteps = axis_steps_per_sqr_second[E_AXIS + extruder];
if ((float)acc_st * bsx / block->step_event_count > xsteps) acc_st = xsteps;
if ((float)acc_st * bsy / block->step_event_count > ysteps) acc_st = ysteps;
if ((float)acc_st * bsz / block->step_event_count > zsteps) acc_st = zsteps;
if ((float)acc_st * bse / block->step_event_count > esteps) acc_st = esteps;
esteps = axis_steps_per_sqr_second[E_AXIS + extruder],
allsteps = block->step_event_count;
if (xsteps < (acc_st * bsx) / allsteps) acc_st = (xsteps * allsteps) / bsx;
if (ysteps < (acc_st * bsy) / allsteps) acc_st = (ysteps * allsteps) / bsy;
if (zsteps < (acc_st * bsz) / allsteps) acc_st = (zsteps * allsteps) / bsz;
if (esteps < (acc_st * bse) / allsteps) acc_st = (esteps * allsteps) / bse;
block->acceleration_st = acc_st;
block->acceleration = acc_st / steps_per_mm;
......@@ -1055,7 +1079,7 @@ float junction_deviation = 0.1;
// Compute maximum allowable entry speed at junction by centripetal acceleration approximation.
// Let a circle be tangent to both previous and current path line segments, where the junction
// deviation is defined as the distance from the junction to the closest edge of the circle,
// colinear with the circle center. The circular segment joining the two paths represents the
// collinear with the circle center. The circular segment joining the two paths represents the
// path of centripetal acceleration. Solve for max velocity based on max acceleration about the
// radius of the circle, defined indirectly by junction deviation. This may be also viewed as
// path width or max_jerk in the previous grbl version. This approach does not actually deviate
......@@ -1139,7 +1163,7 @@ float junction_deviation = 0.1;
}
else {
long acc_dist = estimate_acceleration_distance(0, block->nominal_rate, block->acceleration_st);
float advance = (STEPS_PER_CUBIC_MM_E * EXTRUDER_ADVANCE_K) * (cse * cse * EXTRUSION_AREA * EXTRUSION_AREA) * 256;
float advance = ((STEPS_PER_CUBIC_MM_E) * (EXTRUDER_ADVANCE_K)) * (cse * cse * (EXTRUSION_AREA) * (EXTRUSION_AREA)) * 256;
block->advance = advance;
block->advance_rate = acc_dist ? advance / (float)acc_dist : 0;
}
......@@ -1164,6 +1188,11 @@ float junction_deviation = 0.1;
} // plan_buffer_line()
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
/**
* Get the XYZ position of the steppers as a vector_3.
*
* On CORE machines XYZ is derived from ABC.
*/
vector_3 plan_get_position() {
vector_3 position = vector_3(st_get_axis_position_mm(X_AXIS), st_get_axis_position_mm(Y_AXIS), st_get_axis_position_mm(Z_AXIS));
......@@ -1178,6 +1207,11 @@ float junction_deviation = 0.1;
}
#endif // AUTO_BED_LEVELING_FEATURE
/**
* Directly set the planner XYZ position (hence the stepper positions).
*
* On CORE machines stepper ABC will be translated from the given XYZ.
*/
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
void plan_set_position(float x, float y, float z, const float& e)
#else
......
/*
planner.h - buffers movement commands and manages the acceleration profile plan
Part of Grbl
Copyright (c) 2009-2011 Simen Svale Skogsrud
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
(at your option) any later version.
Grbl 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 Grbl. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* planner.h - Buffer movement commands and manages the acceleration profile plan
* Part of Grbl
*
* Copyright (c) 2009-2011 Simen Svale Skogsrud
*
* 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
* (at your option) any later version.
*
* Grbl 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 Grbl. If not, see <http://www.gnu.org/licenses/>.
*/
// This module is to be considered a sub-module of stepper.c. Please don't include
// this file from any other module.
......@@ -28,7 +50,7 @@
// the source g-code and may never actually be reached if acceleration management is active.
typedef struct {
// Fields used by the bresenham algorithm for tracing the line
long steps[NUM_AXIS]; // Step count along each axis
unsigned long steps[NUM_AXIS]; // Step count along each axis
#if ENABLED(COLOR_MIXING_EXTRUDER)
unsigned long mix_event_count[DRIVER_EXTRUDERS]; // Step count for each stepper in a mixing extruder
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "../../base.h"
#if ENABLED(AUTO_BED_LEVELING_FEATURE) && ENABLED(AUTO_BED_LEVELING_GRID)
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#if ENABLED(AUTO_BED_LEVELING_GRID)
void daxpy(int n, double da, double dx[], int incx, double dy[], int incy);
......
/**
* stepper.cpp - stepper motor driver: executes motion plans using stepper motors
* Marlin Firmware
* MK & MK4due 3D Printer Firmware
*
* Derived from Grbl
* Copyright (c) 2009-2011 Simen Svale Skogsrud
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* Grbl is free software: you can redistribute it and/or modify
* 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.
*
* Grbl is distributed in the hope that it will be useful,
* 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 Grbl. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* The timer calculations of this module informed by the 'RepRap cartesian firmware' by Zack Smith
and Philipp Tiefenbacher. */
/**
* stepper.cpp - stepper motor driver: executes motion plans using stepper motors
* The timer calculations of this module informed by the 'RepRap cartesian firmware' by Zack Smith
* and Philipp Tiefenbacher.
*/
#include "../../base.h"
#include "stepper.h"
......@@ -62,7 +66,7 @@ static int counter_raster;
#endif
// Counter variables for the Bresenham line tracer
static long counter_x, counter_y, counter_z, counter_e;
static long counter_X, counter_Y, counter_Z, counter_E;
volatile static unsigned long step_events_completed; // The number of step events executed in the current block
#if ENABLED(ADVANCE)
......@@ -311,7 +315,7 @@ void checkHitEndstops() {
card.sdprinting = false;
card.closeFile();
#endif
for (int i = 0; i < 3; i++) CBI(axis_known_position, i); // not homed anymore
for (int i = 0; i < 3; i++) axis_known_position[i] = true; // not homed anymore
quickStop(); // kill the planner buffer
Stop(); // restart by M999
}
......@@ -646,7 +650,7 @@ ISR(TIMER1_COMPA_vect) {
current_block = NULL;
plan_discard_current_block();
#if ENABLED(SD_FINISHED_RELEASECOMMAND)
if ((cleaning_buffer_counter == 1) && (SD_FINISHED_STEPPERRELEASE)) enqueuecommands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
if ((cleaning_buffer_counter == 1) && (SD_FINISHED_STEPPERRELEASE)) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
#endif
cleaning_buffer_counter--;
OCR1A = 200;
......@@ -669,8 +673,7 @@ ISR(TIMER1_COMPA_vect) {
trapezoid_generator_reset();
// Initialize Bresenham counters to 1/2 the ceiling
long new_count = -(current_block->step_event_count >> 1);
counter_x = counter_y = counter_z = counter_e = new_count;
counter_X = counter_Y = counter_Z = counter_E = -(current_block->step_event_count >> 1);
#if ENABLED(LASER)
counter_l = counter_x;
laser.dur = current_block->laser_duration;
......@@ -678,7 +681,7 @@ ISR(TIMER1_COMPA_vect) {
#if ENABLED(COLOR_MIXING_EXTRUDER)
for (uint8_t i = 0; i < DRIVER_EXTRUDERS; i++)
counter_m[i] = new_count;
counter_m[i] = -(current_block->step_event_count >> 1);
#endif
step_events_completed = 0;
......@@ -729,9 +732,9 @@ ISR(TIMER1_COMPA_vect) {
MKSERIAL.checkRx(); // Check for serial chars.
#if ENABLED(ADVANCE)
counter_e += current_block->steps[E_AXIS];
if (counter_e > 0) {
counter_e -= current_block->step_event_count;
counter_E += current_block->steps[E_AXIS];
if (counter_E > 0) {
counter_E -= current_block->step_event_count;
#if DISABLED(COLOR_MIXING_EXTRUDER)
// Don't step E for mixing extruder
e_steps[current_block->active_driver] += TEST(out_bits, E_AXIS) ? -1 : 1;
......@@ -750,13 +753,13 @@ ISR(TIMER1_COMPA_vect) {
#endif // !COLOR_MIXING_EXTRUDER
#endif // ADVANCE
#define _COUNTER(axis) counter_## axis
#define _COUNTER(AXIS) counter_## AXIS
#define _APPLY_STEP(AXIS) AXIS ##_APPLY_STEP
#define _INVERT_STEP_PIN(AXIS) INVERT_## AXIS ##_STEP_PIN
#define STEP_START(axis, AXIS) \
_COUNTER(axis) += current_block->steps[_AXIS(AXIS)]; \
if (_COUNTER(axis) > 0) _APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS),0);
#define STEP_START(AXIS) \
_COUNTER(AXIS) += current_block->steps[_AXIS(AXIS)]; \
if (_COUNTER(AXIS) > 0) _APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS),0);
#define STEP_START_MIXING \
for (uint8_t j = 0; j < DRIVER_EXTRUDERS; j++) { \
......@@ -764,9 +767,9 @@ ISR(TIMER1_COMPA_vect) {
if (counter_m[j] > 0) En_STEP_WRITE(j, !INVERT_E_STEP_PIN); \
}
#define STEP_END(axis, AXIS) \
if (_COUNTER(axis) > 0) { \
_COUNTER(axis) -= current_block->step_event_count; \
#define STEP_END(AXIS) \
if (_COUNTER(AXIS) > 0) { \
_COUNTER(AXIS) -= current_block->step_event_count; \
count_position[_AXIS(AXIS)] += count_direction[_AXIS(AXIS)]; \
_APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS),0); \
}
......@@ -779,11 +782,11 @@ ISR(TIMER1_COMPA_vect) {
} \
}
STEP_START(x, X);
STEP_START(y, Y);
STEP_START(z, Z);
STEP_START(X);
STEP_START(Y);
STEP_START(Z);
#if DISABLED(ADVANCE)
STEP_START(e, E);
STEP_START(E);
#if ENABLED(COLOR_MIXING_EXTRUDER)
STEP_START_MIXING;
#endif
......@@ -793,11 +796,11 @@ ISR(TIMER1_COMPA_vect) {
HAL::delayMicroseconds(STEPPER_HIGH_LOW_DELAY);
#endif
STEP_END(x, X);
STEP_END(y, Y);
STEP_END(z, Z);
STEP_END(X);
STEP_END(Y);
STEP_END(Z);
#if DISABLED(ADVANCE)
STEP_END(e, E);
STEP_END(E);
#if ENABLED(COLOR_MIXING_EXTRUDER)
STEP_END_MIXING;
#endif
......@@ -1253,11 +1256,45 @@ void st_init() {
*/
void st_synchronize() { while (blocks_queued()) idle(); }
/**
* Set the stepper positions directly in steps
*
* The input is based on the typical per-axis XYZ steps.
* For CORE machines XYZ needs to be translated to ABC.
*
* This allows get_axis_position_mm to correctly
* derive the current XYZ position later on.
*/
void st_set_position(const long& x, const long& y, const long& z, const long& e) {
CRITICAL_SECTION_START;
count_position[X_AXIS] = x;
count_position[Y_AXIS] = y;
count_position[Z_AXIS] = z;
#if MECH(COREXY)
// corexy positioning
count_position[A_AXIS] = x + COREX_YZ_FACTOR * y;
count_position[B_AXIS] = x - COREX_YZ_FACTOR * y;
count_position[Z_AXIS] = z;
#elif MECH(COREYX)
// coreyx positioning
count_position[A_AXIS] = y + COREX_YZ_FACTOR * x;
count_position[B_AXIS] = y - COREX_YZ_FACTOR * x;
count_position[Z_AXIS] = z;
#elif MECH(COREXZ)
// corexz planning
count_position[A_AXIS] = x + COREX_YZ_FACTOR * z;
count_position[Y_AXIS] = y;
count_position[C_AXIS] = x - COREX_YZ_FACTOR * z;
#elif MECH(COREZX)
// corezx planning
count_position[A_AXIS] = z + COREX_YZ_FACTOR * x;
count_position[Y_AXIS] = y;
count_position[C_AXIS] = z - COREX_YZ_FACTOR * x;
#else
// default non-h-bot planning
count_position[X_AXIS] = x;
count_position[Y_AXIS] = y;
count_position[Z_AXIS] = z;
#endif
count_position[E_AXIS] = e;
CRITICAL_SECTION_END;
}
......@@ -1329,6 +1366,43 @@ void quickStop() {
ENABLE_STEPPER_DRIVER_INTERRUPT();
}
void report_positions() {
CRITICAL_SECTION_START;
long xpos = count_position[X_AXIS],
ypos = count_position[Y_AXIS],
zpos = count_position[Z_AXIS];
CRITICAL_SECTION_END;
#if MECH(COREXY) || MECH(COREYX) || MECH(COREXZ) || MECH(COREZX)
ECHO_M(SERIAL_COUNT_A);
#elif MECH(DELTA)
ECHO_M(SERIAL_COUNT_ALPHA);
#else
ECHO_M(SERIAL_COUNT_X);
#endif
ECHO_V(xpos);
#if MECH(COREXY) || MECH(COREYX)
ECHO_M(" B:");
#elif MECH(DELTA)
ECHO_M(" Beta:");
#else
ECHO_M(" Y:");
#endif
ECHO_V(ypos);
#if MECH(COREXZ) || MECH(COREZX)
ECHO_M(" C:");
#elif MECH(DELTA)
ECHO_M(" Teta:");
#else
ECHO_M(" Z:");
#endif
ECHO_V(zpos);
ECHO_E;
}
#if ENABLED(NPR2)
void colorstep(long csteps,const bool direction) {
enable_e1();
......
/**
* stepper.h - stepper motor driver: executes motion plans of planner.c using the stepper motors
* Part of Grbl
* MK & MK4due 3D Printer Firmware
*
* Copyright (c) 2009-2011 Simen Svale Skogsrud
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* Grbl is free software: you can redistribute it and/or modify
* 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.
*
* Grbl is distributed in the hope that it will be useful,
* 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 Grbl. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* stepper.h - stepper motor driver: executes motion plans of planner.c using the stepper motors
*/
#ifndef STEPPER_H
#define STEPPER_H
......@@ -59,6 +64,11 @@
// to notify the subsystem that it is time to go to work.
void st_wake_up();
//
// Report the positions of the steppers, in steps
//
void report_positions();
void checkHitEndstops(); //call from somewhere to create an serial error message with the locations the endstops where hit, in case they were triggered
void endstops_hit_on_purpose(); //avoid creation of the message, i.e. after homing and before a routine call of checkHitEndstops();
......
/*
stepper_indirection.c - stepper motor driver indirection
to allow some stepper functions to be done via SPI/I2c instead of direct pin manipulation
Part of Marlin
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
Copyright (c) 2015 Dominik Wenger
Marlin 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.
Marlin 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 Marlin. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* stepper_indirection.c - stepper motor driver indirection
* to allow some stepper functions to be done via SPI/I2c instead of direct pin manipulation
*
* Copyright (c) 2015 Dominik Wenger
*
*/
#include "../../base.h"
#include "stepper_indirection.h"
......
/*
stepper_indirection.h - stepper motor driver indirection macros
to allow some stepper functions to be done via SPI/I2c instead of direct pin manipulation
Part of Marlin
Copyright (c) 2015 Dominik Wenger
Marlin 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.
Marlin 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 Marlin. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* stepper_indirection.h - stepper motor driver indirection macros
* to allow some stepper functions to be done via SPI/I2c instead of direct pin manipulation
*
* Copyright (c) 2015 Dominik Wenger
*
*/
#ifndef STEPPER_INDIRECTION_H
#define STEPPER_INDIRECTION_H
......@@ -179,7 +188,7 @@
#define E5_ENABLE_READ READ(E5_ENABLE_PIN)
#if ENABLED(COLOR_MIXING_EXTRUDER)
#define E_STEP_WRITE(v) ; /* not used for mixing extruders! */
#define E_STEP_WRITE(v) NOOP /* not used for mixing extruders! */
#if DRIVER_EXTRUDERS > 5
#define En_STEP_WRITE(n,v) { switch (n) { case 0: E0_STEP_WRITE(v); break; case 1: E1_STEP_WRITE(v); break; case 2: E2_STEP_WRITE(v); break; case 3: E3_STEP_WRITE(v); break; case 4: E4_STEP_WRITE(v); break; case 5: E5_STEP_WRITE(v); } }
#define NORM_E_DIR() { E0_DIR_WRITE(!INVERT_E0_DIR); E1_DIR_WRITE(!INVERT_E1_DIR); E2_DIR_WRITE(!INVERT_E2_DIR); E3_DIR_WRITE(!INVERT_E3_DIR); E4_DIR_WRITE(!INVERT_E4_DIR); E5_DIR_WRITE(!INVERT_E5_DIR); }
......@@ -245,7 +254,7 @@
#define disable_x() do { X_ENABLE_WRITE(!X_ENABLE_ON); X2_ENABLE_WRITE(!X_ENABLE_ON); CBI(axis_known_position, X_AXIS); } while (0)
#elif HAS(X_ENABLE)
#define enable_x() X_ENABLE_WRITE( X_ENABLE_ON)
#define disable_x() { X_ENABLE_WRITE(!X_ENABLE_ON); CBI(axis_known_position, X_AXIS); }
#define disable_x() { X_ENABLE_WRITE(!X_ENABLE_ON); axis_known_position[X_AXIS] = false; }
#else
#define enable_x() ;
#define disable_x() ;
......@@ -257,7 +266,7 @@
#define disable_y() { Y_ENABLE_WRITE(!Y_ENABLE_ON); Y2_ENABLE_WRITE(!Y_ENABLE_ON); CBI(axis_known_position, Y_AXIS); }
#else
#define enable_y() Y_ENABLE_WRITE( Y_ENABLE_ON)
#define disable_y() { Y_ENABLE_WRITE(!Y_ENABLE_ON); CBI(axis_known_position, Y_AXIS); }
#define disable_y() { Y_ENABLE_WRITE(!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; }
#endif
#else
#define enable_y() ;
......@@ -267,10 +276,10 @@
#if HAS(Z_ENABLE)
#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
#define enable_z() { Z_ENABLE_WRITE( Z_ENABLE_ON); Z2_ENABLE_WRITE(Z_ENABLE_ON); }
#define disable_z() { Z_ENABLE_WRITE(!Z_ENABLE_ON); Z2_ENABLE_WRITE(!Z_ENABLE_ON); CBI(axis_known_position, Z_AXIS); }
#define disable_z() { Z_ENABLE_WRITE(!Z_ENABLE_ON); Z2_ENABLE_WRITE(!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }
#else
#define enable_z() Z_ENABLE_WRITE( Z_ENABLE_ON)
#define disable_z() { Z_ENABLE_WRITE(!Z_ENABLE_ON); CBI(axis_known_position, Z_AXIS); }
#define disable_z() { Z_ENABLE_WRITE(!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }
#endif
#else
#define enable_z() ;
......@@ -296,16 +305,16 @@
#define disable_e0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); }
#endif
#define enable_e1() ;
#define disable_e1() ;
#define enable_e2() ;
#define disable_e2() ;
#define enable_e3() ;
#define disable_e3() ;
#define enable_e4() ;
#define disable_e4() ;
#define enable_e5() ;
#define disable_e5() ;
#define enable_e1() NOOP
#define disable_e1() NOOP
#define enable_e2() NOOP
#define disable_e2() NOOP
#define enable_e3() NOOP
#define disable_e3() NOOP
#define enable_e4() NOOP
#define disable_e4() NOOP
#define enable_e5() NOOP
#define disable_e5() NOOP
#else // !COLOR_MIXING_EXTRUDER
......@@ -313,48 +322,48 @@
#define enable_e0() E0_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e0() E0_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_e0() /* nothing */
#define disable_e0() /* nothing */
#define enable_e0() NOOP
#define disable_e0() NOOP
#endif
#if (DRIVER_EXTRUDERS > 1) && HAS(E1_ENABLE)
#define enable_e1() E1_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e1() E1_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_e1() /* nothing */
#define disable_e1() /* nothing */
#define enable_e1() NOOP
#define disable_e1() NOOP
#endif
#if (DRIVER_EXTRUDERS > 2) && HAS(E2_ENABLE)
#define enable_e2() E2_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e2() E2_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_e2() /* nothing */
#define disable_e2() /* nothing */
#define enable_e2() NOOP
#define disable_e2() NOOP
#endif
#if (DRIVER_EXTRUDERS > 3) && HAS(E3_ENABLE)
#define enable_e3() E3_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e3() E3_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_e3() /* nothing */
#define disable_e3() /* nothing */
#define enable_e3() NOOP
#define disable_e3() NOOP
#endif
#if (DRIVER_EXTRUDERS > 4) && HAS(E4_ENABLE)
#define enable_e4() E4_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e4() E4_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_e4() /* nothing */
#define disable_e4() /* nothing */
#define enable_e4() NOOP
#define disable_e4() NOOP
#endif
#if (DRIVER_EXTRUDERS > 5) && HAS(E5_ENABLE)
#define enable_e5() E5_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e5() E5_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_e5() /* nothing */
#define disable_e5() /* nothing */
#define enable_e5() NOOP
#define disable_e5() NOOP
#endif
#endif
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* vector_3.cpp - Vector library for bed leveling
* Copyright (c) 2012 Lars Brubaker. All right reserved.
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* vector_3.cpp - Vector library for bed leveling
* Copyright (c) 2012 Lars Brubaker. All right reserved.
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* Nextion_lcd.cpp
*
* Copyright (c) 2014-2016 Alberto Cotronei @MagoKimbra
*
* 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
* (at your option) any later version.
*
* Grbl 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 Grbl. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../../base.h"
#if ENABLED(NEXTION)
......@@ -276,8 +317,8 @@
char* c;
sprintf_P(cmd, PSTR("M23 %s"), filename);
for(c = &cmd[4]; *c; c++) *c = tolower(*c);
enqueuecommand(cmd);
enqueuecommands_P(PSTR("M24"));
enqueue_and_echo_command(cmd);
enqueue_and_echo_commands_P(PSTR("M24"));
setpageInfo();
}
......@@ -428,14 +469,14 @@
void sethotPopCallback(void *ptr) {
memset(buffer, 0, sizeof(buffer));
set1.getText(buffer, sizeof(buffer));
enqueuecommands_P(buffer);
enqueue_and_echo_commands_P(buffer);
setpageInfo();
}
void setgcodePopCallback(void *ptr) {
memset(buffer, 0, sizeof(buffer));
Tgcode.getText(buffer, sizeof(buffer));
enqueuecommands_P(buffer);
enqueue_and_echo_commands_P(buffer);
Pmenu.show();
}
......@@ -453,9 +494,9 @@
void setmovePopCallback(void *ptr) {
memset(buffer, 0, sizeof(buffer));
movecmd.getText(buffer, sizeof(buffer));
enqueuecommands_P(PSTR("G91"));
enqueuecommands_P(buffer);
enqueuecommands_P(PSTR("G90"));
enqueue_and_echo_commands_P(PSTR("G91"));
enqueue_and_echo_commands_P(buffer);
enqueue_and_echo_commands_P(PSTR("G90"));
}
#if ENABLED(SDSUPPORT)
......@@ -571,30 +612,24 @@
char* valuetemp;
memset(buffer, 0, sizeof(buffer));
strcat(buffer, TEST(axis_known_position, X_AXIS) || !TEST(axis_was_homed, X_AXIS) ? "X" : "?");
if (TEST(axis_was_homed, X_AXIS)) {
strcat(buffer, (axis_known_position[X_AXIS] ? "X" : "?"));
if (axis_homed[X_AXIS]) {
valuetemp = ftostr4sign(current_position[X_AXIS]);
strcat(buffer, valuetemp);
}
else
strcat(buffer, "---");
strcat(buffer, TEST(axis_known_position, Y_AXIS) || !TEST(axis_was_homed, Y_AXIS) ? PSTR(" Y") : PSTR(" ?"));
if (TEST(axis_was_homed, Y_AXIS)) {
strcat(buffer, (axis_known_position[Y_AXIS] ? " Y" : " ?"));
if (axis_homed[Y_AXIS]) {
valuetemp = ftostr4sign(current_position[Y_AXIS]);
strcat(buffer, valuetemp);
}
else
strcat(buffer, "---");
strcat(buffer, TEST(axis_known_position, Z_AXIS) || !TEST(axis_was_homed, Z_AXIS) ? PSTR(" Z ") : PSTR("? "));
if (TEST(axis_was_homed, Z_AXIS)) {
strcat(buffer, (axis_known_position[Z_AXIS] ? " Z " : " ? "));
if (axis_homed[Z_AXIS]) {
valuetemp = ftostr32sp(current_position[Z_AXIS] + 0.00001);
strcat(buffer, valuetemp);
}
else
strcat(buffer, "---");
LedCoord1.setText(buffer);
LedCoord6.setText(buffer);
}
......@@ -647,7 +682,7 @@
NPlay.setPic(17);
// Estimate End Time
uint16_t time = (millis() - print_job_start_ms) / 60000;
uint16_t time = print_job_timer.duration() / 60;
uint16_t end_time = (time * (100 - card.percentDone())) / card.percentDone();
if (end_time > (60 * 23)) {
lcd_setstatus("End --:--");
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* Nextion_lcd.h
*
* Copyright (c) 2014-2016 Alberto Cotronei @MagoKimbra
*
* 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
* (at your option) any later version.
*
* Grbl 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 Grbl. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NEXTIONLCD_H
#define NEXTIONLCD_H
......
/**
* pins.h
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef PINS_H
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* sanitycheck.h
*
......
/* Arduino SdFat Library
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* Arduino SdFat Library
* Copyright (C) 2012 by William Greiman
*
* This file is part of the Arduino SdFat Library
......
/* Arduino SdFat Library
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* Arduino SdFat Library
* Copyright (C) 2012 by William Greiman
*
* This file is part of the Arduino SdFat Library
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "../../base.h"
#if ENABLED(SDSUPPORT)
......@@ -320,7 +342,7 @@ void CardReader::printingHasFinished() {
sdprinting = false;
if (SD_FINISHED_STEPPERRELEASE) {
//finishAndDisableSteppers();
enqueuecommands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
}
autotempShutdown();
}
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef CARDREADER_H
#define CARDREADER_H
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* Copyright (c) 2013 Arduino LLC. All right reserved.
*
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* Copyright (c) 2013 Arduino LLC. All right reserved.
*
......
/*
servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
Copyright (c) 2009 Michael Margolis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
* Copyright (c) 2009 Michael Margolis. All right reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
A servo is activated by creating an instance of the Servo class passing
the desired pin to the attach() method.
The servos are pulsed in the background using the value most recently
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "../../base.h"
#include "stopwatch.h"
Stopwatch::Stopwatch() {
this->reset();
}
void Stopwatch::stop() {
#if ENABLED(DEBUG_STOPWATCH)
debug(PSTR("stop"));
#endif
if (!this->isRunning()) return;
this->status = STPWTCH_STOPPED;
this->stopTimestamp = millis();
}
void Stopwatch::pause() {
#if ENABLED(DEBUG_STOPWATCH)
debug(PSTR("pause"));
#endif
if (!this->isRunning()) return;
this->status = STPWTCH_PAUSED;
this->stopTimestamp = millis();
}
void Stopwatch::start() {
#if ENABLED(DEBUG_STOPWATCH)
debug(PSTR("start"));
#endif
if (this->isRunning()) return;
if (this->isPaused()) this->accumulator = this->duration();
else this->reset();
this->status = STPWTCH_RUNNING;
this->startTimestamp = millis();
}
void Stopwatch::reset() {
#if ENABLED(DEBUG_STOPWATCH)
debug(PSTR("reset"));
#endif
this->status = STPWTCH_STOPPED;
this->startTimestamp = 0;
this->stopTimestamp = 0;
this->accumulator = 0;
}
bool Stopwatch::isRunning() {
return (this->status == STPWTCH_RUNNING) ? true : false;
}
bool Stopwatch::isPaused() {
return (this->status == STPWTCH_PAUSED) ? true : false;
}
uint16_t Stopwatch::duration() {
return (((this->isRunning()) ? millis() : this->stopTimestamp)
- this->startTimestamp) / 1000 + this->accumulator;
}
#if ENABLED(DEBUG_STOPWATCH)
void Stopwatch::debug(const char func[]) {
if (DEBUGGING(INFO)) {
ECHO_MT("Stopwatch::", func);
ECHO_EM("()");
}
}
#endif
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef STOPWATCH_H
#define STOPWATCH_H
// Print debug messages with M111 S2 (Uses 156 bytes of PROGMEM)
//#define DEBUG_STOPWATCH
enum StopwatchStatus {
STPWTCH_STOPPED,
STPWTCH_RUNNING,
STPWTCH_PAUSED
};
/**
* @brief Stopwatch class
* @details This class acts as a timer proving stopwatch functionality including
* the ability to pause the running time counter.
*/
class Stopwatch {
private:
StopwatchStatus status;
uint16_t accumulator;
uint32_t startTimestamp;
uint32_t stopTimestamp;
public:
/**
* @brief Class constructor
*/
Stopwatch();
/**
* @brief Stops the stopwatch
* @details Stops the running timer, it will silently ignore the request if
* no timer is currently running.
*/
void stop();
/**
* @brief Pauses the stopwatch
* @details Pauses the running timer, it will silently ignore the request if
* no timer is currently running.
*/
void pause();
/**
* @brief Starts the stopwatch
* @details Starts the timer, it will silently ignore the request if the
* timer is already running.
*/
void start();
/**
* @brief Resets the stopwatch
* @details Resets all settings to their default values.
*/
void reset();
/**
* @brief Checks if the timer is running
* @details Returns true if the timer is currently running, false otherwise.
* @return bool
*/
bool isRunning();
/**
* @brief Checks if the timer is paused
* @details Returns true if the timer is currently paused, false otherwise.
* @return bool
*/
bool isPaused();
/**
* @brief Gets the running time
* @details Returns the total number of seconds the timer has been running.
* @return uint16_t
*/
uint16_t duration();
#if ENABLED(DEBUG_STOPWATCH)
/**
* @brief Prints a debug message
* @details Prints a simple debug message "Stopwatch::function"
*/
static void debug(const char func[]);
#endif
};
#endif //STOPWATCH_H
/*
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
temperature.cpp - temperature control
Part of Marlin
......@@ -215,8 +237,8 @@ void autotempShutdown() {
#endif
}
#if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED)
void PID_autotune(float temp, int hotend, int ncycles) {
#if HAS(PID_HEATING)
void PID_autotune(float temp, int hotend, int ncycles, bool set_result/*=false*/) {
float input = 0.0;
int cycles = 0;
bool heating = true;
......@@ -226,7 +248,7 @@ void autotempShutdown() {
long bias = 0, d = 0;
float Ku = 0, Tu = 0;
float Kp_temp = 0, Ki_temp = 0, Kd_temp = 0;
float workKp = 0, workKi = 0, workKd = 0;
float max = 0, min = 10000;
#if HAS(AUTO_FAN)
......@@ -312,23 +334,29 @@ void autotempShutdown() {
Tu = ((float)(t_low + t_high) / 1000.0);
ECHO_MV(SERIAL_KU, Ku);
ECHO_EMV(SERIAL_TU, Tu);
Kp_temp = 0.6 * Ku;
Ki_temp = 2 * Kp_temp / Tu;
Kd_temp = Kp_temp * Tu / 8;
workKp = 0.6 * Ku;
workKi = 2 * workKp / Tu;
workKd = workKp * Tu / 8;
ECHO_EM(SERIAL_CLASSIC_PID);
ECHO_MV(SERIAL_KP, Kp_temp);
ECHO_MV(SERIAL_KI, Ki_temp);
ECHO_EMV(SERIAL_KD, Kd_temp);
ECHO_MV(SERIAL_KP, workKp);
ECHO_MV(SERIAL_KI, workKi);
ECHO_EMV(SERIAL_KD, workKd);
}
else {
ECHO_E;
}
}
if (hotend < 0)
soft_pwm_bed = (bias + d) >> 1;
else
#if HAS(PID_FOR_BOTH)
if (hotend < 0)
soft_pwm_bed = (bias + d) >> 1;
else
soft_pwm[hotend] = (bias + d) >> 1;
#elif ENABLED(PIDTEMP)
soft_pwm[hotend] = (bias + d) >> 1;
#else
soft_pwm_bed = (bias + d) >> 1;
#endif
cycles++;
min = temp;
}
......@@ -340,7 +368,7 @@ void autotempShutdown() {
}
// Every 2 seconds...
if (ms > temp_ms + 2000) {
if (ELAPSED(ms, temp_ms + 2000UL)) {
#if HAS(TEMP_0) || HAS(TEMP_BED) || ENABLED(HEATER_0_USES_MAX6675)
print_heaterstates();
ECHO_E;
......@@ -356,23 +384,51 @@ void autotempShutdown() {
}
if (cycles > ncycles) {
ECHO_LM(DB, SERIAL_PID_AUTOTUNE_FINISHED);
#if ENABLED(PIDTEMP)
#if HAS(PID_FOR_BOTH)
if (hotend >= 0) {
PID_PARAM(Kp, hotend) = Kp_temp;
PID_PARAM(Ki, hotend) = scalePID_i(Ki_temp);
PID_PARAM(Kd, hotend) = scalePID_d(Kd_temp);
updatePID();
ECHO_SMV(DB, SERIAL_KP, PID_PARAM(Kp, hotend));
ECHO_MV(SERIAL_KI, unscalePID_i(PID_PARAM(Ki, hotend)));
ECHO_EMV(SERIAL_KD, unscalePID_d(PID_PARAM(Kd, hotend)));
if (set_result) {
PID_PARAM(Kp, hotend) = workKp;
PID_PARAM(Ki, hotend) = scalePID_i(workKi);
PID_PARAM(Kd, hotend) = scalePID_d(workKd);
updatePID();
}
}
else {
ECHO_LMV(DB, "#define DEFAULT_bedKp ", Kp_temp);
ECHO_LMV(DB, "#define DEFAULT_bedKi ", unscalePID_i(Ki_temp));
ECHO_LMV(DB, "#define DEFAULT_bedKd ", unscalePID_d(Kd_temp));
ECHO_LMV(DB, "#define DEFAULT_bedKp ", workKp);
ECHO_LMV(DB, "#define DEFAULT_bedKi ", unscalePID_i(workKi));
ECHO_LMV(DB, "#define DEFAULT_bedKd ", unscalePID_d(workKd));
if (set_result) {
bedKp = workKp;
bedKi = scalePID_i(workKi);
bedKd = scalePID_d(workKd);
updatePID();
}
}
#elif ENABLED(PIDTEMP)
ECHO_SMV(DB, SERIAL_KP, PID_PARAM(Kp, hotend));
ECHO_MV(SERIAL_KI, unscalePID_i(PID_PARAM(Ki, hotend)));
ECHO_EMV(SERIAL_KD, unscalePID_d(PID_PARAM(Kd, hotend)));
if (set_result) {
PID_PARAM(Kp, hotend) = workKp;
PID_PARAM(Ki, hotend) = scalePID_i(workKi);
PID_PARAM(Kd, hotend) = scalePID_d(workKd);
updatePID();
}
#else
ECHO_LMV(DB, "#define DEFAULT_bedKp ", workKp);
ECHO_LMV(DB, "#define DEFAULT_bedKi ", unscalePID_i(workKi));
ECHO_LMV(DB, "#define DEFAULT_bedKd ", unscalePID_d(workKd));
if (set_result) {
bedKp = workKp;
bedKi = scalePID_i(workKi);
bedKd = scalePID_d(workKd);
updatePID();
}
#endif
return;
}
lcd_update();
......
/*
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
temperature.h - temperature controller
Part of Marlin
......@@ -146,7 +168,9 @@ int getHeaterPower(int heater);
void disable_all_heaters();
void updatePID();
void PID_autotune(float temp, int hotend, int ncycles);
#if HAS(PID_HEATING)
void PID_autotune(float temp, int hotend, int ncycles, bool set_result = false);
#endif
void setExtruderAutoFanState(int pin, bool state);
void checkExtruderAutoFans();
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef THERMISTORTABLES_H_
#define THERMISTORTABLES_H_
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "../../base.h"
#if ENABLED(USE_WATCHDOG)
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef WATCHDOG_H
#define WATCHDOG_H
#include <avr/wdt.h>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment