Fix merge conflict/resync

This commit is contained in:
VintagePC 2023-05-06 11:22:31 -04:00
commit e336e2ad08
84 changed files with 12777 additions and 12526 deletions

View File

@ -142,6 +142,7 @@ set(FW_SOURCES
lcd.cpp
Marlin_main.cpp
MarlinSerial.cpp
meatpack.cpp
menu.cpp
mesh_bed_calibration.cpp
mesh_bed_leveling.cpp
@ -177,6 +178,7 @@ set(FW_SOURCES
spi.c
SpoolJoin.cpp
stepper.cpp
strtod.c
swi2c.c
Tcodes.cpp
temperature.cpp

View File

@ -6,7 +6,6 @@
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
//-//
#include <avr/pgmspace.h>
extern const uint16_t _nPrinterType;
extern const char _sPrinterName[] PROGMEM;
@ -17,7 +16,7 @@ extern const char _sPrinterMmuName[] PROGMEM;
#define FW_MAJOR 3
#define FW_MINOR 13
#define FW_REVISION 0
#define FW_FLAVOR BETA //uncomment if DEBUG, DEVEL, ALPHA, BETA or RC
#define FW_FLAVOR RC //uncomment if DEBUG, DEVEL, ALPHA, BETA or RC
#define FW_FLAVERSION 1 //uncomment if FW_FLAVOR is defined and versioning is needed. Limited to max 8.
#ifndef FW_FLAVOR
#define FW_VERSION STR(FW_MAJOR) "." STR(FW_MINOR) "." STR(FW_REVISION)
@ -25,7 +24,7 @@ extern const char _sPrinterMmuName[] PROGMEM;
#define FW_VERSION STR(FW_MAJOR) "." STR(FW_MINOR) "." STR(FW_REVISION) "-" STR(FW_FLAVOR) "" STR(FW_FLAVERSION)
#endif
#define FW_COMMIT_NR 6508
#define FW_COMMIT_NR 6565
// FW_VERSION_UNKNOWN means this is an unofficial build.
// The firmware should only be checked into github with this symbol.
@ -94,6 +93,9 @@ extern const char _sPrinterMmuName[] PROGMEM;
// This determines the communication speed of the printer
#define BAUDRATE 115200
// Enable g-code compression (see https://github.com/scottmudge/OctoPrint-MeatPack)
#define ENABLE_MEATPACK
// This enables the serial port associated to the Bluetooth interface
//#define BTENABLED // Enable BT interface on AT90USB devices

View File

@ -453,14 +453,6 @@ const unsigned int dropsegments=5; //everything with less than this number of st
#define THERMISTORHEATER_0 TEMP_SENSOR_0
#define HEATER_0_USES_THERMISTOR
#endif
#if TEMP_SENSOR_1 > 0
#define THERMISTORHEATER_1 TEMP_SENSOR_1
#define HEATER_1_USES_THERMISTOR
#endif
#if TEMP_SENSOR_2 > 0
#define THERMISTORHEATER_2 TEMP_SENSOR_2
#define HEATER_2_USES_THERMISTOR
#endif
#if TEMP_SENSOR_BED > 0
#define THERMISTORBED TEMP_SENSOR_BED
#define BED_USES_THERMISTOR
@ -474,12 +466,6 @@ const unsigned int dropsegments=5; //everything with less than this number of st
#if TEMP_SENSOR_0 == -1
#define HEATER_0_USES_AD595
#endif
#if TEMP_SENSOR_1 == -1
#define HEATER_1_USES_AD595
#endif
#if TEMP_SENSOR_2 == -1
#define HEATER_2_USES_AD595
#endif
#if TEMP_SENSOR_BED == -1
#define BED_USES_AD595
#endif
@ -490,14 +476,6 @@ const unsigned int dropsegments=5; //everything with less than this number of st
#undef HEATER_0_MINTEMP
#undef HEATER_0_MAXTEMP
#endif
#if TEMP_SENSOR_1 == 0
#undef HEATER_1_MINTEMP
#undef HEATER_1_MAXTEMP
#endif
#if TEMP_SENSOR_2 == 0
#undef HEATER_2_MINTEMP
#undef HEATER_2_MAXTEMP
#endif
#if TEMP_SENSOR_BED == 0
#undef BED_MINTEMP
#undef BED_MAXTEMP

View File

@ -4,7 +4,6 @@
#include "Filament_sensor.h"
#include "Timer.h"
#include "cardreader.h"
#include "eeprom.h"
#include "menu.h"
#include "planner.h"
@ -110,29 +109,29 @@ bool Filament_sensor::checkFilamentEvents() {
void Filament_sensor::triggerFilamentInserted() {
if (autoLoadEnabled
&& (eFilamentAction == FilamentAction::None)
&& (! MMU2::mmu2.Enabled() ) // quick and dirty hack to prevent spurious runouts while the MMU is in charge
&& !(
moves_planned() != 0
|| IS_SD_PRINTING
|| usb_timer.running()
MMU2::mmu2.Enabled() // quick and dirty hack to prevent spurious runouts while the MMU is in charge
|| moves_planned() != 0
|| printJobOngoing()
|| (lcd_commands_type == LcdCommands::Layer1Cal)
|| eeprom_read_byte((uint8_t *)EEPROM_WIZARD_ACTIVE)
)
) {
filAutoLoad();
menu_submenu(lcd_AutoLoadFilament, true);
}
}
void Filament_sensor::triggerFilamentRemoved() {
// SERIAL_ECHOLNPGM("triggerFilamentRemoved");
if (runoutEnabled
&& (! MMU2::mmu2.Enabled() ) // quick and dirty hack to prevent spurious runouts just before the toolchange
&& (eFilamentAction == FilamentAction::None)
&& !saved_printing
&& (
moves_planned() != 0
|| IS_SD_PRINTING
|| usb_timer.running()
|| printJobOngoing()
)
&& !(
saved_printing
|| MMU2::mmu2.Enabled() // quick and dirty hack to prevent spurious runouts just before the toolchange
|| (lcd_commands_type == LcdCommands::Layer1Cal)
|| eeprom_read_byte((uint8_t *)EEPROM_WIZARD_ACTIVE)
)
@ -144,16 +143,6 @@ void Filament_sensor::triggerFilamentRemoved() {
}
}
void Filament_sensor::filAutoLoad() {
eFilamentAction = FilamentAction::AutoLoad;
if (target_temperature[0] >= EXTRUDE_MINTEMP) {
bFilamentPreheatState = true;
menu_submenu(mFilamentItemForce);
} else {
menu_submenu(lcd_generic_preheat_menu);
lcd_timeoutToStatus.start();
}
}
void Filament_sensor::filRunout() {
// SERIAL_ECHOLNPGM("filRunout");
@ -163,7 +152,7 @@ void Filament_sensor::filRunout() {
restore_print_from_ram_and_continue(0);
eeprom_increment_byte((uint8_t *)EEPROM_FERROR_COUNT);
eeprom_increment_word((uint16_t *)EEPROM_FERROR_COUNT_TOT);
enquecommand_front_P((PSTR("M600")));
enquecommand_front_P(MSG_M600);
}
void Filament_sensor::triggerError() {
@ -483,7 +472,7 @@ void PAT9125_sensor::filJam() {
restore_print_from_ram_and_continue(0);
eeprom_increment_byte((uint8_t *)EEPROM_FERROR_COUNT);
eeprom_increment_word((uint16_t *)EEPROM_FERROR_COUNT_TOT);
enquecommand_front_P((PSTR("M600")));
enquecommand_front_P(MSG_M600);
}
bool PAT9125_sensor::updatePAT9125() {
@ -509,7 +498,7 @@ bool PAT9125_sensor::updatePAT9125() {
}
}
if (!pollingTimer.running() || pollingTimer.expired(pollingPeriod)) {
if (pollingTimer.expired_cont(pollingPeriod)) {
pollingTimer.start();
if (!pat9125_update()) {
init(); // try to reinit.

View File

@ -69,9 +69,7 @@ protected:
void triggerFilamentInserted();
void triggerFilamentRemoved();
static void filAutoLoad();
void filRunout();
void triggerError();

View File

@ -182,21 +182,6 @@ void manage_inactivity(bool ignore_stepper_queue=false);
#define disable_z() disable_force_z()
#endif // PSU_Delta
//#if defined(Z_ENABLE_PIN) && Z_ENABLE_PIN > -1
//#ifdef Z_DUAL_STEPPER_DRIVERS
//#define enable_z() { WRITE(Z_ENABLE_PIN, Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN, Z_ENABLE_ON); }
//#define disable_z() { WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN,!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }
//#else
//#define enable_z() WRITE(Z_ENABLE_PIN, Z_ENABLE_ON)
//#define disable_z() { WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }
//#endif
//#else
//#define enable_z() ;
//#define disable_z() ;
//#endif
#if defined(E0_ENABLE_PIN) && (E0_ENABLE_PIN > -1)
#define enable_e0() WRITE(E0_ENABLE_PIN, E_ENABLE_ON)
#define disable_e0() WRITE(E0_ENABLE_PIN,!E_ENABLE_ON)
@ -205,23 +190,6 @@ void manage_inactivity(bool ignore_stepper_queue=false);
#define disable_e0() /* nothing */
#endif
#if (EXTRUDERS > 1) && defined(E1_ENABLE_PIN) && (E1_ENABLE_PIN > -1)
#define enable_e1() WRITE(E1_ENABLE_PIN, E_ENABLE_ON)
#define disable_e1() WRITE(E1_ENABLE_PIN,!E_ENABLE_ON)
#else
#define enable_e1() /* nothing */
#define disable_e1() /* nothing */
#endif
#if (EXTRUDERS > 2) && defined(E2_ENABLE_PIN) && (E2_ENABLE_PIN > -1)
#define enable_e2() WRITE(E2_ENABLE_PIN, E_ENABLE_ON)
#define disable_e2() WRITE(E2_ENABLE_PIN,!E_ENABLE_ON)
#else
#define enable_e2() /* nothing */
#define disable_e2() /* nothing */
#endif
enum AxisEnum {X_AXIS=0, Y_AXIS=1, Z_AXIS=2, E_AXIS=3, X_HEAD=4, Y_HEAD=5};
#define X_AXIS_MASK 1
#define Y_AXIS_MASK 2
@ -235,7 +203,7 @@ void FlushSerialRequestResend();
void ClearToSend();
void update_currents();
void kill(const char *full_screen_message = NULL, unsigned char id = 0);
void kill(const char *full_screen_message = NULL);
void finishAndDisableSteppers();
void UnconditionalStop(); // Stop heaters, motion and clear current print status
@ -279,7 +247,7 @@ extern float destination[NUM_AXIS] ;
extern float min_pos[3];
extern float max_pos[3];
extern bool axis_known_position[3];
extern int fanSpeed;
extern uint8_t fanSpeed; //!< Print fan speed, ranges from 0 to 255
extern uint8_t newFanSpeed;
extern float default_retraction;
@ -288,6 +256,11 @@ void prepare_move(uint16_t start_segment_idx = 0);
void prepare_arc_move(bool isclockwise, uint16_t start_segment_idx = 0);
uint16_t restore_interrupted_gcode();
///@brief Helper function to reduce code size, cheaper to call function than to inline division
///@param feedrate_mm_min feedrate with unit mm per minute
///@returns feedrate with unit mm per second
float __attribute__((noinline)) get_feedrate_mm_s(const float feedrate_mm_min);
#ifdef TMC2130
void homeaxis(uint8_t axis, uint8_t cnt = 1, uint8_t* pstep = 0);
#else
@ -300,19 +273,20 @@ extern float retract_length_swap;
extern float retract_recover_length_swap;
#endif
extern uint8_t host_keepalive_interval;
extern unsigned long starttime;
extern unsigned long stoptime;
extern uint32_t starttime; // milliseconds
extern uint32_t pause_time; // milliseconds
extern uint32_t start_pause_print; // milliseconds
extern ShortTimer usb_timer;
extern bool processing_tcode;
extern bool homing_flag;
extern bool loading_flag;
extern unsigned long total_filament_used;
void save_statistics(unsigned long _total_filament_used, unsigned long _total_print_time);
extern uint8_t heating_status_counter;
extern uint32_t total_filament_used; // mm/100 or 10um
/// @brief Save print statistics to EEPROM
/// @param _total_filament_used has unit mm/100 or 10um
/// @param _total_print_time has unit minutes, for example 123 minutes
void save_statistics(uint32_t _total_filament_used, uint32_t _total_print_time);
extern bool fan_state[2];
extern int fan_edge_counter[2];
extern int fan_speed[2];
@ -320,11 +294,6 @@ extern int fan_speed[2];
// We may even remove the references to it wherever possible in the future
#define active_extruder 0
//Long pause
extern unsigned long pause_time;
extern unsigned long start_pause_print;
extern unsigned long t_fan_rising_edge;
extern bool mesh_bed_leveling_flag;
// save/restore printing
@ -336,7 +305,7 @@ extern uint8_t saved_printing_type;
extern float saved_extruder_temperature; //!< Active extruder temperature
extern float saved_bed_temperature; //!< Bed temperature
extern int saved_fan_speed; //!< Print fan speed
extern uint8_t saved_fan_speed; //!< Print fan speed, ranges from 0 to 255
//estimated time to end of the print
extern uint8_t print_percent_done_normal;
@ -348,14 +317,15 @@ extern uint16_t print_time_to_change_silent;
#define PRINT_TIME_REMAINING_INIT 0xffff
extern uint16_t mcode_in_progress;
extern uint16_t gcode_in_progress;
extern LongTimer safetyTimer;
#define PRINT_PERCENT_DONE_INIT 0xff
extern bool printer_active();
// Returns true if there is a print running. It does not matter if
// the print is paused, that still counts as a "running" print.
bool printJobOngoing();
bool printer_active();
//! Beware - mcode_in_progress is set as soon as the command gets really processed,
//! which is not the same as posting the M600 command into the command queue
@ -366,6 +336,15 @@ extern bool printer_active();
//! I'd normally change this macro, but who knows what would happen in the MMU :)
bool check_fsensor();
//! Condition where Babystepping is allowed:
//! 1) Z-axis position is less than 2.0mm (only allowed during the first couple of layers)
//! 2) Not allowed during Homing (printer busy)
//! 3) Not allowed during Mesh Bed Leveling (printer busy)
//! 4) Allowed if:
//! - First Layer Calibration is running
//! - OR there are queued blocks, printJob is running and it's not paused, and Z-axis position is less than 2.0mm (only allowed during the first couple of layers)
bool babystep_allowed();
extern void calculate_extruder_multipliers();
// Similar to the default Arduino delay function,
@ -407,7 +386,6 @@ void setup_fan_interrupt();
extern bool recover_machine_state_after_power_panic();
extern void restore_print_from_eeprom(bool mbl_was_active);
extern void position_menu();
extern void print_world_coordinates();
extern void print_physical_coordinates();

File diff suppressed because it is too large Load Diff

View File

@ -92,7 +92,7 @@ static void prusa_stat_printinfo() {
SERIAL_ECHO(card.longFilename[0] ? card.longFilename : card.filename);
SERIAL_ECHOPGM("][TIM:");
if (starttime != 0) {
SERIAL_ECHO(_millis() / 1000 - starttime / 1000);
SERIAL_ECHO((_millis() - starttime) / 1000);
}
else {
SERIAL_ECHO(0);

View File

@ -7,7 +7,6 @@
#include "stepper.h"
#include "ultralcd.h"
#include <avr/pgmspace.h>
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
@ -29,11 +28,7 @@ struct SChooseFromMenu {
};
SChooseFromMenu TCodeChooseFromMenu() {
if (MMU2::mmu2.Enabled()) {
return SChooseFromMenu( choose_menu_P(_T(MSG_SELECT_FILAMENT), _T(MSG_FILAMENT)), true );
} else {
return SChooseFromMenu( choose_menu_P(_T(MSG_SELECT_EXTRUDER), _T(MSG_EXTRUDER)), false );
}
return SChooseFromMenu( choose_menu_P(_T(MSG_SELECT_FILAMENT), _T(MSG_FILAMENT)), MMU2::mmu2.Enabled() );
}
void TCodes(char *const strchr_pointer, uint8_t codeValue) {
@ -48,7 +43,7 @@ void TCodes(char *const strchr_pointer, uint8_t codeValue) {
} else if (strchr_pointer[index] == 'x'){
// load to extruder gears; if mmu is not present do nothing
if (MMU2::mmu2.Enabled()) {
MMU2::mmu2.tool_change(strchr_pointer[index], choose_menu_P(_T(MSG_SELECT_EXTRUDER), _T(MSG_EXTRUDER)));
MMU2::mmu2.tool_change(strchr_pointer[index], choose_menu_P(_T(MSG_SELECT_FILAMENT), _T(MSG_FILAMENT)));
}
} else if (strchr_pointer[index] == 'c'){
// load from extruder gears to nozzle (nozzle should be preheated)
@ -84,8 +79,8 @@ void TCodes(char *const strchr_pointer, uint8_t codeValue) {
}
}
} else {
SERIAL_ECHO_START;
if (selectedSlot.slot >= EXTRUDERS) {
SERIAL_ECHO_START;
SERIAL_ECHO('T');
SERIAL_ECHOLN(selectedSlot.slot + '0');
SERIAL_ECHOLNRPGM(_n("Invalid extruder")); ////MSG_INVALID_EXTRUDER
@ -96,9 +91,7 @@ void TCodes(char *const strchr_pointer, uint8_t codeValue) {
// feedrate = next_feedrate;
// }
// }
SERIAL_ECHO_START;
SERIAL_ECHORPGM(_n("Active Extruder: ")); ////MSG_ACTIVE_EXTRUDER
SERIAL_ECHOLN(active_extruder + '0'); // this is not changed in our FW at all, can be optimized away
SERIAL_ECHORPGM(_n("Active Extruder: 0")); ////MSG_ACTIVE_EXTRUDER
}
}
}

View File

@ -14,8 +14,8 @@
#define BL_FLASH_DELAY_MS 25
bool backlightSupport = 0; //only if it's true will any of the settings be visible to the user
int16_t backlightLevel_HIGH = 0;
int16_t backlightLevel_LOW = 0;
uint8_t backlightLevel_HIGH = 0;
uint8_t backlightLevel_LOW = 0;
uint8_t backlightMode = BACKLIGHT_MODE_BRIGHT;
int16_t backlightTimer_period = 10;
LongTimer backlightTimer;
@ -62,8 +62,8 @@ void backlight_wake(const uint8_t flashNo)
void backlight_save() //saves all backlight data to eeprom.
{
eeprom_update_byte((uint8_t *)EEPROM_BACKLIGHT_LEVEL_HIGH, (uint8_t)backlightLevel_HIGH);
eeprom_update_byte((uint8_t *)EEPROM_BACKLIGHT_LEVEL_LOW, (uint8_t)backlightLevel_LOW);
eeprom_update_byte((uint8_t *)EEPROM_BACKLIGHT_LEVEL_HIGH, backlightLevel_HIGH);
eeprom_update_byte((uint8_t *)EEPROM_BACKLIGHT_LEVEL_LOW, backlightLevel_LOW);
eeprom_update_byte((uint8_t *)EEPROM_BACKLIGHT_MODE, backlightMode);
eeprom_update_word((uint16_t *)EEPROM_BACKLIGHT_TIMEOUT, backlightTimer_period);
}

View File

@ -13,8 +13,8 @@ enum Backlight_Mode
BACKLIGHT_MODE_AUTO = 2,
};
extern int16_t backlightLevel_HIGH;
extern int16_t backlightLevel_LOW;
extern uint8_t backlightLevel_HIGH;
extern uint8_t backlightLevel_LOW;
extern uint8_t backlightMode;
extern bool backlightSupport;
extern int16_t backlightTimer_period;

View File

@ -402,7 +402,7 @@ void CardReader::openFileReadFilteredGcode(const char* name, bool replace_curren
// SERIAL_ERROR_START;
// SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:");
// SERIAL_ERRORLN(SD_PROCEDURE_DEPTH);
kill(ofKill, 1);
kill(ofKill);
return;
}
@ -469,7 +469,7 @@ void CardReader::openFileWrite(const char* name)
// SERIAL_ERROR_START;
// SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:");
// SERIAL_ERRORLN(SD_PROCEDURE_DEPTH);
kill(ofKill, 1);
kill(ofKill);
return;
}
@ -649,12 +649,10 @@ void CardReader::checkautostart(bool force)
if(p.name[9]!='~') //skip safety copies
if(strncmp((char*)p.name,autoname,5)==0)
{
char cmd[30];
// M23: Select SD file
sprintf_P(cmd, PSTR("M23 %s"), autoname);
enquecommand(cmd);
enquecommandf_P(MSG_M23, autoname);
// M24: Start/resume SD print
enquecommand_P(PSTR("M24"));
enquecommand_P(MSG_M24);
found=true;
}
}

View File

@ -1,8 +1,10 @@
#include <stdarg.h>
#include <util/atomic.h>
#include "cmdqueue.h"
#include "cardreader.h"
#include "ultralcd.h"
#include "Prusa_farm.h"
#include "meatpack.h"
// Reserve BUFSIZE lines of length MAX_CMD_SIZE plus CMDBUFFER_RESERVE_FRONT.
char cmdbuffer[BUFSIZE * (MAX_CMD_SIZE + 1) + CMDBUFFER_RESERVE_FRONT];
@ -251,6 +253,19 @@ void cmdqueue_dump_to_serial()
static const char bufferFull[] PROGMEM = "\" failed: Buffer full!";
static const char enqueingFront[] PROGMEM = "Enqueing to the front: \"";
void enquecommandf_P(const char *fmt, ...)
{
// MAX_CMD_SIZE is 96, but for formatting
// string we usually don't need more than 30 bytes
char cmd_buffer[30];
va_list ap;
va_start(ap, fmt);
vsnprintf_P(cmd_buffer, sizeof(cmd_buffer), fmt, ap);
va_end(ap);
enquecommand(cmd_buffer, false);
}
//adds an command to the main command buffer
//thats really done in a non-safe way.
//needs overworking someday
@ -351,7 +366,20 @@ void get_command()
// start of serial line processing loop
while (((MYSERIAL.available() > 0 && !saved_printing) || (MYSERIAL.available() > 0 && isPrintPaused)) && !cmdqueue_serial_disabled) { //is print is saved (crash detection or filament detection), dont process data from serial line
#ifdef ENABLE_MEATPACK
// MeatPack Changes
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const int rec = MYSERIAL.read();
if (rec < 0) continue;
mp_handle_rx_char((uint8_t)rec);
char c_res[2] = {0, 0};
const uint8_t char_count = mp_get_result_char(c_res);
// Note -- Paired bracket in preproc switch below
for (uint8_t i = 0; i < char_count; ++i) { char serial_char = c_res[i];
#else
char serial_char = MYSERIAL.read();
#endif
serialTimeoutTimer.start();
@ -441,7 +469,7 @@ void get_command()
// Handle KILL early, even when Stopped
if(strcmp_P(cmd_start, PSTR("M112")) == 0)
kill(MSG_M112_KILL, 2);
kill(MSG_M112_KILL);
// Bypass Stopped for some commands
bool allow_when_stopped = false;
@ -512,6 +540,9 @@ void get_command()
if(serial_char == ';') comment_mode = true;
if(!comment_mode) cmdbuffer[bufindw+CMDHDRSIZE+serial_count++] = serial_char;
}
#ifdef ENABLE_MEATPACK
}
#endif
} // end of serial line processing loop
if (serial_count > 0 && serialTimeoutTimer.expired(farm_mode ? 800 : 2000)) {
@ -624,13 +655,12 @@ void get_command()
card.closefile();
SERIAL_PROTOCOLLNRPGM(_n("Done printing file"));////MSG_FILE_PRINTED
stoptime=_millis();
char time[30];
unsigned long t=(stoptime-starttime-pause_time)/1000;
uint32_t t = (_millis() - starttime - pause_time) / 60000;
pause_time = 0;
int hours, minutes;
minutes=(t/60)%60;
hours=t/60/60;
minutes = t % 60;
hours = t / 60;
save_statistics(total_filament_used, t);
sprintf_P(time, PSTR("%i hours %i minutes"),hours, minutes);
SERIAL_ECHO_START;

View File

@ -61,16 +61,29 @@ extern void cmdqueue_dump_to_serial_single_line(int nr, const char *p);
extern void cmdqueue_dump_to_serial();
#endif /* CMDBUFFER_DEBUG */
extern bool cmd_buffer_empty();
/// @brief Variant of enquecommand which accepts a format string
/// @param fmt a format string residing in PROGMEM
void enquecommandf_P(const char *fmt, ...);
extern void enquecommand(const char *cmd, bool from_progmem = false);
extern void enquecommand_front(const char *cmd, bool from_progmem = false);
extern void repeatcommand_front();
extern void get_command();
extern uint16_t cmdqueue_calc_sd_length();
#if defined(__cplusplus)
extern "C" {
#endif
extern double strtod_noE(const char* nptr, char** endptr);
#if defined(__cplusplus)
}
#endif
// Return True if a character was found
static inline bool code_seen(char code) { return (strchr_pointer = strchr(CMDBUFFER_CURRENT_STRING, code)) != NULL; }
static inline bool code_seen_P(const char *code_PROGMEM) { return (strchr_pointer = strstr_P(CMDBUFFER_CURRENT_STRING, code_PROGMEM)) != NULL; }
static inline float code_value() { return strtod(strchr_pointer+1, NULL);}
static inline float code_value() { return strtod_noE(strchr_pointer+1, NULL);}
static inline long code_value_long() { return strtol(strchr_pointer+1, NULL, 10); }
static inline int16_t code_value_short() { return int16_t(strtol(strchr_pointer+1, NULL, 10)); };
static inline uint8_t code_value_uint8() { return uint8_t(strtol(strchr_pointer+1, NULL, 10)); };

View File

@ -5,21 +5,17 @@
#include "Configuration_var.h"
#include "pins.h"
#if (defined(VOLT_IR_PIN) && defined(IR_SENSOR))
// TODO: IR_SENSOR_ANALOG currently disabled as being incompatible with the new thermal regulation
// # define IR_SENSOR_ANALOG
#endif
//ADC configuration
#ifndef IR_SENSOR_ANALOG
#define ADC_CHAN_MSK 0b0000001001011111 //used AD channels bit mask (0,1,2,3,4,6,9)
#define ADC_DIDR_MSK 0b0000001001011111 //AD channels DIDR mask (1 ~ disabled digital input)
#define ADC_CHAN_CNT 7 //number of used channels)
#else //!IR_SENSOR_ANALOG
#if defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_IR_ANALOG)
#define ADC_CHAN_MSK 0b0000001101011111 //used AD channels bit mask (0,1,2,3,4,6,8,9)
#define ADC_DIDR_MSK 0b0000001001011111 //AD channels DIDR mask (1 ~ disabled digital input)
#define ADC_CHAN_CNT 8 //number of used channels)
#endif //!IR_SENSOR_ANALOG
#else
#define ADC_CHAN_MSK 0b0000001001011111 //used AD channels bit mask (0,1,2,3,4,6,9)
#define ADC_DIDR_MSK 0b0000001001011111 //AD channels DIDR mask (1 ~ disabled digital input)
#define ADC_CHAN_CNT 7 //number of used channels)
#endif
#define ADC_OVRSAMPL 16 //oversampling multiplier
#define ADC_CALLBACK adc_callback //callback function ()

View File

@ -97,8 +97,8 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
| ^ | ^ | ^ | fah 250 | ^ | needs XYZ calibration | ^ | ^
| ^ | ^ | ^ | 00h 0 | ^ | Unknown (legacy) | ^ | ^
| 0x0FF5 4085 | uint16 | EEPROM_BABYSTEP_Z0 | ??? | ff ffh 65535 | Babystep for Z ??? | ??? | D3 Ax0ff5 C2
| 0x0FF1 4081 | unint32 | EEPROM_FILAMENTUSED | ??? | 00 00 00 00h 0 __S/P__| Filament used in meters | ??? | D3 Ax0ff1 C4
| 0x0FED 4077 | unint32 | EEPROM_TOTALTIME | ??? | 00 00 00 00h 0 __S/P__| Total print time | ??? | D3 Ax0fed C4
| 0x0FF1 4081 | uint32 | EEPROM_FILAMENTUSED | ??? | 00 00 00 00h 0 __S/P__| Filament used in meters | ??? | D3 Ax0ff1 C4
| 0x0FED 4077 | uint32 | EEPROM_TOTALTIME | ??? | 00 00 00 00h 0 __S/P__| Total print time in minutes | ??? | D3 Ax0fed C4
| 0x0FE5 4069 | float | EEPROM_BED_CALIBRATION_CENTER | ??? | ff ff ff ffh | ??? | ??? | D3 Ax0fe5 C8
| 0x0FDD 4061 | float | EEPROM_BED_CALIBRATION_VEC_X | ??? | ff ff ff ffh | ??? | ??? | D3 Ax0fdd C8
| 0x0FD5 4053 | float | EEPROM_BED_CALIBRATION_VEC_Y | ??? | ff ff ff ffh | ??? | ??? | D3 Ax0fd5 C8
@ -357,10 +357,13 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
| ^ | ^ | ^ | 20h 32 | ^ | Free bit | ^ | ^
| ^ | ^ | ^ | 40h 64 | ^ | Free bit | ^ | ^
| ^ | ^ | ^ | 80h 128 | ^ | Unknown | ^ | ^
| 0x0CA5 3237 | float | EEPROM_TEMP_MODEL_U | ??? | ff ff ff ffh | Temp model linear temperature coefficient (W/K/W) | Temp model | D3 Ax0ca5 C4
| 0x0CA1 3233 | float | EEPROM_TEMP_MODEL_V | ??? | ff ff ff ffh | Temp model linear temperature intercept (W/W) | Temp model | D3 Ax0ca1 C4
| 0x0C9D 3229 | float | EEPROM_TEMP_MODEL_D | ??? | ff ff ff ffh | Temp model sim. 1st order IIR filter factor | Temp model | D3 Ax0c9d C4
| 0x0C99 3225 | uint16 | EEPROM_TEMP_MODEL_L | 0-2160 | ff ffh | Temp model sim. response lag (ms) | Temp model | D3 Ax0c99 C2
| 0x0CA2 3234 | float | EEPROM_TEMP_MODEL_U | ??? | ff ff ff ffh | Temp model linear temperature coefficient (W/K/W) | Temp model | D3 Ax0ca2 C4
| 0x0C9E 3230 | float | EEPROM_TEMP_MODEL_V | ??? | ff ff ff ffh | Temp model linear temperature intercept (W/W) | Temp model | D3 Ax0c9e C4
| 0x0C9A 3226 | float | EEPROM_TEMP_MODEL_D | ??? | ff ff ff ffh | Temp model sim. 1st order IIR filter factor | Temp model | D3 Ax0c9a C4
| 0x0C98 3224 | uint16 | EEPROM_TEMP_MODEL_L | 0-2160 | ff ffh | Temp model sim. response lag (ms) | Temp model | D3 Ax0c98 C2
| 0x0C97 3223 | uint8 | EEPROM_TEMP_MODEL_VER | 0-255 | ffh | Temp model Version | Temp model | D3 Ax0c97 C1
| 0x0C95 3221 | PGM_P | EEPROM_KILL_MESSAGE | 0-65535 | ff ffh | Kill message PGM pointer | kill() | D3 Ax0c95 C2
| 0x0C94 3220 | uint8 | EEPROM_KILL_PENDING_FLAG | 42h, ffh | ffh | Kill pending flag (0x42 magic value) | kill() | D3 Ax0c94 C1
|Address begin|Bit/Type | Name | Valid values | Default/FactoryReset | Description |Gcode/Function| Debug code
| :--: | :--: | :--: | :--: | :--: | :--: | :--: | :--:
@ -596,8 +599,11 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE);
#define EEPROM_TEMP_MODEL_L (EEPROM_TEMP_MODEL_D-2) //uint16_t
#define EEPROM_TEMP_MODEL_VER (EEPROM_TEMP_MODEL_L-1) //uint8_t
#define EEPROM_KILL_MESSAGE (EEPROM_TEMP_MODEL_VER-2) //PGM_P
#define EEPROM_KILL_PENDING_FLAG (EEPROM_KILL_MESSAGE-1) //uint8
//This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items.
#define EEPROM_LAST_ITEM EEPROM_TEMP_MODEL_VER
#define EEPROM_LAST_ITEM EEPROM_KILL_PENDING_FLAG
// !!!!!
// !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!!
// !!!!!

View File

@ -1,6 +1,5 @@
// fan control and check
#include "fancheck.h"
#include "cardreader.h"
#include "ultralcd.h"
#include "sound.h"
#include "messages.h"
@ -85,7 +84,7 @@ void fanSpeedError(unsigned char _fan) {
if (fan_check_error == EFCE_REPORTED) return;
fan_check_error = EFCE_REPORTED;
if (IS_SD_PRINTING || usb_timer.running()) {
if (printJobOngoing()) {
// A print is ongoing, pause the print normally
if(!isPrintPaused) {
if (usb_timer.running())
@ -221,6 +220,7 @@ void checkExtruderAutoFans()
#if (defined(FANCHECK) && defined(TACH_0) && (TACH_0 > -1))
void readFanTach() {
static bool fan_state[2];
#ifdef FAN_SOFT_PWM
if (READ(TACH_0) != fan_state[0]) {
if(fan_measuring) fan_edge_counter[0] ++;

View File

@ -33,36 +33,45 @@ static constexpr float spacing(float layer_height, float extrusion_width, float
return extrusion_width - layer_height * (overlap_factor - M_PI/4);
}
// Common code extracted into one function to reduce code size
static void lay1cal_common_enqueue_loop(const char * const * cmd_sequence, const uint8_t steps) {
for (uint8_t i = 0; i < steps; ++i)
{
enquecommand_P(static_cast<char*>(pgm_read_ptr(cmd_sequence + i)));
}
}
static const char extrude_fmt[] PROGMEM = "G1 X%d Y%d E%-.5f";
static const char zero_extrusion[] PROGMEM = "G92 E0";
//! @brief Wait for preheat
void lay1cal_wait_preheat()
{
const char * const preheat_cmd[] =
static const char preheat_cmd_2[] PROGMEM = "M190";
static const char preheat_cmd_3[] PROGMEM = "M109";
static const char preheat_cmd_4[] PROGMEM = "G28";
static const char * const preheat_cmd[] PROGMEM =
{
PSTR("M107"),
PSTR("M190"),
PSTR("M109"),
PSTR("G28"),
MSG_M107,
preheat_cmd_2,
preheat_cmd_3,
preheat_cmd_4,
zero_extrusion
};
for (uint8_t i = 0; i < (sizeof(preheat_cmd)/sizeof(preheat_cmd[0])); ++i)
{
enquecommand_P(preheat_cmd[i]);
}
lay1cal_common_enqueue_loop(preheat_cmd, sizeof(preheat_cmd)/sizeof(preheat_cmd[0]));
}
//! @brief Load filament
//! @param cmd_buffer character buffer needed to format gcodes
//! @param filament filament to use (applies for MMU only)
//! @returns true if extra purge distance is needed in case of MMU prints (after a toolchange), otherwise false
bool lay1cal_load_filament(char *cmd_buffer, uint8_t filament)
bool lay1cal_load_filament(uint8_t filament)
{
if (MMU2::mmu2.Enabled())
{
enquecommand_P(PSTR("M83"));
enquecommand_P(MSG_M83);
enquecommand_P(PSTR("G1 Y-3 F1000"));
enquecommand_P(PSTR("G1 Z0.4 F1000"));
@ -72,16 +81,10 @@ bool lay1cal_load_filament(char *cmd_buffer, uint8_t filament)
return false;
} else if( currentTool != (uint8_t)MMU2::FILAMENT_UNKNOWN){
// some other slot is loaded, perform an unload first
enquecommand_P(PSTR("M702"));
enquecommand_P(MSG_M702);
}
// perform a toolchange
// sprintf_P(cmd_buffer, PSTR("T%d"), filament);
// rewriting the trivial T<filament> g-code command saves 30B:
cmd_buffer[0] = 'T';
cmd_buffer[1] = filament + '0';
cmd_buffer[2] = 0;
enquecommand(cmd_buffer);
enquecommandf_P(PSTR("T%d"), filament);
return true;
}
return false;
@ -128,21 +131,16 @@ void lay1cal_intro_line(bool extraPurgeNeeded, float layer_height, float extrusi
}
else
{
char cmd_buffer[30];
static const char fmt1[] PROGMEM = "G1 X%d E%-.3f F1000";
sprintf_P(cmd_buffer, fmt1, 60, count_e(layer_height, extrusion_width * 4.f, 60));
enquecommand(cmd_buffer);
sprintf_P(cmd_buffer, fmt1, 100, count_e(layer_height, extrusion_width * 8.f, 40));
enquecommand(cmd_buffer);
enquecommandf_P(fmt1, 60, count_e(layer_height, extrusion_width * 4.f, 60));
enquecommandf_P(fmt1, 100, count_e(layer_height, extrusion_width * 8.f, 40));
}
}
//! @brief Setup for printing meander
void lay1cal_before_meander()
{
static const char cmd_pre_meander_1[] PROGMEM = "G21"; //set units to millimeters TODO unsupported command
static const char cmd_pre_meander_2[] PROGMEM = "G90"; //use absolute coordinates
static const char cmd_pre_meander_3[] PROGMEM = "M83"; //use relative distances for extrusion TODO: duplicate
static const char cmd_pre_meander_4[] PROGMEM = "G1 E-1.5 F2100";
static const char cmd_pre_meander_5[] PROGMEM = "G1 Z5 F7200";
static const char cmd_pre_meander_6[] PROGMEM = "M204 S1000"; //set acceleration
@ -151,49 +149,37 @@ void lay1cal_before_meander()
static const char * const cmd_pre_meander[] PROGMEM =
{
zero_extrusion,
cmd_pre_meander_1,
cmd_pre_meander_2,
cmd_pre_meander_3,
MSG_M83, // use relative distances for extrusion
cmd_pre_meander_4,
cmd_pre_meander_5,
cmd_pre_meander_6,
cmd_pre_meander_7,
};
for (uint8_t i = 0; i < (sizeof(cmd_pre_meander)/sizeof(cmd_pre_meander[0])); ++i)
{
enquecommand_P(static_cast<char*>(pgm_read_ptr(&cmd_pre_meander[i])));
}
lay1cal_common_enqueue_loop(cmd_pre_meander, (sizeof(cmd_pre_meander)/sizeof(cmd_pre_meander[0])));
}
//! @brief Print meander start
void lay1cal_meander_start(float layer_height, float extrusion_width)
{
char cmd_buffer[30];
enquecommand_P(PSTR("G1 X50 Y155"));
static const char fmt1[] PROGMEM = "G1 Z%-.3f F7200";
sprintf_P(cmd_buffer, fmt1, layer_height);
enquecommand(cmd_buffer);
enquecommandf_P(fmt1, layer_height);
enquecommand_P(PSTR("G1 F1080"));
sprintf_P(cmd_buffer, extrude_fmt, 75, 155, count_e(layer_height, extrusion_width * 4.f, 25));
enquecommand(cmd_buffer);
sprintf_P(cmd_buffer, extrude_fmt, 100, 155, count_e(layer_height, extrusion_width * 2.f, 25));
enquecommand(cmd_buffer);
sprintf_P(cmd_buffer, extrude_fmt, 200, 155, count_e(layer_height, extrusion_width, 100));
enquecommand(cmd_buffer);
sprintf_P(cmd_buffer, extrude_fmt, 200, 135, count_e(layer_height, extrusion_width, 20));
enquecommand(cmd_buffer);
enquecommandf_P(extrude_fmt, 75, 155, count_e(layer_height, extrusion_width * 4.f, 25));
enquecommandf_P(extrude_fmt, 100, 155, count_e(layer_height, extrusion_width * 2.f, 25));
enquecommandf_P(extrude_fmt, 200, 155, count_e(layer_height, extrusion_width, 100));
enquecommandf_P(extrude_fmt, 200, 135, count_e(layer_height, extrusion_width, 20));
}
//! @brief Print meander
//! @param cmd_buffer character buffer needed to format gcodes
void lay1cal_meander(float layer_height, float extrusion_width)
{
char cmd_buffer[30];
const float short_length = 20;
float long_length = 150;
const float long_extrusion = count_e(layer_height, extrusion_width, long_length);
@ -203,13 +189,11 @@ void lay1cal_meander(float layer_height, float extrusion_width)
uint8_t x_pos = 50;
for(uint8_t i = 0; i <= 4; ++i)
{
sprintf_P(cmd_buffer, extrude_fmt, x_pos, y_pos, long_extrusion);
enquecommand(cmd_buffer);
enquecommandf_P(extrude_fmt, x_pos, y_pos, long_extrusion);
y_pos -= short_length;
sprintf_P(cmd_buffer, extrude_fmt, x_pos, y_pos, short_extrusion);
enquecommand(cmd_buffer);
enquecommandf_P(extrude_fmt, x_pos, y_pos, short_extrusion);
x_pos += long_length;
@ -226,7 +210,6 @@ void lay1cal_meander(float layer_height, float extrusion_width)
//! @param i iteration
void lay1cal_square(uint8_t step, float layer_height, float extrusion_width)
{
char cmd_buffer[30];
const float long_length = 20;
const float short_length = spacing(layer_height, extrusion_width);
const float long_extrusion = count_e(layer_height, extrusion_width, long_length);
@ -235,31 +218,24 @@ void lay1cal_square(uint8_t step, float layer_height, float extrusion_width)
for (uint8_t i = step; i < step+4; ++i)
{
sprintf_P(cmd_buffer, fmt1, 70, (35 - i*short_length * 2), long_extrusion);
enquecommand(cmd_buffer);
sprintf_P(cmd_buffer, fmt1, 70, (35 - (2 * i + 1)*short_length), short_extrusion);
enquecommand(cmd_buffer);
sprintf_P(cmd_buffer, fmt1, 50, (35 - (2 * i + 1)*short_length), long_extrusion);
enquecommand(cmd_buffer);
sprintf_P(cmd_buffer, fmt1, 50, (35 - (i + 1)*short_length * 2), short_extrusion);
enquecommand(cmd_buffer);
enquecommandf_P(fmt1, 70, (35 - i*short_length * 2), long_extrusion);
enquecommandf_P(fmt1, 70, (35 - (2 * i + 1)*short_length), short_extrusion);
enquecommandf_P(fmt1, 50, (35 - (2 * i + 1)*short_length), long_extrusion);
enquecommandf_P(fmt1, 50, (35 - (i + 1)*short_length * 2), short_extrusion);
}
}
void lay1cal_finish(bool mmu_enabled)
{
static const char cmd_cal_finish_0[] PROGMEM = "M107"; //turn off printer fan
static const char cmd_cal_finish_1[] PROGMEM = "G1 E-0.075 F2100"; //retract
static const char cmd_cal_finish_2[] PROGMEM = "M104 S0"; // turn off temperature
static const char cmd_cal_finish_3[] PROGMEM = "M140 S0"; // turn off heatbed
static const char cmd_cal_finish_4[] PROGMEM = "G1 Z10 F1300"; //lift Z
static const char cmd_cal_finish_5[] PROGMEM = "G1 X10 Y180 F4000"; //Go to parking position
static const char cmd_cal_finish_6[] PROGMEM = "M702"; //unload from nozzle
static const char cmd_cal_finish_7[] PROGMEM = "M84";// disable motors
static const char * const cmd_cal_finish[] PROGMEM =
{
cmd_cal_finish_0,
MSG_M107, // turn off printer fan
cmd_cal_finish_1,
cmd_cal_finish_2,
cmd_cal_finish_3,
@ -267,11 +243,8 @@ void lay1cal_finish(bool mmu_enabled)
cmd_cal_finish_5
};
for (uint8_t i = 0; i < (sizeof(cmd_cal_finish)/sizeof(cmd_cal_finish[0])); ++i)
{
enquecommand_P(static_cast<char*>(pgm_read_ptr(&cmd_cal_finish[i])));
}
lay1cal_common_enqueue_loop(cmd_cal_finish, (sizeof(cmd_cal_finish)/sizeof(cmd_cal_finish[0])));
if (mmu_enabled) enquecommand_P(cmd_cal_finish_6); //unload from nozzle
enquecommand_P(cmd_cal_finish_7);// disable motors
if (mmu_enabled) enquecommand_P(MSG_M702); //unload from nozzle
enquecommand_P(MSG_M84);// disable motors
}

View File

@ -7,7 +7,7 @@
#include <stdint.h>
void lay1cal_wait_preheat();
[[nodiscard]] bool lay1cal_load_filament(char *cmd_buffer, uint8_t filament);
[[nodiscard]] bool lay1cal_load_filament(uint8_t filament);
void lay1cal_intro_line(bool skipExtraPurge, float layer_height, float extrusion_width);
void lay1cal_before_meander();
void lay1cal_meander_start(float layer_height, float extrusion_width);

View File

@ -4,16 +4,15 @@
#include <stdio.h>
#include <stdarg.h>
#include <avr/pgmspace.h>
#include <util/atomic.h>
#include <util/delay.h>
#include "Timer.h"
#include "Configuration.h"
#include "pins.h"
#include <binary.h>
#include <Arduino.h>
#include "Marlin.h"
#include "fastio.h"
//-//
#include "sound.h"
#include "backlight.h"
@ -632,12 +631,10 @@ void lcd_printNumber(unsigned long n, uint8_t base)
}
uint8_t lcd_draw_update = 2;
int32_t lcd_encoder = 0;
uint8_t lcd_encoder_bits = 0;
int8_t lcd_encoder_diff = 0;
int16_t lcd_encoder = 0;
static int8_t lcd_encoder_diff = 0;
uint8_t lcd_buttons = 0;
uint8_t lcd_button_pressed = 0;
uint8_t lcd_click_trigger = 0;
uint8_t lcd_update_enabled = 1;
static bool lcd_backlight_wake_trigger; // Flag set by interrupt when the knob is pressed or rotated
@ -673,38 +670,47 @@ uint8_t lcd_clicked(void)
return clicked;
}
void lcd_beeper_quick_feedback(void)
{
//-//
Sound_MakeSound(e_SOUND_TYPE_ButtonEcho);
/*
for(int8_t i = 0; i < 10; i++)
{
Sound_MakeCustom(100,0,false);
_delay_us(100);
}
*/
void lcd_beeper_quick_feedback(void) {
Sound_MakeSound(e_SOUND_TYPE_ButtonEcho);
}
void lcd_quick_feedback(void)
{
lcd_draw_update = 2;
lcd_button_pressed = false;
lcd_beeper_quick_feedback();
}
void lcd_knob_update() {
if (lcd_backlight_wake_trigger) {
lcd_backlight_wake_trigger = false;
backlight_wake();
bool did_rotate = false;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
if (abs(lcd_encoder_diff) >= ENCODER_PULSES_PER_STEP) {
lcd_encoder += lcd_encoder_diff / ENCODER_PULSES_PER_STEP;
lcd_encoder_diff %= ENCODER_PULSES_PER_STEP;
did_rotate = true;
}
else {
// Get lcd_encoder_diff in sync with the encoder hard steps.
// We assume that a click happens only when the knob is rotated into a stable position
lcd_encoder_diff = 0;
}
}
Sound_MakeSound(did_rotate ? e_SOUND_TYPE_EncoderMove : e_SOUND_TYPE_ButtonEcho);
if (lcd_draw_update == 0) {
// Update LCD rendering at minimum
lcd_draw_update = 1;
}
}
}
void lcd_update(uint8_t lcdDrawUpdateOverride)
{
if (lcd_draw_update < lcdDrawUpdateOverride)
lcd_draw_update = lcdDrawUpdateOverride;
if (lcd_backlight_wake_trigger) {
lcd_backlight_wake_trigger = false;
backlight_wake();
}
backlight_update();
if (!lcd_update_enabled) return;
if (lcd_lcdupdate_func)
@ -743,16 +749,12 @@ bool lcd_longpress_trigger = 0;
void lcd_buttons_update(void)
{
static uint8_t lcd_long_press_active = 0;
uint8_t newbutton = 0;
if (READ(BTN_EN1) == 0) newbutton |= EN_A;
if (READ(BTN_EN2) == 0) newbutton |= EN_B;
static uint8_t lcd_button_pressed = 0;
if (READ(BTN_ENC) == 0)
{ //button is pressed
if (!buttonBlanking.running() || buttonBlanking.expired(BUTTON_BLANKING_TIME)) {
if (buttonBlanking.expired_cont(BUTTON_BLANKING_TIME)) {
buttonBlanking.start();
safetyTimer.start();
lcd_backlight_wake_trigger = true; // flag event, knob pressed
if ((lcd_button_pressed == 0) && (lcd_long_press_active == 0))
{
longPressTimer.start();
@ -769,57 +771,39 @@ void lcd_buttons_update(void)
{ //button not pressed
if (lcd_button_pressed)
{ //button was released
buttonBlanking.start();
if (lcd_long_press_active == 0)
lcd_button_pressed = 0; // Reset to prevent double triggering
if (!lcd_long_press_active)
{ //button released before long press gets activated
newbutton |= EN_C;
lcd_click_trigger = 1; // This flag is reset when the event is consumed
}
//else if (menu_menu == lcd_move_z) lcd_quick_feedback();
//lcd_button_pressed is set back to false via lcd_quick_feedback function
lcd_backlight_wake_trigger = true; // flag event, knob pressed
lcd_long_press_active = 0;
}
lcd_long_press_active = 0;
}
lcd_buttons = newbutton;
//manage encoder rotation
uint8_t enc = 0;
if (lcd_buttons & EN_A) enc |= B01;
if (lcd_buttons & EN_B) enc |= B10;
if (enc != lcd_encoder_bits)
{
switch (enc)
{
case encrot0:
if (lcd_encoder_bits == encrot3)
lcd_encoder_diff++;
else if (lcd_encoder_bits == encrot1)
lcd_encoder_diff--;
break;
case encrot1:
if (lcd_encoder_bits == encrot0)
lcd_encoder_diff++;
else if (lcd_encoder_bits == encrot2)
lcd_encoder_diff--;
break;
case encrot2:
if (lcd_encoder_bits == encrot1)
lcd_encoder_diff++;
else if (lcd_encoder_bits == encrot3)
lcd_encoder_diff--;
break;
case encrot3:
if (lcd_encoder_bits == encrot2)
lcd_encoder_diff++;
else if (lcd_encoder_bits == encrot0)
lcd_encoder_diff--;
break;
}
//manage encoder rotation
static const int8_t encrot_table[] PROGMEM = {
0, -1, 1, 2,
1, 0, 2, -1,
-1, -2, 0, 1,
-2, 1, -1, 0,
};
if (abs(lcd_encoder_diff) >= ENCODER_PULSES_PER_STEP) {
lcd_backlight_wake_trigger = true; // flag event, knob rotated
}
}
lcd_encoder_bits = enc;
static uint8_t enc_bits_old = 0;
uint8_t enc_bits = 0;
if (!READ(BTN_EN1)) enc_bits |= _BV(0);
if (!READ(BTN_EN2)) enc_bits |= _BV(1);
if (enc_bits != enc_bits_old)
{
int8_t newDiff = pgm_read_byte(&encrot_table[(enc_bits_old << 2) | enc_bits]);
lcd_encoder_diff += newDiff;
if (abs(lcd_encoder_diff) >= ENCODER_PULSES_PER_STEP) {
lcd_backlight_wake_trigger = true; // flag event, knob rotated
}
enc_bits_old = enc_bits;
}
}
@ -827,114 +811,114 @@ void lcd_buttons_update(void)
// Custom character data
const uint8_t lcd_chardata_bedTemp[8] PROGMEM = {
B00000,
B11111,
B10101,
B10001,
B10101,
B11111,
B00000,
B00000}; //thanks Sonny Mounicou
0b00000,
0b11111,
0b10101,
0b10001,
0b10101,
0b11111,
0b00000,
0b00000}; //thanks Sonny Mounicou
const uint8_t lcd_chardata_degree[8] PROGMEM = {
B01100,
B10010,
B10010,
B01100,
B00000,
B00000,
B00000,
B00000};
0b01100,
0b10010,
0b10010,
0b01100,
0b00000,
0b00000,
0b00000,
0b00000};
const uint8_t lcd_chardata_thermometer[8] PROGMEM = {
B00100,
B01010,
B01010,
B01010,
B01010,
B10001,
B10001,
B01110};
0b00100,
0b01010,
0b01010,
0b01010,
0b01010,
0b10001,
0b10001,
0b01110};
const uint8_t lcd_chardata_uplevel[8] PROGMEM = {
B00100,
B01110,
B11111,
B00100,
B11100,
B00000,
B00000,
B00000}; //thanks joris
0b00100,
0b01110,
0b11111,
0b00100,
0b11100,
0b00000,
0b00000,
0b00000}; //thanks joris
const uint8_t lcd_chardata_refresh[8] PROGMEM = {
B00000,
B00110,
B11001,
B11000,
B00011,
B10011,
B01100,
B00000}; //thanks joris
0b00000,
0b00110,
0b11001,
0b11000,
0b00011,
0b10011,
0b01100,
0b00000}; //thanks joris
const uint8_t lcd_chardata_folder[8] PROGMEM = {
B00000,
B11100,
B11111,
B10001,
B10001,
B11111,
B00000,
B00000}; //thanks joris
0b00000,
0b11100,
0b11111,
0b10001,
0b10001,
0b11111,
0b00000,
0b00000}; //thanks joris
/*const uint8_t lcd_chardata_feedrate[8] PROGMEM = {
B11100,
B10000,
B11000,
B10111,
B00101,
B00110,
B00101,
B00000};*/ //thanks Sonny Mounicou
0b11100,
0b10000,
0b11000,
0b10111,
0b00101,
0b00110,
0b00101,
0b00000};*/ //thanks Sonny Mounicou
/*const uint8_t lcd_chardata_feedrate[8] PROGMEM = {
B11100,
B10100,
B11000,
B10100,
B00000,
B00111,
B00010,
B00010};*/
0b11100,
0b10100,
0b11000,
0b10100,
0b00000,
0b00111,
0b00010,
0b00010};*/
/*const uint8_t lcd_chardata_feedrate[8] PROGMEM = {
B01100,
B10011,
B00000,
B01100,
B10011,
B00000,
B01100,
B10011};*/
0b01100,
0b10011,
0b00000,
0b01100,
0b10011,
0b00000,
0b01100,
0b10011};*/
const uint8_t lcd_chardata_feedrate[8] PROGMEM = {
B00000,
B00100,
B10010,
B01001,
B10010,
B00100,
B00000,
B00000};
0b00000,
0b00100,
0b10010,
0b01001,
0b10010,
0b00100,
0b00000,
0b00000};
const uint8_t lcd_chardata_clock[8] PROGMEM = {
B00000,
B01110,
B10011,
B10101,
B10001,
B01110,
B00000,
B00000}; //thanks Sonny Mounicou
0b00000,
0b01110,
0b10011,
0b10101,
0b10001,
0b01110,
0b00000,
0b00000}; //thanks Sonny Mounicou
void lcd_set_custom_characters(void)
{
@ -949,23 +933,24 @@ void lcd_set_custom_characters(void)
}
const uint8_t lcd_chardata_arr2down[8] PROGMEM = {
B00000,
B00000,
B10001,
B01010,
B00100,
B10001,
B01010,
B00100};
0b00000,
0b00000,
0b10001,
0b01010,
0b00100,
0b10001,
0b01010,
0b00100};
const uint8_t lcd_chardata_confirm[8] PROGMEM = {
B00000,
B00001,
B00011,
B10110,
B11100,
B01000,
B00000};
0b00000,
0b00001,
0b00011,
0b10110,
0b11100,
0b01000,
0b00000,
0b00000};
void lcd_set_custom_characters_nextpage(void)
{

View File

@ -98,17 +98,9 @@ typedef void (*lcd_lcdupdate_func_t)(void);
//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)
extern uint8_t lcd_draw_update;
extern int32_t lcd_encoder;
extern int16_t lcd_encoder;
extern uint8_t lcd_encoder_bits;
// lcd_encoder_diff is updated from interrupt context and added to lcd_encoder every LCD update
extern int8_t lcd_encoder_diff;
//the last checked lcd_buttons in a bit array.
extern uint8_t lcd_buttons;
extern uint8_t lcd_button_pressed;
extern uint8_t lcd_click_trigger;
extern uint8_t lcd_update_enabled;
@ -130,6 +122,10 @@ extern void lcd_beeper_quick_feedback(void);
//Cause an LCD refresh, and give the user visual or audible feedback that something has happened
extern void lcd_quick_feedback(void);
/// @brief Check whether knob is rotated or clicked and update relevant
///variables. Flags are set by lcd_buttons_update in ISR context.
extern void lcd_knob_update();
extern void lcd_update(uint8_t lcdDrawUpdateOverride);
extern void lcd_update_enable(uint8_t enabled);
@ -159,20 +155,7 @@ private:
bool m_updateEnabled;
};
////////////////////////////////////
// Setup button and encode mappings for each panel (into 'lcd_buttons' variable
//
// This is just to map common functions (across different panels) onto the same
// macro name. The mapping is independent of whether the button is directly connected or
// via a shift/i2c register.
#define BLEN_B 1
#define BLEN_A 0
#define EN_B (1<<BLEN_B) // The two encoder pins are connected through BTN_EN1 and BTN_EN2
#define EN_A (1<<BLEN_A)
#define BLEN_C 2
#define EN_C (1<<BLEN_C)
//! @brief Was button clicked?
//!
@ -183,17 +166,9 @@ private:
//!
//! @retval 0 button was not clicked
//! @retval 1 button was clicked
#define LCD_CLICKED (lcd_buttons&EN_C)
////////////////////////
// Setup Rotary Encoder Bit Values (for two pin encoders to indicate movement)
// 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
#define encrot0 0
#define encrot1 2
#define encrot2 3
#define encrot3 1
#define LCD_CLICKED (lcd_click_trigger)
////////////////////////////////////
//Custom characters defined in the first 8 characters of the LCD
#define LCD_STR_BEDTEMP "\x00"
@ -215,8 +190,7 @@ extern void lcd_set_custom_characters_nextpage(void);
//! @brief Consume click and longpress event
inline void lcd_consume_click()
{
lcd_button_pressed = 0;
lcd_buttons &= 0xff^EN_C;
lcd_click_trigger = 0;
lcd_longpress_trigger = 0;
}

379
Firmware/meatpack.cpp Normal file
View File

@ -0,0 +1,379 @@
/*
* MeatPack G-Code Compression
*
* Algorithm & Implementation: Scott Mudge - mail@scottmudge.com
* Date: Dec. 2020
*/
#include "meatpack.h"
#ifdef ENABLE_MEATPACK
#include "language.h"
#include "Marlin.h"
//#define MP_DEBUG
// Utility definitions
#define MeatPack_CommandByte 0b11111111
#define MeatPack_NextPackedFirst 0b00000001
#define MeatPack_NextPackedSecond 0b00000010
#define MeatPack_SpaceCharIdx 11U
#define MeatPack_SpaceCharReplace 'E'
#define MeatPack_ProtocolVersion "PV01"
/*
Character Frequencies from ~30 MB of comment-stripped gcode:
'1' -> 4451136
'0' -> 4253577
' ' -> 3053297
'.' -> 3035310
'2' -> 1523296
'8' -> 1366812
'4' -> 1353273
'9' -> 1352147
'3' -> 1262929
'5' -> 1189871
'6' -> 1127900
'7' -> 1112908
'\n' -> 1087683
'G' -> 1075806
'X' -> 975742
'E' -> 965275
'Y' -> 965274
'F' -> 99416
'-' -> 90242
'Z' -> 34109
'M' -> 11879
'S' -> 9910
If spaces are omitted, we add 'E'
*/
// Note:
// I've tried both a switch/case method and a lookup table. The disassembly is exactly the same after compilation, byte-to-byte.
// Thus, performance is identical.
#define USE_LOOKUP_TABLE
// State variables
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
enum MeatPack_ConfigStateFlags {
MPConfig_None = 0,
MPConfig_Active = (1 << 0),
MPConfig_NoSpaces = (1 << 1)
};
uint8_t mp_config = MPConfig_None; // Configuration state
uint8_t mp_cmd_active = 0; // Is a command is pending
uint8_t mp_char_buf = 0; // Buffers a character if dealing with out-of-sequence pairs
uint8_t mp_cmd_count = 0; // Counts how many command bytes are received (need 2)
uint8_t mp_full_char_queue = 0; // Counts how many full-width characters are to be received
uint8_t mp_char_out_buf[2]; // Output buffer for caching up to 2 characters
uint8_t mp_char_out_count = 0; // Stores number of characters to be read out.
#ifdef USE_LOOKUP_TABLE
// The 15 most-common characters used in G-code, ~90-95% of all g-code uses these characters
// NOT storing this with PROGMEM, given how frequently this table will be accessed.
uint8_t MeatPackLookupTbl[16] = {
'0', // 0000
'1', // 0001
'2', // 0010
'3', // 0011
'4', // 0100
'5', // 0101
'6', // 0110
'7', // 0111
'8', // 1000
'9', // 1001
'.', // 1010
' ', // 1011
'\n', // 1100
'G', // 1101
'X', // 1110
'\0' // never used, 0b1111 is used to indicate next 8-bits is a full character
};
#else
inline uint8_t get_char(const uint8_t in) {
switch (in) {
case 0b0000:
return '0';
break;
case 0b0001:
return '1';
break;
case 0b0010:
return '2';
break;
case 0b0011:
return '3';
break;
case 0b0100:
return '4';
break;
case 0b0101:
return '5';
break;
case 0b0110:
return '6';
break;
case 0b0111:
return '7';
break;
case 0b1000:
return '8';
break;
case 0b1001:
return '9';
break;
case 0b1010:
return '.';
break;
case 0b1011:
return (mp_config & MPConfig_NoSpaces) ? MeatPack_SpaceCharReplace : ' ';
break;
case 0b1100:
return '\n';
break;
case 0b1101:
return 'G';
break;
case 0b1110:
return 'X';
break;
}
return 0;
}
#endif
// #DEBUGGING
#ifdef MP_DEBUG
uint32_t mp_chars_decoded = 0;
#endif
void FORCE_INLINE mp_handle_output_char(const uint8_t c) {
mp_char_out_buf[mp_char_out_count++] = c;
#ifdef MP_DEBUG
if (mp_chars_decoded < 4096) {
++mp_chars_decoded;
SERIAL_ECHOPGM("RB: ");
MYSERIAL.print((char)c);
SERIAL_ECHOLNPGM("");
}
#endif
}
// Storing
// packed = ((low & 0xF) << 4) | (high & 0xF);
// Unpacking
// low = (packed >> 4) & 0xF;
// high = (packed & 0xF);
//==========================================================================
uint8_t FORCE_INLINE mp_unpack_chars(const uint8_t pk, uint8_t* __restrict const chars_out) {
uint8_t out = 0;
#ifdef USE_LOOKUP_TABLE
// If lower 4 bytes is 0b1111, the higher 4 are unused, and next char is full.
if ((pk & MeatPack_FirstNotPacked) == MeatPack_FirstNotPacked) out |= MeatPack_NextPackedFirst;
else chars_out[0] = MeatPackLookupTbl[(pk & 0xF)]; // Assign lower char
// Check if upper 4 bytes is 0b1111... if so, we don't need the second char.
if ((pk & MeatPack_SecondNotPacked) == MeatPack_SecondNotPacked) out |= MeatPack_NextPackedSecond;
else chars_out[1] = MeatPackLookupTbl[((pk >> 4) & 0xf)]; // Assign upper char
#else
// If lower 4 bytes is 0b1111, the higher 4 are unused, and next char is full.
if ((pk & MeatPack_FirstNotPacked) == MeatPack_FirstNotPacked) out |= MeatPack_NextPackedFirst;
else chars_out[0] = get_char(pk & 0xF); // Assign lower char
// Check if upper 4 bytes is 0b1111... if so, we don't need the second char.
if ((pk & MeatPack_SecondNotPacked) == MeatPack_SecondNotPacked) out |= MeatPack_NextPackedSecond;
else chars_out[1] = get_char((pk >> 4) & 0xf); // Assign upper char
#endif
return out;
}
//==============================================================================
void FORCE_INLINE mp_reset_state() {
mp_char_out_count = 0;
mp_cmd_active = MPCommand_None;
mp_config = MPConfig_None;
mp_char_buf = 0;
mp_cmd_count = 0;
mp_cmd_active = 0;
mp_full_char_queue = 0;
#ifdef MP_DEBUG
mp_chars_decoded = 0;
SERIAL_ECHOLNPGM("MP Reset");
#endif
}
//==========================================================================
void FORCE_INLINE mp_handle_rx_char_inner(const uint8_t c) {
// Packing enabled, handle character and re-arrange them appropriately.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if (mp_config & MPConfig_Active) {
if (mp_full_char_queue > 0) {
mp_handle_output_char(c);
if (mp_char_buf > 0) {
mp_handle_output_char(mp_char_buf);
mp_char_buf = 0;
}
--mp_full_char_queue;
}
else {
uint8_t buf[2] = { 0,0 };
const uint8_t res = mp_unpack_chars(c, buf);
if (res & MeatPack_NextPackedFirst) {
++mp_full_char_queue;
if (res & MeatPack_NextPackedSecond) ++mp_full_char_queue;
else mp_char_buf = buf[1];
}
else {
mp_handle_output_char(buf[0]);
if (buf[0] != '\n') {
if (res & MeatPack_NextPackedSecond) ++mp_full_char_queue;
else mp_handle_output_char(buf[1]);
}
}
}
}
else // Packing not enabled, just copy character to output
mp_handle_output_char(c);
}
//==========================================================================
void FORCE_INLINE mp_echo_config_state() {
SERIAL_ECHOPGM(" [MP] "); // Add space at idx 0 just in case first character is dropped due to timing/sync issues.
// NOTE: if any configuration vars are added below, the outgoing sync text for host plugin
// should not contain the "PV' substring, as this is used to indicate protocol version
SERIAL_ECHOPGM(MeatPack_ProtocolVersion);
// Echo current state
if (mp_config & MPConfig_Active)
SERIAL_ECHOPGM(" ON");
else
SERIAL_ECHOPGM(" OFF");
if (mp_config & MPConfig_NoSpaces)
SERIAL_ECHOPGM(" NSP"); // [N]o [SP]aces
else
SERIAL_ECHOPGM(" ESP"); // [E]nabled [SP]aces
SERIAL_ECHOLNPGM("");
// Validate config vars
#ifdef USE_LOOKUP_TABLE
if (mp_config & MPConfig_NoSpaces)
MeatPackLookupTbl[MeatPack_SpaceCharIdx] = (uint8_t)(MeatPack_SpaceCharReplace);
else
MeatPackLookupTbl[MeatPack_SpaceCharIdx] = ' ';
#endif
}
//==========================================================================
void FORCE_INLINE mp_handle_cmd(const MeatPack_Command c) {
switch (c) {
case MPCommand_EnablePacking: {
mp_config |= MPConfig_Active;
#ifdef MP_DEBUG
SERIAL_ECHOLNPGM("[MPDBG] ENABL REC");
#endif
} break;
case MPCommand_DisablePacking: {
mp_config &= ~(MPConfig_Active);
#ifdef MP_DEBUG
SERIAL_ECHOLNPGM("[MPDBG] DISBL REC");
#endif
} break;
case MPCommand_ResetAll: {
mp_reset_state();
#ifdef MP_DEBUG
SERIAL_ECHOLNPGM("[MPDBG] RESET REC");
#endif
} break;
case MPCommand_EnableNoSpaces: {
mp_config |= MPConfig_NoSpaces;
#ifdef MP_DEBUG
SERIAL_ECHOLNPGM("[MPDBG] ENABL NSP");
#endif
} break;
case MPCommand_DisableNoSpaces: {
mp_config &= ~(MPConfig_NoSpaces);
#ifdef MP_DEBUG
SERIAL_ECHOLNPGM("[MPDBG] DISBL NSP");
#endif
} break;
default: {
#ifdef MP_DEBUG
SERIAL_ECHOLN("[MPDBG] UNK CMD REC");
#endif
}
case MPCommand_QueryConfig:
break;
}
mp_echo_config_state();
}
//==========================================================================
void mp_handle_rx_char(const uint8_t c) {
// Check for commit complete
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if (c == (uint8_t)(MeatPack_CommandByte)) {
if (mp_cmd_count > 0) {
mp_cmd_active = 1;
mp_cmd_count = 0;
}
else
++mp_cmd_count;
return;
}
if (mp_cmd_active > 0) {
mp_handle_cmd((MeatPack_Command)c);
mp_cmd_active = 0;
return;
}
if (mp_cmd_count > 0) {
mp_handle_rx_char_inner((uint8_t)(MeatPack_CommandByte));
mp_cmd_count = 0;
}
mp_handle_rx_char_inner(c);
}
//==========================================================================
uint8_t mp_get_result_char(char* const __restrict out) {
if (mp_char_out_count > 0) {
const uint8_t res = mp_char_out_count;
for (uint8_t i = 0; i < mp_char_out_count; ++i)
out[i] = (char)mp_char_out_buf[i];
mp_char_out_count = 0;
return res;
}
return 0;
}
//==============================================================================
void mp_trigger_cmd(const MeatPack_Command cmd)
{
mp_handle_cmd(cmd);
}
#endif

70
Firmware/meatpack.h Normal file
View File

@ -0,0 +1,70 @@
/*
* MeatPack G-Code Compression
*
* Algorithm & Implementation: Scott Mudge - mail@scottmudge.com
* Date: Dec. 2020
*
* Specifically optimized for 3D printing G-Code, this is a zero-cost data compression method
* which packs ~180-190% more data into the same amount of bytes going to the CNC controller.
* As a majority of G-Code can be represented by a restricted alphabet, I performed histogram
* analysis on a wide variety of 3D printing gcode samples, and found ~93% of all gcode could
* be represented by the same 15-character alphabet.
*
* This allowed me to design a system of packing 2 8-bit characters into a single byte, assuming
* they fall within this limited 15-character alphabet. Using a 4-bit lookup table, these 8-bit
* characters can be represented by a 4-bit index.
*
* Combined with some logic to allow commingling of full-width characters outside of this 15-
* character alphabet (at the cost of an extra 8-bits per full-width character), and by stripping
* out unnecessary comments, the end result is gcode which is roughly half the original size.
*
* Why did I do this? I noticed micro-stuttering and other data-bottleneck issues while printing
* objects with high curvature, especially at high speeds. There is also the issue of the limited
* baud rate provided by Prusa's Atmega2560-based boards, over the USB serial connection. So soft-
* ware like OctoPrint would also suffer this same micro-stuttering and poor print quality issue.
*
*/
#include <stdint.h>
#include "Configuration.h"
#ifndef MEATPACK_H_
#define MEATPACK_H_
#ifdef ENABLE_MEATPACK
#define MeatPack_SecondNotPacked 0b11110000
#define MeatPack_FirstNotPacked 0b00001111
// These are commands sent to MeatPack to control its behavior.
// They are sent by first sending 2x MeatPack_CommandByte (0xFF) in sequence,
// followed by one of the command bytes below.
// Provided that 0xFF is an exceedingly rare character that is virtually never
// present in g-code naturally, it is safe to assume 2 in sequence should never
// happen naturally, and so it is used as a signal here.
//
// 0xFF *IS* used in "packed" g-code (used to denote that the next 2 characters are
// full-width), however 2 in a row will never occur, as the next 2 bytes will always
// some non-0xFF character.
enum MeatPack_Command {
MPCommand_None = 0U,
// MPCommand_TogglePacking = 253U, -- Unused, byte 253 can be re-used later.
MPCommand_EnablePacking = 251U,
MPCommand_DisablePacking = 250U,
MPCommand_ResetAll = 249U,
MPCommand_QueryConfig = 248U,
MPCommand_EnableNoSpaces = 247U,
MPCommand_DisableNoSpaces = 246U
};
// Pass in a character rx'd by SD card or serial. Automatically parses command/ctrl sequences,
// and will control state internally.
extern void mp_handle_rx_char(const uint8_t c);
// After passing in rx'd char using above method, call this to get characters out. Can return
// from 0 to 2 characters at once.
// @param out [in] Output pointer for unpacked/processed data.
// @return Number of characters returned. Range from 0 to 2.
extern uint8_t mp_get_result_char(char* const __restrict out);
#endif
#endif // MEATPACK_H_

View File

@ -45,7 +45,7 @@ void menu_data_reset(void)
memset(&menu_data, 0, sizeof(menu_data));
}
void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bool reset_menu_state)
void menu_goto(menu_func_t menu, const int16_t encoder, bool reset_menu_state, const bool feedback)
{
CRITICAL_SECTION_START;
if (menu_menu != menu)
@ -53,11 +53,10 @@ void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bo
menu_menu = menu;
lcd_encoder = encoder;
menu_top = 0; //reset menu view. Needed if menu_back() is called from deep inside a menu, such as Support
lcd_draw_update = 2; // Full LCD re-draw
CRITICAL_SECTION_END;
if (reset_menu_state)
menu_data_reset();
if (feedback) lcd_quick_feedback();
if (feedback) lcd_beeper_quick_feedback();
if (reset_menu_state) menu_data_reset();
}
else
CRITICAL_SECTION_END;
@ -65,7 +64,6 @@ void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bo
void menu_start(void)
{
if (lcd_encoder > 0x8000) lcd_encoder = 0;
if (lcd_encoder < 0)
{
lcd_encoder = 0;
@ -74,11 +72,16 @@ void menu_start(void)
if (lcd_encoder < menu_top)
menu_top = lcd_encoder;
menu_line = menu_top;
menu_clicked = LCD_CLICKED;
menu_clicked = lcd_clicked(); // Consume click event
}
void menu_end(void)
{
if (menu_row >= LCD_HEIGHT)
{
// Early abort if the menu was clicked. The current menu might have changed because of the click event
return;
}
if (lcd_encoder >= menu_item)
{
lcd_encoder = menu_item - 1;
@ -96,7 +99,7 @@ void menu_end(void)
void menu_back(uint8_t nLevel)
{
menu_depth = ((menu_depth > nLevel) ? (menu_depth - nLevel) : 0);
menu_goto(menu_stack[menu_depth].menu, menu_stack[menu_depth].position, true, true);
menu_goto(menu_stack[menu_depth].menu, menu_stack[menu_depth].position, true);
}
void menu_back(void)
@ -109,7 +112,7 @@ void menu_back_no_reset(void)
if (menu_depth > 0)
{
menu_depth--;
menu_goto(menu_stack[menu_depth].menu, menu_stack[menu_depth].position, true, false);
menu_goto(menu_stack[menu_depth].menu, menu_stack[menu_depth].position, false);
}
}
@ -119,39 +122,35 @@ void menu_back_if_clicked(void)
menu_back();
}
void menu_back_if_clicked_fb(void)
{
if (lcd_clicked())
{
lcd_quick_feedback();
menu_back();
}
}
void menu_submenu(menu_func_t submenu)
void menu_submenu(menu_func_t submenu, const bool feedback)
{
if (menu_depth < MENU_DEPTH_MAX)
{
menu_stack[menu_depth].menu = menu_menu;
menu_stack[menu_depth++].position = lcd_encoder;
menu_goto(submenu, 0, true, true);
menu_goto(submenu, 0, true, feedback);
}
}
void menu_submenu_no_reset(menu_func_t submenu)
void menu_submenu_no_reset(menu_func_t submenu, const bool feedback)
{
if (menu_depth < MENU_DEPTH_MAX)
{
menu_stack[menu_depth].menu = menu_menu;
menu_stack[menu_depth++].position = lcd_encoder;
menu_goto(submenu, 0, true, false);
menu_goto(submenu, 0, false, feedback);
}
}
uint8_t menu_item_ret(void)
void menu_item_ret(void)
{
lcd_quick_feedback();
return 1;
lcd_draw_update = 2;
menu_item++;
//prevent the rest of the menu items from rendering or getting clicked
menu_row = LCD_HEIGHT; // early exit from the MENU_BEGIN() for loop at the end of the current cycle
menu_line = 0; // prevent subsequent menu items from rendering at all in the current MENU_BEGIN() for loop cycle
menu_clicked = 0; // prevent subsequent items from being able to be clicked in case the current menu or position was changed by the clicked menu item
}
static char menu_selection_mark(){
@ -160,8 +159,7 @@ static char menu_selection_mark(){
static void menu_draw_item_puts_P(char type_char, const char* str)
{
lcd_set_cursor(0, menu_row);
lcd_putc(menu_selection_mark());
lcd_putc_at(0, menu_row, menu_selection_mark());
lcd_print_pad_P(str, LCD_WIDTH - 2);
lcd_putc(type_char);
}
@ -172,13 +170,11 @@ static void menu_draw_toggle_puts_P(const char* str, const char* toggle, const u
//xxxxxcba
//a = selection mark. If it's set(1), then '>' will be used as the first character on the line. Else leave blank
//b = toggle string is from progmem
//c = do not set cursor at all. Must be handled externally.
uint8_t is_progmem = settings & 0x02;
const char eol = (toggle == NULL) ? LCD_STR_ARROW_RIGHT[0] : ' ';
if (toggle == NULL) toggle = _T(MSG_NA);
uint8_t len = 4 + (is_progmem ? strlen_P(toggle) : strlen(toggle));
if (!(settings & 0x04)) lcd_set_cursor(0, menu_row);
lcd_putc((settings & 0x01) ? '>' : ' ');
lcd_putc_at(0, menu_row, (settings & 0x01) ? '>' : ' ');
lcd_print_pad_P(str, LCD_WIDTH - len);
lcd_putc('[');
if (is_progmem)
@ -221,10 +217,9 @@ void menu_format_sheet_select_E(const Sheet &sheet_E, SheetFormatBuffer &buffer)
static void menu_draw_item_select_sheet_E(char type_char, const Sheet &sheet)
{
lcd_set_cursor(0, menu_row);
SheetFormatBuffer buffer;
menu_format_sheet_select_E(sheet, buffer);
lcd_putc(menu_selection_mark());
lcd_putc_at(0, menu_row, menu_selection_mark());
lcd_print_pad(buffer.c, LCD_WIDTH - 2);
lcd_putc(type_char);
}
@ -232,10 +227,9 @@ static void menu_draw_item_select_sheet_E(char type_char, const Sheet &sheet)
static void menu_draw_item_puts_E(char type_char, const Sheet &sheet)
{
lcd_set_cursor(0, menu_row);
SheetFormatBuffer buffer;
menu_format_sheet_E(sheet, buffer);
lcd_putc(menu_selection_mark());
lcd_putc_at(0, menu_row, menu_selection_mark());
lcd_print_pad(buffer.c, LCD_WIDTH - 2);
lcd_putc(type_char);
}
@ -260,13 +254,16 @@ uint8_t menu_item_text_P(const char* str)
{
if (lcd_draw_update) menu_draw_item_puts_P(' ', str);
if (menu_clicked && (lcd_encoder == menu_item))
return menu_item_ret();
{
menu_item_ret();
return 1;
}
}
menu_item++;
return 0;
}
uint8_t menu_item_submenu_P(const char* str, menu_func_t submenu)
void menu_item_submenu_P(const char* str, menu_func_t submenu)
{
if (menu_item == menu_line)
{
@ -274,14 +271,14 @@ uint8_t menu_item_submenu_P(const char* str, menu_func_t submenu)
if (menu_clicked && (lcd_encoder == menu_item))
{
menu_submenu(submenu);
return menu_item_ret();
menu_item_ret();
return;
}
}
menu_item++;
return 0;
}
uint8_t menu_item_submenu_E(const Sheet &sheet, menu_func_t submenu)
void menu_item_submenu_E(const Sheet &sheet, menu_func_t submenu)
{
if (menu_item == menu_line)
{
@ -289,33 +286,31 @@ uint8_t menu_item_submenu_E(const Sheet &sheet, menu_func_t submenu)
if (menu_clicked && (lcd_encoder == menu_item))
{
menu_submenu(submenu);
return menu_item_ret();
menu_item_ret();
return;
}
}
menu_item++;
return 0;
}
uint8_t __attribute__((noinline)) menu_item_function_E(const Sheet &sheet, menu_func_t func)
void __attribute__((noinline)) menu_item_function_E(const Sheet &sheet, menu_func_t func)
{
if (menu_item == menu_line)
{
if (lcd_draw_update) menu_draw_item_select_sheet_E(' ', sheet);
if (menu_clicked && (lcd_encoder == menu_item))
{
menu_clicked = false;
lcd_consume_click();
lcd_update_enabled = 0;
if (func) func();
lcd_update_enabled = 1;
return menu_item_ret();
menu_item_ret();
return;
}
}
menu_item++;
return 0;
}
uint8_t menu_item_back_P(const char* str)
void menu_item_back_P(const char* str)
{
if (menu_item == menu_line)
{
@ -323,34 +318,32 @@ uint8_t menu_item_back_P(const char* str)
if (menu_clicked && (lcd_encoder == menu_item))
{
menu_back();
return menu_item_ret();
menu_item_ret();
return;
}
}
menu_item++;
return 0;
}
bool __attribute__((noinline)) menu_item_leave(){
return ((menu_item == menu_line) && menu_clicked && (lcd_encoder == menu_item)) || menu_leaving;
}
uint8_t menu_item_function_P(const char* str, menu_func_t func)
void menu_item_function_P(const char* str, menu_func_t func)
{
if (menu_item == menu_line)
{
if (lcd_draw_update) menu_draw_item_puts_P(' ', str);
if (menu_clicked && (lcd_encoder == menu_item))
{
menu_clicked = false;
lcd_consume_click();
lcd_update_enabled = 0;
if (func) func();
lcd_update_enabled = 1;
return menu_item_ret();
menu_item_ret();
return;
}
}
menu_item++;
return 0;
}
//! @brief Menu item function taking single parameter
@ -362,26 +355,24 @@ uint8_t menu_item_function_P(const char* str, menu_func_t func)
//! @param fn_par value to be passed to function
//! @retval 0
//! @retval 1 Item was clicked
uint8_t menu_item_function_P(const char* str, char number, void (*func)(uint8_t), uint8_t fn_par)
void menu_item_function_P(const char* str, char number, void (*func)(uint8_t), uint8_t fn_par)
{
if (menu_item == menu_line)
{
if (lcd_draw_update) menu_draw_item_puts_P(' ', str, number);
if (menu_clicked && (lcd_encoder == menu_item))
{
menu_clicked = false;
lcd_consume_click();
lcd_update_enabled = 0;
if (func) func(fn_par);
lcd_update_enabled = 1;
return menu_item_ret();
menu_item_ret();
return;
}
}
menu_item++;
return 0;
}
uint8_t menu_item_toggle_P(const char* str, const char* toggle, menu_func_t func, const uint8_t settings)
void menu_item_toggle_P(const char* str, const char* toggle, menu_func_t func, const uint8_t settings)
{
if (menu_item == menu_line)
{
@ -391,24 +382,21 @@ uint8_t menu_item_toggle_P(const char* str, const char* toggle, menu_func_t func
if (toggle == NULL) // print N/A warning message
{
menu_submenu(func);
return menu_item_ret();
}
else // do the actual toggling
{
menu_clicked = false;
lcd_consume_click();
lcd_update_enabled = 0;
if (func) func();
lcd_update_enabled = 1;
return menu_item_ret();
}
menu_item_ret();
return;
}
}
menu_item++;
return 0;
}
uint8_t menu_item_gcode_P(const char* str, const char* str_gcode)
void menu_item_gcode_P(const char* str, const char* str_gcode)
{
if (menu_item == menu_line)
{
@ -416,11 +404,11 @@ uint8_t menu_item_gcode_P(const char* str, const char* str_gcode)
if (menu_clicked && (lcd_encoder == menu_item))
{
if (str_gcode) enquecommand_P(str_gcode);
return menu_item_ret();
menu_item_ret();
return;
}
}
menu_item++;
return 0;
}
const char menu_fmt_int3[] PROGMEM = "%c%.15S:%s%3d";
@ -429,11 +417,10 @@ const char menu_fmt_float31[] PROGMEM = "%-12.12S%+8.1f";
const char menu_fmt_float13[] PROGMEM = "%c%-13.13S%+5.3f";
template<typename T>
static void menu_draw_P(char chr, const char* str, int16_t val);
template<>
void menu_draw_P<int16_t*>(char chr, const char* str, int16_t val)
template <typename T>
void menu_draw_P(char chr, const char* str, T val)
{
// The LCD row position is controlled externally. We may only modify the column here
lcd_putc(chr);
@ -449,23 +436,11 @@ void menu_draw_P<int16_t*>(char chr, const char* str, int16_t val)
} else { // 3 digits
lcd_set_cursor_column(LCD_WIDTH - 3);
}
lcd_print(val);
lcd_print(val, DEC);
}
template<>
void menu_draw_P<uint8_t*>(char chr, const char* str, int16_t val)
{
menu_data_edit_t* _md = (menu_data_edit_t*)&(menu_data[0]);
float factor = 1.0f + static_cast<float>(val) / 1000.0f;
if (val <= _md->minEditValue)
{
menu_draw_toggle_puts_P(str, _T(MSG_OFF), 0x04 | 0x02 | (chr=='>'));
}
else
{
lcd_printf_P(menu_fmt_float13, chr, str, factor);
}
}
template void menu_draw_P<int16_t>(char chr, const char* str, int16_t val);
template void menu_draw_P<uint8_t>(char chr, const char* str, uint8_t val);
//! @brief Draw up to 10 chars of text and a float number in format from +0.0 to +12345.0. The increased range is necessary
//! for displaying large values of extruder positions, which caused text overflow in the previous implementation.
@ -503,20 +478,23 @@ static void _menu_edit_P(void)
menu_data_edit_t* _md = (menu_data_edit_t*)&(menu_data[0]);
if (lcd_draw_update)
{
if (lcd_encoder < _md->minEditValue) lcd_encoder = _md->minEditValue;
else if (lcd_encoder > _md->maxEditValue) lcd_encoder = _md->maxEditValue;
_md->currentValue += lcd_encoder;
lcd_encoder = 0; // Consume knob rotation event
// Constrain the value in case it's outside the allowed limits
_md->currentValue = constrain(_md->currentValue, _md->minEditValue, _md->maxEditValue);
lcd_set_cursor(0, 1);
menu_draw_P<T>(' ', _md->editLabel, (int)lcd_encoder);
menu_draw_P(' ', _md->editLabel, _md->currentValue);
}
if (LCD_CLICKED)
if (lcd_clicked())
{
*((T)(_md->editValue)) = lcd_encoder;
*((T)(_md->editValue)) = _md->currentValue;
menu_back_no_reset();
}
}
template <typename T>
uint8_t menu_item_edit_P(const char* str, T pval, int16_t min_val, int16_t max_val)
void menu_item_edit_P(const char* str, T pval, int16_t min_val, int16_t max_val)
{
menu_data_edit_t* _md = (menu_data_edit_t*)&(menu_data[0]);
if (menu_item == menu_line)
@ -524,25 +502,25 @@ uint8_t menu_item_edit_P(const char* str, T pval, int16_t min_val, int16_t max_v
if (lcd_draw_update)
{
lcd_set_cursor(0, menu_row);
menu_draw_P<T>(menu_selection_mark(), str, *pval);
menu_draw_P(menu_selection_mark(), str, *pval);
}
if (menu_clicked && (lcd_encoder == menu_item))
{
menu_submenu_no_reset(_menu_edit_P<T>);
_md->editLabel = str;
_md->editValue = pval;
_md->currentValue = *pval;
_md->minEditValue = min_val;
_md->maxEditValue = max_val;
lcd_encoder = *pval;
return menu_item_ret();
menu_item_ret();
return;
}
}
menu_item++;
return 0;
}
template uint8_t menu_item_edit_P<int16_t*>(const char* str, int16_t *pval, int16_t min_val, int16_t max_val);
template uint8_t menu_item_edit_P<uint8_t*>(const char* str, uint8_t *pval, int16_t min_val, int16_t max_val);
template void menu_item_edit_P<int16_t*>(const char* str, int16_t *pval, int16_t min_val, int16_t max_val);
template void menu_item_edit_P<uint8_t*>(const char* str, uint8_t *pval, int16_t min_val, int16_t max_val);
static uint8_t progressbar_block_count = 0;
static uint16_t progressbar_total = 0;

View File

@ -21,8 +21,9 @@ typedef struct
//Variables used when editing values.
const char* editLabel;
void* editValue;
int32_t minEditValue;
int32_t maxEditValue;
int16_t currentValue;
int16_t minEditValue;
int16_t maxEditValue;
} menu_data_edit_t;
extern uint8_t menu_data[MENU_DATA_SIZE];
@ -37,6 +38,7 @@ enum ESeriousErrors {
#ifdef TEMP_MODEL
MENU_BLOCK_TEMP_MODEL_AUTOTUNE = 0x02,
#endif
MENU_BLOCK_STATUS_SCREEN_M0 = 0x04,
}; // and possibly others in the future.
//! this is a flag for disabling entering the main menu and longpress. If this is set to anything !=
@ -48,7 +50,8 @@ extern uint8_t menu_block_mask;
//! a c++ class would have been better
#define menu_set_block(x) menu_block_mask |= x;
#define menu_unset_block(x) menu_block_mask &= ~x;
#define menu_is_blocked(x) (menu_block_mask & x) != 0
#define menu_is_blocked(x) (menu_block_mask & x)
#define menu_is_any_block() (menu_block_mask != MENU_BLOCK_NONE)
extern uint8_t menu_line;
extern uint8_t menu_item;
@ -64,7 +67,7 @@ extern menu_func_t menu_menu;
extern void menu_data_reset(void);
extern void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bool reset_menu_state);
extern void menu_goto(menu_func_t menu, const int16_t encoder, bool reset_menu_state, const bool feedback=false);
#define MENU_BEGIN() menu_start(); for(menu_row = 0; menu_row < LCD_HEIGHT; menu_row++, menu_line++) { menu_item = 0;
void menu_start(void);
@ -78,12 +81,10 @@ extern void menu_back(uint8_t nLevel);
extern void menu_back_if_clicked(void);
extern void menu_back_if_clicked_fb(void);
extern void menu_submenu(menu_func_t submenu, const bool feedback=false);
extern void menu_submenu_no_reset(menu_func_t submenu, const bool feedback=false);
extern void menu_submenu(menu_func_t submenu);
extern void menu_submenu_no_reset(menu_func_t submenu);
extern uint8_t menu_item_ret(void);
extern void menu_item_ret(void);
//extern int menu_draw_item_printf_P(char type_char, const char* format, ...);
@ -93,37 +94,37 @@ extern uint8_t menu_item_ret(void);
#define MENU_ITEM_DUMMY() menu_item_dummy()
extern void menu_item_dummy(void);
#define MENU_ITEM_TEXT_P(str) do { if (menu_item_text_P(str)) return; } while (0)
#define MENU_ITEM_TEXT_P(str) do { menu_item_text_P(str); } while (0)
extern uint8_t menu_item_text_P(const char* str);
#define MENU_ITEM_SUBMENU_P(str, submenu) do { if (menu_item_submenu_P(str, submenu)) return; } while (0)
extern uint8_t menu_item_submenu_P(const char* str, menu_func_t submenu);
#define MENU_ITEM_SUBMENU_P(str, submenu) do { menu_item_submenu_P(str, submenu); } while (0)
extern void menu_item_submenu_P(const char* str, menu_func_t submenu);
#define MENU_ITEM_SUBMENU_E(sheet, submenu) do { if (menu_item_submenu_E(sheet, submenu)) return; } while (0)
extern uint8_t menu_item_submenu_E(const Sheet &sheet, menu_func_t submenu);
#define MENU_ITEM_SUBMENU_E(sheet, submenu) do { menu_item_submenu_E(sheet, submenu); } while (0)
extern void menu_item_submenu_E(const Sheet &sheet, menu_func_t submenu);
#define MENU_ITEM_FUNCTION_E(sheet, submenu) do { if (menu_item_function_E(sheet, submenu)) return; } while (0)
extern uint8_t menu_item_function_E(const Sheet &sheet, menu_func_t func);
#define MENU_ITEM_FUNCTION_E(sheet, submenu) do { menu_item_function_E(sheet, submenu); } while (0)
extern void menu_item_function_E(const Sheet &sheet, menu_func_t func);
#define MENU_ITEM_BACK_P(str) do { if (menu_item_back_P(str)) return; } while (0)
extern uint8_t menu_item_back_P(const char* str);
#define MENU_ITEM_BACK_P(str) do { menu_item_back_P(str); } while (0)
extern void menu_item_back_P(const char* str);
// leaving menu - this condition must be immediately before MENU_ITEM_BACK_P
#define ON_MENU_LEAVE(func) do { if (menu_item_leave()){ func } } while (0)
extern bool menu_item_leave();
#define MENU_ITEM_FUNCTION_P(str, func) do { if (menu_item_function_P(str, func)) return; } while (0)
extern uint8_t menu_item_function_P(const char* str, menu_func_t func);
#define MENU_ITEM_FUNCTION_P(str, func) do { menu_item_function_P(str, func); } while (0)
extern void menu_item_function_P(const char* str, menu_func_t func);
#define MENU_ITEM_FUNCTION_NR_P(str, number, func, fn_par) do { if (menu_item_function_P(str, number, func, fn_par)) return; } while (0)
extern uint8_t menu_item_function_P(const char* str, char number, void (*func)(uint8_t), uint8_t fn_par);
#define MENU_ITEM_FUNCTION_NR_P(str, number, func, fn_par) do { menu_item_function_P(str, number, func, fn_par); } while (0)
extern void menu_item_function_P(const char* str, char number, void (*func)(uint8_t), uint8_t fn_par);
#define MENU_ITEM_TOGGLE_P(str, toggle, func) do { if (menu_item_toggle_P(str, toggle, func, 0x02)) return; } while (0)
#define MENU_ITEM_TOGGLE(str, toggle, func) do { if (menu_item_toggle_P(str, toggle, func, 0x00)) return; } while (0)
extern uint8_t menu_item_toggle_P(const char* str, const char* toggle, menu_func_t func, const uint8_t settings);
#define MENU_ITEM_TOGGLE_P(str, toggle, func) do { menu_item_toggle_P(str, toggle, func, 0x02); } while (0)
#define MENU_ITEM_TOGGLE(str, toggle, func) do { menu_item_toggle_P(str, toggle, func, 0x00); } while (0)
extern void menu_item_toggle_P(const char* str, const char* toggle, menu_func_t func, const uint8_t settings);
#define MENU_ITEM_GCODE_P(str, str_gcode) do { if (menu_item_gcode_P(str, str_gcode)) return; } while (0)
extern uint8_t menu_item_gcode_P(const char* str, const char* str_gcode);
#define MENU_ITEM_GCODE_P(str, str_gcode) do { menu_item_gcode_P(str, str_gcode); } while (0)
extern void menu_item_gcode_P(const char* str, const char* str_gcode);
extern const char menu_fmt_int3[];
@ -143,10 +144,13 @@ struct SheetFormatBuffer
extern void menu_format_sheet_E(const Sheet &sheet_E, SheetFormatBuffer &buffer);
#define MENU_ITEM_EDIT_int3_P(str, pval, minval, maxval) do { if (menu_item_edit_P(str, pval, minval, maxval)) return; } while (0)
#define MENU_ITEM_EDIT_int3_P(str, pval, minval, maxval) do { menu_item_edit_P(str, pval, minval, maxval); } while (0)
//#define MENU_ITEM_EDIT_int3_P(str, pval, minval, maxval) MENU_ITEM_EDIT(int3, str, pval, minval, maxval)
template <typename T>
extern uint8_t menu_item_edit_P(const char* str, T pval, int16_t min_val, int16_t max_val);
extern void menu_item_edit_P(const char* str, T pval, int16_t min_val, int16_t max_val);
template <typename T>
extern void menu_draw_P(char chr, const char* str, T val);
extern void menu_progressbar_init(uint16_t total, const char* title);
extern void menu_progressbar_update(uint16_t newVal);

View File

@ -3106,25 +3106,6 @@ void count_xyz_details(float (&distanceMin)[2]) {
distanceMin[mesh_point] = (y - Y_MIN_POS_CALIBRATION_POINT_OUT_OF_REACH);
}
}
/*
e_MBL_TYPE e_mbl_type = e_MBL_OPTIMAL;
void mbl_mode_set() {
switch (e_mbl_type) {
case e_MBL_OPTIMAL: e_mbl_type = e_MBL_PREC; break;
case e_MBL_PREC: e_mbl_type = e_MBL_FAST; break;
case e_MBL_FAST: e_mbl_type = e_MBL_OPTIMAL; break;
default: e_mbl_type = e_MBL_OPTIMAL; break;
}
eeprom_update_byte((uint8_t*)EEPROM_MBL_TYPE,(uint8_t)e_mbl_type);
}
void mbl_mode_init() {
uint8_t mbl_type = eeprom_read_byte((uint8_t*)EEPROM_MBL_TYPE);
if (mbl_type == 0xFF) e_mbl_type = e_MBL_OPTIMAL;
else e_mbl_type = mbl_type;
}
*/
void mbl_settings_init() {
//3x3 mesh; 3 Z-probes on each point, magnet elimination on

View File

@ -201,15 +201,7 @@ extern void babystep_reset();
extern void count_xyz_details(float (&distanceMin)[2]);
extern bool sample_z();
/*
typedef enum
{
e_MBL_FAST, e_MBL_OPTIMAL, e_MBL_PREC
} e_MBL_TYPE;
*/
//extern e_MBL_TYPE e_mbl_type;
//extern void mbl_mode_set();
//extern void mbl_mode_init();
extern void mbl_settings_init();
extern bool mbl_point_measurement_valid(uint8_t ix, uint8_t iy, uint8_t meas_points, bool zigzag);

View File

@ -34,13 +34,13 @@ const char MSG_FILAMENT[] PROGMEM_I1 = ISTR("Filament"); ////MSG_FILAMENT c=17
const char MSG_FAN_SPEED[] PROGMEM_I1 = ISTR("Fan speed"); ////MSG_FAN_SPEED c=14
const char MSG_HOTEND_FAN_SPEED[] PROGMEM_I1 = ISTR("Hotend fan:");////MSG_HOTEND_FAN_SPEED c=15
const char MSG_PRINT_FAN_SPEED[] PROGMEM_I1 = ISTR("Print fan:"); ////MSG_PRINT_FAN_SPEED c=15
const char MSG_FILAMENT_CLEAN[] PROGMEM_I1 = ISTR("Filament extruding & with correct color?"); ////MSG_FILAMENT_CLEAN c=20 r=2
const char MSG_FILAMENT_LOADED[] PROGMEM_I1 = ISTR("Is filament loaded?"); ////MSG_FILAMENT_LOADED c=20 r=2
const char MSG_FILAMENT_CLEAN[] PROGMEM_I1 = ISTR("Filament extruding & with correct color?"); ////MSG_FILAMENT_CLEAN c=20 r=3
const char MSG_FILAMENT_LOADED[] PROGMEM_I1 = ISTR("Is filament loaded?"); ////MSG_FILAMENT_LOADED c=20 r=3
const char MSG_FILAMENTCHANGE[] PROGMEM_I1 = ISTR("Change filament"); ////MSG_FILAMENTCHANGE c=18
const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE1[] PROGMEM_I1 = ISTR("Searching bed calibration point"); ////MSG_FIND_BED_OFFSET_AND_SKEW_LINE1 c=20 r=3
const char MSG_FINISHING_MOVEMENTS[] PROGMEM_I1 = ISTR("Finishing movements"); ////MSG_FINISHING_MOVEMENTS c=20
const char MSG_FOLLOW_CALIBRATION_FLOW[] PROGMEM_I1 = ISTR("Printer has not been calibrated yet. Please follow the manual, chapter First steps, section Calibration flow."); ////MSG_FOLLOW_CALIBRATION_FLOW c=20 r=8
const char MSG_FOLLOW_Z_CALIBRATION_FLOW[] PROGMEM_I1 = ISTR("There is still a need to make Z calibration. Please follow the manual, chapter First steps, section Calibration flow."); ////MSG_FOLLOW_Z_CALIBRATION_FLOW c=20 r=9
const char MSG_FOLLOW_Z_CALIBRATION_FLOW[] PROGMEM_I1 = ISTR("There is still a need to make Z calibration. Please follow the manual, chapter First steps, section Calibration flow."); ////MSG_FOLLOW_Z_CALIBRATION_FLOW c=20 r=8
const char MSG_FSENSOR_RUNOUT[] PROGMEM_I1 = ISTR("F. runout"); ////MSG_FSENSOR_RUNOUT c=13
const char MSG_FSENSOR_AUTOLOAD[] PROGMEM_I1 = ISTR("F. autoload"); ////MSG_FSENSOR_AUTOLOAD c=13
const char MSG_FSENSOR_JAM_DETECTION[] PROGMEM_I1 = ISTR("F. jam detect"); ////MSG_FSENSOR_JAM_DETECTION c=13
@ -49,7 +49,6 @@ const char MSG_HEATING[] PROGMEM_I1 = ISTR("Heating"); ////MSG_HEATING c=20
const char MSG_HEATING_COMPLETE[] PROGMEM_I1 = ISTR("Heating done."); ////MSG_HEATING_COMPLETE c=20
const char MSG_HOMEYZ[] PROGMEM_I1 = ISTR("Calibrate Z"); ////MSG_HOMEYZ c=18
const char MSG_ITERATION[] PROGMEM_I1 = ISTR("Iteration"); ////MSG_ITERATION c=12
const char MSG_SELECT_EXTRUDER[] PROGMEM_I1 = ISTR("Select extruder:"); ////MSG_SELECT_EXTRUDER c=20
const char MSG_SELECT_FILAMENT[] PROGMEM_I1 = ISTR("Select filament:"); ////MSG_SELECT_FILAMENT c=20
const char MSG_LAST_PRINT[] PROGMEM_I1 = ISTR("Last print"); ////MSG_LAST_PRINT c=18
const char MSG_LAST_PRINT_FAILURES[] PROGMEM_I1 = ISTR("Last print failures"); ////MSG_LAST_PRINT_FAILURES c=20
@ -70,16 +69,16 @@ const char MSG_MMU_LOAD_FAILS[] PROGMEM_I1 = ISTR("MMU load fails"); ////MSG_MMU
const char MSG_MMU_POWER_FAILS[] PROGMEM_I1 = ISTR("MMU power fails"); ////MSG_MMU_POWER_FAILS c=15
const char MSG_NO[] PROGMEM_I1 = ISTR("No"); ////MSG_NO c=4
const char MSG_NOZZLE[] PROGMEM_I1 = ISTR("Nozzle"); ////MSG_NOZZLE c=10
const char MSG_PAPER[] PROGMEM_I1 = ISTR("Place a sheet of paper under the nozzle during the calibration of first 4 points. If the nozzle catches the paper, power off the printer immediately."); ////MSG_PAPER c=20 r=10
const char MSG_PAPER[] PROGMEM_I1 = ISTR("Place a sheet of paper under the nozzle during the calibration of first 4 points. If the nozzle catches the paper, power off the printer immediately."); ////MSG_PAPER c=20 r=8
const char MSG_PAUSE_PRINT[] PROGMEM_I1 = ISTR("Pause print");////MSG_PAUSE_PRINT c=18
const char MSG_PLACE_STEEL_SHEET[] PROGMEM_I1 = ISTR("Please place steel sheet on heatbed."); ////MSG_PLACE_STEEL_SHEET c=20 r=5
const char MSG_PLACE_STEEL_SHEET[] PROGMEM_I1 = ISTR("Please place steel sheet on heatbed."); ////MSG_PLACE_STEEL_SHEET c=20 r=4
const char MSG_PLEASE_WAIT[] PROGMEM_I1 = ISTR("Please wait"); ////MSG_PLEASE_WAIT c=20
const char MSG_POWER_FAILURES[] PROGMEM_I1 = ISTR("Power failures"); ////MSG_POWER_FAILURES c=15
const char MSG_PREHEAT_NOZZLE[] PROGMEM_I1 = ISTR("Preheat the nozzle!"); ////MSG_PREHEAT_NOZZLE c=20
const char MSG_PRESS_TO_UNLOAD[] PROGMEM_I1 = ISTR("Please press the knob to unload filament"); ////MSG_PRESS_TO_UNLOAD c=20 r=4
const char MSG_PRINT_ABORTED[] PROGMEM_I1 = ISTR("Print aborted"); ////MSG_PRINT_ABORTED c=20
const char MSG_PULL_OUT_FILAMENT[] PROGMEM_I1 = ISTR("Please pull out filament immediately"); ////MSG_PULL_OUT_FILAMENT c=20 r=4
const char MSG_RECOVER_PRINT[] PROGMEM_I1 = ISTR("Blackout occurred. Recover print?"); ////MSG_RECOVER_PRINT c=20 r=2
const char MSG_RECOVER_PRINT[] PROGMEM_I1 = ISTR("Blackout occurred. Recover print?"); ////MSG_RECOVER_PRINT c=20 r=3
const char MSG_REFRESH[] PROGMEM_I1 = ISTR("\x04Refresh"); ////MSG_REFRESH c=18
const char MSG_REMOVE_STEEL_SHEET[] PROGMEM_I1 = ISTR("Please remove steel sheet from heatbed."); ////MSG_REMOVE_STEEL_SHEET c=20 r=4
const char MSG_RESET[] PROGMEM_I1 = ISTR("Reset"); ////MSG_RESET c=14
@ -109,7 +108,7 @@ const char MSG_AUTO_POWER[] PROGMEM_I1 = ISTR("Auto power"); ////MSG_AUTO_POWER
const char MSG_SILENT[] PROGMEM_I1 = ISTR("Silent"); ////MSG_SILENT c=7
const char MSG_NORMAL[] PROGMEM_I1 = ISTR("Normal"); ////MSG_NORMAL c=7
const char MSG_STEALTH[] PROGMEM_I1 = ISTR("Stealth"); ////MSG_STEALTH c=7
const char MSG_STEEL_SHEET_CHECK[] PROGMEM_I1 = ISTR("Is steel sheet on heatbed?"); ////MSG_STEEL_SHEET_CHECK c=20 r=2
const char MSG_STEEL_SHEET_CHECK[] PROGMEM_I1 = ISTR("Is steel sheet on heatbed?"); ////MSG_STEEL_SHEET_CHECK c=20 r=3
const char MSG_STOP_PRINT[] PROGMEM_I1 = ISTR("Stop print"); ////MSG_STOP_PRINT c=18
const char MSG_STOPPED[] PROGMEM_I1 = ISTR("STOPPED."); ////MSG_STOPPED c=20
const char MSG_PINDA_CALIBRATION[] PROGMEM_I1 = ISTR("PINDA cal."); ////MSG_PINDA_CALIBRATION c=13
@ -140,7 +139,7 @@ const char MSG_GCODE_NEWER_FIRMWARE_CANCELLED[] PROGMEM_I1 = ISTR("G-code sliced
const char MSG_GCODE_DIFF_CONTINUE[] PROGMEM_I1 = ISTR("G-code sliced for a different level. Continue?"); ////MSG_GCODE_DIFF_CONTINUE c=20 r=3
const char MSG_GCODE_DIFF_CANCELLED[] PROGMEM_I1 = ISTR("G-code sliced for a different level. Please re-slice the model again. Print cancelled."); ////MSG_GCODE_DIFF_CANCELLED c=20 r=8
const char MSG_NOZZLE_DIFFERS_CONTINUE[] PROGMEM_I1 = ISTR("Nozzle diameter differs from the G-code. Continue?"); ////MSG_NOZZLE_DIFFERS_CONTINUE c=20 r=3
const char MSG_NOZZLE_DIFFERS_CANCELLED[] PROGMEM_I1 = ISTR("Nozzle diameter differs from the G-code. Please check the value in settings. Print cancelled."); ////MSG_NOZZLE_DIFFERS_CANCELLED c=20 r=9
const char MSG_NOZZLE_DIFFERS_CANCELLED[] PROGMEM_I1 = ISTR("Nozzle diameter differs from the G-code. Please check the value in settings. Print cancelled."); ////MSG_NOZZLE_DIFFERS_CANCELLED c=20 r=8
const char MSG_NOZZLE_DIAMETER[] PROGMEM_I1 = ISTR("Nozzle d."); ////MSG_NOZZLE_DIAMETER c=10
const char MSG_MMU_MODE[] PROGMEM_I1 = ISTR("MMU Mode"); ////MSG_MMU_MODE c=8
const char MSG_SD_CARD[] PROGMEM_I1 = ISTR("SD card"); ////MSG_SD_CARD c=8
@ -229,3 +228,17 @@ const char MSG_ADVANCE_K[] PROGMEM_N1 = "Advance K:"; ////c=13
const char MSG_POWERPANIC_DETECTED[] PROGMEM_N1 = "POWER PANIC DETECTED"; ////c=20
const char MSG_LCD_STATUS_CHANGED[] PROGMEM_N1 = "LCD status changed";
const char MSG_UNKNOWN_CODE[] PROGMEM_N1 = "Unknown %c code: %s\n";
// Common G-gcodes
const char G1_E_F2700[] PROGMEM_N1 = "G1 E%-.3f F2700";
const char G28W[] PROGMEM_N1 = "G28 W";
const char MSG_M23[] PROGMEM_N1 = "M23 %s";
const char MSG_M24[] PROGMEM_N1 = "M24";
const char MSG_M83[] PROGMEM_N1 = "M83";
const char MSG_M84[] PROGMEM_N1 = "M84";
const char MSG_M107[] PROGMEM_N1 = "M107";
const char MSG_M220[] PROGMEM_N1 = "M220 S%d";
const char MSG_M500[] PROGMEM_N1 = "M500";
const char MSG_M600[] PROGMEM_N1 = "M600";
const char MSG_M701[] PROGMEM_N1 = "M701";
const char MSG_M702[] PROGMEM_N1 = "M702";

View File

@ -55,7 +55,6 @@ extern const char MSG_HEATING[];
extern const char MSG_HEATING_COMPLETE[];
extern const char MSG_HOMEYZ[];
extern const char MSG_ITERATION[];
extern const char MSG_SELECT_EXTRUDER[];
extern const char MSG_SELECT_FILAMENT[];
extern const char MSG_LAST_PRINT[];
extern const char MSG_LAST_PRINT_FAILURES[];
@ -236,6 +235,20 @@ extern const char MSG_POWERPANIC_DETECTED[];
extern const char MSG_LCD_STATUS_CHANGED[];
extern const char MSG_UNKNOWN_CODE[];
// Common G-gcodes
extern const char G1_E_F2700[];
extern const char G28W[];
extern const char MSG_M23[];
extern const char MSG_M24[];
extern const char MSG_M83[];
extern const char MSG_M84[];
extern const char MSG_M107[];
extern const char MSG_M220[];
extern const char MSG_M500[];
extern const char MSG_M600[];
extern const char MSG_M701[];
extern const char MSG_M702[];
#if defined(__cplusplus)
}
#endif //defined(__cplusplus)

View File

@ -49,7 +49,6 @@ MMU2::MMU2()
, mmu_print_saved(SavedState::None)
, loadFilamentStarted(false)
, unloadFilamentStarted(false)
, loadingToNozzle(false)
, toolchange_counter(0)
, tmcFailures(0) {
}
@ -188,7 +187,7 @@ void MMU2::CheckFINDARunout() {
if (SpoolJoin::spooljoin.isSpoolJoinEnabled() && get_current_tool() != (uint8_t)FILAMENT_UNKNOWN){ // Can't auto if F=?
enquecommand_front_P(PSTR("M600 AUTO")); // save print and run M600 command
} else {
enquecommand_front_P(PSTR("M600")); // save print and run M600 command
enquecommand_front_P(MSG_M600); // save print and run M600 command
}
}
}
@ -239,16 +238,64 @@ bool MMU2::VerifyFilamentEnteredPTFE() {
return false;
uint8_t fsensorState = 0;
uint8_t fsensorStateLCD = 0;
uint8_t lcd_cursor_col = 0;
// MMU has finished its load, push the filament further by some defined constant length
// If the filament sensor reads 0 at any moment, then report FAILURE
MoveE(MMU2_EXTRUDER_PTFE_LENGTH + MMU2_EXTRUDER_HEATBREAK_LENGTH + MMU2_VERIFY_LOAD_TO_NOZZLE_TWEAK - (logic.ExtraLoadDistance() - MMU2_FILAMENT_SENSOR_POSITION), MMU2_VERIFY_LOAD_TO_NOZZLE_FEED_RATE);
MoveE(-(MMU2_EXTRUDER_PTFE_LENGTH + MMU2_EXTRUDER_HEATBREAK_LENGTH + MMU2_VERIFY_LOAD_TO_NOZZLE_TWEAK - (logic.ExtraLoadDistance() - MMU2_FILAMENT_SENSOR_POSITION)), MMU2_VERIFY_LOAD_TO_NOZZLE_FEED_RATE);
while (planner_any_moves()) {
// Wait for move to finish and monitor the fsensor the entire time
// A single 0 reading will set the bit.
fsensorState |= (WhereIsFilament() == FilamentState::NOT_PRESENT);
safe_delay_keep_alive(0);
const float delta_mm = MMU2_CHECK_FILAMENT_PRESENCE_EXTRUSION_LENGTH - logic.ExtraLoadDistance();
// The total length is twice delta_mm. Divide that length by number of pixels
// available to get length per pixel.
// Note: Below is the reciprocal of (2 * delta_mm) / LCD_WIDTH [mm/pixel]
const float pixel_per_mm = 0.5f * float(LCD_WIDTH) / (delta_mm);
TryLoadUnloadProgressbarInit();
/* The position is a triangle wave
// current position is not zero, it is an offset
//
// Keep in mind that the relationship between machine position
// and pixel index is not linear. The area around the amplitude
// needs to be taken care of carefully. The current implementation
// handles each move separately so there is no need to watch for the change
// in the slope's sign or check the last machine position.
// y(x)
// ▲
// │ ^◄────────── delta_mm + current_position
// machine / \
// position │ / \◄────────── stepper_position_mm + current_position
// (mm) / \
// / \
// │/ \◄───────current_position
// └──────────────► x
// 0 19
// pixel #
*/
// Pixel index will go from 0 to 10, then back from 10 to 0
// The change in this number is used to indicate a new pixel
// should be drawn on the display
uint8_t dpixel1 = 0;
uint8_t dpixel0 = 0;
for (uint8_t move = 0; move < 2; move++) {
MoveE(move == 0 ? delta_mm : -delta_mm, MMU2_VERIFY_LOAD_TO_NOZZLE_FEED_RATE);
while (planner_any_moves()) {
// Wait for move to finish and monitor the fsensor the entire time
// A single 0 reading will set the bit.
fsensorStateLCD |= (WhereIsFilament() == FilamentState::NOT_PRESENT);
fsensorState |= fsensorStateLCD; // No need to do the above comparison twice, just bitwise OR
// Always round up, you can only have 'whole' pixels. (floor is also an option)
dpixel1 = ceil((stepper_get_machine_position_E_mm() - planner_get_current_position_E()) * pixel_per_mm);
if (dpixel1 - dpixel0) {
dpixel0 = dpixel1;
if (lcd_cursor_col > (LCD_WIDTH - 1)) lcd_cursor_col = LCD_WIDTH - 1;
TryLoadUnloadProgressbar(lcd_cursor_col++, fsensorStateLCD);
fsensorStateLCD = 0; // Clear temporary bit
}
safe_delay_keep_alive(0);
}
}
if (fsensorState) {
@ -354,8 +401,7 @@ bool MMU2::tool_change(char code, uint8_t slot) {
case 'x': {
thermal_setExtrudeMintemp(0); // Allow cold extrusion since Tx only loads to the gears not nozzle
planner_synchronize();
ToolChangeCommon(slot); // the only difference was manage_response(false, false), but probably good enough
tool_change(slot);
thermal_setExtrudeMintemp(EXTRUDE_MINTEMP);
} break;
@ -451,6 +497,7 @@ bool MMU2::cut_filament(uint8_t slot, bool enableFullScreenMsg /*= true*/) {
extruder = MMU2_NO_TOOL;
tool_change_extruder = MMU2_NO_TOOL;
MakeSound(SoundType::Confirm);
ScreenUpdateEnable();
return true;
}
@ -485,23 +532,10 @@ bool MMU2::load_filament(uint8_t slot) {
return true;
}
struct LoadingToNozzleRAII {
MMU2 &mmu2;
explicit inline LoadingToNozzleRAII(MMU2 &mmu2)
: mmu2(mmu2) {
mmu2.loadingToNozzle = true;
}
inline ~LoadingToNozzleRAII() {
mmu2.loadingToNozzle = false;
}
};
bool MMU2::load_filament_to_nozzle(uint8_t slot) {
if (!WaitForMMUReady())
return false;
LoadingToNozzleRAII ln(*this);
WaitForHotendTargetTempBeep();
FullScreenMsgLoad(slot);
@ -873,10 +907,12 @@ void MMU2::ReportError(ErrorCode ec, ErrorSource res) {
switch (logic.Progress()) {
case ProgressCode::UnloadingToFinda:
unloadFilamentStarted = false;
planner_abort_queued_moves(); // Abort excess E-moves to be safe
break;
case ProgressCode::FeedingToFSensor:
// FSENSOR error during load. Make sure E-motor stops moving.
loadFilamentStarted = false;
planner_abort_queued_moves(); // Abort excess E-moves to be safe
break;
default:
break;
@ -991,6 +1027,10 @@ void MMU2::OnMMUProgressMsgSame(ProgressCode pc) {
case FilamentState::AT_FSENSOR:
// fsensor triggered, finish FeedingToExtruder state
loadFilamentStarted = false;
// Abort any excess E-move from the planner queue
planner_abort_queued_moves();
// After the MMU knows the FSENSOR is triggered it will:
// 1. Push the filament by additional 30mm (see fsensorToNozzle)
// 2. Disengage the idler and push another 2mm.
@ -999,7 +1039,12 @@ void MMU2::OnMMUProgressMsgSame(ProgressCode pc) {
case FilamentState::NOT_PRESENT:
// fsensor not triggered, continue moving extruder
if (!planner_any_moves()) { // Only plan a move if there is no move ongoing
MoveE(2.0f, MMU2_LOAD_TO_NOZZLE_FEED_RATE);
// Plan a very long move, where 'very long' is hundreds
// of millimeters. Keep in mind though the move can't be much longer
// than 450mm because the firmware will ignore too long extrusions
// for safety reasons. See PREVENT_LENGTHY_EXTRUDE.
// Use 350mm to be safely away from the prevention threshold
MoveE(350.0f, MMU2_LOAD_TO_NOZZLE_FEED_RATE);
}
break;
default:

View File

@ -307,10 +307,6 @@ private:
bool loadFilamentStarted;
bool unloadFilamentStarted;
friend struct LoadingToNozzleRAII;
/// true in case we are doing the LoadToNozzle operation - that means the filament shall be loaded all the way down to the nozzle
/// unlike the mid-print ToolChange commands, which only load the first ~30mm and then the G-code takes over.
bool loadingToNozzle;
uint16_t toolchange_counter;
uint16_t tmcFailures;
};

View File

@ -56,6 +56,8 @@ enum class ErrorCode : uint_fast16_t {
FILAMENT_EJECTED = 0x800c, ///< Filament was ejected, waiting for user input - technically, this is not an error
MCU_UNDERVOLTAGE_VCC = 0x800d, ///< MCU VCC rail undervoltage.
LOAD_TO_EXTRUDER_FAILED = 0x802a, ///< E32811 internal error of the printer - try-load-unload sequence detected missing filament -> failed load into the nozzle
QUEUE_FULL = 0x802b, ///< E32811 internal logic error - attempt to move with a full queue
VERSION_MISMATCH = 0x802c, ///< E32812 internal error of the printer - incompatible version of the MMU FW

View File

@ -62,6 +62,8 @@ typedef enum : uint16_t {
ERR_ELECTRICAL_SELECTOR_SELFTEST_FAILED = 315,
ERR_ELECTRICAL_IDLER_SELFTEST_FAILED = 325,
ERR_ELECTRICAL_MCU_UNDERVOLTAGE_VCC = 306,
ERR_CONNECT = 400,
ERR_CONNECT_MMU_NOT_RESPONDING = 401,
ERR_CONNECT_COMMUNICATION_ERROR = 402,
@ -117,6 +119,7 @@ static const constexpr uint16_t errorCodes[] PROGMEM = {
ERR_ELECTRICAL_PULLEY_SELFTEST_FAILED,
ERR_ELECTRICAL_SELECTOR_SELFTEST_FAILED,
ERR_ELECTRICAL_IDLER_SELFTEST_FAILED,
ERR_ELECTRICAL_MCU_UNDERVOLTAGE_VCC,
ERR_CONNECT_MMU_NOT_RESPONDING,
ERR_CONNECT_COMMUNICATION_ERROR,
ERR_SYSTEM_FILAMENT_ALREADY_LOADED,
@ -160,6 +163,7 @@ static const char MSG_TITLE_TMC_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("TMC DRI
//static const char MSG_TITLE_TMC_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("TMC DRIVER SHORTED");
//static const char MSG_TITLE_TMC_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("TMC DRIVER SHORTED");
static const char MSG_TITLE_SELFTEST_FAILED[] PROGMEM_I1 = ISTR("MMU SELFTEST FAILED"); ////MSG_TITLE_SELFTEST_FAILED c=20
static const char MSG_TITLE_MCU_UNDERVOLTAGE_VCC[] PROGMEM_I1 = ISTR("MCU UNDERVOLTAGE VCC"); ////MSG_TITLE_MCU_UNDERVOLTAGE_VCC c=20
static const char MSG_TITLE_MMU_NOT_RESPONDING[] PROGMEM_I1 = ISTR("MMU NOT RESPONDING"); ////MSG_TITLE_MMU_NOT_RESPONDING c=20
static const char MSG_TITLE_COMMUNICATION_ERROR[] PROGMEM_I1 = ISTR("COMMUNICATION ERROR"); ////MSG_TITLE_COMMUNICATION_ERROR c=20
static const char MSG_TITLE_FIL_ALREADY_LOADED[] PROGMEM_I1 = ISTR("FILAMENT ALREADY LOA"); ////MSG_TITLE_FIL_ALREADY_LOADED c=20
@ -204,6 +208,7 @@ static const char * const errorTitles [] PROGMEM = {
_R(MSG_TITLE_SELFTEST_FAILED),
_R(MSG_TITLE_SELFTEST_FAILED),
_R(MSG_TITLE_SELFTEST_FAILED),
_R(MSG_TITLE_MCU_UNDERVOLTAGE_VCC),
_R(MSG_TITLE_MMU_NOT_RESPONDING),
_R(MSG_TITLE_COMMUNICATION_ERROR),
_R(MSG_TITLE_FIL_ALREADY_LOADED),
@ -237,29 +242,30 @@ static const char MSG_DESC_TMC[] PROGMEM_I1 = ISTR("More details online."); ////
//static const char MSG_DESC_PULLEY_TMC_OVERHEAT_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Pulley motor is overheated. Cool down the MMU board and reset MMU.");
//static const char MSG_DESC_SELECTOR_TMC_OVERHEAT_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Selector motor is overheated. Cool down the MMU board and reset MMU.");
//static const char MSG_DESC_IDLER_TMC_OVERHEAT_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Idler motor is overheated. Cool down the MMU board and reset MMU.");
//static const char MSG_DESC_PULLEY_TMC_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Pulley motor is not responding. Try resetting the MMU. If the issue persists contact support.");
//static const char MSG_DESC_SELECTOR_TMC_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Selector motor is not responding. Try resetting the MMU. If the issue persists contact support.");
//static const char MSG_DESC_IDLER_TMC_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Idler motor is not responding. Try resetting the MMU. If the issue persists contact support.");
//static const char MSG_DESC_PULLEY_TMC_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Pulley motor is not responding. Try resetting the MMU.");
//static const char MSG_DESC_SELECTOR_TMC_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Selector motor is not responding. Try resetting the MMU.");
//static const char MSG_DESC_IDLER_TMC_DRIVER_ERROR[] PROGMEM_I1 = ISTR("TMC driver for the Idler motor is not responding. Try resetting the MMU.");
//static const char MSG_DESC_PULLEY_TMC_DRIVER_RESET[] PROGMEM_I1 = ISTR("TMC driver for the Pulley motor was restarted. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_SELECTOR_TMC_DRIVER_RESET[] PROGMEM_I1 = ISTR("TMC driver for the Selector motor was restarted. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_IDLER_TMC_DRIVER_RESET[] PROGMEM_I1 = ISTR("TMC driver for the Idler motor was restarted. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_PULLEY_TMC_UNDERVOLTAGE_ERROR[] PROGMEM_I1 = ISTR("Not enough current for the Pulley TMC driver. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_SELECTOR_TMC_UNDERVOLTAGE_ERROR[] PROGMEM_I1 = ISTR("Not enough current for the Selector TMC driver. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_IDLER_TMC_UNDERVOLTAGE_ERROR[] PROGMEM_I1 = ISTR("Not enough current for the Idler TMC driver. There is probably an issue with the electronics. Check the wiring and connectors.");
//static const char MSG_DESC_PULLEY_TMC_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("Short circuit on the Pulley TMC driver. Check the wiring and connectors. If the issue persists contact support.");
//static const char MSG_DESC_SELECTOR_TMC_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("Short circuit on the Selector TMC driver. Check the wiring and connectors. If the issue persists contact support.");
//static const char MSG_DESC_IDLER_TMC_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("Short circuit on the Idler TMC driver. Check the wiring and connectors. If the issue persists contact support.");
static const char MSG_DESC_MMU_NOT_RESPONDING[] PROGMEM_I1 = ISTR("MMU unit not responding. Check the wiring and connectors. If the issue persists, contact support."); ////MSG_DESC_MMU_NOT_RESPONDING c=20 r=8
static const char MSG_DESC_COMMUNICATION_ERROR[] PROGMEM_I1 = ISTR("MMU unit not responding correctly. Check the wiring and connectors. If the issue persists, contact support."); ////MSG_DESC_COMMUNICATION_ERROR c=20 r=9
//static const char MSG_DESC_PULLEY_TMC_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("Short circuit on the Pulley TMC driver. Check the wiring and connectors.");
//static const char MSG_DESC_SELECTOR_TMC_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("Short circuit on the Selector TMC driver. Check the wiring and connectors.");
//static const char MSG_DESC_IDLER_TMC_DRIVER_SHORTED[] PROGMEM_I1 = ISTR("Short circuit on the Idler TMC driver. Check the wiring and connectors.");
//static const char MSG_DESC_MCU_UNDERVOLTAGE_VCC[] PROGMEM_I1 = ISTR("MMU MCU detected a 5V undervoltage. There might be an issue with the electronics. Check the wiring and connectors"); ////MSG_DESC_MCU_UNDERVOLTAGE_VCC c=20 r=8
static const char MSG_DESC_MMU_NOT_RESPONDING[] PROGMEM_I1 = ISTR("MMU not responding. Check the wiring and connectors."); ////MSG_DESC_MMU_NOT_RESPONDING c=20 r=4
static const char MSG_DESC_COMMUNICATION_ERROR[] PROGMEM_I1 = ISTR("MMU not responding correctly. Check the wiring and connectors."); ////MSG_DESC_COMMUNICATION_ERROR c=20 r=4
static const char MSG_DESC_FILAMENT_ALREADY_LOADED[] PROGMEM_I1 = ISTR("Cannot perform the action, filament is already loaded. Unload it first."); ////MSG_DESC_FILAMENT_ALREADY_LOADED c=20 r=8
static const char MSG_DESC_INVALID_TOOL[] PROGMEM_I1 = ISTR("Requested filament tool is not available on this hardware. Check the G-code for tool index out of range (T0-T4)."); ////MSG_DESC_INVALID_TOOL c=20 r=8
static const char MSG_DESC_QUEUE_FULL[] PROGMEM_I1 = ISTR("MMU Firmware internal error, please reset the MMU."); ////MSG_DESC_QUEUE_FULL c=20 r=8
static const char MSG_DESC_FW_RUNTIME_ERROR[] PROGMEM_I1 = ISTR("Internal runtime error. Try resetting the MMU unit or updating the firmware. If the issue persists, contact support."); ////MSG_DESC_FW_RUNTIME_ERROR c=20 r=11
static const char MSG_DESC_FW_RUNTIME_ERROR[] PROGMEM_I1 = ISTR("Internal runtime error. Try resetting the MMU or updating the firmware."); ////MSG_DESC_FW_RUNTIME_ERROR c=20 r=8
static const char MSG_DESC_UNLOAD_MANUALLY[] PROGMEM_I1 = ISTR("Filament detected unexpectedly. Ensure no filament is loaded. Check the sensors and wiring."); ////MSG_DESC_UNLOAD_MANUALLY c=20 r=8
static const char MSG_DESC_FILAMENT_EJECTED[] PROGMEM_I1 = ISTR("Remove the ejected filament from the front of the MMU unit."); ////MSG_DESC_FILAMENT_EJECTED c=20 r=8
static const char MSG_DESC_FILAMENT_EJECTED[] PROGMEM_I1 = ISTR("Remove the ejected filament from the front of the MMU."); ////MSG_DESC_FILAMENT_EJECTED c=20 r=8
// Read explanation in mmu2_protocol_logic.cpp -> supportedMmuFWVersion
static constexpr char MSG_DESC_FW_UPDATE_NEEDED[] PROGMEM_I1 = ISTR("The MMU unit firmware version incompatible with the printer's FW. Update to version 2.1.7."); ////MSG_DESC_FW_UPDATE_NEEDED c=20 r=9
static constexpr char MSG_DESC_FW_UPDATE_NEEDED[] PROGMEM_I1 = ISTR("The MMU firmware version incompatible with the printer's FW. Update to version 2.1.9."); ////MSG_DESC_FW_UPDATE_NEEDED c=20 r=8
static constexpr uint8_t szFWUN = sizeof(MSG_DESC_FW_UPDATE_NEEDED);
// at least check the individual version characters in MSG_DESC_FW_UPDATE_NEEDED
static_assert(MSG_DESC_FW_UPDATE_NEEDED[szFWUN - 7] == ('0' + mmuVersionMajor));
@ -300,6 +306,7 @@ static const char * const errorDescs[] PROGMEM = {
_R(MSG_DESC_TMC), // descPULLEY_SELFTEST_FAILED
_R(MSG_DESC_TMC), // descSELECTOR_SELFTEST_FAILED
_R(MSG_DESC_TMC), // descIDLER_SELFTEST_FAILED
_R(MSG_DESC_TMC), // descMSG_DESC_MCU_UNDERVOLTAGE_VCC
_R(MSG_DESC_MMU_NOT_RESPONDING),
_R(MSG_DESC_COMMUNICATION_ERROR),
_R(MSG_DESC_FILAMENT_ALREADY_LOADED),
@ -325,7 +332,7 @@ static const char MSG_BTN_RESTART_MMU[] PROGMEM_I1 = ISTR("RstMMU"); ////MSG_BTN
static const char MSG_BTN_UNLOAD[] PROGMEM_I1 = ISTR("Unload"); ////MSG_BTN_UNLOAD c=8
static const char MSG_BTN_STOP[] PROGMEM_I1 = ISTR("Stop"); ////MSG_BTN_STOP c=8
static const char MSG_BTN_DISABLE_MMU[] PROGMEM_I1 = ISTR("Disable"); ////MSG_BTN_DISABLE_MMU c=8
static const char MSG_BTN_MORE[] PROGMEM_I1 = ISTR("\x06"); ////MSG_BTN_MORE c=8 //@todo convert to PROGMEM_N1
static const char MSG_BTN_MORE[] PROGMEM_N1 = "\x06";
// Used to parse the buttons from Btns().
static const char * const btnOperation[] PROGMEM = {
@ -381,6 +388,7 @@ static const uint8_t errorButtons[] PROGMEM = {
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//PULLEY_SELFTEST_FAILED
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//SELECTOR_SELFTEST_FAILED
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//IDLER_SELFTEST_FAILED
Btns(ButtonOperations::RestartMMU, ButtonOperations::NoOperation),//MCU_UNDERVOLTAGE_VCC
Btns(ButtonOperations::RestartMMU, ButtonOperations::DisableMMU),//MMU_NOT_RESPONDING
Btns(ButtonOperations::RestartMMU, ButtonOperations::DisableMMU),//COMMUNICATION_ERROR

View File

@ -40,6 +40,11 @@ static constexpr float MMU2_VERIFY_LOAD_TO_NOZZLE_TWEAK = -5.F; // mm used to sh
static constexpr float MMU2_RETRY_UNLOAD_TO_FINDA_LENGTH = 80.0f; // mm
static constexpr float MMU2_RETRY_UNLOAD_TO_FINDA_FEED_RATE = 80.0f; // mm/s
// After loading a new filament, the printer will extrude the filament by this distance
// and then retract it back to the original position. This is used to check if the
// filament sensor reading flickers or filament is jammed.
static constexpr float MMU2_CHECK_FILAMENT_PRESENCE_EXTRUSION_LENGTH = MMU2_EXTRUDER_PTFE_LENGTH + MMU2_EXTRUDER_HEATBREAK_LENGTH + MMU2_VERIFY_LOAD_TO_NOZZLE_TWEAK + MMU2_FILAMENT_SENSOR_POSITION;
static constexpr uint8_t MMU2_NO_TOOL = 99;
static constexpr uint32_t MMU_BAUD = 115200;

View File

@ -40,6 +40,11 @@ static constexpr float MMU2_VERIFY_LOAD_TO_NOZZLE_TWEAK = -5.F; // mm used to sh
static constexpr float MMU2_RETRY_UNLOAD_TO_FINDA_LENGTH = 80.0f; // mm
static constexpr float MMU2_RETRY_UNLOAD_TO_FINDA_FEED_RATE = 80.0f; // mm/s
// After loading a new filament, the printer will extrude the filament by this distance
// and then retract it back to the original position. This is used to check if the
// filament sensor reading flickers or filament is jammed.
static constexpr float MMU2_CHECK_FILAMENT_PRESENCE_EXTRUSION_LENGTH = MMU2_EXTRUDER_PTFE_LENGTH + MMU2_EXTRUDER_HEATBREAK_LENGTH + MMU2_VERIFY_LOAD_TO_NOZZLE_TWEAK + MMU2_FILAMENT_SENSOR_POSITION;
static constexpr uint8_t MMU2_NO_TOOL = 99;
static constexpr uint32_t MMU_BAUD = 115200;

View File

@ -84,6 +84,8 @@ uint8_t PrusaErrorCodeIndex(uint16_t ec) {
return FindErrorIndex(ERR_SYSTEM_FW_RUNTIME_ERROR);
case (uint16_t)ErrorCode::FINDA_VS_EEPROM_DISREPANCY:
return FindErrorIndex(ERR_SYSTEM_UNLOAD_MANUALLY);
case (uint16_t)ErrorCode::MCU_UNDERVOLTAGE_VCC:
return FindErrorIndex(ERR_ELECTRICAL_MCU_UNDERVOLTAGE_VCC);
}
// Electrical issues which can be detected somehow.
@ -170,7 +172,7 @@ const char * PrusaErrorButtonTitle(uint8_t bi){
}
const char * PrusaErrorButtonMore(){
return _R(MSG_BTN_MORE);//@todo convert to PROGMEM_N1
return MSG_BTN_MORE;
}
struct ResetOnExit {
@ -265,6 +267,7 @@ Buttons ButtonAvailable(uint16_t ec) {
case ERR_SYSTEM_QUEUE_FULL:
case ERR_SYSTEM_FW_RUNTIME_ERROR:
case ERR_ELECTRICAL_MCU_UNDERVOLTAGE_VCC:
switch (buttonSelectedOperation) {
case ButtonOperations::RestartMMU: // "Restart MMU"
return RestartMMU;

View File

@ -3,7 +3,7 @@
namespace MMU2 {
void LogErrorEvent_P(const char *msg){
SERIAL_ECHO_START; //!@todo Decide MMU2 errors on serial line
SERIAL_ECHO_START; //!@todo Decide MMU errors on serial line
SERIAL_MMU2();
SERIAL_ECHOLNRPGM(msg);
}

View File

@ -33,21 +33,21 @@ void LogEchoEvent_P(const char *msg);
SERIAL_MMU2(); \
SERIAL_ECHOLN(S); \
} while (0)
#define MMU2_ERROR_MSGLN(S) MMU2_ECHO_MSGLN(S) //!@todo Decide MMU2 errors on serial line
#define MMU2_ERROR_MSGLN(S) MMU2_ECHO_MSGLN(S) //!@todo Decide MMU errors on serial line
#define MMU2_ECHO_MSGRPGM(S) \
do { \
SERIAL_ECHO_START; \
SERIAL_MMU2(); \
SERIAL_ECHORPGM(S); \
} while (0)
#define MMU2_ERROR_MSGRPGM(S) MMU2_ECHO_MSGRPGM(S) //!@todo Decide MMU2 errors on serial line
#define MMU2_ERROR_MSGRPGM(S) MMU2_ECHO_MSGRPGM(S) //!@todo Decide MMU errors on serial line
#define MMU2_ECHO_MSG(S) \
do { \
SERIAL_ECHO_START; \
SERIAL_MMU2(); \
SERIAL_ECHO(S); \
} while (0)
#define MMU2_ERROR_MSG(S) MMU2_ECHO_MSG(S) //!@todo Decide MMU2 errors on serial line
#define MMU2_ERROR_MSG(S) MMU2_ECHO_MSG(S) //!@todo Decide MMU errors on serial line
#else // #ifndef UNITTEST

View File

@ -1,8 +1,8 @@
/// @file
/// The sole purpose of this interface is to separate Marlin1/Marlin2 from the MMU2 top logic layer.
/// The sole purpose of this interface is to separate Marlin1/Marlin2 from the MMU top logic layer.
/// Why?
/// - unify implementation among MK3 and Buddy FW
/// - enable unit testing of MMU2 top layer
/// - enable unit testing of MMU top layer
#pragma once
#include <stdint.h>
@ -26,9 +26,11 @@ void MoveE(float delta, float feedRate);
float MoveRaiseZ(float delta);
void planner_abort_queued_moves();
void planner_synchronize();
bool planner_any_moves();
float planner_get_machine_position_E_mm();
float stepper_get_machine_position_E_mm();
float planner_get_current_position_E();
void planner_set_current_position_E(float e);
void planner_line_to_current_position(float feedRate_mm_s);

View File

@ -18,6 +18,17 @@ float MoveRaiseZ(float delta) {
return raise_z(delta);
}
void planner_abort_queued_moves() {
planner_abort_hard();
// Unblock the planner. This should be safe in the
// toolchange context. Currently we are mainly aborting
// excess E-moves after detecting filament during toolchange.
// If a MMU error is reported, the planner must be unblocked
// as well so the extruder can be parked safely.
planner_aborted = false;
}
void planner_synchronize() {
st_synchronize();
}
@ -30,6 +41,10 @@ float planner_get_machine_position_E_mm(){
return current_position[E_AXIS];
}
float stepper_get_machine_position_E_mm(){
return st_get_position_mm(E_AXIS);
}
float planner_get_current_position_E(){
return current_position[E_AXIS];
}

View File

@ -20,7 +20,7 @@ namespace MMU2 {
/// Changing the supportedMmuVersion numbers requires patching MSG_DESC_FW_UPDATE_NEEDED and all its related translations by hand.
///
/// The message reads:
/// "The MMU unit firmware version incompatible with the printer's FW. Update to version 2.1.6."
/// "The MMU firmware version incompatible with the printer's FW. Update to version 2.1.6."
///
/// Currently, this is not possible to perform automatically at compile time with the existing languages/translations infrastructure.
/// To save space a "dumb" solution was chosen + a few static_assert checks in errors_list.h preventing the code from compiling when the string doesn't match.
@ -705,9 +705,8 @@ void ProtocolLogic::FormatLastResponseMsgAndClearLRB(char *dst) {
*dst++ = '<';
for (uint8_t i = 0; i < lrb; ++i) {
uint8_t b = lastReceivedBytes[i];
if (b < 32)
b = '.';
if (b > 127)
// Check for printable character, including space
if (b < 32 || b > 127)
b = '.';
*dst++ = b;
}
@ -721,9 +720,8 @@ void ProtocolLogic::LogRequestMsg(const uint8_t *txbuff, uint8_t size) {
static char lastMsg[rqs] = "";
for (uint8_t i = 0; i < size; ++i) {
uint8_t b = txbuff[i];
if (b < 32)
b = '.';
if (b > 127)
// Check for printable character, including space
if (b < 32 || b > 127)
b = '.';
tmp[i + 1] = b;
}

View File

@ -20,7 +20,9 @@ void BeginReport(CommandInProgress /*cip*/, uint16_t ec) {
void EndReport(CommandInProgress /*cip*/, uint16_t /*ec*/) {
// clear the status msg line - let the printed filename get visible again
lcd_setstatuspgm(MSG_WELCOME); // should be seen only when the printer is not printing a file
if (!printJobOngoing()) {
lcd_setstatuspgm(MSG_WELCOME);
}
custom_message_type = CustomMsg::Status;
}
@ -77,8 +79,7 @@ static void ReportErrorHookStaticRender(uint8_t ei) {
ReportErrorHookSensorLineRender();
// Render the choices
//@todo convert MSG_BTN_MORE to PROGMEM_N1
lcd_show_choices_prompt_P(two_choices ? LCD_LEFT_BUTTON_CHOICE : LCD_MIDDLE_BUTTON_CHOICE, _T(PrusaErrorButtonTitle(button_op_middle)), _T(two_choices ? PrusaErrorButtonMore() : PrusaErrorButtonTitle(button_op_right)), two_choices ? 18 : 9, two_choices ? nullptr : _T(PrusaErrorButtonMore()));
lcd_show_choices_prompt_P(two_choices ? LCD_LEFT_BUTTON_CHOICE : LCD_MIDDLE_BUTTON_CHOICE, _T(PrusaErrorButtonTitle(button_op_middle)), two_choices ? PrusaErrorButtonMore() : _T(PrusaErrorButtonTitle(button_op_right)), two_choices ? 18 : 9, two_choices ? nullptr : PrusaErrorButtonMore());
}
void ReportErrorHookSensorLineRender(){
@ -100,16 +101,8 @@ void ReportErrorHookSensorLineRender(){
static uint8_t ReportErrorHookMonitor(uint8_t ei) {
uint8_t ret = 0;
bool two_choices = false;
static int8_t enc_dif = lcd_encoder_diff;
static uint8_t reset_button_selection;
if (lcd_encoder_diff == 0)
{
// lcd_update_enable(true) was called outside ReportErrorHookMonitor
// It will set lcd_encoder_diff to 0, sync enc_dif
enc_dif = 0;
}
// Read and determine what operations should be shown on the menu
const uint8_t button_operation = PrusaErrorButtons(ei);
const uint8_t button_op_right = BUTTON_OP_RIGHT(button_operation);
@ -133,20 +126,20 @@ static uint8_t ReportErrorHookMonitor(uint8_t ei) {
}
// Check if knob was rotated
if (abs(enc_dif - lcd_encoder_diff) >= ENCODER_PULSES_PER_STEP) {
if (lcd_encoder) {
if (two_choices == false) { // third_choice is not nullptr, safe to dereference
if (enc_dif > lcd_encoder_diff && current_selection != LCD_LEFT_BUTTON_CHOICE) {
if (lcd_encoder < 0 && current_selection != LCD_LEFT_BUTTON_CHOICE) {
// Rotating knob counter clockwise
current_selection--;
} else if (enc_dif < lcd_encoder_diff && current_selection != LCD_RIGHT_BUTTON_CHOICE) {
} else if (lcd_encoder > 0 && current_selection != LCD_RIGHT_BUTTON_CHOICE) {
// Rotating knob clockwise
current_selection++;
}
} else {
if (enc_dif > lcd_encoder_diff && current_selection != LCD_LEFT_BUTTON_CHOICE) {
if (lcd_encoder < 0 && current_selection != LCD_LEFT_BUTTON_CHOICE) {
// Rotating knob counter clockwise
current_selection = LCD_LEFT_BUTTON_CHOICE;
} else if (enc_dif < lcd_encoder_diff && current_selection != LCD_MIDDLE_BUTTON_CHOICE) {
} else if (lcd_encoder > 0 && current_selection != LCD_MIDDLE_BUTTON_CHOICE) {
// Rotating knob clockwise
current_selection = LCD_MIDDLE_BUTTON_CHOICE;
}
@ -180,14 +173,12 @@ static uint8_t ReportErrorHookMonitor(uint8_t ei) {
// More button for two button screen
lcd_putc_at(18, 3, current_selection == LCD_MIDDLE_BUTTON_CHOICE ? '>': ' ');
}
// Consume rotation event and make feedback sound
enc_dif = lcd_encoder_diff;
Sound_MakeSound(e_SOUND_TYPE_EncoderMove);
// Consume rotation event
lcd_encoder = 0;
}
// Check if knob was clicked and consume the event
if (lcd_clicked()) {
Sound_MakeSound(e_SOUND_TYPE_ButtonEcho);
choice_selected = current_selection;
} else {
// continue monitoring
@ -281,14 +272,22 @@ void ReportProgressHook(CommandInProgress cip, uint16_t ec) {
if (cip != CommandInProgress::NoCommand) {
custom_message_type = CustomMsg::MMUProgress;
lcd_setstatuspgm( _T(ProgressCodeToText(ec)) );
} else {
// If there is no command in progress we can display other
// useful information such as the name of the SD file
// being printed
custom_message_type = CustomMsg::Status;
}
}
void TryLoadUnloadProgressbarInit() {
// Clear the status line
lcd_set_cursor(0, 3);
lcd_space(LCD_WIDTH);
}
void TryLoadUnloadProgressbar(uint8_t col, bool sensorState) {
// Set the cursor position each time in case some other
// part of the firmware changes the cursor position
lcd_putc_at(col, 3, sensorState ? '-' : LCD_STR_SOLID_BLOCK[0]);
lcd_reset_status_message_timeout();
}
void IncrementLoadFails(){
eeprom_increment_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL);
eeprom_increment_word((uint16_t *)EEPROM_MMU_LOAD_FAIL_TOT);

View File

@ -32,6 +32,14 @@ void ReportErrorHook(CommandInProgress cip, uint16_t ec, uint8_t es);
/// Called when the MMU sends operation progress update
void ReportProgressHook(CommandInProgress cip, uint16_t ec);
/// @brief Clear the status line and setup the LCD cursor
void TryLoadUnloadProgressbarInit();
/// @brief Add one block to the progress bar
/// @param col pixel position on the LCD status line, should range from 0 to (LCD_WIDTH - 1)
/// @param sensorState if true, filament is not present, else filament is present. This controls which character to render
void TryLoadUnloadProgressbar(uint8_t col, bool sensorState);
/// Remders the sensor status line. Also used by the "resume temperature" screen.
void ReportErrorHookDynamicRender();

View File

@ -10,7 +10,7 @@ namespace MMU2 {
/// - Connecting
/// - Stopped
///
/// When the printer's FW starts, the MMU2 mode is either Stopped or NotResponding (based on user's preference).
/// When the printer's FW starts, the MMU mode is either Stopped or NotResponding (based on user's preference).
/// When the MMU successfully establishes communication, the state changes to Active.
enum class xState : uint_fast8_t {
Active, ///< MMU has been detected, connected, communicates and is ready to be worked with.

View File

@ -5,6 +5,6 @@ namespace MMU2 {
static constexpr uint8_t mmuVersionMajor = 2;
static constexpr uint8_t mmuVersionMinor = 1;
static constexpr uint8_t mmuVersionPatch = 7;
static constexpr uint8_t mmuVersionPatch = 9;
} // namespace MMU2

View File

@ -207,7 +207,7 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit
if (final_rate > block->nominal_rate)
final_rate = block->nominal_rate;
uint32_t acceleration = block->acceleration_st;
uint32_t acceleration = block->acceleration_steps_per_s2;
if (acceleration == 0)
// Don't allow zero acceleration.
acceleration = 1;
@ -530,11 +530,11 @@ bool e_active()
void check_axes_activity()
{
unsigned char x_active = 0;
unsigned char y_active = 0;
unsigned char z_active = 0;
unsigned char e_active = 0;
unsigned char tail_fan_speed = fanSpeed;
uint8_t x_active = 0;
uint8_t y_active = 0;
uint8_t z_active = 0;
uint8_t e_active = 0;
uint8_t tail_fan_speed = fanSpeed;
block_t *block;
if(block_buffer_tail != block_buffer_head)
@ -554,12 +554,7 @@ void check_axes_activity()
if((DISABLE_X) && (x_active == 0)) disable_x();
if((DISABLE_Y) && (y_active == 0)) disable_y();
if((DISABLE_Z) && (z_active == 0)) disable_z();
if((DISABLE_E) && (e_active == 0))
{
disable_e0();
disable_e1();
disable_e2();
}
if((DISABLE_E) && (e_active == 0)) disable_e0();
#if defined(FAN_PIN) && FAN_PIN > -1
#ifdef FAN_KICKSTART_TIME
static unsigned long fan_kick_end;
@ -825,9 +820,16 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate
target[Z_AXIS] = lround(z*cs.axis_steps_per_unit[Z_AXIS]);
#endif // ENABLE_MESH_BED_LEVELING
target[E_AXIS] = lround(e*cs.axis_steps_per_unit[E_AXIS]);
// Calculate subtraction to re-use result in many places
// This saves memory and speeds up calculations
int32_t de = target[E_AXIS] - position[E_AXIS];
int32_t dx = target[X_AXIS] - position[X_AXIS];
int32_t dy = target[Y_AXIS] - position[Y_AXIS];
int32_t dz = target[Z_AXIS] - position[Z_AXIS];
#ifdef PREVENT_DANGEROUS_EXTRUDE
if(target[E_AXIS]!=position[E_AXIS])
if(de)
{
if((int)degHotend(active_extruder)<extrude_min_temp)
{
@ -835,17 +837,19 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate
#ifdef LIN_ADVANCE
position_float[E_AXIS] = e;
#endif
de = 0; // no difference
SERIAL_ECHO_START;
SERIAL_ECHOLNRPGM(_n(" cold extrusion prevented"));////MSG_ERR_COLD_EXTRUDE_STOP
}
#ifdef PREVENT_LENGTHY_EXTRUDE
if(labs(target[E_AXIS]-position[E_AXIS])>cs.axis_steps_per_unit[E_AXIS]*EXTRUDE_MAXLENGTH)
if(labs(de) > cs.axis_steps_per_unit[E_AXIS]*EXTRUDE_MAXLENGTH)
{
position[E_AXIS]=target[E_AXIS]; //behave as if the move really took place, but ignore E part
#ifdef LIN_ADVANCE
position_float[E_AXIS] = e;
#endif
de = 0; // no difference
SERIAL_ECHO_START;
SERIAL_ECHOLNRPGM(_n(" too long extrusion prevented"));////MSG_ERR_LONG_EXTRUDE_STOP
}
@ -856,16 +860,16 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate
// Number of steps for each axis
#ifndef COREXY
// default non-h-bot planning
block->steps_x.wide = labs(target[X_AXIS]-position[X_AXIS]);
block->steps_y.wide = labs(target[Y_AXIS]-position[Y_AXIS]);
block->steps_x.wide = labs(dx);
block->steps_y.wide = labs(dy);
#else
// corexy planning
// these equations follow the form of the dA and dB equations on http://www.corexy.com/theory.html
block->steps_x.wide = labs((target[X_AXIS]-position[X_AXIS]) + (target[Y_AXIS]-position[Y_AXIS]));
block->steps_y.wide = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-position[Y_AXIS]));
block->steps_x.wide = labs(dx + dy);
block->steps_y.wide = labs(dx - dy);
#endif
block->steps_z.wide = labs(target[Z_AXIS]-position[Z_AXIS]);
block->steps_e.wide = labs(target[E_AXIS]-position[E_AXIS]);
block->steps_z.wide = labs(dz);
block->steps_e.wide = labs(de);
block->step_event_count.wide = max(block->steps_x.wide, max(block->steps_y.wide, max(block->steps_z.wide, block->steps_e.wide)));
// Bail if this is a zero-length block
@ -879,35 +883,17 @@ block->steps_y.wide = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-p
block->fan_speed = fanSpeed;
// Compute direction bits for this block
// Compute direction bits for this block
block->direction_bits = 0;
#ifndef COREXY
if (target[X_AXIS] < position[X_AXIS])
{
block->direction_bits |= (1<<X_AXIS);
}
if (target[Y_AXIS] < position[Y_AXIS])
{
block->direction_bits |= (1<<Y_AXIS);
}
if (dx < 0) block->direction_bits |= _BV(X_AXIS);
if (dy < 0) block->direction_bits |= _BV(Y_AXIS);
#else
if ((target[X_AXIS]-position[X_AXIS]) + (target[Y_AXIS]-position[Y_AXIS]) < 0)
{
block->direction_bits |= (1<<X_AXIS);
}
if ((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-position[Y_AXIS]) < 0)
{
block->direction_bits |= (1<<Y_AXIS);
}
if (dx + dy < 0) block->direction_bits |= _BV(X_AXIS);
if (dx - dy < 0) block->direction_bits |= _BV(Y_AXIS);
#endif
if (target[Z_AXIS] < position[Z_AXIS])
{
block->direction_bits |= (1<<Z_AXIS);
}
if (target[E_AXIS] < position[E_AXIS])
{
block->direction_bits |= (1<<E_AXIS);
}
if (dz < 0) block->direction_bits |= _BV(Z_AXIS);
if (de < 0) block->direction_bits |= _BV(E_AXIS);
//enable active axes
#ifdef COREXY
@ -941,17 +927,17 @@ Having the real displacement of the head, we can calculate the total movement le
*/
#ifndef COREXY
float delta_mm[4];
delta_mm[X_AXIS] = (target[X_AXIS]-position[X_AXIS])/cs.axis_steps_per_unit[X_AXIS];
delta_mm[Y_AXIS] = (target[Y_AXIS]-position[Y_AXIS])/cs.axis_steps_per_unit[Y_AXIS];
delta_mm[X_AXIS] = dx / cs.axis_steps_per_unit[X_AXIS];
delta_mm[Y_AXIS] = dy / cs.axis_steps_per_unit[Y_AXIS];
#else
float delta_mm[6];
delta_mm[X_HEAD] = (target[X_AXIS]-position[X_AXIS])/cs.axis_steps_per_unit[X_AXIS];
delta_mm[Y_HEAD] = (target[Y_AXIS]-position[Y_AXIS])/cs.axis_steps_per_unit[Y_AXIS];
delta_mm[X_AXIS] = ((target[X_AXIS]-position[X_AXIS]) + (target[Y_AXIS]-position[Y_AXIS]))/cs.axis_steps_per_unit[X_AXIS];
delta_mm[Y_AXIS] = ((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-position[Y_AXIS]))/cs.axis_steps_per_unit[Y_AXIS];
delta_mm[X_HEAD] = dx / cs.axis_steps_per_unit[X_AXIS];
delta_mm[Y_HEAD] = dy / cs.axis_steps_per_unit[Y_AXIS];
delta_mm[X_AXIS] = (dx + dy) / cs.axis_steps_per_unit[X_AXIS];
delta_mm[Y_AXIS] = (dx - dy) / cs.axis_steps_per_unit[Y_AXIS];
#endif
delta_mm[Z_AXIS] = (target[Z_AXIS]-position[Z_AXIS])/cs.axis_steps_per_unit[Z_AXIS];
delta_mm[E_AXIS] = (target[E_AXIS]-position[E_AXIS])/cs.axis_steps_per_unit[E_AXIS];
delta_mm[Z_AXIS] = dz / cs.axis_steps_per_unit[Z_AXIS];
delta_mm[E_AXIS] = de / cs.axis_steps_per_unit[E_AXIS];
if ( block->steps_x.wide <=dropsegments && block->steps_y.wide <=dropsegments && block->steps_z.wide <=dropsegments )
{
block->millimeters = fabs(delta_mm[E_AXIS]);
@ -1017,17 +1003,17 @@ Having the real displacement of the head, we can calculate the total movement le
// block->step_event_count ... event count of the fastest axis
// block->millimeters ... Euclidian length of the XYZ movement or the E length, if no XYZ movement.
float steps_per_mm = block->step_event_count.wide/block->millimeters;
uint32_t accel;
if(block->steps_x.wide == 0 && block->steps_y.wide == 0 && block->steps_z.wide == 0)
{
block->acceleration_st = ceil(cs.retract_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
accel = ceil(cs.retract_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
#ifdef LIN_ADVANCE
block->use_advance_lead = false;
#endif
}
else
{
float acceleration = (block->steps_e.wide == 0? cs.travel_acceleration: cs.acceleration);
block->acceleration_st = ceil(acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
accel = ceil((block->steps_e.wide ? cs.acceleration : cs.travel_acceleration) * steps_per_mm); // convert to: acceleration steps/sec^2
#ifdef LIN_ADVANCE
/**
@ -1063,9 +1049,9 @@ Having the real displacement of the head, we can calculate the total movement le
if (e_D_ratio > 3.0)
block->use_advance_lead = false;
else if (e_D_ratio > 0) {
const float max_accel_per_s2 = cs.max_jerk[E_AXIS] / (extruder_advance_K * e_D_ratio);
if (cs.acceleration > max_accel_per_s2) {
block->acceleration_st = ceil(max_accel_per_s2 * steps_per_mm);
const uint32_t max_accel_steps_per_s2 = ceil(cs.max_jerk[E_AXIS] / (extruder_advance_K * e_D_ratio) * steps_per_mm);
if (accel > max_accel_steps_per_s2) {
accel = max_accel_steps_per_s2;
#ifdef LA_DEBUG
SERIAL_ECHOLNPGM("LA: Block acceleration limited due to max E-jerk");
#endif
@ -1076,35 +1062,19 @@ Having the real displacement of the head, we can calculate the total movement le
// Limit acceleration per axis
//FIXME Vojtech: One shall rather limit a projection of the acceleration vector instead of using the limit.
if(((float)block->acceleration_st * (float)block->steps_x.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[X_AXIS])
{ block->acceleration_st = axis_steps_per_sqr_second[X_AXIS]; }
if(((float)block->acceleration_st * (float)block->steps_y.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[Y_AXIS])
{ block->acceleration_st = axis_steps_per_sqr_second[Y_AXIS]; }
if(((float)block->acceleration_st * (float)block->steps_e.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[E_AXIS])
{ block->acceleration_st = axis_steps_per_sqr_second[E_AXIS]; }
if(((float)block->acceleration_st * (float)block->steps_z.wide / (float)block->step_event_count.wide ) > axis_steps_per_sqr_second[Z_AXIS])
{ block->acceleration_st = axis_steps_per_sqr_second[Z_AXIS]; }
if(((float)accel * (float)block->steps_x.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[X_AXIS])
{ accel = axis_steps_per_sqr_second[X_AXIS]; }
if(((float)accel * (float)block->steps_y.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[Y_AXIS])
{ accel = axis_steps_per_sqr_second[Y_AXIS]; }
if(((float)accel * (float)block->steps_e.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[E_AXIS])
{ accel = axis_steps_per_sqr_second[E_AXIS]; }
if(((float)accel * (float)block->steps_z.wide / (float)block->step_event_count.wide ) > axis_steps_per_sqr_second[Z_AXIS])
{ accel = axis_steps_per_sqr_second[Z_AXIS]; }
}
// Acceleration of the segment, in mm/sec^2
block->acceleration = block->acceleration_st / steps_per_mm;
#if 0
// Oversample diagonal movements by a power of 2 up to 8x
// to achieve more accurate diagonal movements.
uint8_t bresenham_oversample = 1;
for (uint8_t i = 0; i < 3; ++ i) {
if (block->nominal_rate >= 5000) // 5kHz
break;
block->nominal_rate << 1;
bresenham_oversample << 1;
block->step_event_count << 1;
}
if (bresenham_oversample > 1)
// Lower the acceleration steps/sec^2 to account for the oversampling.
block->acceleration_st = (block->acceleration_st + (bresenham_oversample >> 1)) / bresenham_oversample;
#endif
block->acceleration_rate = ((float)block->acceleration_st * (16777216.0 / (F_CPU / 8.0)));
block->acceleration_steps_per_s2 = accel;
block->acceleration = accel / steps_per_mm;
block->acceleration_rate = (uint32_t)(accel * (float(1UL << 24) / ((F_CPU) / 8.0f)));
// Start with a safe speed.
// Safe speed is the speed, from which the machine may halt to stop immediately.
@ -1420,10 +1390,6 @@ void update_mode_profile()
}
#endif //TMC2130
uint8_t number_of_blocks()
{
return (block_buffer_head + BLOCK_BUFFER_SIZE - block_buffer_tail) & (BLOCK_BUFFER_SIZE - 1);
}
#ifdef PLANNER_DIAGNOSTICS
uint8_t planner_queue_min()
{

View File

@ -99,12 +99,11 @@ typedef struct {
// Settings for the trapezoid generator (runs inside an interrupt handler).
// Changing the following values in the planner needs to be synchronized with the interrupt handler by disabling the interrupts.
unsigned long nominal_rate; // The nominal step rate for this block in step_events/sec
unsigned long initial_rate; // The jerk-adjusted step rate at start of block
unsigned long final_rate; // The minimal rate at exit
unsigned long acceleration_st; // acceleration steps/sec^2
//FIXME does it have to be int? Probably uint8_t would be just fine. Need to change in other places as well
int fan_speed;
uint32_t nominal_rate; // The nominal step rate for this block in step_events/sec
uint32_t initial_rate; // The jerk-adjusted step rate at start of block
uint32_t final_rate; // The minimal rate at exit
uint32_t acceleration_steps_per_s2; // acceleration steps/sec^2
uint8_t fan_speed; // Print fan speed, ranges from 0 to 255
volatile char busy;
@ -274,8 +273,6 @@ void reset_acceleration_rates();
void update_mode_profile();
uint8_t number_of_blocks();
// #define PLANNER_DIAGNOSTICS
#ifdef PLANNER_DIAGNOSTICS
// Diagnostic functions to display planner buffer underflow on the display.

View File

@ -1073,10 +1073,10 @@ void st_init()
{
#ifdef TMC2130
tmc2130_init(TMCInitParams(false, FarmOrUserECool()));
#endif //TMC2130
#else
st_current_init(); //Initialize Digipot Motor Current
microstep_init(); //Initialize Microstepping Pins
#endif //TMC2130
//Initialize Dir Pins
#if defined(X_DIR_PIN) && X_DIR_PIN > -1
@ -1102,12 +1102,6 @@ void st_init()
#if defined(E0_DIR_PIN) && E0_DIR_PIN > -1
SET_OUTPUT(E0_DIR_PIN);
#endif
#if defined(E1_DIR_PIN) && (E1_DIR_PIN > -1)
SET_OUTPUT(E1_DIR_PIN);
#endif
#if defined(E2_DIR_PIN) && (E2_DIR_PIN > -1)
SET_OUTPUT(E2_DIR_PIN);
#endif
//Initialize Enable Pins - steppers default to disabled.
@ -1141,14 +1135,6 @@ void st_init()
SET_OUTPUT(E0_ENABLE_PIN);
if(!E_ENABLE_ON) WRITE(E0_ENABLE_PIN,HIGH);
#endif
#if defined(E1_ENABLE_PIN) && (E1_ENABLE_PIN > -1)
SET_OUTPUT(E1_ENABLE_PIN);
if(!E_ENABLE_ON) WRITE(E1_ENABLE_PIN,HIGH);
#endif
#if defined(E2_ENABLE_PIN) && (E2_ENABLE_PIN > -1)
SET_OUTPUT(E2_ENABLE_PIN);
if(!E_ENABLE_ON) WRITE(E2_ENABLE_PIN,HIGH);
#endif
//endstops and pullups
#if defined(X_MIN_PIN) && X_MIN_PIN > -1
@ -1246,16 +1232,6 @@ void st_init()
WRITE(E0_STEP_PIN,INVERT_E_STEP_PIN);
disable_e0();
#endif
#if defined(E1_STEP_PIN) && (E1_STEP_PIN > -1)
SET_OUTPUT(E1_STEP_PIN);
WRITE(E1_STEP_PIN,INVERT_E_STEP_PIN);
disable_e1();
#endif
#if defined(E2_STEP_PIN) && (E2_STEP_PIN > -1)
SET_OUTPUT(E2_STEP_PIN);
WRITE(E2_STEP_PIN,INVERT_E_STEP_PIN);
disable_e2();
#endif
// waveform generation = 0100 = CTC
TCCR1B &= ~(1<<WGM13);
@ -1513,6 +1489,7 @@ void digitalPotWrite(int address, int value) // From Arduino DigitalPotControl e
}
#endif
#ifndef TMC2130
void st_current_init() //Initialize Digipot Motor Current
{
#ifdef MOTOR_CURRENT_PWM_XY_PIN
@ -1542,8 +1519,6 @@ void st_current_init() //Initialize Digipot Motor Current
#endif
}
#ifdef MOTOR_CURRENT_PWM_XY_PIN
void st_current_set(uint8_t driver, int current)
{
@ -1577,9 +1552,6 @@ void microstep_init()
#endif
}
#ifndef TMC2130
void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2)
{
if(ms1 > -1) switch(driver)
@ -1637,4 +1609,4 @@ void microstep_readings()
SERIAL_PROTOCOLLN( READ(E1_MS2_PIN));
#endif
}
#endif //TMC2130
#endif //!TMC2130

View File

@ -76,12 +76,15 @@ void quickStop();
#if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1
void digitalPotWrite(int address, int value);
#endif //defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1
#ifndef TMC2130
void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2);
void microstep_mode(uint8_t driver, uint8_t stepping);
void st_current_init();
void st_current_set(uint8_t driver, int current);
void microstep_init();
void microstep_readings();
#endif //!TMC2130
#ifdef BABYSTEPPING
void babystep(const uint8_t axis,const bool direction); // perform a short step with a single stepper motor, outside of any convention

178
Firmware/strtod.c Normal file
View File

@ -0,0 +1,178 @@
// Note -- This is a modified stdtod() method, to prevent the catching of uppercase "E", used in 3D printing g-code.
#if !defined(__AVR_TINY__)
#include <avr/pgmspace.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <math.h> /* INFINITY, NAN */
#include <stdlib.h>
/* Only GCC 4.2 calls the library function to convert an unsigned long
to float. Other GCC-es (including 4.3) use a signed long to float
conversion along with a large inline code to correct the result. */
extern double __floatunsisf(unsigned long);
PROGMEM static const float pwr_p10[6] = {
1e+1, 1e+2, 1e+4, 1e+8, 1e+16, 1e+32
};
PROGMEM static const float pwr_m10[6] = {
1e-1, 1e-2, 1e-4, 1e-8, 1e-16, 1e-32
};
/* PSTR() is not used to save 1 byte per string: '\0' at the tail. */
PROGMEM static const char pstr_inf[] = { 'I','N','F' };
PROGMEM static const char pstr_inity[] = { 'I','N','I','T','Y' };
PROGMEM static const char pstr_nan[] = { 'N','A','N' };
double strtod_noE(const char* nptr, char** endptr)
{
union {
unsigned long u32;
float flt;
} x;
unsigned char c;
int exp;
unsigned char flag;
#define FL_MINUS 0x01 /* number is negative */
#define FL_ANY 0x02 /* any digit was readed */
#define FL_OVFL 0x04 /* overflow was */
#define FL_DOT 0x08 /* decimal '.' was */
#define FL_MEXP 0x10 /* exponent 'e' is neg. */
if (endptr)
*endptr = (char*)nptr;
do {
c = *nptr++;
} while (isspace(c));
flag = 0;
if (c == '-') {
flag = FL_MINUS;
c = *nptr++;
}
else if (c == '+') {
c = *nptr++;
}
if (!strncasecmp_P(nptr - 1, pstr_inf, 3)) {
nptr += 2;
if (!strncasecmp_P(nptr, pstr_inity, 5))
nptr += 5;
if (endptr)
*endptr = (char*)nptr;
return flag & FL_MINUS ? -INFINITY : +INFINITY;
}
/* NAN() construction is not realised.
Length would be 3 characters only. */
if (!strncasecmp_P(nptr - 1, pstr_nan, 3)) {
if (endptr)
*endptr = (char*)nptr + 2;
return NAN;
}
x.u32 = 0;
exp = 0;
while (1) {
c -= '0';
if (c <= 9) {
flag |= FL_ANY;
if (flag & FL_OVFL) {
if (!(flag & FL_DOT))
exp += 1;
}
else {
if (flag & FL_DOT)
exp -= 1;
/* x.u32 = x.u32 * 10 + c */
x.u32 = (((x.u32 << 2) + x.u32) << 1) + c;
if (x.u32 >= (ULONG_MAX - 9) / 10)
flag |= FL_OVFL;
}
}
else if (c == (('.' - '0') & 0xff) && !(flag & FL_DOT)) {
flag |= FL_DOT;
}
else {
break;
}
c = *nptr++;
}
// Check for exponent "E", but disable capital E
if (c == (('e' - '0') & 0xff) /*|| c == (('E' - '0') & 0xff)*/)
{
int i;
c = *nptr++;
i = 2;
if (c == '-') {
flag |= FL_MEXP;
c = *nptr++;
}
else if (c == '+') {
c = *nptr++;
}
else {
i = 1;
}
c -= '0';
if (c > 9) {
nptr -= i;
}
else {
i = 0;
do {
if (i < 3200)
i = (((i << 2) + i) << 1) + c; /* i = 10*i + c */
c = *nptr++ - '0';
} while (c <= 9);
if (flag & FL_MEXP)
i = -i;
exp += i;
}
}
if ((flag & FL_ANY) && endptr)
*endptr = (char*)nptr - 1;
x.flt = __floatunsisf(x.u32); /* manually */
if ((flag & FL_MINUS) && (flag & FL_ANY))
x.flt = -x.flt;
if (x.flt != 0) {
int pwr;
if (exp < 0) {
nptr = (void*)(pwr_m10 + 5);
exp = -exp;
}
else {
nptr = (void*)(pwr_p10 + 5);
}
for (pwr = 32; pwr; pwr >>= 1) {
for (; exp >= pwr; exp -= pwr) {
union {
unsigned long u32;
float flt;
} y;
y.u32 = pgm_read_dword((float*)nptr);
x.flt *= y.flt;
}
nptr -= sizeof(float);
}
if (!isfinite(x.flt) || x.flt == 0)
errno = ERANGE;
}
return x.flt;
}
#endif

View File

@ -189,21 +189,13 @@ static volatile bool temp_meas_ready = false;
#endif
uint8_t fanSpeedBckp = 255;
#if EXTRUDERS > 3
# error Unsupported number of extruders
#elif EXTRUDERS > 2
# define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1, v2, v3 }
#elif EXTRUDERS > 1
# define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1, v2 }
#else
# define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1 }
#endif
#define ARRAY_BY_EXTRUDERS(v1 ) { v1 }
// Init min and max temp with extreme values to prevent false errors during startup
static int minttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP );
static int maxttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP );
static int minttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 0, 0, 0 );
static int maxttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 16383, 16383, 16383 );
static int minttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_LO_TEMP );
static int maxttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_HI_TEMP );
static int minttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 0 );
static int maxttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 16383 );
#ifdef BED_MINTEMP
static int bed_minttemp_raw = HEATER_BED_RAW_LO_TEMP;
#endif
@ -217,8 +209,8 @@ static int ambient_minttemp_raw = AMBIENT_RAW_LO_TEMP;
static int ambient_maxttemp_raw = AMBIENT_RAW_HI_TEMP;
#endif
static void *heater_ttbl_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( (void *)HEATER_0_TEMPTABLE, (void *)HEATER_1_TEMPTABLE, (void *)HEATER_2_TEMPTABLE );
static uint8_t heater_ttbllen_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN, HEATER_2_TEMPTABLE_LEN );
static void *heater_ttbl_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( (void *)HEATER_0_TEMPTABLE );
static uint8_t heater_ttbllen_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_TEMPTABLE_LEN );
static float analog2temp(int raw, uint8_t e);
static float analog2tempBed(int raw);
@ -252,14 +244,6 @@ static void temp_runaway_check(uint8_t _heater_id, float _target_temperature, fl
static void temp_runaway_stop(bool isPreheat, bool isBed);
#endif
// return "false", if all extruder-heaters are 'off' (ie. "true", if any heater is 'on')
bool checkAllHotends(void)
{
bool result=false;
for(int i=0;i<EXTRUDERS;i++) result=(result||(target_temperature[i]!=0));
return(result);
}
// WARNING: the following function has been marked noinline to avoid a GCC 4.9.2 LTO
// codegen bug causing a stack overwrite issue in process_commands()
void __attribute__((noinline)) PID_autotune(float temp, int extruder, int ncycles)
@ -598,7 +582,7 @@ static float analog2temp(int raw, uint8_t e) {
SERIAL_ERROR_START;
SERIAL_ERROR((int)e);
SERIAL_ERRORLNPGM(" - Invalid extruder number !");
kill(NULL, 6);
kill();
return 0.0;
}
#ifdef HEATER_0_USES_MAX6675
@ -714,7 +698,7 @@ static float analog2tempAmbient(int raw)
void soft_pwm_init()
{
#if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))
#if MB(RUMBA) && ((TEMP_SENSOR_0==-1) || (TEMP_SENSOR_BED==-1))
//disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector
MCUCR=(1<<JTD);
MCUCR=(1<<JTD);
@ -736,13 +720,7 @@ void soft_pwm_init()
#if defined(HEATER_0_PIN) && (HEATER_0_PIN > -1)
SET_OUTPUT(HEATER_0_PIN);
#endif
#if defined(HEATER_1_PIN) && (HEATER_1_PIN > -1)
SET_OUTPUT(HEATER_1_PIN);
#endif
#if defined(HEATER_2_PIN) && (HEATER_2_PIN > -1)
SET_OUTPUT(HEATER_2_PIN);
#endif
#endif
#if defined(HEATER_BED_PIN) && (HEATER_BED_PIN > -1)
SET_OUTPUT(HEATER_BED_PIN);
#endif
@ -797,48 +775,6 @@ void soft_pwm_init()
}
#endif //MAXTEMP
#if (EXTRUDERS > 1) && defined(HEATER_1_MINTEMP)
minttemp[1] = HEATER_1_MINTEMP;
while(analog2temp(minttemp_raw[1], 1) < HEATER_1_MINTEMP) {
#if HEATER_1_RAW_LO_TEMP < HEATER_1_RAW_HI_TEMP
minttemp_raw[1] += OVERSAMPLENR;
#else
minttemp_raw[1] -= OVERSAMPLENR;
#endif
}
#endif // MINTEMP 1
#if (EXTRUDERS > 1) && defined(HEATER_1_MAXTEMP)
maxttemp[1] = HEATER_1_MAXTEMP;
while(analog2temp(maxttemp_raw[1], 1) > HEATER_1_MAXTEMP) {
#if HEATER_1_RAW_LO_TEMP < HEATER_1_RAW_HI_TEMP
maxttemp_raw[1] -= OVERSAMPLENR;
#else
maxttemp_raw[1] += OVERSAMPLENR;
#endif
}
#endif //MAXTEMP 1
#if (EXTRUDERS > 2) && defined(HEATER_2_MINTEMP)
minttemp[2] = HEATER_2_MINTEMP;
while(analog2temp(minttemp_raw[2], 2) < HEATER_2_MINTEMP) {
#if HEATER_2_RAW_LO_TEMP < HEATER_2_RAW_HI_TEMP
minttemp_raw[2] += OVERSAMPLENR;
#else
minttemp_raw[2] -= OVERSAMPLENR;
#endif
}
#endif //MINTEMP 2
#if (EXTRUDERS > 2) && defined(HEATER_2_MAXTEMP)
maxttemp[2] = HEATER_2_MAXTEMP;
while(analog2temp(maxttemp_raw[2], 2) > HEATER_2_MAXTEMP) {
#if HEATER_2_RAW_LO_TEMP < HEATER_2_RAW_HI_TEMP
maxttemp_raw[2] -= OVERSAMPLENR;
#else
maxttemp_raw[2] += OVERSAMPLENR;
#endif
}
#endif //MAXTEMP 2
#ifdef BED_MINTEMP
while(analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) {
#if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP
@ -944,17 +880,6 @@ static void temp_runaway_check(uint8_t _heater_id, float _target_temperature, fl
__preheat_counter[_heater_id]++;
if (__preheat_counter[_heater_id] > ((_isbed) ? 16 : 8)) // periodicaly check if current temperature changes
{
/*SERIAL_ECHOPGM("Heater:");
MYSERIAL.print(_heater_id);
SERIAL_ECHOPGM(" T:");
MYSERIAL.print(_current_temperature);
SERIAL_ECHOPGM(" Tstart:");
MYSERIAL.print(__preheat_start[_heater_id]);
SERIAL_ECHOPGM(" delta:");
MYSERIAL.print(_current_temperature-__preheat_start[_heater_id]);*/
//-// if (_current_temperature - __preheat_start[_heater_id] < 2) {
//-// if (_current_temperature - __preheat_start[_heater_id] < ((_isbed && (_current_temperature>105.0))?0.6:2.0)) {
__delta=2.0;
if(_isbed)
{
@ -964,11 +889,7 @@ static void temp_runaway_check(uint8_t _heater_id, float _target_temperature, fl
}
if (_current_temperature - __preheat_start[_heater_id] < __delta) {
__preheat_errors[_heater_id]++;
/*SERIAL_ECHOPGM(" Preheat errors:");
MYSERIAL.println(__preheat_errors[_heater_id]);*/
}
else {
//SERIAL_ECHOLNPGM("");
} else {
__preheat_errors[_heater_id] = 0;
}
@ -980,12 +901,8 @@ static void temp_runaway_check(uint8_t _heater_id, float _target_temperature, fl
}
}
//-// if (_current_temperature >= _target_temperature && temp_runaway_status[_heater_id] == TempRunaway_PREHEAT)
if ((_current_temperature > (_target_temperature - __hysteresis)) && temp_runaway_status[_heater_id] == TempRunaway_PREHEAT)
{
/*SERIAL_ECHOPGM("Heater:");
MYSERIAL.print(_heater_id);
MYSERIAL.println(" ->tempRunaway");*/
temp_runaway_status[_heater_id] = TempRunaway_ACTIVE;
temp_runaway_check_active = false;
temp_runaway_error_counter[_heater_id] = 0;
@ -1210,28 +1127,11 @@ FORCE_INLINE static void soft_pwm_core()
static unsigned char slow_pwm_count = 0;
static unsigned char state_heater_0 = 0;
static unsigned char state_timer_heater_0 = 0;
#endif
#if (EXTRUDERS > 1) || defined(HEATERS_PARALLEL)
static unsigned char soft_pwm_1;
#ifdef SLOW_PWM_HEATERS
static unsigned char state_heater_1 = 0;
static unsigned char state_timer_heater_1 = 0;
#endif
#endif
#if EXTRUDERS > 2
static unsigned char soft_pwm_2;
#ifdef SLOW_PWM_HEATERS
static unsigned char state_heater_2 = 0;
static unsigned char state_timer_heater_2 = 0;
#endif
#endif
#if HEATER_BED_PIN > -1
// @@DR static unsigned char soft_pwm_b;
#ifdef SLOW_PWM_HEATERS
static unsigned char state_heater_b = 0;
static unsigned char state_timer_heater_b = 0;
#endif
#endif
#endif // HEATER_BED_PIN > -1
#endif // SLOW_PWM_HEATERS
#ifndef SLOW_PWM_HEATERS
/*
@ -1247,14 +1147,6 @@ FORCE_INLINE static void soft_pwm_core()
WRITE(HEATER_1_PIN,1);
#endif
} else WRITE(HEATER_0_PIN,0);
#if EXTRUDERS > 1
soft_pwm_1 = soft_pwm[1];
if(soft_pwm_1 > 0) WRITE(HEATER_1_PIN,1); else WRITE(HEATER_1_PIN,0);
#endif
#if EXTRUDERS > 2
soft_pwm_2 = soft_pwm[2];
if(soft_pwm_2 > 0) WRITE(HEATER_2_PIN,1); else WRITE(HEATER_2_PIN,0);
#endif
}
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
@ -1291,13 +1183,6 @@ FORCE_INLINE static void soft_pwm_core()
#endif
}
#if EXTRUDERS > 1
if(soft_pwm_1 < pwm_count) WRITE(HEATER_1_PIN,0);
#endif
#if EXTRUDERS > 2
if(soft_pwm_2 < pwm_count) WRITE(HEATER_2_PIN,0);
#endif
#if 0 // @@DR
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
if (soft_pwm_b < (pwm_count & ((1 << HEATER_BED_SOFT_PWM_BITS) - 1))){
@ -1352,59 +1237,7 @@ FORCE_INLINE static void soft_pwm_core()
#endif
}
}
#if EXTRUDERS > 1
// EXTRUDER 1
soft_pwm_1 = soft_pwm[1];
if (soft_pwm_1 > 0) {
// turn ON heather only if the minimum time is up
if (state_timer_heater_1 == 0) {
// if change state set timer
if (state_heater_1 == 0) {
state_timer_heater_1 = MIN_STATE_TIME;
}
state_heater_1 = 1;
WRITE(HEATER_1_PIN, 1);
}
} else {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_1 == 0) {
// if change state set timer
if (state_heater_1 == 1) {
state_timer_heater_1 = MIN_STATE_TIME;
}
state_heater_1 = 0;
WRITE(HEATER_1_PIN, 0);
}
}
#endif
#if EXTRUDERS > 2
// EXTRUDER 2
soft_pwm_2 = soft_pwm[2];
if (soft_pwm_2 > 0) {
// turn ON heather only if the minimum time is up
if (state_timer_heater_2 == 0) {
// if change state set timer
if (state_heater_2 == 0) {
state_timer_heater_2 = MIN_STATE_TIME;
}
state_heater_2 = 1;
WRITE(HEATER_2_PIN, 1);
}
} else {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_2 == 0) {
// if change state set timer
if (state_heater_2 == 1) {
state_timer_heater_2 = MIN_STATE_TIME;
}
state_heater_2 = 0;
WRITE(HEATER_2_PIN, 0);
}
}
#endif
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
// BED
soft_pwm_b = soft_pwm_bed;
@ -1447,37 +1280,7 @@ FORCE_INLINE static void soft_pwm_core()
#endif
}
}
#if EXTRUDERS > 1
// EXTRUDER 1
if (soft_pwm_1 < slow_pwm_count) {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_1 == 0) {
// if change state set timer
if (state_heater_1 == 1) {
state_timer_heater_1 = MIN_STATE_TIME;
}
state_heater_1 = 0;
WRITE(HEATER_1_PIN, 0);
}
}
#endif
#if EXTRUDERS > 2
// EXTRUDER 2
if (soft_pwm_2 < slow_pwm_count) {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_2 == 0) {
// if change state set timer
if (state_heater_2 == 1) {
state_timer_heater_2 = MIN_STATE_TIME;
}
state_heater_2 = 0;
WRITE(HEATER_2_PIN, 0);
}
}
#endif
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
// BED
if (soft_pwm_b < slow_pwm_count) {
@ -1512,20 +1315,8 @@ FORCE_INLINE static void soft_pwm_core()
// Extruder 0
if (state_timer_heater_0 > 0) {
state_timer_heater_0--;
}
#if EXTRUDERS > 1
// Extruder 1
if (state_timer_heater_1 > 0)
state_timer_heater_1--;
#endif
#if EXTRUDERS > 2
// Extruder 2
if (state_timer_heater_2 > 0)
state_timer_heater_2--;
#endif
}
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
// Bed
if (state_timer_heater_b > 0)
@ -2093,9 +1884,9 @@ void adc_callback()
#ifdef VOLT_BED_PIN
current_voltage_raw_bed = adc_values[ADC_PIN_IDX(VOLT_BED_PIN)]; // 6->9
#endif
#ifdef IR_SENSOR_ANALOG
current_voltage_raw_IR = adc_values[ADC_PIN_IDX(VOLT_IR_PIN)];
#endif //IR_SENSOR_ANALOG
#if defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_IR_ANALOG)
fsensor.voltUpdate(adc_values[ADC_PIN_IDX(VOLT_IR_PIN)]);
#endif //defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_IR_ANALOG)
adc_values_ready = true;
}
@ -2222,12 +2013,6 @@ void disable_heater()
#if defined(HEATER_0_PIN) && HEATER_0_PIN > -1 && EXTRUDERS > 0
WRITE(HEATER_0_PIN,LOW);
#endif
#if defined(HEATER_1_PIN) && HEATER_1_PIN > -1 && EXTRUDERS > 1
WRITE(HEATER_1_PIN,LOW);
#endif
#if defined(HEATER_2_PIN) && HEATER_2_PIN > -1 && EXTRUDERS > 2
WRITE(HEATER_2_PIN,LOW);
#endif
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
// TODO: this doesn't take immediate effect!
timer02_set_pwm0(0);
@ -2261,7 +2046,7 @@ static void check_min_temp_raw()
if(target_temperature_isr[active_extruder]>minttemp[active_extruder]) {
// ~ nozzle heating is on
bCheckingOnHeater=bCheckingOnHeater||(current_temperature_isr[active_extruder]>(minttemp[active_extruder]+TEMP_HYSTERESIS)); // for eventually delay cutting
if(oTimer4minTempHeater.expired(HEATER_MINTEMP_DELAY)||(!oTimer4minTempHeater.running())||bCheckingOnHeater) {
if(oTimer4minTempHeater.expired_cont(HEATER_MINTEMP_DELAY) || bCheckingOnHeater) {
bCheckingOnHeater=true; // not necessary
check_min_temp_heater0(); // delay is elapsed or temperature is/was over minTemp => periodical checking is active
}
@ -2275,7 +2060,7 @@ static void check_min_temp_raw()
if(target_temperature_bed_isr>BED_MINTEMP) {
// ~ bed heating is on
bCheckingOnBed=bCheckingOnBed||(current_temperature_bed_isr>(BED_MINTEMP+TEMP_HYSTERESIS)); // for eventually delay cutting
if(oTimer4minTempBed.expired(BED_MINTEMP_DELAY)||(!oTimer4minTempBed.running())||bCheckingOnBed) {
if(oTimer4minTempBed.expired_cont(BED_MINTEMP_DELAY) || bCheckingOnBed) {
bCheckingOnBed=true; // not necessary
check_min_temp_bed(); // delay is elapsed or temperature is/was over minTemp => periodical checking is active
}

View File

@ -30,8 +30,6 @@ void temp_mgr_init(); //initialize the temperature handler
void manage_heater(); //it is critical that this is called periodically.
bool get_temp_error(); //return true if any thermal error is set
extern bool checkAllHotends(void);
// low level conversion routines
// do not use these routines and variables outside of temperature.cpp
extern int target_temperature[EXTRUDERS];
@ -62,10 +60,6 @@ extern int current_voltage_raw_pwr;
extern int current_voltage_raw_bed;
#endif
#ifdef IR_SENSOR_ANALOG
extern uint16_t current_voltage_raw_IR;
#endif //IR_SENSOR_ANALOG
extern bool bedPWMDisabled;
#ifdef PIDTEMP
@ -160,7 +154,7 @@ FORCE_INLINE bool isCoolingBed() {
#define isCoolingHotend0() isCoolingHotend(0)
// return "false", if all heaters are 'off' (ie. "true", if any heater is 'on')
#define CHECK_ALL_HEATERS (checkAllHotends()||(target_temperature_bed!=0))
#define CHECK_ALL_HEATERS ((target_temperature[0] != 0) || (target_temperature_bed != 0))
int getHeaterPower(int heater);
void disable_heater(); // Disable all heaters *instantaneously*

View File

@ -6,7 +6,7 @@
#define OVERSAMPLENR 16
#if (THERMISTORHEATER_0 == 1) || (THERMISTORHEATER_1 == 1) || (THERMISTORHEATER_2 == 1) || (THERMISTORBED == 1) //100k bed thermistor
#if (THERMISTORHEATER_0 == 1) || (THERMISTORBED == 1) //100k bed thermistor
const short temptable_1[][2] PROGMEM = {
{ 23*OVERSAMPLENR , 300 },
@ -72,7 +72,7 @@ const short temptable_1[][2] PROGMEM = {
{ 1008*OVERSAMPLENR , 0 } //safety
};
#endif
#if (THERMISTORHEATER_0 == 2) || (THERMISTORHEATER_1 == 2) || (THERMISTORHEATER_2 == 2) || (THERMISTORBED == 2) //200k bed thermistor
#if (THERMISTORHEATER_0 == 2) || (THERMISTORBED == 2) //200k bed thermistor
const short temptable_2[][2] PROGMEM = {
//200k ATC Semitec 204GT-2
//Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf
@ -112,7 +112,7 @@ const short temptable_2[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 3) || (THERMISTORHEATER_1 == 3) || (THERMISTORHEATER_2 == 3) || (THERMISTORBED == 3) //mendel-parts
#if (THERMISTORHEATER_0 == 3) || (THERMISTORBED == 3) //mendel-parts
const short temptable_3[][2] PROGMEM = {
{1*OVERSAMPLENR,864},
{21*OVERSAMPLENR,300},
@ -145,7 +145,7 @@ const short temptable_3[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 4) || (THERMISTORHEATER_1 == 4) || (THERMISTORHEATER_2 == 4) || (THERMISTORBED == 4) //10k thermistor
#if (THERMISTORHEATER_0 == 4) || (THERMISTORBED == 4) //10k thermistor
const short temptable_4[][2] PROGMEM = {
{1*OVERSAMPLENR, 430},
{54*OVERSAMPLENR, 137},
@ -170,7 +170,7 @@ const short temptable_4[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 5) || (THERMISTORHEATER_1 == 5) || (THERMISTORHEATER_2 == 5) || (THERMISTORBED == 5) //100k ParCan thermistor (104GT-2)
#if (THERMISTORHEATER_0 == 5) || (THERMISTORBED == 5) //100k ParCan thermistor (104GT-2)
const short temptable_5[][2] PROGMEM = {
// ATC Semitec 104GT-2 (Used in ParCan)
// Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf
@ -210,7 +210,7 @@ const short temptable_5[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 6) || (THERMISTORHEATER_1 == 6) || (THERMISTORHEATER_2 == 6) || (THERMISTORBED == 6) // 100k Epcos thermistor
#if (THERMISTORHEATER_0 == 6) || (THERMISTORBED == 6) // 100k Epcos thermistor
const short temptable_6[][2] PROGMEM = {
{1*OVERSAMPLENR, 350},
{28*OVERSAMPLENR, 250}, //top rating 250C
@ -253,7 +253,7 @@ const short temptable_6[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 7) || (THERMISTORHEATER_1 == 7) || (THERMISTORHEATER_2 == 7) || (THERMISTORBED == 7) // 100k Honeywell 135-104LAG-J01
#if (THERMISTORHEATER_0 == 7) || (THERMISTORBED == 7) // 100k Honeywell 135-104LAG-J01
const short temptable_7[][2] PROGMEM = {
{1*OVERSAMPLENR, 941},
{19*OVERSAMPLENR, 362},
@ -316,7 +316,7 @@ const short temptable_7[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 71) || (THERMISTORHEATER_1 == 71) || (THERMISTORHEATER_2 == 71) || (THERMISTORBED == 71) // 100k Honeywell 135-104LAF-J01
#if (THERMISTORHEATER_0 == 71) || (THERMISTORBED == 71) // 100k Honeywell 135-104LAF-J01
// R0 = 100000 Ohm
// T0 = 25 °C
// Beta = 3974
@ -467,7 +467,7 @@ const short temptable_71[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 8) || (THERMISTORHEATER_1 == 8) || (THERMISTORHEATER_2 == 8) || (THERMISTORBED == 8)
#if (THERMISTORHEATER_0 == 8) || (THERMISTORBED == 8)
// 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup)
const short temptable_8[][2] PROGMEM = {
{1*OVERSAMPLENR, 704},
@ -492,7 +492,7 @@ const short temptable_8[][2] PROGMEM = {
{1008*OVERSAMPLENR, 0}
};
#endif
#if (THERMISTORHEATER_0 == 9) || (THERMISTORHEATER_1 == 9) || (THERMISTORHEATER_2 == 9) || (THERMISTORBED == 9)
#if (THERMISTORHEATER_0 == 9) || (THERMISTORBED == 9)
// 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup)
const short temptable_9[][2] PROGMEM = {
{1*OVERSAMPLENR, 936},
@ -528,7 +528,7 @@ const short temptable_9[][2] PROGMEM = {
{1016*OVERSAMPLENR, 0}
};
#endif
#if (THERMISTORHEATER_0 == 10) || (THERMISTORHEATER_1 == 10) || (THERMISTORHEATER_2 == 10) || (THERMISTORBED == 10)
#if (THERMISTORHEATER_0 == 10) || (THERMISTORBED == 10)
// 100k RS thermistor 198-961 (4.7k pullup)
const short temptable_10[][2] PROGMEM = {
{1*OVERSAMPLENR, 929},
@ -565,7 +565,7 @@ const short temptable_10[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 11) || (THERMISTORHEATER_1 == 11) || (THERMISTORHEATER_2 == 11) || (THERMISTORBED == 11)
#if (THERMISTORHEATER_0 == 11) || (THERMISTORBED == 11)
// QU-BD silicone bed QWG-104F-3950 thermistor
const short temptable_11[][2] PROGMEM = {
@ -622,7 +622,7 @@ const short temptable_11[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 13) || (THERMISTORHEATER_1 == 13) || (THERMISTORHEATER_2 == 13) || (THERMISTORBED == 13)
#if (THERMISTORHEATER_0 == 13) || (THERMISTORBED == 13)
// Hisens thermistor B25/50 =3950 +/-1%
const short temptable_13[][2] PROGMEM = {
@ -691,21 +691,13 @@ const short temptable_13[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 20) || (THERMISTORHEATER_1 == 20) || (THERMISTORHEATER_2 == 20) || (THERMISTORBED == 20) // PT100 with INA826 amp on Ultimaker v2.0 electronics
#if (THERMISTORHEATER_0 == 20) || (THERMISTORBED == 20) // PT100 with INA826 amp on Ultimaker v2.0 electronics
/* The PT100 in the Ultimaker v2.0 electronics has a high sample value for a high temperature.
This does not match the normal thermistor behaviour so we need to set the following defines */
#if (THERMISTORHEATER_0 == 20)
# define HEATER_0_RAW_HI_TEMP 16383
# define HEATER_0_RAW_LO_TEMP 0
#endif
#if (THERMISTORHEATER_1 == 20)
# define HEATER_1_RAW_HI_TEMP 16383
# define HEATER_1_RAW_LO_TEMP 0
#endif
#if (THERMISTORHEATER_2 == 20)
# define HEATER_2_RAW_HI_TEMP 16383
# define HEATER_2_RAW_LO_TEMP 0
#endif
#if (THERMISTORBED == 20)
# define HEATER_BED_RAW_HI_TEMP 16383
# define HEATER_BED_RAW_LO_TEMP 0
@ -763,7 +755,7 @@ const short temptable_20[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 51) || (THERMISTORHEATER_1 == 51) || (THERMISTORHEATER_2 == 51) || (THERMISTORBED == 51)
#if (THERMISTORHEATER_0 == 51) || (THERMISTORBED == 51)
// 100k EPCOS (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!)
// Verified by linagee.
// Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance
@ -825,7 +817,7 @@ const short temptable_51[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 52) || (THERMISTORHEATER_1 == 52) || (THERMISTORHEATER_2 == 52) || (THERMISTORBED == 52)
#if (THERMISTORHEATER_0 == 52) || (THERMISTORBED == 52)
// 200k ATC Semitec 204GT-2 (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!)
// Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf
// Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance
@ -866,7 +858,7 @@ const short temptable_52[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 55) || (THERMISTORHEATER_1 == 55) || (THERMISTORHEATER_2 == 55) || (THERMISTORBED == 55)
#if (THERMISTORHEATER_0 == 55) || (THERMISTORBED == 55)
// 100k ATC Semitec 104GT-2 (Used on ParCan) (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!)
// Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf
// Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance
@ -907,7 +899,7 @@ const short temptable_55[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 60) || (THERMISTORHEATER_1 == 60) || (THERMISTORHEATER_2 == 60) || (THERMISTORBED == 60) // Maker's Tool Works Kapton Bed Thermister
#if (THERMISTORHEATER_0 == 60) || (THERMISTORBED == 60) // Maker's Tool Works Kapton Bed Thermister
// ./createTemperatureLookup.py --r0=100000 --t0=25 --r1=0 --r2=4700 --beta=3950
// r0: 100000
// t0: 25
@ -1040,7 +1032,7 @@ const short temptable_12[][2] PROGMEM = {
#define PtAdVal(T,R0,Rup) (short)(1024/(Rup/PtRt(T,R0)+1))
#define PtLine(T,R0,Rup) { PtAdVal(T,R0,Rup)*OVERSAMPLENR, T },
#if (THERMISTORHEATER_0 == 110) || (THERMISTORHEATER_1 == 110) || (THERMISTORHEATER_2 == 110) || (THERMISTORBED == 110) // Pt100 with 1k0 pullup
#if (THERMISTORHEATER_0 == 110) || (THERMISTORBED == 110) // Pt100 with 1k0 pullup
const short temptable_110[][2] PROGMEM = {
// only few values are needed as the curve is very flat
PtLine(0,100,1000)
@ -1052,7 +1044,7 @@ const short temptable_110[][2] PROGMEM = {
PtLine(300,100,1000)
};
#endif
#if (THERMISTORHEATER_0 == 147) || (THERMISTORHEATER_1 == 147) || (THERMISTORHEATER_2 == 147) || (THERMISTORBED == 147) // Pt100 with 4k7 pullup
#if (THERMISTORHEATER_0 == 147) || (THERMISTORBED == 147) // Pt100 with 4k7 pullup
const short temptable_147[][2] PROGMEM = {
// only few values are needed as the curve is very flat
PtLine(0,100,4700)
@ -1065,7 +1057,7 @@ const short temptable_147[][2] PROGMEM = {
};
#endif
// E3D Pt100 with 4k7 MiniRambo pullup, no Amp on the MiniRambo v1.3a
#if (THERMISTORHEATER_0 == 148) || (THERMISTORHEATER_1 == 148) || (THERMISTORHEATER_2 == 148) || (THERMISTORBED == 148)
#if (THERMISTORHEATER_0 == 148) || (THERMISTORBED == 148)
const short temptable_148[][2] PROGMEM = {
// These values have been calculated and tested over many days. See https://docs.google.com/spreadsheets/d/1MJXa6feEe0mGVCT2TrBwLxVOMoLDkJlvfQ4JXhAdV_E
// Values that are missing from the 5C gap are missing due to resolution limits.
@ -1127,7 +1119,7 @@ const short temptable_148[][2] PROGMEM = {
{49.00000 * OVERSAMPLENR,405},
};
#endif
#if (THERMISTORHEATER_0 == 247) || (THERMISTORHEATER_1 == 247) || (THERMISTORHEATER_2 == 247) || (THERMISTORBED == 247) // Pt100 with 4k7 MiniRambo pullup & PT100 Amplifier
#if (THERMISTORHEATER_0 == 247) || (THERMISTORBED == 247) // Pt100 with 4k7 MiniRambo pullup & PT100 Amplifier
const short temptable_247[][2] PROGMEM = {
// Calculated from Bob-the-Kuhn's PT100 calculator listed in https://github.com/MarlinFirmware/Marlin/issues/5543
// and the table provided by E3D at http://wiki.e3d-online.com/wiki/E3D_PT100_Amplifier_Documentation#Output_Characteristics.
@ -1182,7 +1174,7 @@ const short temptable_247[][2] PROGMEM = {
{960 * OVERSAMPLENR, 1100},
};
#endif
#if (THERMISTORHEATER_0 == 1010) || (THERMISTORHEATER_1 == 1010) || (THERMISTORHEATER_2 == 1010) || (THERMISTORBED == 1010) // Pt1000 with 1k0 pullup
#if (THERMISTORHEATER_0 == 1010) || (THERMISTORBED == 1010) // Pt1000 with 1k0 pullup
const short temptable_1010[][2] PROGMEM = {
PtLine(0,1000,1000)
PtLine(25,1000,1000)
@ -1199,7 +1191,7 @@ const short temptable_1010[][2] PROGMEM = {
PtLine(300,1000,1000)
};
#endif
#if (THERMISTORHEATER_0 == 1047) || (THERMISTORHEATER_1 == 1047) || (THERMISTORHEATER_2 == 1047) || (THERMISTORBED == 1047) // Pt1000 with 4k7 pullup
#if (THERMISTORHEATER_0 == 1047) || (THERMISTORBED == 1047) // Pt1000 with 4k7 pullup
const short temptable_1047[][2] PROGMEM = {
// only few values are needed as the curve is very flat
PtLine(0,1000,4700)
@ -1315,52 +1307,6 @@ const short temptable_2000[][2] PROGMEM = {
# endif
#endif
#ifdef THERMISTORHEATER_1
# define HEATER_1_TEMPTABLE TT_NAME(THERMISTORHEATER_1)
# define HEATER_1_TEMPTABLE_LEN (sizeof(HEATER_1_TEMPTABLE)/sizeof(*HEATER_1_TEMPTABLE))
#else
# ifdef HEATER_1_USES_THERMISTOR
# error No heater 1 thermistor table specified
# else // HEATER_1_USES_THERMISTOR
# define HEATER_1_TEMPTABLE NULL
# define HEATER_1_TEMPTABLE_LEN 0
# endif // HEATER_1_USES_THERMISTOR
#endif
//Set the high and low raw values for the heater, this indicates which raw value is a high or low temperature
#ifndef HEATER_1_RAW_HI_TEMP
# ifdef HEATER_1_USES_THERMISTOR //In case of a thermistor the highest temperature results in the lowest ADC value
# define HEATER_1_RAW_HI_TEMP 0
# define HEATER_1_RAW_LO_TEMP 16383
# else //In case of an thermocouple the highest temperature results in the highest ADC value
# define HEATER_1_RAW_HI_TEMP 16383
# define HEATER_1_RAW_LO_TEMP 0
# endif
#endif
#ifdef THERMISTORHEATER_2
# define HEATER_2_TEMPTABLE TT_NAME(THERMISTORHEATER_2)
# define HEATER_2_TEMPTABLE_LEN (sizeof(HEATER_2_TEMPTABLE)/sizeof(*HEATER_2_TEMPTABLE))
#else
# ifdef HEATER_2_USES_THERMISTOR
# error No heater 2 thermistor table specified
# else // HEATER_2_USES_THERMISTOR
# define HEATER_2_TEMPTABLE NULL
# define HEATER_2_TEMPTABLE_LEN 0
# endif // HEATER_2_USES_THERMISTOR
#endif
//Set the high and low raw values for the heater, this indicates which raw value is a high or low temperature
#ifndef HEATER_2_RAW_HI_TEMP
# ifdef HEATER_2_USES_THERMISTOR //In case of a thermistor the highest temperature results in the lowest ADC value
# define HEATER_2_RAW_HI_TEMP 0
# define HEATER_2_RAW_LO_TEMP 16383
# else //In case of an thermocouple the highest temperature results in the highest ADC value
# define HEATER_2_RAW_HI_TEMP 16383
# define HEATER_2_RAW_LO_TEMP 0
# endif
#endif
#ifdef THERMISTORBED
# define BEDTEMPTABLE TT_NAME(THERMISTORBED)
# define BEDTEMPTABLE_LEN (sizeof(BEDTEMPTABLE)/sizeof(*BEDTEMPTABLE))

View File

@ -12,6 +12,7 @@
#define TMC2130_GCONF_NORMAL 0x00000000 // spreadCycle
#define TMC2130_GCONF_SGSENS 0x00000180 // spreadCycle with stallguard (stall activates DIAG0 and DIAG1 [open collector])
#define TMC2130_GCONF_DYNAMIC_SGSENS 0x00000184 // stealthChop/spreadCycle (dynamic) with stallguard (stall activates DIAG0 and DIAG1 [open collector])
#define TMC2130_GCONF_SILENT 0x00000004 // stealthChop
@ -22,32 +23,32 @@ uint8_t tmc2130_current_h[4] = TMC2130_CURRENTS_H;
uint8_t tmc2130_current_r[4] = TMC2130_CURRENTS_R;
//running currents for homing
uint8_t tmc2130_current_r_home[4] = TMC2130_CURRENTS_R_HOME;
static uint8_t tmc2130_current_r_home[4] = TMC2130_CURRENTS_R_HOME;
//pwm_ampl
uint8_t tmc2130_pwm_ampl[4] = {TMC2130_PWM_AMPL_X, TMC2130_PWM_AMPL_Y, TMC2130_PWM_AMPL_Z, TMC2130_PWM_AMPL_E};
static uint8_t tmc2130_pwm_ampl[4] = {TMC2130_PWM_AMPL_X, TMC2130_PWM_AMPL_Y, TMC2130_PWM_AMPL_Z, TMC2130_PWM_AMPL_E};
//pwm_grad
uint8_t tmc2130_pwm_grad[4] = {TMC2130_PWM_GRAD_X, TMC2130_PWM_GRAD_Y, TMC2130_PWM_GRAD_Z, TMC2130_PWM_GRAD_E};
static uint8_t tmc2130_pwm_grad[4] = {TMC2130_PWM_GRAD_X, TMC2130_PWM_GRAD_Y, TMC2130_PWM_GRAD_Z, TMC2130_PWM_GRAD_E};
//pwm_auto
uint8_t tmc2130_pwm_auto[4] = {TMC2130_PWM_AUTO_X, TMC2130_PWM_AUTO_Y, TMC2130_PWM_AUTO_Z, TMC2130_PWM_AUTO_E};
static uint8_t tmc2130_pwm_auto[4] = {TMC2130_PWM_AUTO_X, TMC2130_PWM_AUTO_Y, TMC2130_PWM_AUTO_Z, TMC2130_PWM_AUTO_E};
//pwm_freq
uint8_t tmc2130_pwm_freq[4] = {TMC2130_PWM_FREQ_X, TMC2130_PWM_FREQ_Y, TMC2130_PWM_FREQ_Z, TMC2130_PWM_FREQ_E};
static uint8_t tmc2130_pwm_freq[4] = {TMC2130_PWM_FREQ_X, TMC2130_PWM_FREQ_Y, TMC2130_PWM_FREQ_Z, TMC2130_PWM_FREQ_E};
uint8_t tmc2130_mres[4] = {0, 0, 0, 0}; //will be filed at begin of init
uint8_t tmc2130_sg_thr[4] = {TMC2130_SG_THRS_X, TMC2130_SG_THRS_Y, TMC2130_SG_THRS_Z, TMC2130_SG_THRS_E};
uint8_t tmc2130_sg_thr_home[4] = TMC2130_SG_THRS_HOME;
static uint8_t tmc2130_sg_thr_home[4] = TMC2130_SG_THRS_HOME;
uint8_t tmc2130_sg_homing_axes_mask = 0x00;
const char eMotorCurrentScalingEnabled[] PROGMEM = "E-motor current scaling enabled";
uint8_t tmc2130_sg_measure = 0xff;
uint32_t tmc2130_sg_measure_cnt = 0;
uint32_t tmc2130_sg_measure_val = 0;
static uint8_t tmc2130_sg_measure = 0xff;
static uint32_t tmc2130_sg_measure_cnt = 0;
static uint32_t tmc2130_sg_measure_val = 0;
uint8_t tmc2130_home_enabled = 0;
uint8_t tmc2130_home_origin[2] = {0, 0};
@ -64,11 +65,10 @@ tmc2130_chopper_config_t tmc2130_chopper_config[4] = {
};
bool tmc2130_sg_stop_on_crash = true;
uint8_t tmc2130_sg_diag_mask = 0x00;
uint8_t tmc2130_sg_crash = 0;
//used for triggering a periodic check (1s) of the overtemperature pre-warning flag at ~120C (+-20C)
ShortTimer tmc2130_overtemp_timer;
static ShortTimer tmc2130_overtemp_timer;
#define DBG(args...)
//printf_P(args)
@ -182,9 +182,9 @@ void tmc2130_init(TMCInitParams params)
#else //TMC2130_STEALTH_Z
tmc2130_wr(axis, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[axis]) << 16) | ((uint32_t)1 << 24));
tmc2130_wr(axis, TMC2130_REG_TCOOLTHRS, (tmc2130_mode == TMC2130_MODE_SILENT)?0:__tcoolthrs(axis));
tmc2130_wr(axis, TMC2130_REG_GCONF, (tmc2130_mode == TMC2130_MODE_SILENT)?TMC2130_GCONF_SILENT:TMC2130_GCONF_SGSENS);
tmc2130_wr(axis, TMC2130_REG_GCONF, (tmc2130_mode == TMC2130_MODE_SILENT)?TMC2130_GCONF_SILENT:TMC2130_GCONF_DYNAMIC_SGSENS);
tmc2130_wr_PWMCONF(axis, tmc2130_pwm_ampl[axis], tmc2130_pwm_grad[axis], tmc2130_pwm_freq[axis], tmc2130_pwm_auto[axis], 0, 0);
tmc2130_wr_TPWMTHRS(axis, TMC2130_TPWMTHRS);
tmc2130_wr_TPWMTHRS(axis, (tmc2130_mode == TMC2130_MODE_SILENT)?0:0xFFFF0);
#endif //TMC2130_STEALTH_Z
}
for (uint_least8_t axis = 3; axis < 4; axis++) // E axis
@ -267,11 +267,10 @@ void tmc2130_home_enter(uint8_t axes_mask)
{
printf_P(PSTR("tmc2130_home_enter(axes_mask=0x%02x)\n"), axes_mask);
#ifdef TMC2130_SG_HOMING
if (axes_mask & 0x03) //X or Y
if (axes_mask & (X_AXIS_MASK | Y_AXIS_MASK)) //X or Y
tmc2130_wait_standstill_xy(1000);
for (uint8_t axis = X_AXIS; axis <= Z_AXIS; axis++) //X Y and Z axes
for (uint8_t axis = X_AXIS, mask = X_AXIS_MASK; axis <= Z_AXIS; axis++, mask <<= 1) //X Y and Z axes
{
uint8_t mask = (X_AXIS_MASK << axis);
if (axes_mask & mask)
{
tmc2130_sg_homing_axes_mask |= mask;
@ -280,8 +279,7 @@ void tmc2130_home_enter(uint8_t axes_mask)
tmc2130_wr(axis, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr_home[axis]) << 16));
tmc2130_wr(axis, TMC2130_REG_TCOOLTHRS, __tcoolthrs(axis));
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r_home[axis]);
if (mask & (X_AXIS_MASK | Y_AXIS_MASK | Z_AXIS_MASK))
tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS); //stallguard output DIAG1, DIAG1 = pushpull
tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS); //stallguard output DIAG1, DIAG1 = pushpull
}
}
#endif //TMC2130_SG_HOMING
@ -295,10 +293,9 @@ void tmc2130_home_exit()
tmc2130_wait_standstill_xy(1000);
if (tmc2130_sg_homing_axes_mask)
{
for (uint8_t axis = X_AXIS; axis <= Z_AXIS; axis++) //X Y and Z axes
for (uint8_t axis = X_AXIS, mask = X_AXIS_MASK; axis <= Z_AXIS; axis++, mask <<= 1) //X Y and Z axes
{
uint8_t mask = (X_AXIS_MASK << axis);
if (tmc2130_sg_homing_axes_mask & mask & (X_AXIS_MASK | Y_AXIS_MASK | Z_AXIS_MASK))
if (tmc2130_sg_homing_axes_mask & mask)
{
#ifndef TMC2130_STEALTH_Z
if ((tmc2130_mode == TMC2130_MODE_SILENT) && (axis != Z_AXIS))
@ -360,7 +357,7 @@ bool tmc2130_wait_standstill_xy(int timeout)
void tmc2130_check_overtemp()
{
if (tmc2130_overtemp_timer.expired(1000) || !tmc2130_overtemp_timer.running())
if (tmc2130_overtemp_timer.expired_cont(1000))
{
for (uint_least8_t i = 0; i < 4; i++)
{

View File

@ -16,10 +16,6 @@ extern uint8_t tmc2130_sg_thr[4];
extern bool tmc2130_sg_stop_on_crash;
extern uint8_t tmc2130_sg_crash; //crash mask
extern uint8_t tmc2130_sg_measure;
extern uint32_t tmc2130_sg_measure_cnt;
extern uint32_t tmc2130_sg_measure_val;
extern uint8_t tmc2130_sg_homing_axes_mask;
extern const char eMotorCurrentScalingEnabled[];

File diff suppressed because it is too large Load Diff

View File

@ -17,11 +17,13 @@ void ultralcd_init();
#define LCD_STATUS_NONE 0 //< No alert message set
#define LCD_STATUS_INFO_TIMEOUT 20000
#define LCD_STATUS_DELAYED_TIMEOUT 4000
// Set the current status message (equivalent to LCD_STATUS_NONE)
void lcd_setstatus(const char* message);
void lcd_setstatuspgm(const char* message);
void lcd_setstatus_serial(const char* message);
void lcd_reset_status_message_timeout();
//! return to the main status screen and display the alert message
//! Beware - it has sideeffects:
@ -111,7 +113,6 @@ extern void lcd_bed_calibration_show_result(BedSkewOffsetDetectionResultType res
enum class LcdCommands : uint_least8_t
{
Idle,
LoadFilament,
StopPrint,
LongPause,
PidExtruder,
@ -123,7 +124,6 @@ enum class LcdCommands : uint_least8_t
};
extern LcdCommands lcd_commands_type;
extern int8_t FSensorStateMenu;
enum class CustomMsg : uint_least8_t
{
@ -158,18 +158,15 @@ extern bool FarmOrUserECool();
#if defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_IR_ANALOG)
void printf_IRSensorAnalogBoardChange();
#endif //IR_SENSOR_ANALOG
#endif //defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_IR_ANALOG)
extern int8_t SilentModeMenu;
extern uint8_t SilentModeMenu_MMU;
extern bool cancel_heatup;
extern bool isPrintPaused;
extern uint8_t scrollstuff;
void lcd_ignore_click(bool b=true);
void lcd_commands();
@ -192,12 +189,10 @@ enum class FilamentAction : uint_least8_t
};
extern FilamentAction eFilamentAction;
extern bool bFilamentPreheatState;
extern bool bFilamentAction;
void mFilamentItem(uint16_t nTemp,uint16_t nTempBed);
void mFilamentItemForce();
void lcd_generic_preheat_menu();
void unload_filament(float unloadLength);
void lcd_AutoLoadFilament();
void lcd_wait_for_heater();

View File

@ -240,43 +240,26 @@ void update_current_firmware_version_to_eeprom()
eeprom_update_word((uint16_t*)EEPROM_FIRMWARE_VERSION_FLAVOR, (uint16_t)pgm_read_word(&FW_VERSION_NR[3]));
}
ClNozzleDiameter oNozzleDiameter=ClNozzleDiameter::_Diameter_400;
ClCheckMode oCheckMode=ClCheckMode::_None;
ClCheckModel oCheckModel=ClCheckModel::_None;
ClCheckVersion oCheckVersion=ClCheckVersion::_None;
ClCheckGcode oCheckGcode=ClCheckGcode::_None;
ClNozzleDiameter oNozzleDiameter;
ClCheckMode oCheckMode;
ClCheckModel oCheckModel;
ClCheckVersion oCheckVersion;
ClCheckGcode oCheckGcode;
void fCheckModeInit() {
oCheckMode = (ClCheckMode)eeprom_read_byte((uint8_t *)EEPROM_CHECK_MODE);
if (oCheckMode == ClCheckMode::_Undef) {
oCheckMode = ClCheckMode::_Warn;
eeprom_update_byte((uint8_t *)EEPROM_CHECK_MODE, (uint8_t)oCheckMode);
}
oCheckMode = (ClCheckMode)eeprom_init_default_byte((uint8_t *)EEPROM_CHECK_MODE, (uint8_t)ClCheckMode::_Warn);
if (farm_mode) {
oCheckMode = ClCheckMode::_Strict;
eeprom_init_default_word((uint16_t *)EEPROM_NOZZLE_DIAMETER_uM, EEPROM_NOZZLE_DIAMETER_uM_DEFAULT);
}
oNozzleDiameter = (ClNozzleDiameter)eeprom_read_byte((uint8_t *)EEPROM_NOZZLE_DIAMETER);
if ((oNozzleDiameter == ClNozzleDiameter::_Diameter_Undef) && !farm_mode) {
oNozzleDiameter = ClNozzleDiameter::_Diameter_400;
eeprom_update_byte((uint8_t *)EEPROM_NOZZLE_DIAMETER, (uint8_t)oNozzleDiameter);
eeprom_update_word((uint16_t *)EEPROM_NOZZLE_DIAMETER_uM, EEPROM_NOZZLE_DIAMETER_uM_DEFAULT);
}
oCheckModel = (ClCheckModel)eeprom_read_byte((uint8_t *)EEPROM_CHECK_MODEL);
if (oCheckModel == ClCheckModel::_Undef) {
oCheckModel = ClCheckModel::_Warn;
eeprom_update_byte((uint8_t *)EEPROM_CHECK_MODEL, (uint8_t)oCheckModel);
}
oCheckVersion = (ClCheckVersion)eeprom_read_byte((uint8_t *)EEPROM_CHECK_VERSION);
if (oCheckVersion == ClCheckVersion::_Undef) {
oCheckVersion = ClCheckVersion::_Warn;
eeprom_update_byte((uint8_t *)EEPROM_CHECK_VERSION, (uint8_t)oCheckVersion);
}
oCheckGcode = (ClCheckGcode)eeprom_read_byte((uint8_t *)EEPROM_CHECK_GCODE);
if (oCheckGcode == ClCheckGcode::_Undef) {
oCheckGcode = ClCheckGcode::_Warn;
eeprom_update_byte((uint8_t *)EEPROM_CHECK_GCODE, (uint8_t)oCheckGcode);
eeprom_update_byte((uint8_t *)EEPROM_CHECK_MODE, (uint8_t)ClCheckMode::_Strict);
}
oNozzleDiameter = (ClNozzleDiameter)eeprom_init_default_byte((uint8_t *)EEPROM_NOZZLE_DIAMETER, (uint8_t)ClNozzleDiameter::_Diameter_400);
eeprom_init_default_word((uint16_t *)EEPROM_NOZZLE_DIAMETER_uM, EEPROM_NOZZLE_DIAMETER_uM_DEFAULT);
oCheckModel = (ClCheckModel)eeprom_init_default_byte((uint8_t *)EEPROM_CHECK_MODEL, (uint8_t)ClCheckModel::_Warn);
oCheckVersion = (ClCheckVersion)eeprom_init_default_byte((uint8_t *)EEPROM_CHECK_VERSION, (uint8_t)ClCheckVersion::_Warn);
oCheckGcode = (ClCheckGcode)eeprom_init_default_byte((uint8_t *)EEPROM_CHECK_GCODE, (uint8_t)ClCheckGcode::_Warn);
}
static void render_M862_warnings(const char* warning, const char* strict, uint8_t check)

View File

@ -21,8 +21,6 @@ bool show_upgrade_dialog_if_version_newer(const char *version_string);
bool eeprom_fw_version_older_than_p(const uint16_t (&req_ver)[4]);
void update_current_firmware_version_to_eeprom();
//-//
#define EEPROM_NOZZLE_DIAMETER_uM_DEFAULT 400
enum class ClPrintChecking:uint_least8_t

View File

@ -16,9 +16,6 @@
#define FILAMENT_SIZE "1_75mm_MK25"
#define NOZZLE_TYPE "E3Dv6full"
// Developer flag
#define DEVELOPER
// Printer name
#define CUSTOM_MENDEL_NAME "Prusa i3 MK2.5"
@ -53,8 +50,6 @@
#define INVERT_Y_DIR 0 // for Mendel set to 1, for Orca set to 0
#define INVERT_Z_DIR 0 // for Mendel set to 0, for Orca set to 1
#define INVERT_E0_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
#define INVERT_E1_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
#define INVERT_E2_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
// Home position
#define MANUAL_X_HOME_POS 0
@ -166,8 +161,6 @@
// Mintemps
#define HEATER_0_MINTEMP 30
#define HEATER_1_MINTEMP 5
#define HEATER_2_MINTEMP 5
#define HEATER_MINTEMP_DELAY 15000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if HEATER_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see HEATER_MINTEMP_DELAY definition)"
@ -187,8 +180,6 @@
#else
#define HEATER_0_MAXTEMP 305
#endif
#define HEATER_1_MAXTEMP 305
#define HEATER_2_MAXTEMP 305
#define BED_MAXTEMP 125
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
@ -211,28 +202,12 @@
// Extruder cooling fans
#define EXTRUDER_0_AUTO_FAN_PIN 8
#define EXTRUDER_1_AUTO_FAN_PIN -1
#define EXTRUDER_2_AUTO_FAN_PIN -1
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed
#define FANCHECK_AUTO_PRINT_FAN_THRS 70 //[RPS] - Used during selftest to identify swapped fans automatically
#define FANCHECK_AUTO_FAIL_THRS 20 //[RPS] - Used during selftest to identify a faulty fan
/*------------------------------------
LOAD/UNLOAD FILAMENT SETTINGS
*------------------------------------*/
// Load filament commands
#define LOAD_FILAMENT_0 "M83"
#define LOAD_FILAMENT_1 "G1 E70 F400"
#define LOAD_FILAMENT_2 "G1 E40 F100"
// Unload filament commands
#define UNLOAD_FILAMENT_0 "M83"
#define UNLOAD_FILAMENT_1 "G1 E-80 F7000"
/*------------------------------------
CHANGE FILAMENT SETTINGS
*------------------------------------*/
@ -454,8 +429,6 @@
#else
#define TEMP_SENSOR_0 5
#endif
#define TEMP_SENSOR_1 0
#define TEMP_SENSOR_2 0
#if defined(E3D_PT100_BED_WITH_AMP)
#define TEMP_SENSOR_BED 247
#elif defined(E3D_PT100_BED_NO_AMP)
@ -503,16 +476,11 @@
//#define SUPPORT_VERBOSITY
#define MMU_CONFIG_FILE "mmu2/variants/config_MMU2.h"
#define MMU_FILAMENT_COUNT 5
#define MMU_REQUIRED_FW_BUILDNR 132
#define MMU_FORCE_STEALTH_MODE
#define MMU_DEBUG //print communication between MMU2 and printer on serial
#define MMU_DEBUG //print communication between MMU and printer on serial
#define MMU_HAS_CUTTER
#define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
// MMU Error pause position
#define MMU_ERR_X_PAUSE_POS 125
#define MMU_ERR_Y_PAUSE_POS 0

View File

@ -16,9 +16,6 @@
#define FILAMENT_SIZE "1_75mm_MK25"
#define NOZZLE_TYPE "E3Dv6full"
// Developer flag
#define DEVELOPER
// Printer name
#define CUSTOM_MENDEL_NAME "Prusa i3 MK2.5"
@ -53,8 +50,6 @@
#define INVERT_Y_DIR 0 // for Mendel set to 1, for Orca set to 0
#define INVERT_Z_DIR 0 // for Mendel set to 0, for Orca set to 1
#define INVERT_E0_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
#define INVERT_E1_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
#define INVERT_E2_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
// Home position
#define MANUAL_X_HOME_POS 0
@ -167,8 +162,6 @@
// Mintemps
#define HEATER_0_MINTEMP 30
#define HEATER_1_MINTEMP 5
#define HEATER_2_MINTEMP 5
#define HEATER_MINTEMP_DELAY 15000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if HEATER_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see HEATER_MINTEMP_DELAY definition)"
@ -188,8 +181,6 @@
#else
#define HEATER_0_MAXTEMP 305
#endif
#define HEATER_1_MAXTEMP 305
#define HEATER_2_MAXTEMP 305
#define BED_MAXTEMP 125
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
@ -212,28 +203,12 @@
// Extruder cooling fans
#define EXTRUDER_0_AUTO_FAN_PIN 8
#define EXTRUDER_1_AUTO_FAN_PIN -1
#define EXTRUDER_2_AUTO_FAN_PIN -1
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed
#define FANCHECK_AUTO_PRINT_FAN_THRS 70 //[RPS] - Used during selftest to identify swapped fans automatically
#define FANCHECK_AUTO_FAIL_THRS 20 //[RPS] - Used during selftest to identify a faulty fan
/*------------------------------------
LOAD/UNLOAD FILAMENT SETTINGS
*------------------------------------*/
// Load filament commands
#define LOAD_FILAMENT_0 "M83"
#define LOAD_FILAMENT_1 "G1 E70 F400"
#define LOAD_FILAMENT_2 "G1 E40 F100"
// Unload filament commands
#define UNLOAD_FILAMENT_0 "M83"
#define UNLOAD_FILAMENT_1 "G1 E-80 F7000"
/*------------------------------------
CHANGE FILAMENT SETTINGS
*------------------------------------*/
@ -455,8 +430,6 @@
#else
#define TEMP_SENSOR_0 5
#endif
#define TEMP_SENSOR_1 0
#define TEMP_SENSOR_2 0
#if defined(E3D_PT100_BED_WITH_AMP)
#define TEMP_SENSOR_BED 247
#elif defined(E3D_PT100_BED_NO_AMP)
@ -504,16 +477,11 @@
//#define SUPPORT_VERBOSITY
#define MMU_CONFIG_FILE "mmu2/variants/config_MMU2.h"
#define MMU_FILAMENT_COUNT 5
#define MMU_REQUIRED_FW_BUILDNR 132
#define MMU_FORCE_STEALTH_MODE
#define MMU_DEBUG //print communication between MMU2 and printer on serial
#define MMU_DEBUG //print communication between MMU and printer on serial
#define MMU_HAS_CUTTER
#define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
// MMU Error pause position
#define MMU_ERR_X_PAUSE_POS 125
#define MMU_ERR_Y_PAUSE_POS 0

View File

@ -16,9 +16,6 @@
#define FILAMENT_SIZE "1_75mm_MK25S"
#define NOZZLE_TYPE "E3Dv6full"
// Developer flag
#define DEVELOPER
// Printer name
#define CUSTOM_MENDEL_NAME "Prusa i3 MK2.5S"
@ -53,8 +50,6 @@
#define INVERT_Y_DIR 0 // for Mendel set to 1, for Orca set to 0
#define INVERT_Z_DIR 0 // for Mendel set to 0, for Orca set to 1
#define INVERT_E0_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
#define INVERT_E1_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
#define INVERT_E2_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
// Home position
#define MANUAL_X_HOME_POS 0
@ -166,8 +161,6 @@
// Mintemps
#define HEATER_0_MINTEMP 30
#define HEATER_1_MINTEMP 5
#define HEATER_2_MINTEMP 5
#define HEATER_MINTEMP_DELAY 15000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if HEATER_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see HEATER_MINTEMP_DELAY definition)"
@ -187,8 +180,6 @@
#else
#define HEATER_0_MAXTEMP 305
#endif
#define HEATER_1_MAXTEMP 305
#define HEATER_2_MAXTEMP 305
#define BED_MAXTEMP 125
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
@ -211,28 +202,12 @@
// Extruder cooling fans
#define EXTRUDER_0_AUTO_FAN_PIN 8
#define EXTRUDER_1_AUTO_FAN_PIN -1
#define EXTRUDER_2_AUTO_FAN_PIN -1
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed
#define FANCHECK_AUTO_PRINT_FAN_THRS 70 //[RPS] - Used during selftest to identify swapped fans automatically
#define FANCHECK_AUTO_FAIL_THRS 20 //[RPS] - Used during selftest to identify a faulty fan
/*------------------------------------
LOAD/UNLOAD FILAMENT SETTINGS
*------------------------------------*/
// Load filament commands
#define LOAD_FILAMENT_0 "M83"
#define LOAD_FILAMENT_1 "G1 E70 F400"
#define LOAD_FILAMENT_2 "G1 E40 F100"
// Unload filament commands
#define UNLOAD_FILAMENT_0 "M83"
#define UNLOAD_FILAMENT_1 "G1 E-80 F7000"
/*------------------------------------
CHANGE FILAMENT SETTINGS
*------------------------------------*/
@ -454,8 +429,6 @@
#else
#define TEMP_SENSOR_0 5
#endif
#define TEMP_SENSOR_1 0
#define TEMP_SENSOR_2 0
#if defined(E3D_PT100_BED_WITH_AMP)
#define TEMP_SENSOR_BED 247
#elif defined(E3D_PT100_BED_NO_AMP)
@ -503,12 +476,9 @@
//#define SUPPORT_VERBOSITY
#define MMU_CONFIG_FILE "mmu2/variants/config_MMU2S.h"
#define MMU_FILAMENT_COUNT 5
#define MMU_REQUIRED_FW_BUILDNR 132
#define MMU_FORCE_STEALTH_MODE
#define MMU_DEBUG //print communication between MMU2 and printer on serial
#define MMU_DEBUG //print communication between MMU and printer on serial
#define MMU_HAS_CUTTER
// This is experimental feature requested by our test department.
@ -518,7 +488,6 @@
// defined.
//#define MMU_ALWAYS_CUT
#define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
// MMU Error pause position
#define MMU_ERR_X_PAUSE_POS 125

View File

@ -16,9 +16,6 @@
#define FILAMENT_SIZE "1_75mm_MK25S"
#define NOZZLE_TYPE "E3Dv6full"
// Developer flag
#define DEVELOPER
// Printer name
#define CUSTOM_MENDEL_NAME "Prusa i3 MK2.5S"
@ -53,8 +50,6 @@
#define INVERT_Y_DIR 0 // for Mendel set to 1, for Orca set to 0
#define INVERT_Z_DIR 0 // for Mendel set to 0, for Orca set to 1
#define INVERT_E0_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
#define INVERT_E1_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
#define INVERT_E2_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
// Home position
#define MANUAL_X_HOME_POS 0
@ -167,8 +162,6 @@
// Mintemps
#define HEATER_0_MINTEMP 30
#define HEATER_1_MINTEMP 5
#define HEATER_2_MINTEMP 5
#define HEATER_MINTEMP_DELAY 15000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if HEATER_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see HEATER_MINTEMP_DELAY definition)"
@ -188,8 +181,6 @@
#else
#define HEATER_0_MAXTEMP 305
#endif
#define HEATER_1_MAXTEMP 305
#define HEATER_2_MAXTEMP 305
#define BED_MAXTEMP 125
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
@ -212,28 +203,12 @@
// Extruder cooling fans
#define EXTRUDER_0_AUTO_FAN_PIN 8
#define EXTRUDER_1_AUTO_FAN_PIN -1
#define EXTRUDER_2_AUTO_FAN_PIN -1
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed
#define FANCHECK_AUTO_PRINT_FAN_THRS 70 //[RPS] - Used during selftest to identify swapped fans automatically
#define FANCHECK_AUTO_FAIL_THRS 20 //[RPS] - Used during selftest to identify a faulty fan
/*------------------------------------
LOAD/UNLOAD FILAMENT SETTINGS
*------------------------------------*/
// Load filament commands
#define LOAD_FILAMENT_0 "M83"
#define LOAD_FILAMENT_1 "G1 E70 F400"
#define LOAD_FILAMENT_2 "G1 E40 F100"
// Unload filament commands
#define UNLOAD_FILAMENT_0 "M83"
#define UNLOAD_FILAMENT_1 "G1 E-80 F7000"
/*------------------------------------
CHANGE FILAMENT SETTINGS
*------------------------------------*/
@ -455,8 +430,6 @@
#else
#define TEMP_SENSOR_0 5
#endif
#define TEMP_SENSOR_1 0
#define TEMP_SENSOR_2 0
#if defined(E3D_PT100_BED_WITH_AMP)
#define TEMP_SENSOR_BED 247
#elif defined(E3D_PT100_BED_NO_AMP)
@ -504,12 +477,9 @@
//#define SUPPORT_VERBOSITY
#define MMU_CONFIG_FILE "mmu2/variants/config_MMU2S.h"
#define MMU_FILAMENT_COUNT 5
#define MMU_REQUIRED_FW_BUILDNR 132
#define MMU_FORCE_STEALTH_MODE
#define MMU_DEBUG //print communication between MMU2 and printer on serial
#define MMU_DEBUG //print communication between MMU and printer on serial
#define MMU_HAS_CUTTER
// This is experimental feature requested by our test department.
@ -519,7 +489,6 @@
// defined.
//#define MMU_ALWAYS_CUT
#define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
// MMU Error pause position
#define MMU_ERR_X_PAUSE_POS 125

View File

@ -17,9 +17,6 @@
#define FILAMENT_SIZE "1_75mm_MK3"
#define NOZZLE_TYPE "E3Dv6full"
// Developer flag
#define DEVELOPER
// Printer name
#define CUSTOM_MENDEL_NAME "Prusa i3 MK3"
@ -55,8 +52,6 @@
#define INVERT_Y_DIR 0 // for Mendel set to 1, for Orca set to 0
#define INVERT_Z_DIR 1 // for Mendel set to 0, for Orca set to 1
#define INVERT_E0_DIR 0 // for direct drive extruder v9 set to 1, for geared extruder set to 0
#define INVERT_E1_DIR 0 // for direct drive extruder v9 set to 1, for geared extruder set to 0
#define INVERT_E2_DIR 0 // for direct drive extruder v9 set to 1, for geared extruder set to 0
// Home position
#define MANUAL_X_HOME_POS 0
@ -303,8 +298,6 @@
// Mintemps
#define HEATER_0_MINTEMP 10
#define HEATER_1_MINTEMP 5
#define HEATER_2_MINTEMP 5
#define HEATER_MINTEMP_DELAY 15000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if HEATER_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see HEATER_MINTEMP_DELAY definition)"
@ -325,8 +318,6 @@
#else
#define HEATER_0_MAXTEMP 305
#endif
#define HEATER_1_MAXTEMP 305
#define HEATER_2_MAXTEMP 305
#define BED_MAXTEMP 125
#define AMBIENT_MAXTEMP 100
@ -350,28 +341,12 @@
// Extruder cooling fans
#define EXTRUDER_0_AUTO_FAN_PIN 8
#define EXTRUDER_1_AUTO_FAN_PIN -1
#define EXTRUDER_2_AUTO_FAN_PIN -1
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed
#define FANCHECK_AUTO_PRINT_FAN_THRS 70 //[RPS] - Used during selftest to identify swapped fans automatically
#define FANCHECK_AUTO_FAIL_THRS 20 //[RPS] - Used during selftest to identify a faulty fan
/*------------------------------------
LOAD/UNLOAD FILAMENT SETTINGS
*------------------------------------*/
// Load filament commands
#define LOAD_FILAMENT_0 "M83"
#define LOAD_FILAMENT_1 "G1 E70 F400"
#define LOAD_FILAMENT_2 "G1 E40 F100"
// Unload filament commands
#define UNLOAD_FILAMENT_0 "M83"
#define UNLOAD_FILAMENT_1 "G1 E-80 F7000"
/*------------------------------------
CHANGE FILAMENT SETTINGS
*------------------------------------*/
@ -605,8 +580,6 @@
#else
#define TEMP_SENSOR_0 5
#endif
#define TEMP_SENSOR_1 0
#define TEMP_SENSOR_2 0
#if defined(E3D_PT100_BED_WITH_AMP)
#define TEMP_SENSOR_BED 247
#elif defined(E3D_PT100_BED_NO_AMP)
@ -672,14 +645,11 @@
//#define SUPPORT_VERBOSITY
#define MMU_CONFIG_FILE "mmu2/variants/config_MMU2.h"
#define MMU_FILAMENT_COUNT 5
#define MMU_REQUIRED_FW_BUILDNR 83
//#define MMU_FORCE_STEALTH_MODE
#define MMU_HWRESET
#define MMU_DEBUG //print communication between MMU2 and printer on serial
#define MMU_DEBUG //print communication between MMU and printer on serial
#define MMU_HAS_CUTTER
#define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
// MMU Error pause position
#define MMU_ERR_X_PAUSE_POS 125

View File

@ -16,9 +16,6 @@
#define FILAMENT_SIZE "1_75mm_MK3S"
#define NOZZLE_TYPE "E3Dv6full"
// Developer flag
#define DEVELOPER
// Printer name
#define CUSTOM_MENDEL_NAME "Prusa i3 MK3S"
@ -28,7 +25,7 @@
#define HAS_SECOND_SERIAL_PORT
// PSU
#define PSU_Delta // uncomment if DeltaElectronics PSU installed
// #define PSU_Delta // uncomment if DeltaElectronics PSU installed
// Uncomment the below for the E3D PT100 temperature sensor (with or without PT100 Amplifier)
@ -57,8 +54,6 @@
#define INVERT_Y_DIR 0 // for Mendel set to 1, for Orca set to 0
#define INVERT_Z_DIR 1 // for Mendel set to 0, for Orca set to 1
#define INVERT_E0_DIR 0 // for direct drive extruder v9 set to 1, for geared extruder set to 0
#define INVERT_E1_DIR 0 // for direct drive extruder v9 set to 1, for geared extruder set to 0
#define INVERT_E2_DIR 0 // for direct drive extruder v9 set to 1, for geared extruder set to 0
// Home position
#define MANUAL_X_HOME_POS 0
@ -305,8 +300,6 @@
// Mintemps
#define HEATER_0_MINTEMP 10
#define HEATER_1_MINTEMP 5
#define HEATER_2_MINTEMP 5
#define HEATER_MINTEMP_DELAY 15000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if HEATER_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see HEATER_MINTEMP_DELAY definition)"
@ -327,8 +320,6 @@
#else
#define HEATER_0_MAXTEMP 305
#endif
#define HEATER_1_MAXTEMP 305
#define HEATER_2_MAXTEMP 305
#define BED_MAXTEMP 125
#define AMBIENT_MAXTEMP 100
@ -352,8 +343,6 @@
// Extruder cooling fans
#define EXTRUDER_0_AUTO_FAN_PIN 8
#define EXTRUDER_1_AUTO_FAN_PIN -1
#define EXTRUDER_2_AUTO_FAN_PIN -1
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed
#define EXTRUDER_ALTFAN_DETECT
@ -362,20 +351,6 @@
#define FANCHECK_AUTO_PRINT_FAN_THRS 70 //[RPS] - Used during selftest to identify swapped fans automatically
#define FANCHECK_AUTO_FAIL_THRS 20 //[RPS] - Used during selftest to identify a faulty fan
/*------------------------------------
LOAD/UNLOAD FILAMENT SETTINGS
*------------------------------------*/
// Load filament commands
#define LOAD_FILAMENT_0 "M83"
#define LOAD_FILAMENT_1 "G1 E70 F400"
#define LOAD_FILAMENT_2 "G1 E40 F100"
// Unload filament commands
#define UNLOAD_FILAMENT_0 "M83"
#define UNLOAD_FILAMENT_1 "G1 E-80 F7000"
/*------------------------------------
CHANGE FILAMENT SETTINGS
*------------------------------------*/
@ -609,8 +584,6 @@
#else
#define TEMP_SENSOR_0 5
#endif
#define TEMP_SENSOR_1 0
#define TEMP_SENSOR_2 0
#if defined(E3D_PT100_BED_WITH_AMP)
#define TEMP_SENSOR_BED 247
#elif defined(E3D_PT100_BED_NO_AMP)
@ -676,12 +649,10 @@
//#define SUPPORT_VERBOSITY
#define MMU_CONFIG_FILE "mmu2/variants/config_MMU2S.h"
#define MMU_FILAMENT_COUNT 5
#define MMU_REQUIRED_FW_BUILDNR 83
//#define MMU_FORCE_STEALTH_MODE
#define MMU_HWRESET
#define MMU_DEBUG //print communication between MMU2 and printer on serial
#define MMU_DEBUG //print communication between MMU and printer on serial
#define MMU_HAS_CUTTER
// This is experimental feature requested by our test department.
@ -691,7 +662,6 @@
// defined.
//#define MMU_ALWAYS_CUT
#define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
// MMU Error pause position
#define MMU_ERR_X_PAUSE_POS 125

View File

@ -15,9 +15,6 @@ GENERAL SETTINGS
#define FILAMENT_SIZE "1_75mm_MK2"
#define NOZZLE_TYPE "E3Dv6full"
// Developer flag
#define DEVELOPER
// Printer name
#define CUSTOM_MENDEL_NAME "Prusa i3 MK2"
@ -49,9 +46,6 @@ AXIS SETTINGS
#define INVERT_Y_DIR 0 // for Mendel set to 1, for Orca set to 0
#define INVERT_Z_DIR 0 // for Mendel set to 0, for Orca set to 1
#define INVERT_E0_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
#define INVERT_E1_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
#define INVERT_E2_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
// Home position
#define MANUAL_X_HOME_POS 0
@ -105,8 +99,6 @@ EXTRUDER SETTINGS
// Mintemps
#define HEATER_0_MINTEMP 30
#define HEATER_1_MINTEMP 5
#define HEATER_2_MINTEMP 5
#define HEATER_MINTEMP_DELAY 15000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if HEATER_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see HEATER_MINTEMP_DELAY definition)"
@ -123,8 +115,6 @@ EXTRUDER SETTINGS
#else
#define HEATER_0_MAXTEMP 305
#endif
#define HEATER_1_MAXTEMP 305
#define HEATER_2_MAXTEMP 305
#define BED_MAXTEMP 150
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
@ -144,8 +134,6 @@ EXTRUDER SETTINGS
// Extruder cooling fans
#define EXTRUDER_0_AUTO_FAN_PIN 8
#define EXTRUDER_1_AUTO_FAN_PIN -1
#define EXTRUDER_2_AUTO_FAN_PIN -1
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed
@ -370,8 +358,6 @@ THERMISTORS SETTINGS
#else
#define TEMP_SENSOR_0 5
#endif
#define TEMP_SENSOR_1 0
#define TEMP_SENSOR_2 0
#if defined(E3D_PT100_BED_WITH_AMP)
#define TEMP_SENSOR_BED 247
#elif defined(E3D_PT100_BED_NO_AMP)
@ -415,13 +401,8 @@ THERMISTORS SETTINGS
#define M600_TIMEOUT 600 //seconds
#define MMU_FILAMENT_COUNT 5
#define MMU_REQUIRED_FW_BUILDNR 132
//#define SUPPORT_VERBOSITY
#define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
// Default Arc Interpolation Settings (Now configurable via M214)
#define DEFAULT_N_ARC_CORRECTION 25 // Number of interpolated segments between corrections.
/* A value of 1 or less for N_ARC_CORRECTION will trigger the use of Sin and Cos for every arc, which will improve accuracy at the

View File

@ -15,9 +15,6 @@ GENERAL SETTINGS
#define FILAMENT_SIZE "1_75mm_MK2"
#define NOZZLE_TYPE "E3Dv6full"
// Developer flag
#define DEVELOPER
// Printer name
#define CUSTOM_MENDEL_NAME "Prusa i3 MK2"
@ -49,9 +46,6 @@ AXIS SETTINGS
#define INVERT_Y_DIR 0 // for Mendel set to 1, for Orca set to 0
#define INVERT_Z_DIR 0 // for Mendel set to 0, for Orca set to 1
#define INVERT_E0_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
#define INVERT_E1_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
#define INVERT_E2_DIR 1 // for direct drive extruder v9 set to 1, for geared extruder set to 0
// Home position
#define MANUAL_X_HOME_POS 0
@ -104,8 +98,6 @@ EXTRUDER SETTINGS
// Mintemps
#define HEATER_0_MINTEMP 30
#define HEATER_1_MINTEMP 5
#define HEATER_2_MINTEMP 5
#define HEATER_MINTEMP_DELAY 15000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if HEATER_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see HEATER_MINTEMP_DELAY definition)"
@ -122,8 +114,6 @@ EXTRUDER SETTINGS
#else
#define HEATER_0_MAXTEMP 305
#endif
#define HEATER_1_MAXTEMP 305
#define HEATER_2_MAXTEMP 305
#define BED_MAXTEMP 150
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
@ -143,8 +133,6 @@ EXTRUDER SETTINGS
// Extruder cooling fans
#define EXTRUDER_0_AUTO_FAN_PIN 8
#define EXTRUDER_1_AUTO_FAN_PIN -1
#define EXTRUDER_2_AUTO_FAN_PIN -1
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed
@ -369,8 +357,6 @@ THERMISTORS SETTINGS
#else
#define TEMP_SENSOR_0 5
#endif
#define TEMP_SENSOR_1 0
#define TEMP_SENSOR_2 0
#if defined(E3D_PT100_BED_WITH_AMP)
#define TEMP_SENSOR_BED 247
#elif defined(E3D_PT100_BED_NO_AMP)
@ -414,13 +400,8 @@ THERMISTORS SETTINGS
#define M600_TIMEOUT 600 //seconds
#define MMU_FILAMENT_COUNT 5
#define MMU_REQUIRED_FW_BUILDNR 132
//#define SUPPORT_VERBOSITY
#define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
// Default Arc Interpolation Settings (Now configurable via M214)
#define DEFAULT_N_ARC_CORRECTION 25 // Number of interpolated segments between corrections.
/* A value of 1 or less for N_ARC_CORRECTION will trigger the use of Sin and Cos for every arc, which will improve accuracy at the

View File

@ -415,22 +415,20 @@ void print_hysteresis(int16_t min_z, int16_t max_z, int16_t step){
}
}
void update_position_1_step(uint8_t axis, uint8_t dir){
if (axis & X_AXIS_MASK)
_X_ += dir & X_AXIS_MASK ? -1 : 1;
if (axis & Y_AXIS_MASK)
_Y_ += dir & Y_AXIS_MASK ? -1 : 1;
if (axis & Z_AXIS_MASK)
_Z_ += dir & Z_AXIS_MASK ? -1 : 1;
static void update_position_1_step(const uint8_t axis, const uint8_t dir) {
for (uint8_t i = X_AXIS, mask = X_AXIS_MASK; i <= Z_AXIS; i++, mask <<= 1) {
if (axis & mask) {
count_position[i] += dir & mask ? -1L : 1L;
}
}
}
void set_axes_dir(uint8_t axes, uint8_t dir){
if (axes & X_AXIS_MASK)
sm4_set_dir(X_AXIS, dir & X_AXIS_MASK);
if (axes & Y_AXIS_MASK)
sm4_set_dir(Y_AXIS, dir & Y_AXIS_MASK);
if (axes & Z_AXIS_MASK)
sm4_set_dir(Z_AXIS, dir & Z_AXIS_MASK);
static void __attribute__((noinline)) set_axes_dir(const uint8_t axis, const uint8_t dir) {
for (uint8_t i = X_AXIS, mask = X_AXIS_MASK; i <= Z_AXIS; i++, mask <<= 1) {
if (axis & mask) {
sm4_set_dir(i, dir & mask);
}
}
}
/// Accelerate up to max.speed (defined by @min_delay_us)

View File

@ -240,7 +240,7 @@ fi
if [[ "$MK404_PRINTER" == "MK25" || "$MK404_PRINTER" == "MK25S" ]]; then
MK404_PRINTER="${MK404_PRINTER}_mR13"
else
if [ "$mk404_flag" == "2" ]; then # Check if MMU2 is selected only for MK3/S
if [ "$mk404_flag" == "2" ]; then # Check if MMU is selected only for MK3/S
MK404_PRINTER="${MK404_PRINTER}MMU2"
fi
fi

View File

@ -1511,7 +1511,7 @@ if [[ "$output_flag" == "1" || -z "$output_flag" ]]; then
fi
# For MMU2S
if [[ "$mk404_flag" == "2" || "$mk404_flag" == "MMU2" || "$mk404_flag" == "MMU2S" ]]; then # Check if MMU2 is selected only for MK3/S
if [[ "$mk404_flag" == "2" || "$mk404_flag" == "MMU2" || "$mk404_flag" == "MMU2S" ]]; then # Check if MMU is selected only for MK3/S
mk404_flag=2
fi

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff