Merge branch 'MK3_3.9.0' into flashair_display_ip

This commit is contained in:
odaki 2020-04-28 00:14:47 +09:00
commit c34c622b3c
39 changed files with 1934 additions and 1125 deletions

View File

@ -16,8 +16,8 @@ extern uint16_t nPrinterType;
extern PGM_P sPrinterName;
// Firmware version
#define FW_VERSION "3.9.0"
#define FW_COMMIT_NR 3175
#define FW_VERSION "3.9.0-RC2"
#define FW_COMMIT_NR 3398
// FW_VERSION_UNKNOWN means this is an unofficial build.
// The firmware should only be checked into github with this symbol.
#define FW_DEV_VERSION FW_VERSION_UNKNOWN
@ -424,7 +424,7 @@ your extruder heater takes 2 minutes to hit the target on heating.
#define DEFAULT_XJERK 10 // (mm/sec)
#define DEFAULT_YJERK 10 // (mm/sec)
#define DEFAULT_ZJERK 0.4 // (mm/sec)
#define DEFAULT_EJERK 2.5 // (mm/sec)
#define DEFAULT_EJERK 4.5 // (mm/sec)
//===========================================================================
//=============================Additional Features===========================

View File

@ -152,7 +152,6 @@
#define Z_HOME_RETRACT_MM 2
//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially.
#define AXIS_RELATIVE_MODES {0, 0, 0, 0}
#define MAX_STEP_FREQUENCY 40000 // Max step frequency for Ultimaker (5000 pps / half step). Toshiba steppers are 4x slower, but Prusa3D does not use those.
//By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
#define INVERT_X_STEP_PIN 0

View File

@ -1,5 +1,6 @@
#include "Dcodes.h"
//#include "Marlin.h"
#include "Configuration.h"
#include "language.h"
#include "cmdqueue.h"
#include <stdio.h>
@ -97,19 +98,25 @@ void print_mem(uint32_t address, uint16_t count, uint8_t type, uint8_t countperl
}
}
#ifdef DEBUG_DCODE3
#if defined DEBUG_DCODE3 || defined DEBUG_DCODES
#define EEPROM_SIZE 0x1000
/*!
*
### D3 - Read/Write EEPROM <a href="https://reprap.org/wiki/G-code#D3:_Read.2FWrite_EEPROM">D3: Read/Write EEPROM</a>
This command can be used without any additional parameters. It will read the entire eeprom.
D3 [ A | C | X ]
- `A` - Address (0x0000-0x0fff)
- `C` - Count (0x0001-0x1000)
- `X` - Data
*
#### Usage
D3 [ A | C | X ]
#### Parameters
- `A` - Address (x0000-x0fff)
- `C` - Count (1-4096)
- `X` - Data (hex)
#### Notes
- The hex address needs to be lowercase without the 0 before the x
- Count is decimal
- The hex data needs to be lowercase
*/
void dcode_3()
{
@ -179,7 +186,6 @@ void dcode_3()
#define BOOT_APP_FLG_COPY 0x02
#define BOOT_APP_FLG_FLASH 0x04
extern uint8_t fsensor_log;
extern float current_temperature_pinda;
extern float axis_steps_per_unit[NUM_AXIS];
@ -206,13 +212,13 @@ void dcode__1()
#ifdef DEBUG_DCODES
/*!
*
### D0 - Reset <a href="https://reprap.org/wiki/G-code#D0:_Reset">D0: Reset</a>
D0 [ B ]
- `B` - Bootloader
*
#### Usage
D0 [ B ]
#### Parameters
- `B` - Bootloader
*/
void dcode_0()
{
@ -251,16 +257,22 @@ void dcode_1()
}
/*!
*
### D2 - Read/Write RAM <a href="https://reprap.org/wiki/G-code#D2:_Read.2FWrite_RAM">D3: Read/Write RAM</a>
This command can be used without any additional parameters. It will read the entire RAM.
D3 [ A | C | X ]
- `A` - Address (0x0000-0x1fff)
- `C` - Count (0x0001-0x2000)
- `X` - Data
*
#### Usage
D2 [ A | C | X ]
#### Parameters
- `A` - Address (x0000-x1fff)
- `C` - Count (1-8192)
- `X` - Data
#### Notes
- The hex address needs to be lowercase without the 0 before the x
- Count is decimal
- The hex data needs to be lowercase
*/
void dcode_2()
{
@ -306,17 +318,17 @@ void dcode_2()
}
/*!
*
### D4 - Read/Write PIN <a href="https://reprap.org/wiki/G-code#D4:_Read.2FWrite_PIN">D4: Read/Write PIN</a>
### D4 - Read/Write PIN <a href="https://reprap.org/wiki/G-code#D4:_Read.2FWrite_PIN">D4: Read/Write PIN</a>
To read the digital value of a pin you need only to define the pin number.
D4 [ P | F | V ]
- `P` - Pin (0-255)
- `F` - Function in/out (0/1)
- `V` - Value (0/1)
*
#### Usage
D4 [ P | F | V ]
#### Parameters
- `P` - Pin (0-255)
- `F` - Function in/out (0/1)
- `V` - Value (0/1)
*/
void dcode_4()
{
@ -348,21 +360,27 @@ void dcode_4()
}
#endif //DEBUG_DCODES
#ifdef DEBUG_DCODE5
#if defined DEBUG_DCODE5 || defined DEBUG_DCODES
/*!
*
### D5 - Read/Write FLASH <a href="https://reprap.org/wiki/G-code#D5:_Read.2FWrite_FLASH">D5: Read/Write Flash</a>
This command can be used without any additional parameters. It will read the 1kb FLASH.
D3 [ A | C | X | E ]
- `A` - Address (0x00000-0x3ffff)
- `C` - Count (0x0001-0x2000)
- `X` - Data
- `E` - Erase
*
*/
#### Usage
D5 [ A | C | X | E ]
#### Parameters
- `A` - Address (x00000-x3ffff)
- `C` - Count (1-8192)
- `X` - Data (hex)
- `E` - Erase
#### Notes
- The hex address needs to be lowercase without the 0 before the x
- Count is decimal
- The hex data needs to be lowercase
*/
void dcode_5()
{
printf_P(PSTR("D5 - Read/Write FLASH\n"));
@ -427,24 +445,18 @@ void dcode_5()
#ifdef DEBUG_DCODES
/*!
*
### D6 - Read/Write external FLASH <a href="https://reprap.org/wiki/G-code#D6:_Read.2FWrite_external_FLASH">D6: Read/Write external Flash</a>
Reserved
*
*/
*/
void dcode_6()
{
LOG("D6 - Read/Write external FLASH\n");
}
/*!
*
### D7 - Read/Write Bootloader <a href="https://reprap.org/wiki/G-code#D7:_Read.2FWrite_Bootloader">D7: Read/Write Bootloader</a>
Reserved
*
*/
*/
void dcode_7()
{
LOG("D7 - Read/Write Bootloader\n");
@ -461,16 +473,16 @@ void dcode_7()
}
/*!
*
### D8 - Read/Write PINDA <a href="https://reprap.org/wiki/G-code#D8:_Read.2FWrite_PINDA">D8: Read/Write PINDA</a>
D8 [ ? | ! | P | Z ]
- `?` - Read PINDA temperature shift values
- `!` - Reset PINDA temperature shift values to default
- `P` - Pinda temperature [C]
- `Z` - Z Offset [mm]
*
#### Usage
D8 [ ? | ! | P | Z ]
#### Parameters
- `?` - Read PINDA temperature shift values
- `!` - Reset PINDA temperature shift values to default
- `P` - Pinda temperature [C]
- `Z` - Z Offset [mm]
*/
void dcode_8()
{
@ -514,21 +526,21 @@ void dcode_8()
}
/*!
*
### D9 - Read ADC <a href="https://reprap.org/wiki/G-code#D9:_Read.2FWrite_ADC">D9: Read ADC</a>
D9 [ I | V ]
- `I` - ADC channel index
- `0` - Heater 0 temperature
- `1` - Heater 1 temperature
- `2` - Bed temperature
- `3` - PINDA temperature
- `4` - PWR voltage
- `5` - Ambient temperature
- `6` - BED voltage
- `V` Value to be written as simulated
*
#### Usage
D9 [ I | V ]
#### Parameters
- `I` - ADC channel index
- `0` - Heater 0 temperature
- `1` - Heater 1 temperature
- `2` - Bed temperature
- `3` - PINDA temperature
- `4` - PWR voltage
- `5` - Ambient temperature
- `6` - BED voltage
- `V` Value to be written as simulated
*/
const char* dcode_9_ADC_name(uint8_t i)
{
@ -604,11 +616,8 @@ void dcode_9()
}
/*!
*
### D10 - Set XYZ calibration = OK <a href="https://reprap.org/wiki/G-code#D10:_Set_XYZ_calibration_.3D_OK">D10: Set XYZ calibration = OK</a>
*
*/
*/
void dcode_10()
{//Tell the printer that XYZ calibration went OK
LOG("D10 - XYZ calibration = OK\n");
@ -616,54 +625,168 @@ void dcode_10()
}
/*!
*
### D12 - Time <a href="https://reprap.org/wiki/G-code#D12:_Time">D12: Time</a>
*
*/
Writes the current time in the log file.
*/
void dcode_12()
{//Time
LOG("D12 - Time\n");
}
#ifdef HEATBED_ANALYSIS
/*!
### D80 - Bed check <a href="https://reprap.org/wiki/G-code#D80:_Bed_check">D80: Bed check</a>
This command will log data to SD card file "mesh.txt".
#### Usage
D80 [ E | F | G | H | I | J ]
#### Parameters
- `E` - Dimension X (default 40)
- `F` - Dimention Y (default 40)
- `G` - Points X (default 40)
- `H` - Points Y (default 40)
- `I` - Offset X (default 74)
- `J` - Offset Y (default 34)
*/
void dcode_80()
{
float dimension_x = 40;
float dimension_y = 40;
int points_x = 40;
int points_y = 40;
float offset_x = 74;
float offset_y = 33;
if (code_seen('E')) dimension_x = code_value();
if (code_seen('F')) dimension_y = code_value();
if (code_seen('G')) {points_x = code_value(); }
if (code_seen('H')) {points_y = code_value(); }
if (code_seen('I')) {offset_x = code_value(); }
if (code_seen('J')) {offset_y = code_value(); }
printf_P(PSTR("DIM X: %f\n"), dimension_x);
printf_P(PSTR("DIM Y: %f\n"), dimension_y);
printf_P(PSTR("POINTS X: %d\n"), points_x);
printf_P(PSTR("POINTS Y: %d\n"), points_y);
printf_P(PSTR("OFFSET X: %f\n"), offset_x);
printf_P(PSTR("OFFSET Y: %f\n"), offset_y);
bed_check(dimension_x,dimension_y,points_x,points_y,offset_x,offset_y);
}
/*!
### D81 - Bed analysis <a href="https://reprap.org/wiki/G-code#D81:_Bed_analysis">D80: Bed analysis</a>
This command will log data to SD card file "wldsd.txt".
#### Usage
D81 [ E | F | G | H | I | J ]
#### Parameters
- `E` - Dimension X (default 40)
- `F` - Dimention Y (default 40)
- `G` - Points X (default 40)
- `H` - Points Y (default 40)
- `I` - Offset X (default 74)
- `J` - Offset Y (default 34)
*/
void dcode_81()
{
float dimension_x = 40;
float dimension_y = 40;
int points_x = 40;
int points_y = 40;
float offset_x = 74;
float offset_y = 33;
if (code_seen('E')) dimension_x = code_value();
if (code_seen('F')) dimension_y = code_value();
if (code_seen("G")) { strchr_pointer+=1; points_x = code_value(); }
if (code_seen("H")) { strchr_pointer+=1; points_y = code_value(); }
if (code_seen("I")) { strchr_pointer+=1; offset_x = code_value(); }
if (code_seen("J")) { strchr_pointer+=1; offset_y = code_value(); }
bed_analysis(dimension_x,dimension_y,points_x,points_y,offset_x,offset_y);
}
#endif //HEATBED_ANALYSIS
/*!
### D106 - Print measured fan speed for different pwm values <a href="https://reprap.org/wiki/G-code#D106:_Print_measured_fan_speed_for_different_pwm_values">D106: Print measured fan speed for different pwm values</a>
*/
void dcode_106()
{
for (int i = 255; i > 0; i = i - 5) {
fanSpeed = i;
//delay_keep_alive(2000);
for (int j = 0; j < 100; j++) {
delay_keep_alive(100);
}
printf_P(_N("%d: %d\n"), i, fan_speed[1]);
}
}
#ifdef TMC2130
#include "planner.h"
#include "tmc2130.h"
extern void st_synchronize();
/**
* @brief D2130 Trinamic stepper controller
* D2130<axis><command>[subcommand][value]
* * Axis
* * * 'X'
* * * 'Y'
* * * 'Z'
* * * 'E'
* * command
* * * '0' current off
* * * '1' current on
* * * '+' single step
* * * * value sereval steps
* * * '-' dtto oposite direction
* * * '?' read register
* * * * "mres"
* * * * "step"
* * * * "mscnt"
* * * * "mscuract"
* * * * "wave"
* * * '!' set register
* * * * "mres"
* * * * "step"
* * * * "wave"
* * * * *0, 180..250 meaning: off, 0.9..1.25, recommended value is 1.1
* * * '@' home calibrate axis
*
* Example:
* D2130E?wave //print extruder microstep linearity compensation curve
* D2130E!wave0 //disable extruder linearity compensation curve, (sine curve is used)
* D2130E!wave220 // (sin(x))^1.1 extruder microstep compensation curve used
*/
/*!
### D2130 - Trinamic stepper controller <a href="https://reprap.org/wiki/G-code#D2130:_Trinamic_stepper_controller">D2130: Trinamic stepper controller</a>
@todo Please review by owner of the code. RepRap Wiki Gcode needs to be updated after review of owner as well.
#### Usage
D2130 [ Axis | Command | Subcommand | Value ]
#### Parameters
- Axis
- `X` - X stepper driver
- `Y` - Y stepper driver
- `Z` - Z stepper driver
- `E` - Extruder stepper driver
- Commands
- `0` - Current off
- `1` - Current on
- `+` - Single step
- `-` - Single step oposite direction
- `NNN` - Value sereval steps
- `?` - Read register
- Subcommands for read register
- `mres` - Micro step resolution. More information in datasheet '5.5.2 CHOPCONF Chopper Configuration'
- `step` - Step
- `mscnt` - Microstep counter. More information in datasheet '5.5 Motor Driver Registers'
- `mscuract` - Actual microstep current for motor. More information in datasheet '5.5 Motor Driver Registers'
- `wave` - Microstep linearity compensation curve
- `!` - Set register
- Subcommands for set register
- `mres` - Micro step resolution
- `step` - Step
- `wave` - Microstep linearity compensation curve
- Values for set register
- `0, 180 --> 250` - Off
- `0.9 --> 1.25` - Valid values (recommended is 1.1)
- `@` - Home calibrate axis
Examples:
D2130E?wave
Print extruder microstep linearity compensation curve
D2130E!wave0
Disable extruder linearity compensation curve, (sine curve is used)
D2130E!wave220
(sin(x))^1.1 extruder microstep compensation curve used
Notes:
For more information see https://www.trinamic.com/fileadmin/assets/Products/ICs_Documents/TMC2130_datasheet.pdf
*
*/
void dcode_2130()
{
printf_P(PSTR("D2130 - TMC2130\n"));
@ -767,18 +890,18 @@ void dcode_2130()
#ifdef PAT9125
/*!
*
### D9125 - PAT9125 filament sensor <a href="https://reprap.org/wiki/G-code#D9:_Read.2FWrite_ADC">D9125: PAT9125 filament sensor</a>
D9125 [ ? | ! | R | X | Y | L ]
- `?` - Print values
- `!` - Print values
- `R` - Resolution. Not active in code
- `X` - X values
- `Y` - Y values
- `L` - Activate filament sensor log
*
#### Usage
D9125 [ ? | ! | R | X | Y | L ]
#### Parameters
- `?` - Print values
- `!` - Print values
- `R` - Resolution. Not active in code
- `X` - X values
- `Y` - Y values
- `L` - Activate filament sensor log
*/
void dcode_9125()
{
@ -812,11 +935,13 @@ void dcode_9125()
pat9125_y = (int)code_value();
LOG("pat9125_y=%d\n", pat9125_y);
}
#ifdef DEBUG_FSENSOR_LOG
if (code_seen('L'))
{
fsensor_log = (int)code_value();
LOG("fsensor_log=%d\n", fsensor_log);
}
#endif //DEBUG_FSENSOR_LOG
}
#endif //PAT9125

View File

@ -2,26 +2,40 @@
#define DCODES_H
extern void dcode__1(); //D-1 - Endless loop (to simulate deadlock)
extern void dcode_0(); //D0 - Reset
extern void dcode_1(); //D1 - Clear EEPROM
extern void dcode_2(); //D2 - Read/Write RAM
#if defined DEBUG_DCODE3 || defined DEBUG_DCODES
extern void dcode_3(); //D3 - Read/Write EEPROM
#endif //DEBUG_DCODE3
extern void dcode_4(); //D4 - Read/Write PIN
#if defined DEBUG_DCODE5 || defined DEBUG_DCODES
extern void dcode_5(); //D5 - Read/Write FLASH
#endif //DEBUG_DCODE5
extern void dcode_6(); //D6 - Read/Write external FLASH
extern void dcode_7(); //D7 - Read/Write Bootloader
extern void dcode_8(); //D8 - Read/Write PINDA
extern void dcode_9(); //D9 - Read/Write ADC (Write=enable simulated, Read=disable simulated)
extern void dcode_10(); //D10 - XYZ calibration = OK
extern void dcode_12(); //D12 - Log time. Writes the current time in the log file.
#ifdef HEATBED_ANALYSIS
extern void dcode_80(); //D80 - Bed check. This command will log data to SD card file "mesh.txt".
extern void dcode_81(); //D81 - Bed analysis. This command will log data to SD card file "wldsd.txt".
#endif //HEATBED_ANALYSIS
extern void dcode_106(); //D106 - Print measured fan speed for different pwm values
#ifdef TMC2130
extern void dcode_2130(); //D2130 - TMC2130
extern void dcode_2130(); //D2130 - TMC2130
#endif //TMC2130
#ifdef PAT9125
extern void dcode_9125(); //D9125 - PAT9125
extern void dcode_9125(); //D9125 - PAT9125
#endif //PAT9125

View File

@ -146,40 +146,39 @@ void manage_inactivity(bool ignore_stepper_queue=false);
#if defined(Z_ENABLE_PIN) && Z_ENABLE_PIN > -1
#if defined(Z_AXIS_ALWAYS_ON)
#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; }
#define poweron_z() { WRITE(Z_ENABLE_PIN, Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN, Z_ENABLE_ON); }
#define poweroff_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() {}
#define poweron_z() WRITE(Z_ENABLE_PIN, Z_ENABLE_ON)
#define poweroff_z() {}
#endif
#else
#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; }
#define poweron_z() { WRITE(Z_ENABLE_PIN, Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN, Z_ENABLE_ON); }
#define poweroff_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; }
#define poweron_z() WRITE(Z_ENABLE_PIN, Z_ENABLE_ON)
#define poweroff_z() { WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }
#endif
#endif
#else
#define enable_z() {}
#define disable_z() {}
#define poweron_z() {}
#define poweroff_z() {}
#endif
#ifdef PSU_Delta
#ifndef PSU_Delta
#define enable_z() poweron_z()
#define disable_z() poweroff_z()
#else
void init_force_z();
void check_force_z();
#undef disable_z
#define disable_z() disable_force_z()
void disable_force_z();
#undef enable_z
#define enable_z() enable_force_z()
void enable_force_z();
void disable_force_z();
#define enable_z() enable_force_z()
#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); }
@ -295,7 +294,7 @@ void setPwmFrequency(uint8_t pin, int val);
extern bool fans_check_enabled;
extern float homing_feedrate[];
extern bool axis_relative_modes[];
extern uint8_t axis_relative_modes;
extern float feedrate;
extern int feedmultiply;
extern int extrudemultiply; // Sets extrude multiply factor (in percent) for all extruders
@ -445,9 +444,8 @@ void setup_uvlo_interrupt();
void setup_fan_interrupt();
#endif
//extern void recover_machine_state_after_power_panic();
extern void recover_machine_state_after_power_panic(bool bTiny);
extern void restore_print_from_eeprom();
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();

File diff suppressed because it is too large Load Diff

View File

@ -136,8 +136,17 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
SERIAL_ECHOPGM("Access date: ");
MYSERIAL.println(p.lastAccessDate);
SERIAL_ECHOLNPGM("");*/
modificationDate = p.lastWriteDate;
modificationTime = p.lastWriteTime;
crmodDate = p.lastWriteDate;
crmodTime = p.lastWriteTime;
// There are scenarios when simple modification time is not enough (on MS Windows)
// For example - extract an old g-code from an archive onto the SD card.
// In such case the creation time is current time (which is correct), but the modification time
// stays the same - i.e. old.
// Therefore let's pick the most recent timestamp from both creation and modification timestamps
if( crmodDate < p.creationDate || ( crmodDate == p.creationDate && crmodTime < p.creationTime ) ){
crmodDate = p.creationDate;
crmodTime = p.creationTime;
}
//writeDate = p.lastAccessDate;
if (match != NULL) {
if (strcasecmp(match, filename) == 0) return;
@ -773,8 +782,8 @@ void CardReader::presort() {
// retaining only two filenames at a time. This is very
// slow but is safest and uses minimal RAM.
char name1[LONG_FILENAME_LENGTH + 1];
uint16_t modification_time_bckp;
uint16_t modification_date_bckp;
uint16_t crmod_time_bckp;
uint16_t crmod_date_bckp;
#endif
position = 0;
@ -800,8 +809,8 @@ void CardReader::presort() {
#else
// Copy filenames into the static array
strcpy(sortnames[i], LONGEST_FILENAME);
modification_time[i] = modificationTime;
modification_date[i] = modificationDate;
modification_time[i] = crmodTime;
modification_date[i] = crmodDate;
#if SDSORT_CACHE_NAMES
strcpy(sortshort[i], filename);
#endif
@ -830,8 +839,8 @@ void CardReader::presort() {
(modification_date[o1] < modification_date [o2]))
#else
#define _SORT_CMP_NODIR() (strcasecmp(name1, name2) > 0) //true if lowercase(name1) > lowercase(name2)
#define _SORT_CMP_TIME_NODIR() (((modification_date_bckp == modificationDate) && (modification_time_bckp > modificationTime)) || \
(modification_date_bckp > modificationDate))
#define _SORT_CMP_TIME_NODIR() (((crmod_date_bckp == crmodDate) && (crmod_time_bckp > crmodTime)) || \
(crmod_date_bckp > crmodDate))
#endif
@ -882,8 +891,8 @@ void CardReader::presort() {
counter++;
getfilename_simple(positions[o1]);
strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it)
modification_date_bckp = modificationDate;
modification_time_bckp = modificationTime;
crmod_date_bckp = crmodDate;
crmod_time_bckp = crmodTime;
#if HAS_FOLDER_SORTING
bool dir1 = filenameIsDir;
#endif

View File

@ -75,7 +75,9 @@ public:
bool sdprinting ;
bool cardOK ;
char filename[13];
uint16_t modificationTime, modificationDate;
// There are scenarios when simple modification time is not enough (on MS Windows)
// Therefore these timestamps hold the most recent one of creation/modification date/times
uint16_t crmodTime, crmodDate;
uint32_t cluster, position;
char longFilename[LONG_FILENAME_LENGTH];
bool filenameIsDir;

View File

@ -5,10 +5,12 @@
#include "Configuration_prusa.h"
#include "pins.h"
#define IR_SENSOR_ANALOG (defined(VOLT_IR_PIN) && defined(IR_SENSOR))
#if (defined(VOLT_IR_PIN) && defined(IR_SENSOR))
# define IR_SENSOR_ANALOG
#endif
//ADC configuration
#if !IR_SENSOR_ANALOG
#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)
@ -34,7 +36,8 @@
//#define PAT9125_I2C_ADDR 0x79 //ID=HI
//#define PAT9125_I2C_ADDR 0x73 //ID=NC
#define PAT9125_XRES 0
#define PAT9125_YRES 240
#define PAT9125_YRES 240 // maximum resolution (5*X cpi)
#define PAT9124_YRES_MM (5*PAT9125_YRES/25.4) // counts per mm
//SM4 configuration
#define SM4_DEFDELAY 500 //default step delay [us]
@ -55,7 +58,7 @@
#define W25X20CL_SPSR SPI_SPSR(W25X20CL_SPI_RATE)
//LANG - Multi-language support
//define LANG_MODE 0 // primary language only
//#define LANG_MODE 0 // primary language only
#define LANG_MODE 1 // sec. language support
#define LANG_SIZE_RESERVED 0x3000 // reserved space for secondary language (12288 bytes)

View File

@ -1,3 +1,13 @@
/**
* @file
* @author 3d-gussner
*/
/** \ingroup eeprom_table */
//! _This is a EEPROM table of currently implemented in Prusa firmware (dynamically generated from doxygen)._
#ifndef EEPROM_H
#define EEPROM_H
@ -26,6 +36,338 @@ typedef struct
#ifdef __cplusplus
static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEPROM_SHEETS_SIZEOF.");
#endif
/** @defgroup eeprom_table EEPROM Table
*
---------------------------------------------------------------------------------
EEPROM 8-bit Empty value = 0xFFh 255
EEPROM 16-bit Empty value = 0xFFFFh 65535
_Italic = unused or default_
__Bold = Status__
In Default/FactoryReset column the
- __L__ Language
- __S__ Statistics
- __P__ Shipping prep
- __S/P__ Statistics and Shipping prep
will overwrite existing values to 0 or default.
A FactoryReset All Data will overwrite the whole EEPROM with ffh and some values will be initialized automatically,
others need a reset / reboot.
---------------------------------------------------------------------------------
How can you use the debug codes?
- Serial terminal like Putty.
- Octoprint does support D-codes
- _Pronterface_ does __not__ support D-codes
### !!! D-codes are case sensitive so please don't use upper case A,C or X in the address you want to read !!!
#### Useful tools/links:
To convert hex to ascii https://www.rapidtables.com/convert/number/hex-to-ascii.html
To convert hex to dec https://www.rapidtables.com/convert/number/hex-to-decimal.html
Version: 1.0.1
---------------------------------------------------------------------------------
| Address begin | Bit/Type | Name | Valid values | Default/FactoryReset | Description | Gcode/Function| Debug code
| :-- | :-- | :-- | :--: | :--: | :-- | :--: | :--:
| 0x0FFFh 4095 | uchar | EEPROM_SILENT | 00h 0 | ffh 255 | TMC Stealth mode: __off__ / miniRambo Power mode | LCD menu | D3 Ax0fff C1
| ^ | ^ | ^ | 01h 1 | ^ | TMC Stealth mode: __on__ / miniRambo Silent mode | ^ | ^
| 0x0FFEh 4094 | uchar | EEPROM_LANG | 00h 0 | ffh 255 __L__ | English / LANG_ID_PRI | LCD menu | D3 Ax0ffe C1
| ^ | ^ | ^ | 01h 1 | ^ | Other language LANG_ID_SEC | ^ | ^
| 0x0FFCh 4092 | uint16 | EEPROM_BABYSTEP_X | ??? | ff ffh 65535 | Babystep for X axis _unsued_ | ??? | D3 Ax0ffc C2
| 0x0FFAh 4090 | uint16 | EEPROM_BABYSTEP_Y | ??? | ff ffh 65535 | Babystep for Y axis _unsued_ | ^ | D3 Ax0ffa C2
| 0x0FF8h 4088 | uint16 | EEPROM_BABYSTEP_Z | ??? | ff ffh 65535 | Babystep for Z axis _lagacy_ | ^ | D3 Ax0ff8 C2
| ^ | ^ | ^ | ^ | ^ | multiple values stored now in EEPROM_Sheets_base | ^ | ^
| 0x0FF7h 4087 | uint8 | EEPROM_CALIBRATION_STATUS | ffh 255 | ffh 255 | Assembled _default_ | ??? | D3 Ax0ff7 C1
| ^ | ^ | ^ | 01h 1 | ^ | Calibrated | ^ | ^
| ^ | ^ | ^ | e6h 230 | ^ | needs Live Z adjustment | ^ | ^
| ^ | ^ | ^ | f0h 240 | ^ __P__ | needs Z calibration | ^ | ^
| ^ | ^ | ^ | fah 250 | ^ | needs XYZ calibration | ^ | ^
| ^ | ^ | ^ | 00h 0 | ^ | Unknown | ^ | ^
| 0x0FF5h 4085 | uint16 | EEPROM_BABYSTEP_Z0 | ??? | ff ffh 65535 | Babystep for Z ??? | ??? | D3 Ax0ff5 C2
| 0x0FF1h 4081 | uint32 | EEPROM_FILAMENTUSED | ??? | 00 00 00 00h 0 __S/P__| Filament used in meters | ??? | D3 Ax0ff1 C4
| 0x0FEDh 4077 | uint32 | EEPROM_TOTALTIME | ??? | 00 00 00 00h 0 __S/P__| Total print time | ??? | D3 Ax0fed C4
| 0x0FE5h 4069 | float | EEPROM_BED_CALIBRATION_CENTER | ??? | ff ff ff ffh | ??? | ??? | D3 Ax0fe5 C8
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| 0x0FDDh 4061 | float | EEPROM_BED_CALIBRATION_VEC_X | ??? | ff ff ff ffh | ??? | ??? | D3 Ax0fdd C8
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| 0x0FD5h 4053 | float | EEPROM_BED_CALIBRATION_VEC_Y | ??? | ff ff ff ffh | ??? | ??? | D3 Ax0fd5 C8
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| 0x0FC5h 4037 | int16 | EEPROM_BED_CALIBRATION_Z_JITTER | ??? | ff ffh 65535 | ??? | ??? | D3 Ax0fc5 C16
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| 0x0FC4h 4036 | bool | EEPROM_FARM_MODE | 00h 0 | ffh 255 __P__ | Prusa farm mode: __off__ | G99 | D3 Ax0fc4 C1
| ^ | ^ | ^ | 01h 1 | ^ | Prusa farm mode: __on__ | G98 | ^
| 0x0FC3h 4035 | free | _EEPROM_FREE_NR1_ | ??? | ffh 255 | _Free EEPROM space_ | _free space_ | D3 Ax0fc3 C1
| 0x0FC1h 4033 | ??? | EEPROM_FARM_NUMBER | 000-999 | ff ffh / 000 __P__ | Prusa farm number _only 0-9 are allowed: 000-999_ | LCD menu | D3 Ax0fc1 C2
| 0x0FC0h 4032 | bool | EEPROM_BED_CORRECTION_VALID | 00h 0 | 00h 0 | Bed correction invalid | ??? | D3 Ax0fc0 C1
| ^ | ^ | ^ | ffh 255 | | Bed correction valid | ??? | ^
| 0x0FBFh 4031 | char | EEPROM_BED_CORRECTION_LEFT | 00h ffh | 00h 0 | Bed manual correction left | LCD menu | D3 Ax0fbf C1
| ^ | ^ | ^ | ^ | ^ | At this moment limited to +-100um | G80 Lxxx | ^
| 0x0FBEh 4030 | char | EEPROM_BED_CORRECTION_RIGHT | 00h ffh | 00h 0 | Bed manual correction right | LCD menu | D3 Ax0fbe C1
| ^ | ^ | ^ | ^ | ^ | At this moment limited to +-100um | G80 Rxxx | ^
| 0x0FBDh 4029 | char | EEPROM_BED_CORRECTION_FRONT | 00h ffh | 00h 0 | Bed manual correction front | LCD menu | D3 Ax0fbd C1
| ^ | ^ | ^ | ^ | ^ | At this moment limited to +-100um | G80 Fxxx | ^
| 0x0FBCh 4028 | char | EEPROM_BED_CORRECTION_BACK | 00h ffh | 00h 0 | Bed manual correction back | LCD menu | D3 Ax0fbc C1
| ^ | ^ | ^ | ^ | ^ | At this moment limited to +-100um | G80 Bxxx | ^
| 0x0FBBh 4027 | bool | EEPROM_TOSHIBA_FLASH_AIR_COMPATIBLITY | 00h 0 | ffh 255 | Toshiba Air: __off__ | LCD menu | D3 Ax0fbb C1
| ^ | ^ | ^ | 01h 1 | ^ | Toshiba Air: __on__ | ^ | ^
| 0x0FBAh 4026 | uchar | EEPROM_PRINT_FLAG | ??? | ??? | _unsued_ | ??? | D3 Ax0fba C1
| 0x0FB0h 4016 | int16 | EEPROM_PROBE_TEMP_SHIFT | ??? | ??? | ??? | ??? | D3 Ax0fb0 C10
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| 0x0FAFh 4015 | bool | EEPROM_TEMP_CAL_ACTIVE | 00h 0 | 00h 0 | PINDA Temp cal.: __inactive__ | LCD menu | D3 Ax0faf C1
| ^ | ^ | ^ | ffh 255 | ^ | PINDA Temp cal.: __active__ | ^ | ^
| 0x0FA7h 4007 | uint32 | EEPROM_BOWDEN_LENGTH | ??? | ff 00 00 00h | Bowden length | ??? | D3 Ax0fae C8
| ^ | ^ | ^ | ^ | 00 00 00 00h | ^ | ^ | ^
| 0x0FA6h 4006 | uint8 | EEPROM_CALIBRATION_STATUS_PINDA | 00h 0 | ffh 255 | PINDA Temp: __not calibrated__ | ??? | D3 Ax0fa6 C1
| ^ | ^ | ^ | 01h 1 | ^ | PINDA Temp: __calibrated__ | ^ | ^
| 0x0FA5h 4005 | uint8 | EEPROM_UVLO | 00h 0 | ffh 255 | Power Panic flag: __inactive__ | ??? | D3 Ax0fa5 C1
| ^ | ^ | ^ | 01h 1 | ^ | Power Panic flag: __active__ | ^ | ^
| ^ | ^ | ^ | 02h 2 | ^ | Power Panic flag: __???__ | ^ | ^
| 0x0F9Dh 3997 | float | EEPROM_UVLO_CURRENT_POSITION | ??? | ffh 255 | Power Panic position | ??? | D3 Ax0f9d C8
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| 0x0F95h 3989 | char | EEPROM_FILENAME | ??? | ffh 255 | Power Panic Filename | ??? | D3 Ax0f95 C8
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| 0x0F91h 39851 | uint32 | EEPROM_FILE_POSITION | ??? | ff ff ff ffh | Power Panic File Position | ??? | D3 Ax0f91 C4
| 0x0F8Dh 3981 | float | EEPROM_UVLO_CURRENT_POSITION_Z | ??? | ff ff ff ffh | Power Panic Z Position | ^ | D3 Ax0f8d C4
| 0x0F8Ch 3980 | ??? | EEPROM_UVLO_UNUSED_001 | ??? | ffh 255 | Power Panic _unused_ | ^ | D3 Ax0f8c C1
| 0x0F8Bh 3979 | uint8 | EEPROM_UVLO_TARGET_BED | ??? | ffh 255 | Power Panic Bed temperature | ^ | D3 Ax0f8b C1
| 0x0F89h 3977 | uint16 | EEPROM_UVLO_FEEDRATE | ??? | ff ffh 65535 | Power Panic Feedrate | ^ | D3 Ax0f89 C2
| 0x0F88h 3976 | uint8 | EEPROM_UVLO_FAN_SPEED | ??? | ffh 255 | Power Panic Fan speed | ^ | D3 Ax0f88 C1
| 0x0F87h 3975 | uint8 | EEPROM_FAN_CHECK_ENABLED | 00h 0 | ??? | Fan Check __disabled__ | LCD menu | D3 Ax0f87 C1
| ^ | ^ | ^ | 01h 1 | ffh 255 | Fan Check __enabled__ | ^ | ^
| 0x0F75h 3957 | uint16 | EEPROM_UVLO_MESH_BED_LEVELING | ??? | ff ffh 65535 | Power Panic Mesh Bed Leveling | ??? | D3 Ax0f75 C18
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ^ | ^ | ^ | ^ | ^
| 0x0F73h 3955 | uint16 | EEPROM_UVLO_Z_MICROSTEPS | ??? | ff ffh 65535 | Power Panic Z microsteps | ??? | D3 Ax0f73 C2
| 0x0F72h 3954 | uint8 | EEPROM_UVLO_E_ABS | ??? | ffh 255 | Power Panic ??? position | ??? | D3 Ax0f72 C1
| 0x0F6Eh 3950 | foat | EEPROM_UVLO_CURRENT_POSITION_E | ??? | ff ff ff ffh | Power Panic E position | ??? | D3 Ax0f6e C4
| 0x0F6Dh 3949 | ??? | _EEPROM_FREE_NR2_ | ??? | ffh 255 | _Free EEPROM space_ | _free space_ | D3 Ax0f6d C1
| 0x0F6Ch 3948 | ??? | _EEPROM_FREE_NR3_ | ??? | ffh 255 | _Free EEPROM space_ | _free space_ | D3 Ax0f6c C1
| 0x0F6Bh 3947 | ??? | _EEPROM_FREE_NR4_ | ??? | ffh 255 | _Free EEPROM space_ | _free space_ | D3 Ax0f6b C1
| 0x0F6Ah 3946 | ??? | _EEPROM_FREE_NR5_ | ??? | ffh 255 | _Free EEPROM space_ | _free space_ | D3 Ax0f6a C1
| 0x0F69h 3945 | uint8 | EEPROM_CRASH_DET | ffh 255 | ffh 255 | Crash detection: __enabled__ | LCD menu | D3 Ax0f69 C1
| ^ | ^ | ^ | 00h 0 | ^ | Crash detection: __disabled__ | LCD menu | ^
| 0x0F68h 3944 | uint8 | EEPROM_CRASH_COUNT_Y | 00h-ffh 0-255 | ffh 255 __S/P__ | Crashes detected on y axis | ??? | D3 Ax0f68 C1
| 0x0F67h 3943 | uint8 | EEPROM_FSENSOR | 01h 1 | ffh 255 __P__ | Filament sensor: __enabled__ | LCD menu | D3 Ax0f67 C1
| ^ | ^ | ^ | 00h 0 | ^ | Filament sensor: __disabled__ | LCD menu | ^
| 0x0F65h 3942 | uint8 | EEPROM_CRASH_COUNT_X | 00h-ffh 0-255 | ffh 255 __S/P__ | Crashes detected on x axis | ??? | D3 Ax0f66 C1
| 0x0F65h 3941 | uint8 | EEPROM_FERROR_COUNT | 00h-ffh 0-255 | ffh 255 __S/P__ | Filament sensor error counter | ??? | D3 Ax0f65 C1
| 0x0F64h 3940 | uint8 | EEPROM_POWER_COUNT | 00h-ffh 0-255 | ffh 255 __S/P__ | Power failure counter | ??? | D3 Ax0f64 C1
| 0x0F60h 3936 | float | EEPROM_XYZ_CAL_SKEW | ??? | ff ff ff ffh | XYZ skew value | ??? | D3 Ax0f60 C4
| 0x0F5Fh 3935 | uint8 | EEPROM_WIZARD_ACTIVE | 01h 1 | 01h 1 __P__ | Wizard __active__ | ??? | D3 Ax0f5f C1
| ^ | ^ | ^ | 00h 0 | ^ | Wizard __inactive__ | ^ | ^
| 0x0F5Dh 3933 | uint16 | EEPROM_BELTSTATUS_X | ??? | ff ffh | X Beltstatus | ??? | D3 Ax0f5d C2
| 0x0F5Bh 3931 | uint16 | EEPROM_BELTSTATUS_Y | ??? | ff ffh | Y Beltstatus | ??? | D3 Ax0f5b C2
| 0x0F5Ah 3930 | uint8 | EEPROM_DIR_DEPTH | 00h-ffh 0-255 | ffh 255 | Directory depth | ??? | D3 Ax0f5a C1
| 0x0F0Ah 3850 | uint8 | EEPROM_DIRS | ??? | ffh 255 | Directories ??? | ??? | D3 Ax0f0a C80
| 0x0F09h 3849 | uint8 | EEPROM_SD_SORT | 00h 0 | ffh 255 | SD card sort by: __time__ | LCD menu | D3 Ax0f09 C1
| ^ | ^ | ^ | 01h 1 | ^ | SD card sort by: __alphabet__ | LCD menu | ^
| ^ | ^ | ^ | 02h 1 | ^ | SD card: __not sorted__ | LCD menu | ^
| 0x0F08h 3848 | uint8 | EEPROM_SECOND_SERIAL_ACTIVE | 00h 0 | ffh 255 | RPi Port: __disabled__ | LCD menu | D3 Ax0f08 C1
| ^ | ^ | ^ | 01h 1 | ^ | RPi Port: __enabled__ | LCD menu | ^
| 0x0F07h 3847 | uint8 | EEPROM_FSENS_AUTOLOAD_ENABLED | 01h 1 | ffh 255 __P__ | Filament autoload: __enabled__ | LCD menu | D3 Ax0f07 C1
| ^ | ^ | ^ | 00h 0 | ^ | Filament autoload: __disabled__ | LCD menu | ^
| 0x0F05h 3845 | uint16 | EEPROM_CRASH_COUNT_X_TOT | 0000-fffe | ff ffh __S/P__ | Total crashes on x axis | ??? | D3 Ax0f05 C2
| 0x0F03h 3843 | uint16 | EEPROM_CRASH_COUNT_Y_TOT | 0000-fffe | ff ffh __S/P__ | Total crashes on y axis | ??? | D3 Ax0f03 C2
| 0x0F01h 3841 | uint16 | EEPROM_FERROR_COUNT_TOT | 0000-fffe | ff ffh __S/P__ | Total filament sensor errors | ??? | D3 Ax0f01 C2
| 0x0EFFh 3839 | uint16 | EEPROM_POWER_COUNT_TOT | 0000-fffe | ff ffh __S/P__ | Total power failures | ??? | D3 Ax0eff C2
| 0x0EFEh 3838 | uint8 | EEPROM_TMC2130_HOME_X_ORIGIN | ??? | ffh 255 | ??? | ??? | D3 Ax0efe C1
| 0x0EFDh 3837 | uint8 | EEPROM MC2130_HOME_X_BSTEPS | ??? | ffh 255 | ??? | ??? | D3 Ax0efd C1
| 0x0EFCh 3836 | uint8 | EEPROM_TMC2130_HOME_X_FSTEPS | ??? | ffh 255 | ??? | ??? | D3 Ax0efc C1
| 0x0EFBh 3835 | uint8 | EEPROM_TMC2130_HOME_Y_ORIGIN | ??? | ffh 255 | ??? | ??? | D3 Ax0efb C1
| 0x0EFAh 3834 | uint8 | EEPROM_TMC2130_HOME_Y_BSTEPS | ??? | ffh 255 | ??? | ??? | D3 Ax0efa C1
| 0x0EF9h 3833 | uint8 | EEPROM_TMC2130_HOME_Y_FSTEPS | ??? | ffh 255 | ??? | ??? | D3 Ax0ef9 C1
| 0x0EF8h 3832 | uint8 | EEPROM_TMC2130_HOME_ENABLED | ??? | ffh 255 | ??? | ??? | D3 Ax0ef8 C1
| 0x0EF7h 3831 | uint8 | EEPROM_TMC2130_WAVE_X_FAC | ??? | ffh 255 | ??? | ??? | D3 Ax0ef7 C1
| 0x0EF6h 3830 | uint8 | EEPROM_TMC2130_WAVE_Y_FAC | ??? | ffh 255 | ??? | ??? | D3 Ax0ef6 C1
| 0x0EF5h 3829 | uint8 | EEPROM_TMC2130_WAVE_Z_FAC | ??? | ffh 255 | ??? | ??? | D3 Ax0ef5 C1
| 0x0EF4h 3828 | uint8 | EEPROM_TMC2130_WAVE_E_FAC | ??? | ffh 255 | ??? | ??? | D3 Ax0ef4 C1
| 0x0EF3h 3827 | uint8 | EEPROM_TMC2130_X_MRES | ??? | ffh 255 | ??? | ??? | D3 Ax0ef3 C1
| 0x0EF2h 3826 | uint8 | EEPROM_TMC2130_Y_MRES | ??? | ffh 255 | ??? | ??? | D3 Ax0ef2 C1
| 0x0EF1h 3825 | uint8 | EEPROM_TMC2130_Z_MRES | ??? | ffh 255 | ??? | ??? | D3 Ax0ef1 C1
| 0x0EF0h 3824 | uint8 | EEPROM_TMC2130_E_MRES | ??? | ffh 255 | ??? | ??? | D3 Ax0ef0 C1
| 0x0EEE 3822 | uint16 | EEPROM_PRINTER_TYPE | ??? | ff ffh 65535 | Printer Type | ??? | D3 Ax0eee C2
| ^ | ^ | ^ | 64 00h 100 | ^ | PRINTER_MK1 | ??? | ^
| ^ | ^ | ^ | c8 00h 200 | ^ | PRINTER_MK2 | ??? | ^
| ^ | ^ | ^ | c9 00h 201 | ^ | PRINTER_MK2 with MMU1 | ??? | ^
| ^ | ^ | ^ | ca 00h 202 | ^ | PRINTER_MK2S | ??? | ^
| ^ | ^ | ^ | cb 00h 203 | ^ | PRINTER_MK2S with MMU1 | ??? | ^
| ^ | ^ | ^ | fa 00h 250 | ^ | PRINTER_MK2.5 | ??? | ^
| ^ | ^ | ^ | 1a 4fh 20250 | ^ | PRINTER_MK2.5 with MMU2 | ??? | ^
| ^ | ^ | ^ | fc 00h 252 | ^ | PRINTER_MK2.5S | ??? | ^
| ^ | ^ | ^ | 1c 4fh 20252 | ^ | PRINTER_MK2.5S with MMU2S | ??? | ^
| ^ | ^ | ^ | 2c 01h 300 | ^ | PRINTER_MK3 | ??? | ^
| ^ | ^ | ^ | 4c 4fh 20300 | ^ | PRINTER_MK3 with MMU2 | ??? | ^
| ^ | ^ | ^ | 2e 01h 302 | ^ | PRINTER_MK3S | ??? | ^
| ^ | ^ | ^ | 4e 4fh 20302 | ^ | PRINTER_MK3S with MMU2S | ??? | ^
| 0x0EEC 3820 | uint16 | EEPROM_BOARD_TYPE | ??? | ff ffh 65535 | Board Type | ??? | D3 Ax0eec C2
| ^ | ^ | ^ | c8 00h 200 | ^ | BOARD_RAMBO_MINI_1_0 | ??? | ^
| ^ | ^ | ^ | cb 00h 203 | ^ | BOARD_RAMBO_MINI_1_3 | ??? | ^
| ^ | ^ | ^ | 36 01h 310 | ^ | BOARD_EINSY_1_0a | ??? | ^
| 0x0EE8 3816 | float | EEPROM_EXTRUDER_MULTIPLIER_0 | ??? | ff ff ff ffh | Power panic Extruder 0 multiplier | ??? | D3 Ax0ee8 C4
| 0x0EE4 3812 | float | EEPROM_EXTRUDER_MULTIPLIER_1 | ??? | ff ff ff ffh | Power panic Extruder 1 multiplier | ??? | D3 Ax0ee4 C4
| 0x0EE0 3808 | float | EEPROM_EXTRUDER_MULTIPLIER_2 | ??? | ff ff ff ffh | Power panic Extruder 2 multiplier | ??? | D3 Ax0ee0 C4
| 0x0EDE 3806 | uint16 | EEPROM_EXTRUDEMULTIPLY | ??? | ff ffh 65535 | Power panic Extruder multiplier | ??? | D3 Ax0ede C2
| 0x0EDA 3802 | float | EEPROM_UVLO_TINY_CURRENT_POSITION_Z | ??? | ff ff ff ffh | Power panic Z position | ??? | D3 Ax0eda C4
| 0x0ED8 3800 | uint16 | EEPROM_UVLO_TARGET_HOTEND | ??? | ff ffh 65535 | Power panic target Hotend temperature | ??? | D3 Ax0ed8 C2
| 0x0ED7 3799 | uint8 | EEPROM_SOUND_MODE | 00h 0 | ffh 255 | Sound mode: __loud__ | ??? | D3 Ax0ed7 C1
| ^ | ^ | ^ | 01h 1 | ^ | Sound mode: __once__ | ^ | ^
| ^ | ^ | ^ | 02h 1 | ^ | Sound mode: __silent__ | ^ | ^
| ^ | ^ | ^ | 03h 1 | ^ | Sound mode: __assist__ | ^ | ^
| 0x0ED6 3798 | bool | EEPROM_AUTO_DEPLETE | 01h 1 | ffh 255 | MMU2/s autodeplete: __on__ | ??? | D3 Ax0ed6 C1
| ^ | ^ | ^ | 00h 0 | ^ | MMU2/s autodeplete: __off__ | ^ | ^
| 0x0ED5 3797 | bool | EEPROM_FSENS_OQ_MEASS_ENABLED | ??? | ffh 255 | PAT1925 ??? | ??? | D3 Ax0ed5 C1
| ^ | ^ | ^ | ??? | ^ | PAT1925 ??? | ^ | ^
| 0x0ED3 3795 | uint16 | EEPROM_MMU_FAIL_TOT | ??? | ff ffh 65535 __S/P__ | MMU2/s total failures | ??? | D3 Ax0ed3 C2
| 0x0ED2 3794 | uint8 | EEPROM_MMU_FAIL | ??? | ffh 255 __S/P__ | MMU2/s fails during print | ??? | D3 Ax0ed2 C1
| 0x0ED0 3792 | uint16 | EEPROM_MMU_LOAD_FAIL_TOT | ??? | ff ffh 65535 __S/P__ | MMU2/s total load failures | ??? | D3 Ax0ed0 C2
| 0x0ECF 3791 | uint8 | EEPROM_MMU_LOAD_FAIL | ??? | ffh 255 __S/P__ | MMU2/s load failures during print | ??? | D3 Ax0ecf C1
| 0x0ECE 3790 | uint8 | EEPROM_MMU_CUTTER_ENABLED | 00h 0 | ffh 255 | MMU2/s cutter: __disabled__ | LCD menu | D3 Ax0ece C1
| ^ | ^ | ^ | 01h 1 | ^ | MMU2/s cutter: __enabled__ | ^ | ^
| ^ | ^ | ^ | 02h 2 | ^ | MMU2/s cutter: __always__ | ^ | ^
| 0x0DAE 3502 | uint16 | EEPROM_UVLO_MESH_BED_LEVELING_FULL | ??? | ff ffh 65535 | Power panic Mesh bed leveling points | ??? | D3 Ax0dae C288
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| ^ | ^ | ^ | ??? | ^ | ^ | ^ | ^
| 0x0DAD 3501 | uint8 | EEPROM_MBL_TYPE | ??? | ffh 255 | Mesh bed leveling precision _unused atm_ | ??? | D3 Ax0dad C1
| 0x0DAC 3500 | bool | EEPROM_MBL_MAGNET_ELIMINATION | 01h 1 | ffh 255 | Mesh bed leveling does: __ignores__ magnets | LCD menu | D3 Ax0dac C1
| ^ | ^ | ^ | 00h 0 | ^ | Mesh bed leveling does: __NOT ignores__ magnets | ^ | ^
| 0x0DAB 3499 | uint8 | EEPROM_MBL_POINTS_NR | 03h 3 | ffh 255 | Mesh bed leveling points: __3x3__ | LCD menu | D3 Ax0dab C1
| ^ | ^ | ^ | 07h 7 | ^ | Mesh bed leveling points: __7x7__ | ^ | ^
| 0x0DAA 3498 | uint8 | EEPROM_MBL_PROBE_NR | 03h 3 | ffh 255 | MBL times measurements for each point: __3__ | LCD menu | D3 Ax0daa C1
| ^ | ^ | ^ | 05h 5 | ^ | MBL times measurements for each point: __5__ | ^ | ^
| ^ | ^ | ^ | 01h 1 | ^ | MBL times measurements for each point: __1__ | ^ | ^
| 0x0DA9 3497 | uint8 | EEPROM_MMU_STEALTH | 01h 1 | ffh 255 | MMU2/s Silent mode: __on__ | ??? | D3 Ax0da9 C1
| ^ | ^ | ^ | 00h 0 | ^ | MMU2/s Silent mode: __off__ | ^ | ^
| 0x0DA8 3496 | uint8 | EEPROM_CHECK_MODE | 01h 1 | ffh 255 | Check mode for nozzle is: __warn__ | LCD menu | D3 Ax0da8 C1
| ^ | ^ | ^ | 02h 0 | ^ | Check mode for nozzle is: __strict__ | ^ | ^
| ^ | ^ | ^ | 00h 0 | ^ | Check mode for nozzle is: __none__ | ^ | ^
| 0x0DA7 3495 | uint8 | EEPROM_NOZZLE_DIAMETER | 28h 40 | ffh 255 | Nozzle diameter is: __40 or 0.40mm__ | LCD menu | D3 Ax0da7 C1
| ^ | ^ | ^ | 3ch 60 | ^ | Nozzle diameter is: __60 or 0.60mm__ | ^ | ^
| ^ | ^ | ^ | 19h 25 | ^ | Nozzle diameter is: __25 or 0.25mm__ | ^ | ^
| 0x0DA5 3493 | uint16 | EEPROM_NOZZLE_DIAMETER_uM | 9001h | ff ffh 65535 | Nozzle diameter is: __400um__ | LCD menu | D3 Ax0da5 C2
| ^ | ^ | ^ | 5802h | ^ | Nozzle diameter is: __600um__ | ^ | ^
| ^ | ^ | ^ | fa00h | ^ | Nozzle diameter is: __250um__ | ^ | ^
| 0x0DA4 3492 | uint8 | EEPROM_CHECK_MODEL | 01h 1 | ffh 255 | Check mode for printer model is: __warn__ | LCD menu | D3 Ax0da4 C1
| ^ | ^ | ^ | 02h 0 | ^ | Check mode for printer model is: __strict__ | ^ | ^
| ^ | ^ | ^ | 00h 0 | ^ | Check mode for printer model is: __none__ | ^ | ^
| 0x0DA3 3491 | uint8 | EEPROM_CHECK_VERSION | 01h 1 | ffh 255 | Check mode for firmware is: __warn__ | LCD menu | D3 Ax0da3 C1
| ^ | ^ | ^ | 02h 0 | ^ | Check mode for firmware is: __strict__ | ^ | ^
| ^ | ^ | ^ | 00h 0 | ^ | Check mode for firmware is: __none__ | ^ | ^
| 0x0DA2 3490 | uint8 | EEPROM_CHECK_GCODE | 01h 1 | ffh 255 | Check mode for gcode is: __warn__ _unused atm_ | LCD menu | D3 Ax0da2 C1
| ^ | ^ | ^ | 02h 0 | ^ | Check mode for gcode is: __strict__ _unused atm_ | ^ | ^
| ^ | ^ | ^ | 00h 0 | ^ | Check mode for gcode is: __none__ _unused atm_ | ^ | ^
| 0x0D49 3401 | uint16 | EEPROM_SHEETS_BASE | ??? | ffh 255 | ??? | LCD menu | D3 Ax0d49 C89
| 0x0D49 3401 | char | _1st Sheet block_ | 536d6f6f746831| ffffffffffffff | 1st sheet - Name: _Smooth1_ | ^ | D3 Ax0d49 C7
| 0x0D50 3408 | uint16 | ^ | 00 00h 0 | ff ffh 65535 | 1st sheet - Z offset | ^ | D3 Ax0d50 C2
| 0x0D52 3410 | uint8 | ^ | 00h 0 | ffh 255 | 1st sheet - bed temp | ^ | D3 Ax0d52 C1
| 0x0D53 3411 | uint8 | ^ | 00h 0 | ffh 255 | 1st sheet - PINDA temp | ^ | D3 Ax0d53 C1
| 0x0D54 3412 | char | _2nd Sheet block_ | 536d6f6f746832| ffffffffffffff | 2nd sheet - Name: _Smooth2_ | ^ | D3 Ax0d54 C7
| 0x0D5B 3419 | uint16 | ^ | 00 00h 0 | ff ffh 65535 | 2nd sheet - Z offset | ^ | D3 Ax0d5b C2
| 0x0D5D 3421 | uint8 | ^ | 00h 0 | ffh 255 | 2nd sheet - bed temp | ^ | D3 Ax0d5d C1
| 0x0D5E 3422 | uint8 | ^ | 00h 0 | ffh 255 | 2nd sheet - PINDA temp | ^ | D3 Ax0d5e C1
| 0x0D5F 3423 | char | _3rd Sheet block_ | 54657874757231| ffffffffffffff | 3rd sheet - Name: _Textur1_ | ^ | D3 Ax0d5f C7
| 0x0D66 3430 | uint16 | ^ | 00 00h 0 | ff ffh 65535 | 3rd sheet - Z offset | ^ | D3 Ax0d66 C2
| 0x0D68 3432 | uint8 | ^ | 00h 0 | ffh 255 | 3rd sheet - bed temp | ^ | D3 Ax0d68 C1
| 0x0D69 3433 | uint8 | ^ | 00h 0 | ffh 255 | 3rd sheet - PINDA temp | ^ | D3 Ax0d69 C1
| 0x0D6A 3434 | char | _4th Sheet block_ | 54657874757232| ffffffffffffff | 4th sheet - Name: _Textur2_ | ^ | D3 Ax0d6a C7
| 0x0D71 3441 | uint16 | ^ | 00 00h 0 | ff ffh 65535 | 4th sheet - Z offset | ^ | D3 Ax0d71 C2
| 0x0D73 3443 | uint8 | ^ | 00h 0 | ffh 255 | 4th sheet - bed temp | ^ | D3 Ax0d73 C1
| 0x0D74 3444 | uint8 | ^ | 00h 0 | ffh 255 | 4th sheet - PINDA temp | ^ | D3 Ax0d74 C1
| 0x0D75 3445 | char | _5th Sheet block_ | 437573746f6d31| ffffffffffffff | 5th sheet - Name: _Custom1_ | ^ | D3 Ax0d75 C7
| 0x0D7C 3452 | uint16 | ^ | 00 00h 0 | ff ffh 65535 | 5th sheet - Z offset | ^ | D3 Ax0d7c C2
| 0x0D7E 3454 | uint8 | ^ | 00h 0 | ffh 255 | 5th sheet - bed temp | ^ | D3 Ax0d7e C1
| 0x0D7F 3455 | uint8 | ^ | 00h 0 | ffh 255 | 5th sheet - PINDA temp | ^ | D3 Ax0d7f C1
| 0x0D80 3456 | char | _6th Sheet block_ | 437573746f6d32| ffffffffffffff | 6th sheet - Name: _Custom2_ | ^ | D3 Ax0d80 C7
| 0x0D87 3463 | uint16 | ^ | 00 00h 0 | ff ffh 65535 | 6th sheet - Z offset | ^ | D3 Ax0d87 C2
| 0x0D89 3465 | uint8 | ^ | 00h 0 | ffh 255 | 6th sheet - bed temp | ^ | D3 Ax0d89 C1
| 0x0D8A 3466 | uint8 | ^ | 00h 0 | ffh 255 | 6th sheet - PINDA temp | ^ | D3 Ax0d8a C1
| 0x0D8B 3467 | char | _7th Sheet block_ | 437573746f6d33| ffffffffffffff | 7th sheet - Name: _Custom3_ | ^ | D3 Ax0d8b C7
| 0x0D92 3474 | uint16 | ^ | 00 00h 0 | ff ffh 65535 | 7th sheet - Z offset | ^ | D3 Ax0d92 C2
| 0x0D94 3476 | uint8 | ^ | 00h 0 | ffh 255 | 7th sheet - bed temp | ^ | D3 Ax0d94 C1
| 0x0D95 3477 | uint8 | ^ | 00h 0 | ffh 255 | 7th sheet - PINDA temp | ^ | D3 Ax0d95 C1
| 0x0D96 3478 | char | _8th Sheet block_ | 437573746f6d34| ffffffffffffff | 8th sheet - Name: _Custom4_ | ^ | D3 Ax0d96 C7
| 0x0D9D 3485 | uint16 | ^ | 00 00h 0 | ff ffh 65535 | 8th sheet - Z offset | ^ | D3 Ax0d9d C2
| 0x0D9F 3487 | uint8 | ^ | 00h 0 | ffh 255 | 8th sheet - bed temp | ^ | D3 Ax0d9f C1
| 0x0DA0 3488 | uint8 | ^ | 00h 0 | ffh 255 | 8th sheet - PINDA temp | ^ | D3 Ax0da0 C1
| 0x0DA1 3489 | uint8 | ??? | 00h 0 | ffh 255 | ??? | ??? | D3 Ax0da1 C1
| 0x0D48 3400 | uint8 | EEPROM_FSENSOR_PCB | ??? | ffh 255 | Filament Sensor type old vs new | ??? | D3 Ax0d48 C1
| ^ | ^ | ^ | ??? | ^ | Filament Sensor type ??? | ^ | ^
| 0x0D47 3399 | uint8 | EEPROM_FSENSOR_ACTION_NA | 00h 0 | ffh 255 | Filament Sensor action: __Continue__ | LCD menu | D3 Ax0d47 C1
| ^ | ^ | ^ | 01h 1 | ^ | Filament Sensor action: __Pause__ | ^ | ^
| 0x0D37 3383 | float | EEPROM_UVLO_SAVED_TARGET | ??? | ff ff ff ffh | Power panic saved target all-axis | ??? | D3 Ax0d37 C16
| ^ | ^ | ^ | ??? | ^ | Power panic saved target e-axis | ^ | D3 Ax0d43 C4
| ^ | ^ | ^ | ??? | ^ | Power panic saved target z-axis | ^ | D3 Ax0d3f C4
| ^ | ^ | ^ | ??? | ^ | Power panic saved target y-axis | ^ | D3 Ax0d3b C4
| ^ | ^ | ^ | ??? | ^ | Power panic saved target x-axis | ^ | D3 Ax0d37 C4
| 0x0D35 3381 | uint16 | EEPROM_UVLO_FEEDMULTIPLY | ??? | ff ffh 65355 | Power panic saved feed multiplier | ??? | D3 Ax0d35 C2
| 0x0D34 3380 | uint8 | EEPROM_BACKLIGHT_LEVEL_HIGH | 00h - ffh | 82h 130 | LCD backlight bright: __128__ Dim value to 255 | LCD menu | D3 Ax0d34 C1
| 0x0D33 3379 | uint8 | EEPROM_BACKLIGHT_LEVEL_LOW | 00h - ffh | 32h 50 | LCD backlight dim: __50__ 0 to Bright value | LCD menu | D3 Ax0d33 C1
| 0x0D32 3378 | uint8 | EEPROM_BACKLIGHT_MODE | 02h 2 | ffh 255 | LCD backlight mode: __Auto__ | LCD menu | D3 Ax0d32 C1
| ^ | ^ | ^ | 01h 1 | ^ | LCD backlight mode: __Bright__ | ^ | ^
| ^ | ^ | ^ | 00h 0 | ^ | LCD backlight mode: __Dim__ | ^ | ^
| 0x0D30 3376 | uint16 | EEPROM_BACKLIGHT_TIMEOUT | 01 00 - ff ff | 0a 00h 65535 | LCD backlight timeout: __10__ seconds | LCD menu | D3 Ax0d30 C2
| 0x0D2C 3372 | float | EEPROM_UVLO_LA_K | ??? | ff ff ff ffh | Power panic saved Linear Advanced K value | ??? | D3 Ax0d2c C4
| Address begin | Bit/Type | Name | Valid values | Default/FactoryReset | Description | Gcode/Function| Debug code
| :--: | :--: | :--: | :--: | :--: | :--: | :--: | :--:
| 0x0012 18 | uint16 | EEPROM_FIRMWARE_VERSION_END | ??? | ff ffh 65535 | ??? | ??? | D3 Ax0012 C2
| 0x0010 16 | uint16 | EEPROM_FIRMWARE_VERSION_FLAVOR | ??? | ff ffh 65535 | ??? | ??? | D3 Ax0010 C2
| 0x000E 14 | uint16 | EEPROM_FIRMWARE_VERSION_REVISION | ??? | ff ffh 65535 | Firmware version revision number DEV/ALPHA/BETA/RC| ??? | D3 Ax000e C2
| 0x000C 12 | uint16 | EEPROM_FIRMWARE_VERSION_MINOR | ??? | ff ffh 65535 | Firmware version minor number | ??? | D3 Ax000c C2
| 0x000A 10 | uint16 | EEPROM_FIRMWARE_VERSION_MAJOR | ??? | ff ffh 65535 | Firmware version major number | ??? | D3 Ax000a C2
| 0x0000 0 | char | FW_PRUSA3D_MAGIC | ??? | ffffffffffffffffffff | __`PRUSA3DFW`__ | ??? | D3 Ax0000 C10
*/
#define EEPROM_EMPTY_VALUE 0xFF
#define EEPROM_EMPTY_VALUE16 0xFFFF
@ -51,7 +393,8 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
// The offsets are saved as 16bit signed int, scaled to tenths of microns.
#define EEPROM_BED_CALIBRATION_Z_JITTER (EEPROM_BED_CALIBRATION_VEC_Y-2*8)
#define EEPROM_FARM_MODE (EEPROM_BED_CALIBRATION_Z_JITTER-1)
#define EEPROM_FARM_NUMBER (EEPROM_FARM_MODE-3)
#define EEPROM_FREE_NR1 (EEPROM_FARM_MODE-1)
#define EEPROM_FARM_NUMBER (EEPROM_FREE_NR1-2)
// Correction of the bed leveling, in micrometers.
// Maximum 50 micrometers allowed.
@ -72,19 +415,23 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
#define EEPROM_FILENAME (EEPROM_UVLO_CURRENT_POSITION - 8) //8chars to store filename without extension
#define EEPROM_FILE_POSITION (EEPROM_FILENAME - 4) //32 bit for uint32_t file position
#define EEPROM_UVLO_CURRENT_POSITION_Z (EEPROM_FILE_POSITION - 4) //float for current position in Z
#define EEPROM_UVLO_TARGET_HOTEND (EEPROM_UVLO_CURRENT_POSITION_Z - 1)
#define EEPROM_UVLO_TARGET_BED (EEPROM_UVLO_TARGET_HOTEND - 1)
#define EEPROM_UVLO_UNUSED_001 (EEPROM_UVLO_CURRENT_POSITION_Z - 1) // uint8_t (unused)
#define EEPROM_UVLO_TARGET_BED (EEPROM_UVLO_UNUSED_001 - 1)
#define EEPROM_UVLO_FEEDRATE (EEPROM_UVLO_TARGET_BED - 2) //uint16_t
#define EEPROM_UVLO_FAN_SPEED (EEPROM_UVLO_FEEDRATE - 1)
#define EEPROM_FAN_CHECK_ENABLED (EEPROM_UVLO_FAN_SPEED - 1)
#define EEPROM_UVLO_MESH_BED_LEVELING (EEPROM_FAN_CHECK_ENABLED - 9*2)
#define EEPROM_UVLO_Z_MICROSTEPS (EEPROM_UVLO_MESH_BED_LEVELING - 2)
#define EEPROM_UVLO_Z_MICROSTEPS (EEPROM_UVLO_MESH_BED_LEVELING - 2) // uint16_t (could be removed)
#define EEPROM_UVLO_E_ABS (EEPROM_UVLO_Z_MICROSTEPS - 1)
#define EEPROM_UVLO_CURRENT_POSITION_E (EEPROM_UVLO_E_ABS - 4) //float for current position in E
#define EEPROM_FREE_NR2 (EEPROM_UVLO_CURRENT_POSITION_E - 1) // FREE EEPROM SPACE
#define EEPROM_FREE_NR3 (EEPROM_FREE_NR2 - 1) // FREE EEPROM SPACE
#define EEPROM_FREE_NR4 (EEPROM_FREE_NR3 - 1) // FREE EEPROM SPACE
#define EEPROM_FREE_NR5 (EEPROM_FREE_NR4 - 1) // FREE EEPROM SPACE
// Crash detection mode EEPROM setting
#define EEPROM_CRASH_DET (EEPROM_UVLO_CURRENT_POSITION_E - 5) // float (orig EEPROM_UVLO_MESH_BED_LEVELING-12)
#define EEPROM_CRASH_DET (EEPROM_FREE_NR5 - 1) // uint8 (orig EEPROM_UVLO_MESH_BED_LEVELING-12)
// Crash detection counter Y (last print)
#define EEPROM_CRASH_COUNT_Y (EEPROM_CRASH_DET - 1) // uint8 (orig EEPROM_UVLO_MESH_BED_LEVELING-15)
// Filament sensor on/off EEPROM setting
@ -165,13 +512,11 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
#define EEPROM_EXTRUDER_MULTIPLIER_2 (EEPROM_EXTRUDER_MULTIPLIER_1 - 4) //float
#define EEPROM_EXTRUDEMULTIPLY (EEPROM_EXTRUDER_MULTIPLIER_2 - 2) // uint16
//
#define EEPROM_UVLO_TINY_CURRENT_POSITION_Z (EEPROM_EXTRUDEMULTIPLY-4) // float
#define EEPROM_UVLO_TINY_Z_MICROSTEPS (EEPROM_UVLO_TINY_CURRENT_POSITION_Z-2) // uint16
#define EEPROM_UVLO_TARGET_HOTEND (EEPROM_UVLO_TINY_CURRENT_POSITION_Z-2) // uint16
// Sound Mode
//#define EEPROM_SOUND_MODE (EEPROM_EXTRUDEMULTIPLY-1) // uint8
#define EEPROM_SOUND_MODE (EEPROM_UVLO_TINY_Z_MICROSTEPS-1) // uint8
#define EEPROM_SOUND_MODE (EEPROM_UVLO_TARGET_HOTEND-1) // uint8
#define EEPROM_AUTO_DEPLETE (EEPROM_SOUND_MODE-1) //bool
#define EEPROM_FSENS_OQ_MEASS_ENABLED (EEPROM_AUTO_DEPLETE - 1) //bool

View File

@ -18,19 +18,19 @@
//! @name Basic parameters
//! @{
#define FSENSOR_CHUNK_LEN 0.64F //!< filament sensor chunk length 0.64mm
#define FSENSOR_ERR_MAX 17 //!< filament sensor maximum error count for runout detection
#define FSENSOR_CHUNK_LEN 1.25 //!< filament sensor chunk length (mm)
#define FSENSOR_ERR_MAX 4 //!< filament sensor maximum error/chunk count for runout detection
#define FSENSOR_SOFTERR_CMAX 3 //!< number of contiguous soft failures before a triggering a runout
#define FSENSOR_SOFTERR_DELTA 30000 //!< maximum interval (ms) to consider soft failures contiguous
//! @}
//! @name Optical quality measurement parameters
//! @{
#define FSENSOR_OQ_MAX_ES 6 //!< maximum error sum while loading (length ~64mm = 100chunks)
#define FSENSOR_OQ_MAX_EM 2 //!< maximum error counter value while loading
#define FSENSOR_OQ_MIN_YD 2 //!< minimum yd per chunk (applied to avg value)
#define FSENSOR_OQ_MAX_YD 200 //!< maximum yd per chunk (applied to avg value)
#define FSENSOR_OQ_MAX_PD 4 //!< maximum positive deviation (= yd_max/yd_avg)
#define FSENSOR_OQ_MAX_ND 5 //!< maximum negative deviation (= yd_avg/yd_min)
#define FSENSOR_OQ_MAX_SH 13 //!< maximum shutter value
#define FSENSOR_OQ_MAX_ES 2 //!< maximum sum of error blocks during filament recheck
#define FSENSOR_OQ_MIN_YD 2 //!< minimum yd sum during filament check (counts per inch)
#define FSENSOR_OQ_MIN_BR 80 //!< minimum brightness value
#define FSENSOR_OQ_MAX_SH 10 //!< maximum shutter value
//! @}
const char ERRMSG_PAT9125_NOT_RESP[] PROGMEM = "PAT9125 not responding (%d)!\n";
@ -44,28 +44,35 @@ const char ERRMSG_PAT9125_NOT_RESP[] PROGMEM = "PAT9125 not responding (%d)!\n";
#define FSENSOR_INT_PIN_PCMSK_BIT PCINT13 // PinChange Interrupt / PinChange Enable Mask @ PJ4
#define FSENSOR_INT_PIN_PCICR_BIT PCIE1 // PinChange Interrupt Enable / Flag @ PJ4
//uint8_t fsensor_int_pin = FSENSOR_INT_PIN;
uint8_t fsensor_int_pin_old = 0;
int16_t fsensor_chunk_len = 0;
//! enabled = initialized and sampled every chunk event
bool fsensor_enabled = true;
//! runout watching is done in fsensor_update (called from main loop)
bool fsensor_watch_runout = true;
//! not responding - is set if any communication error occurred during initialization or readout
bool fsensor_not_responding = false;
#ifdef PAT9125
uint8_t fsensor_int_pin_old = 0;
//! optical checking "chunk lenght" (already in steps)
int16_t fsensor_chunk_len = 0;
//! enable/disable quality meassurement
bool fsensor_oq_meassure_enabled = false;
//! number of errors, updated in ISR
uint8_t fsensor_err_cnt = 0;
//! variable for accumulating step count (updated callbacks from stepper and ISR)
int16_t fsensor_st_cnt = 0;
//! last dy value from pat9125 sensor (used in ISR)
int16_t fsensor_dy_old = 0;
//! count of total sensor "soft" failures (filament status checks)
uint8_t fsensor_softfail = 0;
//! timestamp of last soft failure
unsigned long fsensor_softfail_last = 0;
//! count of soft failures within the configured time
uint8_t fsensor_softfail_ccnt = 0;
#endif
#ifdef DEBUG_FSENSOR_LOG
//! log flag: 0=log disabled, 1=log enabled
uint8_t fsensor_log = 1;
#endif //DEBUG_FSENSOR_LOG
//! @name filament autoload variables
@ -75,6 +82,8 @@ uint8_t fsensor_log = 1;
bool fsensor_autoload_enabled = true;
//! autoload watching enable/disable flag
bool fsensor_watch_autoload = false;
#ifdef PAT9125
//
uint16_t fsensor_autoload_y;
//
@ -84,6 +93,7 @@ uint32_t fsensor_autoload_last_millis;
//
uint8_t fsensor_autoload_sum;
//! @}
#endif
//! @name filament optical quality measurement variables
@ -111,7 +121,7 @@ int16_t fsensor_oq_yd_max;
uint16_t fsensor_oq_sh_sum;
//! @}
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
ClFsensorPCB oFsensorPCB;
ClFsensorActionNA oFsensorActionNA;
bool bIRsensorStateFlag=false;
@ -121,14 +131,34 @@ unsigned long nIRsensorLastTime;
void fsensor_stop_and_save_print(void)
{
printf_P(PSTR("fsensor_stop_and_save_print\n"));
stop_and_save_print_to_ram(0, 0); //XYZE - no change
stop_and_save_print_to_ram(0, 0);
fsensor_watch_runout = false;
}
#ifdef PAT9125
// Reset all internal counters to zero, including stepper callbacks
void fsensor_reset_err_cnt()
{
fsensor_err_cnt = 0;
pat9125_y = 0;
st_reset_fsensor();
}
void fsensor_set_axis_steps_per_unit(float u)
{
fsensor_chunk_len = (int16_t)(FSENSOR_CHUNK_LEN * u);
}
#endif
void fsensor_restore_print_and_continue(void)
{
printf_P(PSTR("fsensor_restore_print_and_continue\n"));
fsensor_err_cnt = 0;
restore_print_from_ram_and_continue(0); //XYZ = orig, E - no change
fsensor_watch_runout = true;
#ifdef PAT9125
fsensor_reset_err_cnt();
#endif
restore_print_from_ram_and_continue(0);
}
// fsensor_checkpoint_print cuts the current print job at the current position,
@ -152,7 +182,7 @@ void fsensor_init(void)
#ifdef PAT9125
uint8_t oq_meassure_enabled = eeprom_read_byte((uint8_t*)EEPROM_FSENS_OQ_MEASS_ENABLED);
fsensor_oq_meassure_enabled = (oq_meassure_enabled == 1)?true:false;
fsensor_chunk_len = (int16_t)(FSENSOR_CHUNK_LEN * cs.axis_steps_per_unit[E_AXIS]);
fsensor_set_axis_steps_per_unit(cs.axis_steps_per_unit[E_AXIS]);
if (!pat9125)
{
@ -160,7 +190,7 @@ void fsensor_init(void)
fsensor_not_responding = true;
}
#endif //PAT9125
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
bIRsensorStateFlag=false;
oFsensorPCB=(ClFsensorPCB)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_PCB);
oFsensorActionNA=(ClFsensorActionNA)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_ACTION_NA);
@ -170,8 +200,8 @@ void fsensor_init(void)
else
fsensor_disable(false); // (in this case) EEPROM update is not necessary
printf_P(PSTR("FSensor %S"), (fsensor_enabled?PSTR("ENABLED"):PSTR("DISABLED")));
#if IR_SENSOR_ANALOG
printf_P(PSTR(" (sensor board revision: %S)\n"),(oFsensorPCB==ClFsensorPCB::_Rev03b)?PSTR("03b or newer"):PSTR("03 or older"));
#ifdef IR_SENSOR_ANALOG
printf_P(PSTR(" (sensor board revision: %S)\n"),(oFsensorPCB==ClFsensorPCB::_Rev04) ? MSG_04_OR_NEWER : MSG_03_OR_OLDER);
#else //IR_SENSOR_ANALOG
printf_P(PSTR("\n"));
#endif //IR_SENSOR_ANALOG
@ -192,8 +222,7 @@ bool fsensor_enable(bool bUpdateEEPROM)
fsensor_enabled = pat9125 ? true : false;
fsensor_watch_runout = true;
fsensor_oq_meassure = false;
fsensor_err_cnt = 0;
fsensor_dy_old = 0;
fsensor_reset_err_cnt();
eeprom_update_byte((uint8_t*)EEPROM_FSENSOR, fsensor_enabled ? 0x01 : 0x00);
FSensorStateMenu = fsensor_enabled ? 1 : 0;
}
@ -204,7 +233,7 @@ bool fsensor_enable(bool bUpdateEEPROM)
FSensorStateMenu = 1;
}
#else // PAT9125
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
if(!fsensor_IR_check())
{
bUpdateEEPROM=true;
@ -217,7 +246,7 @@ bool fsensor_enable(bool bUpdateEEPROM)
fsensor_enabled=true;
fsensor_not_responding=false;
FSensorStateMenu=1;
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
}
#endif //IR_SENSOR_ANALOG
if(bUpdateEEPROM)
@ -273,12 +302,11 @@ void fsensor_autoload_check_start(void)
fsensor_autoload_last_millis = _millis();
fsensor_watch_runout = false;
fsensor_watch_autoload = true;
fsensor_err_cnt = 0;
}
void fsensor_autoload_check_stop(void)
{
// puts_P(_N("fsensor_autoload_check_stop\n"));
if (!fsensor_enabled) return;
// puts_P(_N("fsensor_autoload_check_stop 1\n"));
@ -289,7 +317,7 @@ void fsensor_autoload_check_stop(void)
fsensor_autoload_sum = 0;
fsensor_watch_autoload = false;
fsensor_watch_runout = true;
fsensor_err_cnt = 0;
fsensor_reset_err_cnt();
}
#endif //PAT9125
@ -354,6 +382,7 @@ bool fsensor_check_autoload(void)
return false;
}
#ifdef PAT9125
void fsensor_oq_meassure_set(bool State)
{
fsensor_oq_meassure_enabled = State;
@ -371,12 +400,11 @@ void fsensor_oq_meassure_start(uint8_t skip)
fsensor_oq_yd_sum = 0;
fsensor_oq_er_sum = 0;
fsensor_oq_er_max = 0;
fsensor_oq_yd_min = FSENSOR_OQ_MAX_YD;
fsensor_oq_yd_min = INT16_MAX;
fsensor_oq_yd_max = 0;
fsensor_oq_sh_sum = 0;
pat9125_update();
pat9125_y = 0;
fsensor_watch_runout = false;
fsensor_oq_meassure = true;
}
@ -388,10 +416,9 @@ void fsensor_oq_meassure_stop(void)
printf_P(_N(" st_sum=%u yd_sum=%u er_sum=%u er_max=%hhu\n"), fsensor_oq_st_sum, fsensor_oq_yd_sum, fsensor_oq_er_sum, fsensor_oq_er_max);
printf_P(_N(" yd_min=%u yd_max=%u yd_avg=%u sh_avg=%u\n"), fsensor_oq_yd_min, fsensor_oq_yd_max, (uint16_t)((uint32_t)fsensor_oq_yd_sum * fsensor_chunk_len / fsensor_oq_st_sum), (uint16_t)(fsensor_oq_sh_sum / fsensor_oq_samples));
fsensor_oq_meassure = false;
fsensor_watch_runout = true;
fsensor_err_cnt = 0;
}
#ifdef FSENSOR_QUALITY
const char _OK[] PROGMEM = "OK";
const char _NG[] PROGMEM = "NG!";
@ -427,18 +454,24 @@ bool fsensor_oq_result(void)
printf_P(_N("fsensor_oq_result %S\n"), (res?_OK:_NG));
return res;
}
#ifdef PAT9125
#endif //FSENSOR_QUALITY
ISR(FSENSOR_INT_PIN_VECT)
{
if (mmu_enabled || ir_sensor_detected) return;
if (!((fsensor_int_pin_old ^ FSENSOR_INT_PIN_PIN_REG) & FSENSOR_INT_PIN_MASK)) return;
fsensor_int_pin_old = FSENSOR_INT_PIN_PIN_REG;
// prevent isr re-entry
static bool _lock = false;
if (_lock) return;
_lock = true;
// fetch fsensor_st_cnt atomically
int st_cnt = fsensor_st_cnt;
fsensor_st_cnt = 0;
sei();
uint8_t old_err_cnt = fsensor_err_cnt;
uint8_t pat9125_res = fsensor_oq_meassure?pat9125_update():pat9125_update_y();
if (!pat9125_res)
@ -447,56 +480,71 @@ ISR(FSENSOR_INT_PIN_VECT)
fsensor_not_responding = true;
printf_P(ERRMSG_PAT9125_NOT_RESP, 1);
}
if (st_cnt != 0)
{ //movement
if (st_cnt > 0) //positive movement
{
if (pat9125_y < 0)
{
if (fsensor_err_cnt)
fsensor_err_cnt += 2;
else
fsensor_err_cnt++;
}
else if (pat9125_y > 0)
{
if (fsensor_err_cnt)
fsensor_err_cnt--;
}
else //(pat9125_y == 0)
if (((fsensor_dy_old <= 0) || (fsensor_err_cnt)) && (st_cnt > (fsensor_chunk_len >> 1)))
fsensor_err_cnt++;
if (fsensor_oq_meassure)
{
if (fsensor_oq_skipchunk)
{
fsensor_oq_skipchunk--;
fsensor_err_cnt = 0;
}
else
{
if (st_cnt == fsensor_chunk_len)
{
if (pat9125_y > 0) if (fsensor_oq_yd_min > pat9125_y) fsensor_oq_yd_min = (fsensor_oq_yd_min + pat9125_y) / 2;
if (pat9125_y >= 0) if (fsensor_oq_yd_max < pat9125_y) fsensor_oq_yd_max = (fsensor_oq_yd_max + pat9125_y) / 2;
}
fsensor_oq_samples++;
fsensor_oq_st_sum += st_cnt;
if (pat9125_y > 0) fsensor_oq_yd_sum += pat9125_y;
if (fsensor_err_cnt > old_err_cnt)
fsensor_oq_er_sum += (fsensor_err_cnt - old_err_cnt);
if (fsensor_oq_er_max < fsensor_err_cnt)
fsensor_oq_er_max = fsensor_err_cnt;
fsensor_oq_sh_sum += pat9125_s;
}
}
}
else //negative movement
{
}
}
else
{ //no movement
{
// movement was planned, check for sensor movement
int8_t st_dir = st_cnt >= 0;
int8_t pat9125_dir = pat9125_y >= 0;
if (pat9125_y == 0)
{
if (st_dir)
{
// no movement detected: we might be within a blind sensor range,
// update the frame and shutter parameters we didn't earlier
if (!fsensor_oq_meassure)
pat9125_update_bs();
// increment the error count only if underexposed: filament likely missing
if ((pat9125_b < FSENSOR_OQ_MIN_BR) && (pat9125_s > FSENSOR_OQ_MAX_SH))
{
// check for a dark frame (<30% avg brightness) with long exposure
++fsensor_err_cnt;
}
else
{
// good frame, filament likely present
if(fsensor_err_cnt) --fsensor_err_cnt;
}
}
}
else if (pat9125_dir != st_dir)
{
// detected direction opposite of motor movement
if (st_dir) ++fsensor_err_cnt;
}
else if (pat9125_dir == st_dir)
{
// direction agreeing with planned movement
if (fsensor_err_cnt) --fsensor_err_cnt;
}
if (st_dir && fsensor_oq_meassure)
{
// extruding with quality assessment
if (fsensor_oq_skipchunk)
{
fsensor_oq_skipchunk--;
fsensor_err_cnt = 0;
}
else
{
if (st_cnt == fsensor_chunk_len)
{
if (pat9125_y > 0) if (fsensor_oq_yd_min > pat9125_y) fsensor_oq_yd_min = (fsensor_oq_yd_min + pat9125_y) / 2;
if (pat9125_y >= 0) if (fsensor_oq_yd_max < pat9125_y) fsensor_oq_yd_max = (fsensor_oq_yd_max + pat9125_y) / 2;
}
fsensor_oq_samples++;
fsensor_oq_st_sum += st_cnt;
if (pat9125_y > 0) fsensor_oq_yd_sum += pat9125_y;
if (fsensor_err_cnt > old_err_cnt)
fsensor_oq_er_sum += (fsensor_err_cnt - old_err_cnt);
if (fsensor_oq_er_max < fsensor_err_cnt)
fsensor_oq_er_max = fsensor_err_cnt;
fsensor_oq_sh_sum += pat9125_s;
}
}
}
#ifdef DEBUG_FSENSOR_LOG
@ -507,9 +555,7 @@ ISR(FSENSOR_INT_PIN_VECT)
}
#endif //DEBUG_FSENSOR_LOG
fsensor_dy_old = pat9125_y;
pat9125_y = 0;
_lock = false;
return;
}
@ -529,19 +575,16 @@ void fsensor_setup_interrupt(void)
PCICR |= bit(FSENSOR_INT_PIN_PCICR_BIT); // enable corresponding PinChangeInterrupt (set of pins)
}
#endif //PAT9125
void fsensor_st_block_chunk(int cnt)
{
if (!fsensor_enabled) return;
fsensor_st_cnt += cnt;
if (abs(fsensor_st_cnt) >= fsensor_chunk_len)
{
// !!! bit toggling (PINxn <- 1) (for PinChangeInterrupt) does not work for some MCU pins
if (PIN_GET(FSENSOR_INT_PIN)) {PIN_VAL(FSENSOR_INT_PIN, LOW);}
else {PIN_VAL(FSENSOR_INT_PIN, HIGH);}
}
// !!! bit toggling (PINxn <- 1) (for PinChangeInterrupt) does not work for some MCU pins
if (PIN_GET(FSENSOR_INT_PIN)) {PIN_VAL(FSENSOR_INT_PIN, LOW);}
else {PIN_VAL(FSENSOR_INT_PIN, HIGH);}
}
#endif //PAT9125
//! Common code for enqueing M600 and supplemental codes into the command queue.
@ -561,54 +604,65 @@ void fsensor_enque_M600(){
void fsensor_update(void)
{
#ifdef PAT9125
if (fsensor_enabled && fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX))
if (fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX))
{
fsensor_stop_and_save_print();
KEEPALIVE_STATE(IN_HANDLER);
bool autoload_enabled_tmp = fsensor_autoload_enabled;
fsensor_autoload_enabled = false;
bool oq_meassure_enabled_tmp = fsensor_oq_meassure_enabled;
fsensor_oq_meassure_enabled = true;
fsensor_stop_and_save_print();
// move the nozzle away while checking the filament
current_position[Z_AXIS] += 0.8;
if(current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS;
plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS], active_extruder);
st_synchronize();
fsensor_err_cnt = 0;
// check the filament in isolation
fsensor_reset_err_cnt();
fsensor_oq_meassure_start(0);
enquecommand_front_P((PSTR("G1 E-3 F200")));
process_commands();
KEEPALIVE_STATE(IN_HANDLER);
cmdqueue_pop_front();
st_synchronize();
enquecommand_front_P((PSTR("G1 E3 F200")));
process_commands();
KEEPALIVE_STATE(IN_HANDLER);
cmdqueue_pop_front();
st_synchronize();
uint8_t err_cnt = fsensor_err_cnt;
float e_tmp = current_position[E_AXIS];
current_position[E_AXIS] -= 3;
plan_buffer_line_curposXYZE(250/60, active_extruder);
current_position[E_AXIS] = e_tmp;
plan_buffer_line_curposXYZE(200/60, active_extruder);
st_synchronize();
fsensor_oq_meassure_stop();
bool err = false;
err |= (err_cnt > 1);
err |= (fsensor_oq_er_sum > 2);
err |= (fsensor_oq_yd_sum < (4 * FSENSOR_OQ_MIN_YD));
err |= (fsensor_err_cnt > 0); // final error count is non-zero
err |= (fsensor_oq_er_sum > FSENSOR_OQ_MAX_ES); // total error count is above limit
err |= (fsensor_oq_yd_sum < FSENSOR_OQ_MIN_YD); // total measured distance is below limit
fsensor_restore_print_and_continue();
fsensor_autoload_enabled = autoload_enabled_tmp;
fsensor_oq_meassure_enabled = oq_meassure_enabled_tmp;
fsensor_autoload_enabled = autoload_enabled_tmp;
fsensor_oq_meassure_enabled = oq_meassure_enabled_tmp;
if (!err)
printf_P(PSTR("fsensor_err_cnt = 0\n"));
else
fsensor_enque_M600();
unsigned long now = _millis();
if (!err && (now - fsensor_softfail_last) > FSENSOR_SOFTERR_DELTA)
fsensor_softfail_ccnt = 0;
if (!err && fsensor_softfail_ccnt <= FSENSOR_SOFTERR_CMAX)
{
printf_P(PSTR("fsensor_err_cnt = 0\n"));
++fsensor_softfail;
++fsensor_softfail_ccnt;
fsensor_softfail_last = now;
}
else
{
fsensor_softfail_ccnt = 0;
fsensor_softfail_last = 0;
fsensor_enque_M600();
}
}
#else //PAT9125
if (CHECK_FSENSOR && fsensor_enabled && ir_sensor_detected)
if (CHECK_FSENSOR && ir_sensor_detected)
{
if(digitalRead(IR_SENSOR_PIN))
{ // IR_SENSOR_PIN ~ H
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
if(!bIRsensorStateFlag)
{
bIRsensorStateFlag=true;
@ -637,7 +691,7 @@ void fsensor_update(void)
ADCSRB=nMUX2;
ENABLE_TEMPERATURE_INTERRUPT();
// end of sequence for ...
if((oFsensorPCB==ClFsensorPCB::_Rev03b)&&((nADC*OVERSAMPLENR)>((int)IRsensor_Hopen_TRESHOLD)))
if((oFsensorPCB==ClFsensorPCB::_Rev04)&&((nADC*OVERSAMPLENR)>((int)IRsensor_Hopen_TRESHOLD)))
{
fsensor_disable();
fsensor_not_responding = true;
@ -651,7 +705,7 @@ void fsensor_update(void)
#endif //IR_SENSOR_ANALOG
fsensor_checkpoint_print();
fsensor_enque_M600();
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
}
}
}
@ -665,7 +719,7 @@ void fsensor_update(void)
#endif //PAT9125
}
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
bool fsensor_IR_check()
{
uint16_t volt_IR_int;
@ -673,7 +727,7 @@ bool bCheckResult;
volt_IR_int=current_voltage_raw_IR;
bCheckResult=(volt_IR_int<((int)IRsensor_Lmax_TRESHOLD))||(volt_IR_int>((int)IRsensor_Hmin_TRESHOLD));
bCheckResult=bCheckResult&&(!((oFsensorPCB==ClFsensorPCB::_Rev03b)&&(volt_IR_int>((int)IRsensor_Hopen_TRESHOLD))));
bCheckResult=bCheckResult&&(!((oFsensorPCB==ClFsensorPCB::_Rev04)&&(volt_IR_int>((int)IRsensor_Hopen_TRESHOLD))));
return(bCheckResult);
}
#endif //IR_SENSOR_ANALOG

View File

@ -6,15 +6,16 @@
#include "config.h"
//! minimum meassured chunk length in steps
extern int16_t fsensor_chunk_len;
// enable/disable flag
extern bool fsensor_enabled;
// not responding flag
extern bool fsensor_not_responding;
//enable/disable quality meassurement
extern bool fsensor_oq_meassure_enabled;
#ifdef PAT9125
// optical checking "chunk lenght" (already in steps)
extern int16_t fsensor_chunk_len;
// count of soft failures
extern uint8_t fsensor_softfail;
#endif
//! @name save restore printing
//! @{
@ -28,6 +29,11 @@ extern void fsensor_checkpoint_print(void);
//! initialize
extern void fsensor_init(void);
#ifdef PAT9125
//! update axis resolution
extern void fsensor_set_axis_steps_per_unit(float u);
#endif
//! @name enable/disable
//! @{
extern bool fsensor_enable(bool bUpdateEEPROM=true);
@ -52,8 +58,10 @@ extern void fsensor_autoload_check_stop(void);
extern bool fsensor_check_autoload(void);
//! @}
#ifdef PAT9125
//! @name optical quality measurement support
//! @{
extern bool fsensor_oq_meassure_enabled;
extern void fsensor_oq_meassure_set(bool State);
extern void fsensor_oq_meassure_start(uint8_t skip);
extern void fsensor_oq_meassure_stop(void);
@ -64,21 +72,25 @@ extern bool fsensor_oq_result(void);
//! @{
extern void fsensor_st_block_chunk(int cnt);
// debugging
extern uint8_t fsensor_log;
// There's really nothing to do in block_begin: the stepper ISR likely has
// called us already at the end of the last block, making this integration
// redundant. LA1.5 might not always do that during a coasting move, so attempt
// to drain fsensor_st_cnt anyway at the beginning of the new block.
#define fsensor_st_block_begin(rev) fsensor_st_block_chunk(0)
//! @}
#endif //PAT9125
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
#define IR_SENSOR_STEADY 10 // [ms]
enum class ClFsensorPCB:uint_least8_t
{
_Old=0,
_Rev03b=1,
_Rev04=1,
_Undef=EEPROM_EMPTY_VALUE
};

View File

@ -1,180 +1,190 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#include "io_atmega2560.h"
// All this is about silencing the heat bed, as it behaves like a loudspeaker.
// Basically, we want the PWM heating switched at 30Hz (or so) which is a well ballanced
// frequency for both power supply units (i.e. both PSUs are reasonably silent).
// The only trouble is the rising or falling edge of bed heating - that creates an audible click.
// This audible click may be suppressed by making the rising or falling edge NOT sharp.
// Of course, making non-sharp edges in digital technology is not easy, but there is a solution.
// It is possible to do a fast PWM sequence with duty starting from 0 to 255.
// Doing this at higher frequency than the bed "loudspeaker" can handle makes the click barely audible.
// Technically:
// timer0 is set to fast PWM mode at 62.5kHz (timer0 is linked to the bed heating pin) (zero prescaler)
// To keep the bed switching at 30Hz - we don't want the PWM running at 62kHz all the time
// since it would burn the heatbed's MOSFET:
// 16MHz/256 levels of PWM duty gives us 62.5kHz
// 62.5kHz/256 gives ~244Hz, that is still too fast - 244/8 gives ~30Hz, that's what we need
// So the automaton runs atop of inner 8 (or 16) cycles.
// The finite automaton is running in the ISR(TIMER0_OVF_vect)
// 2019-08-14 update: the original algorithm worked very well, however there were 2 regressions:
// 1. 62kHz ISR requires considerable amount of processing power,
// USB transfer speed dropped by 20%, which was most notable when doing short G-code segments.
// 2. Some users reported TLed PSU started clicking when running at 120V/60Hz.
// This looks like the original algorithm didn't maintain base PWM 30Hz, but only 15Hz
// To address both issues, there is an improved approach based on the idea of leveraging
// different CLK prescalers in some automaton states - i.e. when holding LOW or HIGH on the output pin,
// we don't have to clock 62kHz, but we can increase the CLK prescaler for these states to 8 (or even 64).
// That shall result in the ISR not being called that much resulting in regained performance
// Theoretically this is relatively easy, however one must be very carefull handling the AVR's timer
// control registers correctly, especially setting them in a correct order.
// Some registers are double buffered, some changes are applied in next cycles etc.
// The biggest problem was with the CLK prescaler itself - this circuit is shared among almost all timers,
// we don't want to reset the prescaler counted value when transiting among automaton states.
// Resetting the prescaler would make the PWM more precise, right now there are temporal segments
// of variable period ranging from 0 to 7 62kHz ticks - that's logical, the timer must "sync"
// to the new slower CLK after setting the slower prescaler value.
// In our application, this isn't any significant problem and may be ignored.
// Doing changes in timer's registers non-correctly results in artefacts on the output pin
// - it can toggle unnoticed, which will result in bed clicking again.
// That's why there are special transition states ZERO_TO_RISE and ONE_TO_FALL, which enable the
// counter change its operation atomically and without artefacts on the output pin.
// The resulting signal on the output pin was checked with an osciloscope.
// If there are any change requirements in the future, the signal must be checked with an osciloscope again,
// ad-hoc changes may completely screw things up!
///! Definition off finite automaton states
enum class States : uint8_t {
ZERO_START = 0,///< entry point of the automaton - reads the soft_pwm_bed value for the next whole PWM cycle
ZERO, ///< steady 0 (OFF), no change for the whole period
ZERO_TO_RISE, ///< metastate allowing the timer change its state atomically without artefacts on the output pin
RISE, ///< 16 fast PWM cycles with increasing duty up to steady ON
RISE_TO_ONE, ///< metastate allowing the timer change its state atomically without artefacts on the output pin
ONE, ///< steady 1 (ON), no change for the whole period
ONE_TO_FALL, ///< metastate allowing the timer change its state atomically without artefacts on the output pin
FALL, ///< 16 fast PWM cycles with decreasing duty down to steady OFF
FALL_TO_ZERO ///< metastate allowing the timer change its state atomically without artefacts on the output pin
};
///! Inner states of the finite automaton
static States state = States::ZERO_START;
///! Fast PWM counter is used in the RISE and FALL states (62.5kHz)
static uint8_t slowCounter = 0;
///! Slow PWM counter is used in the ZERO and ONE states (62.5kHz/8 or 64)
static uint8_t fastCounter = 0;
///! PWM counter for the whole cycle - a cache for soft_pwm_bed
static uint8_t pwm = 0;
///! The slow PWM duty for the next 30Hz cycle
///! Set in the whole firmware at various places
extern unsigned char soft_pwm_bed;
/// fastMax - how many fast PWM steps to do in RISE and FALL states
/// 16 is a good compromise between silenced bed ("smooth" edges)
/// and not burning the switching MOSFET
static const uint8_t fastMax = 16;
/// Scaler 16->256 for fast PWM
static const uint8_t fastShift = 4;
/// Increment slow PWM counter by slowInc every ZERO or ONE state
/// This allows for fine-tuning the basic PWM switching frequency
/// A possible further optimization - use a 64 prescaler (instead of 8)
/// increment slowCounter by 1
/// but use less bits of soft PWM - something like soft_pwm_bed >> 2
/// that may further reduce the CPU cycles required by the bed heating automaton
/// Due to the nature of bed heating the reduced PID precision may not be a major issue, however doing 8x less ISR(timer0_ovf) may significantly improve the performance
static const uint8_t slowInc = 1;
ISR(TIMER0_OVF_vect) // timer compare interrupt service routine
{
switch(state){
case States::ZERO_START:
pwm = soft_pwm_bed << 1;// expecting soft_pwm_bed to be 7bit!
if( pwm != 0 ){
state = States::ZERO; // do nothing, let it tick once again after the 30Hz period
}
break;
case States::ZERO: // end of state ZERO - we'll either stay in ZERO or change to RISE
// In any case update our cache of pwm value for the next whole cycle from soft_pwm_bed
slowCounter += slowInc; // this does software timer_clk/256 or less (depends on slowInc)
if( slowCounter > pwm ){
return;
} // otherwise moving towards RISE
state = States::ZERO_TO_RISE; // and finalize the change in a transitional state RISE0
break;
// even though it may look like the ZERO state may be glued together with the ZERO_TO_RISE, don't do it
// the timer must tick once more in order to get rid of occasional output pin toggles.
case States::ZERO_TO_RISE: // special state for handling transition between prescalers and switching inverted->non-inverted fast-PWM without toggling the output pin.
// It must be done in consequent steps, otherwise the pin will get flipped up and down during one PWM cycle.
// Also beware of the correct sequence of the following timer control registers initialization - it really matters!
state = States::RISE; // prepare for standard RISE cycles
fastCounter = fastMax - 1;// we'll do 16-1 cycles of RISE
TCNT0 = 255; // force overflow on the next clock cycle
TCCR0B = (1 << CS00); // change prescaler to 1, i.e. 62.5kHz
TCCR0A &= ~(1 << COM0B0); // Clear OC0B on Compare Match, set OC0B at BOTTOM (non-inverting mode)
break;
case States::RISE:
OCR0B = (fastMax - fastCounter) << fastShift;
if( fastCounter ){
--fastCounter;
} else { // end of RISE cycles, changing into state ONE
state = States::RISE_TO_ONE;
OCR0B = 255; // full duty
TCNT0 = 254; // make the timer overflow in the next cycle
// @@TODO these constants are still subject to investigation
}
break;
case States::RISE_TO_ONE:
state = States::ONE;
OCR0B = 255; // full duty
TCNT0 = 255; // make the timer overflow in the next cycle
TCCR0B = (1 << CS01); // change prescaler to 8, i.e. 7.8kHz
break;
case States::ONE: // state ONE - we'll either stay in ONE or change to FALL
OCR0B = 255;
slowCounter += slowInc; // this does software timer_clk/256 or less
if( slowCounter < pwm ){
return;
}
if( (soft_pwm_bed << 1) >= (255 - slowInc - 1) ){ //@@TODO simplify & explain
// if slowInc==2, soft_pwm == 251 will be the first to do short drops to zero. 252 will keep full heating
return; // want full duty for the next ONE cycle again - so keep on heating and just wait for the next timer ovf
}
// otherwise moving towards FALL
// @@TODO it looks like ONE_TO_FALL isn't necessary, there are no artefacts at all
state = States::ONE;//_TO_FALL;
// TCCR0B = (1 << CS00); // change prescaler to 1, i.e. 62.5kHz
// break;
// case States::ONE_TO_FALL:
// OCR0B = 255; // zero duty
state=States::FALL;
fastCounter = fastMax - 1;// we'll do 16-1 cycles of RISE
TCNT0 = 255; // force overflow on the next clock cycle
TCCR0B = (1 << CS00); // change prescaler to 1, i.e. 62.5kHz
// must switch to inverting mode already here, because it takes a whole PWM cycle and it would make a "1" at the end of this pwm cycle
// COM0B1 remains set both in inverting and non-inverting mode
TCCR0A |= (1 << COM0B0); // inverting mode
break;
case States::FALL:
OCR0B = (fastMax - fastCounter) << fastShift; // this is the same as in RISE, because now we are setting the zero part of duty due to inverting mode
//TCCR0A |= (1 << COM0B0); // already set in ONE_TO_FALL
if( fastCounter ){
--fastCounter;
} else { // end of FALL cycles, changing into state ZERO
state = States::FALL_TO_ZERO;
TCNT0 = 128; //@@TODO again - need to wait long enough to propagate the timer state changes
OCR0B = 255;
}
break;
case States::FALL_TO_ZERO:
state = States::ZERO_START; // go to read new soft_pwm_bed value for the next cycle
TCNT0 = 128;
OCR0B = 255;
TCCR0B = (1 << CS01); // change prescaler to 8, i.e. 7.8kHz
break;
}
}
#include <avr/io.h>
#include <avr/interrupt.h>
#include "io_atmega2560.h"
// All this is about silencing the heat bed, as it behaves like a loudspeaker.
// Basically, we want the PWM heating switched at 30Hz (or so) which is a well ballanced
// frequency for both power supply units (i.e. both PSUs are reasonably silent).
// The only trouble is the rising or falling edge of bed heating - that creates an audible click.
// This audible click may be suppressed by making the rising or falling edge NOT sharp.
// Of course, making non-sharp edges in digital technology is not easy, but there is a solution.
// It is possible to do a fast PWM sequence with duty starting from 0 to 255.
// Doing this at higher frequency than the bed "loudspeaker" can handle makes the click barely audible.
// Technically:
// timer0 is set to fast PWM mode at 62.5kHz (timer0 is linked to the bed heating pin) (zero prescaler)
// To keep the bed switching at 30Hz - we don't want the PWM running at 62kHz all the time
// since it would burn the heatbed's MOSFET:
// 16MHz/256 levels of PWM duty gives us 62.5kHz
// 62.5kHz/256 gives ~244Hz, that is still too fast - 244/8 gives ~30Hz, that's what we need
// So the automaton runs atop of inner 8 (or 16) cycles.
// The finite automaton is running in the ISR(TIMER0_OVF_vect)
// 2019-08-14 update: the original algorithm worked very well, however there were 2 regressions:
// 1. 62kHz ISR requires considerable amount of processing power,
// USB transfer speed dropped by 20%, which was most notable when doing short G-code segments.
// 2. Some users reported TLed PSU started clicking when running at 120V/60Hz.
// This looks like the original algorithm didn't maintain base PWM 30Hz, but only 15Hz
// To address both issues, there is an improved approach based on the idea of leveraging
// different CLK prescalers in some automaton states - i.e. when holding LOW or HIGH on the output pin,
// we don't have to clock 62kHz, but we can increase the CLK prescaler for these states to 8 (or even 64).
// That shall result in the ISR not being called that much resulting in regained performance
// Theoretically this is relatively easy, however one must be very carefull handling the AVR's timer
// control registers correctly, especially setting them in a correct order.
// Some registers are double buffered, some changes are applied in next cycles etc.
// The biggest problem was with the CLK prescaler itself - this circuit is shared among almost all timers,
// we don't want to reset the prescaler counted value when transiting among automaton states.
// Resetting the prescaler would make the PWM more precise, right now there are temporal segments
// of variable period ranging from 0 to 7 62kHz ticks - that's logical, the timer must "sync"
// to the new slower CLK after setting the slower prescaler value.
// In our application, this isn't any significant problem and may be ignored.
// Doing changes in timer's registers non-correctly results in artefacts on the output pin
// - it can toggle unnoticed, which will result in bed clicking again.
// That's why there are special transition states ZERO_TO_RISE and ONE_TO_FALL, which enable the
// counter change its operation atomically and without artefacts on the output pin.
// The resulting signal on the output pin was checked with an osciloscope.
// If there are any change requirements in the future, the signal must be checked with an osciloscope again,
// ad-hoc changes may completely screw things up!
// 2020-01-29 update: we are introducing a new option to the automaton that will allow us to force the output state
// to either full ON or OFF. This is so that interference during the MBL probing is minimal.
// To accomplish this goal we use bedPWMDisabled. It is only supposed to be used for brief periods of time as to
// not make the bed temperature too unstable. Also, careful consideration should be used when using this
// option as leaving this enabled will also keep the bed output in the state it stopped in.
///! Definition off finite automaton states
enum class States : uint8_t {
ZERO_START = 0,///< entry point of the automaton - reads the soft_pwm_bed value for the next whole PWM cycle
ZERO, ///< steady 0 (OFF), no change for the whole period
ZERO_TO_RISE, ///< metastate allowing the timer change its state atomically without artefacts on the output pin
RISE, ///< 16 fast PWM cycles with increasing duty up to steady ON
RISE_TO_ONE, ///< metastate allowing the timer change its state atomically without artefacts on the output pin
ONE, ///< steady 1 (ON), no change for the whole period
ONE_TO_FALL, ///< metastate allowing the timer change its state atomically without artefacts on the output pin
FALL, ///< 16 fast PWM cycles with decreasing duty down to steady OFF
FALL_TO_ZERO ///< metastate allowing the timer change its state atomically without artefacts on the output pin
};
///! Inner states of the finite automaton
static States state = States::ZERO_START;
bool bedPWMDisabled = 0;
///! Fast PWM counter is used in the RISE and FALL states (62.5kHz)
static uint8_t slowCounter = 0;
///! Slow PWM counter is used in the ZERO and ONE states (62.5kHz/8 or 64)
static uint8_t fastCounter = 0;
///! PWM counter for the whole cycle - a cache for soft_pwm_bed
static uint8_t pwm = 0;
///! The slow PWM duty for the next 30Hz cycle
///! Set in the whole firmware at various places
extern unsigned char soft_pwm_bed;
/// fastMax - how many fast PWM steps to do in RISE and FALL states
/// 16 is a good compromise between silenced bed ("smooth" edges)
/// and not burning the switching MOSFET
static const uint8_t fastMax = 16;
/// Scaler 16->256 for fast PWM
static const uint8_t fastShift = 4;
/// Increment slow PWM counter by slowInc every ZERO or ONE state
/// This allows for fine-tuning the basic PWM switching frequency
/// A possible further optimization - use a 64 prescaler (instead of 8)
/// increment slowCounter by 1
/// but use less bits of soft PWM - something like soft_pwm_bed >> 2
/// that may further reduce the CPU cycles required by the bed heating automaton
/// Due to the nature of bed heating the reduced PID precision may not be a major issue, however doing 8x less ISR(timer0_ovf) may significantly improve the performance
static const uint8_t slowInc = 1;
ISR(TIMER0_OVF_vect) // timer compare interrupt service routine
{
switch(state){
case States::ZERO_START:
if (bedPWMDisabled) return; // stay in the OFF state and do not change the output pin
pwm = soft_pwm_bed << 1;// expecting soft_pwm_bed to be 7bit!
if( pwm != 0 ){
state = States::ZERO; // do nothing, let it tick once again after the 30Hz period
}
break;
case States::ZERO: // end of state ZERO - we'll either stay in ZERO or change to RISE
// In any case update our cache of pwm value for the next whole cycle from soft_pwm_bed
slowCounter += slowInc; // this does software timer_clk/256 or less (depends on slowInc)
if( slowCounter > pwm ){
return;
} // otherwise moving towards RISE
state = States::ZERO_TO_RISE; // and finalize the change in a transitional state RISE0
break;
// even though it may look like the ZERO state may be glued together with the ZERO_TO_RISE, don't do it
// the timer must tick once more in order to get rid of occasional output pin toggles.
case States::ZERO_TO_RISE: // special state for handling transition between prescalers and switching inverted->non-inverted fast-PWM without toggling the output pin.
// It must be done in consequent steps, otherwise the pin will get flipped up and down during one PWM cycle.
// Also beware of the correct sequence of the following timer control registers initialization - it really matters!
state = States::RISE; // prepare for standard RISE cycles
fastCounter = fastMax - 1;// we'll do 16-1 cycles of RISE
TCNT0 = 255; // force overflow on the next clock cycle
TCCR0B = (1 << CS00); // change prescaler to 1, i.e. 62.5kHz
TCCR0A &= ~(1 << COM0B0); // Clear OC0B on Compare Match, set OC0B at BOTTOM (non-inverting mode)
break;
case States::RISE:
OCR0B = (fastMax - fastCounter) << fastShift;
if( fastCounter ){
--fastCounter;
} else { // end of RISE cycles, changing into state ONE
state = States::RISE_TO_ONE;
OCR0B = 255; // full duty
TCNT0 = 254; // make the timer overflow in the next cycle
// @@TODO these constants are still subject to investigation
}
break;
case States::RISE_TO_ONE:
state = States::ONE;
OCR0B = 255; // full duty
TCNT0 = 255; // make the timer overflow in the next cycle
TCCR0B = (1 << CS01); // change prescaler to 8, i.e. 7.8kHz
break;
case States::ONE: // state ONE - we'll either stay in ONE or change to FALL
OCR0B = 255;
if (bedPWMDisabled) return; // stay in the ON state and do not change the output pin
slowCounter += slowInc; // this does software timer_clk/256 or less
if( slowCounter < pwm ){
return;
}
if( (soft_pwm_bed << 1) >= (255 - slowInc - 1) ){ //@@TODO simplify & explain
// if slowInc==2, soft_pwm == 251 will be the first to do short drops to zero. 252 will keep full heating
return; // want full duty for the next ONE cycle again - so keep on heating and just wait for the next timer ovf
}
// otherwise moving towards FALL
// @@TODO it looks like ONE_TO_FALL isn't necessary, there are no artefacts at all
state = States::ONE;//_TO_FALL;
// TCCR0B = (1 << CS00); // change prescaler to 1, i.e. 62.5kHz
// break;
// case States::ONE_TO_FALL:
// OCR0B = 255; // zero duty
state=States::FALL;
fastCounter = fastMax - 1;// we'll do 16-1 cycles of RISE
TCNT0 = 255; // force overflow on the next clock cycle
TCCR0B = (1 << CS00); // change prescaler to 1, i.e. 62.5kHz
// must switch to inverting mode already here, because it takes a whole PWM cycle and it would make a "1" at the end of this pwm cycle
// COM0B1 remains set both in inverting and non-inverting mode
TCCR0A |= (1 << COM0B0); // inverting mode
break;
case States::FALL:
OCR0B = (fastMax - fastCounter) << fastShift; // this is the same as in RISE, because now we are setting the zero part of duty due to inverting mode
//TCCR0A |= (1 << COM0B0); // already set in ONE_TO_FALL
if( fastCounter ){
--fastCounter;
} else { // end of FALL cycles, changing into state ZERO
state = States::FALL_TO_ZERO;
TCNT0 = 128; //@@TODO again - need to wait long enough to propagate the timer state changes
OCR0B = 255;
}
break;
case States::FALL_TO_ZERO:
state = States::ZERO_START; // go to read new soft_pwm_bed value for the next cycle
TCNT0 = 128;
OCR0B = 255;
TCCR0B = (1 << CS01); // change prescaler to 8, i.e. 7.8kHz
break;
}
}

View File

@ -2,13 +2,24 @@
#include "Marlin.h"
static LA10C_MODE la10c_mode = LA10C_UNKNOWN;
static LA10C_MODE la10c_mode = LA10C_UNKNOWN; // Current LA compatibility mode
static float la10c_orig_jerk = 0; // Unadjusted/saved e-jerk
LA10C_MODE la10c_mode_get()
{
return la10c_mode;
}
void la10c_mode_change(LA10C_MODE mode)
{
if(mode == la10c_mode) return;
// always restore to the last unadjusted E-jerk value
if(la10c_orig_jerk)
cs.max_jerk[E_AXIS] = la10c_orig_jerk;
SERIAL_ECHOPGM("LA10C: Linear Advance mode: ");
switch(mode)
{
@ -17,13 +28,16 @@ void la10c_mode_change(LA10C_MODE mode)
case LA10C_LA10: SERIAL_ECHOLNPGM("1.0"); break;
}
la10c_mode = mode;
// adjust the E-jerk if needed
cs.max_jerk[E_AXIS] = la10c_jerk(cs.max_jerk[E_AXIS]);
}
// Approximate a LA10 value to a LA15 equivalent.
static float la10c_convert(float k)
{
float new_K = k * 0.004 - 0.06;
float new_K = k * 0.004 - 0.05;
return (new_K < 0? 0: new_K);
}
@ -46,3 +60,29 @@ float la10c_value(float k)
else
return (k >= 0? la10c_convert(k): -1);
}
float la10c_jerk(float j)
{
la10c_orig_jerk = j;
if(la10c_mode != LA10C_LA10)
return j;
// check for a compatible range of values prior to convert (be sure that
// a higher E-jerk would still be compatible wrt the E accell range)
if(j < 4.5 && cs.max_acceleration_units_per_sq_second_normal[E_AXIS] < 2000)
return j;
// bring low E-jerk values into equivalent LA 1.5 values by
// flattening the response in the (1-4.5) range using a piecewise
// function. Is it truly worth to preserve the difference between
// 1.5/2.5 E-jerk for LA1.0? Probably not, but we try nonetheless.
j = j < 1.0? j * 3.625:
j < 4.5? j * 0.25 + 3.375:
j;
SERIAL_ECHOPGM("LA10C: Adjusted E-Jerk: ");
SERIAL_ECHOLN(j);
return j;
}

View File

@ -5,6 +5,9 @@
// compatbility mode is active the K factor is converted to a LA15
// equivalent (that is, the return value is always a LA15 value).
//
// E-jerk<2 is also bumped in LA10 mode to restore the the printing speed
// to values comparable to existing settings.
//
// Once the interpretation mode has been set it is kept until the mode
// is explicitly reset. This is done to handle transparent fallback for
// old firmware revisions in combination with the following gcode
@ -31,9 +34,13 @@ enum __attribute__((packed)) LA10C_MODE
LA10C_LA10 = 2
};
// Explicitly set/reset the interpretation mode for la10c_value()
// Explicitly set/get/reset the interpretation mode for la10c_value()
void la10c_mode_change(LA10C_MODE mode);
LA10C_MODE la10c_mode_get();
static inline void la10c_reset() { la10c_mode_change(LA10C_UNKNOWN); }
// Return a LA15 K value according to the supplied value and mode
float la10c_value(float k);
// Return an updated LA15 E-jerk value according to the current mode
float la10c_jerk(float j);

View File

@ -6,7 +6,9 @@
#include "config.h"
#include <inttypes.h>
//#include <stdio.h>
#ifdef DEBUG_SEC_LANG
#include <stdio.h>
#endif //DEBUG_SEC_LANG
#define PROTOCOL_VERSION "1.0"

View File

@ -6,6 +6,7 @@
#include "mesh_bed_leveling.h"
#include "stepper.h"
#include "ultralcd.h"
#include "temperature.h"
#ifdef TMC2130
#include "tmc2130.h"
@ -946,6 +947,7 @@ inline bool find_bed_induction_sensor_point_z(float minimum_z, uint8_t n_iter, i
)
{
bool high_deviation_occured = false;
bedPWMDisabled = 1;
#ifdef TMC2130
FORCE_HIGH_POWER_START;
#endif
@ -1044,6 +1046,7 @@ inline bool find_bed_induction_sensor_point_z(float minimum_z, uint8_t n_iter, i
#ifdef TMC2130
FORCE_HIGH_POWER_END;
#endif
bedPWMDisabled = 0;
return true;
error:
@ -1053,6 +1056,7 @@ error:
#ifdef TMC2130
FORCE_HIGH_POWER_END;
#endif
bedPWMDisabled = 0;
return false;
}

View File

@ -138,6 +138,11 @@ const char MSG_TIMEOUT[] PROGMEM_I1 = ISTR("Timeout"); ////
const char MSG_BRIGHT[] PROGMEM_I1 = ISTR("Bright"); ////
const char MSG_DIM[] PROGMEM_I1 = ISTR("Dim"); ////
const char MSG_AUTO[] PROGMEM_I1 = ISTR("Auto"); ////
#ifdef IR_SENSOR_ANALOG
// Beware - the space at the beginning is necessary since it is reused in LCD menu items which are to be with a space
const char MSG_04_OR_NEWER[] PROGMEM_I1 = ISTR(" 0.4 or newer");
const char MSG_03_OR_OLDER[] PROGMEM_I1 = ISTR(" 0.3 or older");
#endif
//not internationalized messages
const char MSG_SD_WORKDIR_FAIL[] PROGMEM_N1 = "workDir open failed"; ////
@ -168,6 +173,6 @@ const char MSG_OCTOPRINT_CANCEL[] PROGMEM_N1 = "// action:cancel"; ////
const char MSG_FANCHECK_EXTRUDER[] PROGMEM_N1 = "Err: EXTR. FAN ERROR"; ////c=20
const char MSG_FANCHECK_PRINT[] PROGMEM_N1 = "Err: PRINT FAN ERROR"; ////c=20
const char MSG_M112_KILL[] PROGMEM_N1 = "M112 called. Emergency Stop."; ////c=20
#ifdef LA_LIVE_K
const char MSG_ADVANCE_K[] PROGMEM_N1 = "Advance K:"; ////c=13
#endif
const char MSG_POWERPANIC_DETECTED[] PROGMEM_N1 = "POWER PANIC DETECTED"; ////c=20

View File

@ -138,6 +138,10 @@ extern const char MSG_TIMEOUT[];
extern const char MSG_BRIGHT[];
extern const char MSG_DIM[];
extern const char MSG_AUTO[];
#ifdef IR_SENSOR_ANALOG
extern const char MSG_04_OR_NEWER[];
extern const char MSG_03_OR_OLDER[];
#endif
//not internationalized messages
extern const char MSG_BROWNOUT_RESET[];
@ -170,6 +174,7 @@ extern const char MSG_FANCHECK_EXTRUDER[];
extern const char MSG_FANCHECK_PRINT[];
extern const char MSG_M112_KILL[];
extern const char MSG_ADVANCE_K[];
extern const char MSG_POWERPANIC_DETECTED[];
#if defined(__cplusplus)
}

View File

@ -383,8 +383,9 @@ void mmu_loop(void)
//printf_P(PSTR("Eact: %d\n"), int(e_active()));
if (!mmu_finda && CHECK_FSENSOR && fsensor_enabled) {
fsensor_checkpoint_print();
ad_markDepleted(mmu_extruder);
if (lcd_autoDepleteEnabled() && !ad_allDepleted())
if (mmu_extruder != MMU_FILAMENT_UNKNOWN) // Can't deplete unknown extruder.
ad_markDepleted(mmu_extruder);
if (lcd_autoDepleteEnabled() && !ad_allDepleted() && mmu_extruder != MMU_FILAMENT_UNKNOWN) // Can't auto if F=?
{
enquecommand_front_P(PSTR("M600 AUTO")); //save print and run M600 command
}
@ -795,8 +796,8 @@ void mmu_load_to_nozzle()
{
st_synchronize();
bool saved_e_relative_mode = axis_relative_modes[E_AXIS];
if (!saved_e_relative_mode) axis_relative_modes[E_AXIS] = true;
const bool saved_e_relative_mode = axis_relative_modes & E_AXIS_MASK;
if (!saved_e_relative_mode) axis_relative_modes |= E_AXIS_MASK;
if (ir_sensor_detected)
{
current_position[E_AXIS] += 3.0f;
@ -820,7 +821,7 @@ void mmu_load_to_nozzle()
feedrate = 871;
plan_buffer_line_curposXYZE(feedrate / 60, active_extruder);
st_synchronize();
if (!saved_e_relative_mode) axis_relative_modes[E_AXIS] = false;
if (!saved_e_relative_mode) axis_relative_modes &= ~E_AXIS_MASK;
}
void mmu_M600_wait_and_beep() {

View File

@ -183,9 +183,9 @@ uint8_t pat9125_update(void)
if (pat9125_PID1 == 0xff) return 0;
if (ucMotion & 0x80)
{
uint8_t ucXL = pat9125_rd_reg(PAT9125_DELTA_XL);
uint8_t ucYL = pat9125_rd_reg(PAT9125_DELTA_YL);
uint8_t ucXYH = pat9125_rd_reg(PAT9125_DELTA_XYH);
uint16_t ucXL = pat9125_rd_reg(PAT9125_DELTA_XL);
uint16_t ucYL = pat9125_rd_reg(PAT9125_DELTA_YL);
uint16_t ucXYH = pat9125_rd_reg(PAT9125_DELTA_XYH);
if (pat9125_PID1 == 0xff) return 0;
int16_t iDX = ucXL | ((ucXYH << 4) & 0xf00);
int16_t iDY = ucYL | ((ucXYH << 8) & 0xf00);
@ -207,8 +207,8 @@ uint8_t pat9125_update_y(void)
if (pat9125_PID1 == 0xff) return 0;
if (ucMotion & 0x80)
{
uint8_t ucYL = pat9125_rd_reg(PAT9125_DELTA_YL);
uint8_t ucXYH = pat9125_rd_reg(PAT9125_DELTA_XYH);
uint16_t ucYL = pat9125_rd_reg(PAT9125_DELTA_YL);
uint16_t ucXYH = pat9125_rd_reg(PAT9125_DELTA_XYH);
if (pat9125_PID1 == 0xff) return 0;
int16_t iDY = ucYL | ((ucXYH << 8) & 0xf00);
if (iDY & 0x800) iDY -= 4096;
@ -219,18 +219,13 @@ uint8_t pat9125_update_y(void)
return 0;
}
uint8_t pat9125_update_y2(void)
uint8_t pat9125_update_bs(void)
{
if ((pat9125_PID1 == 0x31) && (pat9125_PID2 == 0x91))
{
uint8_t ucMotion = pat9125_rd_reg(PAT9125_MOTION);
if (pat9125_PID1 == 0xff) return 0; //NOACK error
if (ucMotion & 0x80)
{
int8_t dy = pat9125_rd_reg(PAT9125_DELTA_YL);
if (pat9125_PID1 == 0xff) return 0; //NOACK error
pat9125_y -= dy; //negative number, because direction switching does not work
}
pat9125_b = pat9125_rd_reg(PAT9125_FRAME);
pat9125_s = pat9125_rd_reg(PAT9125_SHUTTER);
if (pat9125_PID1 == 0xff) return 0;
return 1;
}
return 0;

View File

@ -19,9 +19,9 @@ extern uint8_t pat9125_b;
extern uint8_t pat9125_s;
extern uint8_t pat9125_init(void);
extern uint8_t pat9125_update(void);
extern uint8_t pat9125_update_y(void);
extern uint8_t pat9125_update_y2(void);
extern uint8_t pat9125_update(void); // update all sensor data
extern uint8_t pat9125_update_y(void); // update _y only
extern uint8_t pat9125_update_bs(void); // update _b/_s only
#if defined(__cplusplus)

View File

@ -1061,16 +1061,16 @@ Having the real displacement of the head, we can calculate the total movement le
/**
* Use LIN_ADVANCE within this block if all these are true:
*
* block->steps_e : This is a print move, because we checked for X, Y, Z steps before.
* extruder_advance_K : There is an advance factor set.
* delta_mm[E_AXIS] > 0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves)
* delta_mm[E_AXIS] >= 0 : Extruding or traveling, but _not_ retracting.
* |delta_mm[Z_AXIS]| < 0.5 : Z is only moved for leveling (_not_ for priming)
*/
block->use_advance_lead = block->steps_e.wide
&& extruder_advance_K
&& delta_mm[E_AXIS] > 0
block->use_advance_lead = extruder_advance_K > 0
&& delta_mm[E_AXIS] >= 0
&& abs(delta_mm[Z_AXIS]) < 0.5;
if (block->use_advance_lead) {
// all extrusion moves with LA require a compression which is proportional to the
// extrusion_length to distance ratio (e/D)
e_D_ratio = (e - position_float[E_AXIS]) /
sqrt(sq(x - position_float[X_AXIS])
+ sq(y - position_float[Y_AXIS])
@ -1082,10 +1082,10 @@ Having the real displacement of the head, we can calculate the total movement le
// 100mm wide lines using 3mm filament or 35mm wide lines using 1.75mm filament.
if (e_D_ratio > 3.0)
block->use_advance_lead = false;
else {
const uint32_t max_accel_steps_per_s2 = cs.max_jerk[E_AXIS] / (extruder_advance_K * e_D_ratio) * steps_per_mm;
if (block->acceleration_st > max_accel_steps_per_s2) {
block->acceleration_st = max_accel_steps_per_s2;
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);
#ifdef LA_DEBUG
SERIAL_ECHOLNPGM("LA: Block acceleration limited due to max E-jerk");
#endif
@ -1133,21 +1133,33 @@ Having the real displacement of the head, we can calculate the total movement le
block->adv_comp = extruder_advance_K * e_D_ratio * cs.axis_steps_per_unit[E_AXIS];
block->max_adv_steps = block->nominal_speed * block->adv_comp;
float advance_speed;
if (e_D_ratio > 0)
advance_speed = (extruder_advance_K * e_D_ratio * block->acceleration * cs.axis_steps_per_unit[E_AXIS]);
else
advance_speed = cs.max_jerk[E_AXIS] * cs.axis_steps_per_unit[E_AXIS];
// to save more space we avoid another copy of calc_timer and go through slow division, but we
// still need to replicate the *exact* same step grouping policy (see below)
float advance_speed = (extruder_advance_K * e_D_ratio * block->acceleration * cs.axis_steps_per_unit[E_AXIS]);
if (advance_speed > MAX_STEP_FREQUENCY) advance_speed = MAX_STEP_FREQUENCY;
block->advance_rate = (F_CPU / 8.0) / advance_speed;
if (block->advance_rate > 20000) {
block->advance_rate = (block->advance_rate >> 2)&0x3fff;
float advance_rate = (F_CPU / 8.0) / advance_speed;
if (advance_speed > 20000) {
block->advance_rate = advance_rate * 4;
block->advance_step_loops = 4;
}
else if (block->advance_rate > 10000) {
block->advance_rate = (block->advance_rate >> 1)&0x7fff;
else if (advance_speed > 10000) {
block->advance_rate = advance_rate * 2;
block->advance_step_loops = 2;
}
else
{
// never overflow the internal accumulator with very low rates
if (advance_rate < UINT16_MAX)
block->advance_rate = advance_rate;
else
block->advance_rate = UINT16_MAX;
block->advance_step_loops = 1;
}
#ifdef LA_DEBUG
if (block->advance_step_loops > 2)
@ -1345,14 +1357,7 @@ void plan_set_position(float x, float y, float z, const float &e)
apply_rotation_xyz(plan_bed_level_matrix, x, y, z);
#endif // ENABLE_AUTO_BED_LEVELING
// Apply the machine correction matrix.
if (world2machine_correction_mode != WORLD2MACHINE_CORRECTION_NONE)
{
float tmpx = x;
float tmpy = y;
x = world2machine_rotation_and_skew[0][0] * tmpx + world2machine_rotation_and_skew[0][1] * tmpy + world2machine_shift[0];
y = world2machine_rotation_and_skew[1][0] * tmpx + world2machine_rotation_and_skew[1][1] * tmpy + world2machine_shift[1];
}
world2machine(x, y);
position[X_AXIS] = lround(x*cs.axis_steps_per_unit[X_AXIS]);
position[Y_AXIS] = lround(y*cs.axis_steps_per_unit[Y_AXIS]);

View File

@ -173,6 +173,9 @@ void plan_set_e_position(const float &e);
// Reset the E position to zero at the start of the next segment
void plan_reset_next_e();
inline void set_current_to_destination() { memcpy(current_position, destination, sizeof(current_position)); }
inline void set_destination_to_current() { memcpy(destination, current_position, sizeof(destination)); }
extern bool e_active();
void check_axes_activity();

View File

@ -36,9 +36,9 @@
#include "tmc2130.h"
#endif //TMC2130
#ifdef FILAMENT_SENSOR
#if defined(FILAMENT_SENSOR) && defined(PAT9125)
#include "fsensor.h"
int fsensor_counter = 0; //counter for e-steps
int fsensor_counter; //counter for e-steps
#endif //FILAMENT_SENSOR
#include "mmu.h"
@ -117,8 +117,8 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1};
void advance_isr();
static const uint16_t ADV_NEVER = 0xFFFF;
static const uint8_t ADV_INIT = 0b01;
static const uint8_t ADV_DECELERATE = 0b10;
static const uint8_t ADV_INIT = 0b01; // initialize LA
static const uint8_t ADV_ACC_VARY = 0b10; // varying acceleration phase
static uint16_t nextMainISR;
static uint16_t nextAdvanceISR;
@ -128,13 +128,12 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1};
static uint16_t eISR_Err;
static uint16_t current_adv_steps;
static uint16_t final_adv_steps;
static uint16_t max_adv_steps;
static uint32_t LA_decelerate_after;
static uint16_t target_adv_steps;
static int8_t e_steps;
static uint8_t e_step_loops;
static int8_t LA_phase;
static int8_t e_steps; // scheduled e-steps during each isr loop
static uint8_t e_step_loops; // e-steps to execute at most in each isr loop
static uint8_t e_extruding; // current move is an extrusion move
static int8_t LA_phase; // LA compensation phase
#define _NEXT_ISR(T) main_Rate = nextMainISR = T
#else
@ -349,15 +348,12 @@ FORCE_INLINE void stepper_next_block()
#ifdef LIN_ADVANCE
if (current_block->use_advance_lead) {
LA_decelerate_after = current_block->decelerate_after;
final_adv_steps = current_block->final_adv_steps;
max_adv_steps = current_block->max_adv_steps;
e_step_loops = current_block->advance_step_loops;
target_adv_steps = current_block->max_adv_steps;
} else {
e_steps = 0;
e_step_loops = 1;
current_adv_steps = 0;
}
e_steps = 0;
nextAdvanceISR = ADV_NEVER;
LA_phase = -1;
#endif
@ -371,11 +367,17 @@ FORCE_INLINE void stepper_next_block()
counter_y.lo = counter_x.lo;
counter_z.lo = counter_x.lo;
counter_e.lo = counter_x.lo;
#ifdef LIN_ADVANCE
e_extruding = current_block->steps_e.lo != 0;
#endif
} else {
counter_x.wide = -(current_block->step_event_count.wide >> 1);
counter_y.wide = counter_x.wide;
counter_z.wide = counter_x.wide;
counter_e.wide = counter_x.wide;
#ifdef LIN_ADVANCE
e_extruding = current_block->steps_e.wide != 0;
#endif
}
step_events_completed.wide = 0;
// Set directions.
@ -421,9 +423,8 @@ FORCE_INLINE void stepper_next_block()
#endif /* LIN_ADVANCE */
count_direction[E_AXIS] = 1;
}
#ifdef FILAMENT_SENSOR
fsensor_counter = 0;
fsensor_st_block_begin(count_direction[E_AXIS] < 0);
#if defined(FILAMENT_SENSOR) && defined(PAT9125)
fsensor_st_block_begin(count_direction[E_AXIS] < 0);
#endif //FILAMENT_SENSOR
}
else {
@ -812,7 +813,7 @@ FORCE_INLINE void isr() {
#ifdef LIN_ADVANCE
if (current_block->use_advance_lead) {
if (step_events_completed.wide <= (unsigned long int)step_loops)
la_state = ADV_INIT;
la_state = ADV_INIT | ADV_ACC_VARY;
}
#endif
}
@ -828,11 +829,13 @@ FORCE_INLINE void isr() {
uint16_t timer = calc_timer(step_rate, step_loops);
_NEXT_ISR(timer);
deceleration_time += timer;
#ifdef LIN_ADVANCE
if (current_block->use_advance_lead) {
la_state = ADV_DECELERATE;
if (step_events_completed.wide <= (unsigned long int)current_block->decelerate_after + step_loops)
la_state |= ADV_INIT;
if (step_events_completed.wide <= (unsigned long int)current_block->decelerate_after + step_loops) {
target_adv_steps = current_block->final_adv_steps;
la_state = ADV_INIT | ADV_ACC_VARY;
}
}
#endif
}
@ -842,6 +845,17 @@ FORCE_INLINE void isr() {
// the initial interrupt blocking.
OCR1A_nominal = calc_timer(uint16_t(current_block->nominal_rate), step_loops);
step_loops_nominal = step_loops;
#ifdef LIN_ADVANCE
if(current_block->use_advance_lead) {
if (!nextAdvanceISR) {
// Due to E-jerk, there can be discontinuities in pressure state where an
// acceleration or deceleration can be skipped or joined with the previous block.
// If LA was not previously active, re-check the pressure level
la_state = ADV_INIT;
}
}
#endif
}
_NEXT_ISR(OCR1A_nominal);
}
@ -850,10 +864,23 @@ FORCE_INLINE void isr() {
#ifdef LIN_ADVANCE
// avoid multiple instances or function calls to advance_spread
if (la_state & ADV_INIT) eISR_Err = current_block->advance_rate / 4;
if (la_state & ADV_INIT) {
if (current_adv_steps == target_adv_steps) {
// nothing to be done in this phase
la_state = 0;
}
else {
eISR_Err = current_block->advance_rate / 4;
if ((la_state & ADV_ACC_VARY) && e_extruding && (current_adv_steps > target_adv_steps)) {
// LA could reverse the direction of extrusion in this phase
LA_phase = 0;
}
}
}
if (la_state & ADV_INIT || nextAdvanceISR != ADV_NEVER) {
// update timers & phase for the next iteration
advance_spread(main_Rate);
if (la_state & ADV_DECELERATE) {
if (LA_phase >= 0) {
if (step_loops == e_step_loops)
LA_phase = (eISR_Rate > main_Rate);
else {
@ -899,7 +926,7 @@ FORCE_INLINE void isr() {
// Timer interrupt for E. e_steps is set in the main routine.
FORCE_INLINE void advance_isr() {
if (step_events_completed.wide > LA_decelerate_after && current_adv_steps > final_adv_steps) {
if (current_adv_steps > target_adv_steps) {
// decompression
e_steps -= e_step_loops;
if (e_steps) WRITE_NC(E0_DIR_PIN, e_steps < 0? INVERT_E0_DIR: !INVERT_E0_DIR);
@ -909,7 +936,7 @@ FORCE_INLINE void advance_isr() {
current_adv_steps = 0;
nextAdvanceISR = eISR_Rate;
}
else if (step_events_completed.wide < LA_decelerate_after && current_adv_steps < max_adv_steps) {
else if (current_adv_steps < target_adv_steps) {
// compression
e_steps += e_step_loops;
if (e_steps) WRITE_NC(E0_DIR_PIN, e_steps < 0? INVERT_E0_DIR: !INVERT_E0_DIR);
@ -973,13 +1000,13 @@ FORCE_INLINE void advance_isr_scheduler() {
WRITE_NC(E0_STEP_PIN, !INVERT_E_STEP_PIN);
e_steps += (rev? 1: -1);
WRITE_NC(E0_STEP_PIN, INVERT_E_STEP_PIN);
#ifdef FILAMENT_SENSOR
#if defined(FILAMENT_SENSOR) && defined(PAT9125)
fsensor_counter += (rev? -1: 1);
#endif
}
while(--max_ticks);
#ifdef FILAMENT_SENSOR
#if defined(FILAMENT_SENSOR) && defined(PAT9125)
if (abs(fsensor_counter) >= fsensor_chunk_len)
{
fsensor_st_block_chunk(fsensor_counter);
@ -1234,9 +1261,6 @@ void st_init()
nextMainISR = 0;
nextAdvanceISR = ADV_NEVER;
main_Rate = ADV_NEVER;
e_steps = 0;
e_step_loops = 1;
LA_phase = -1;
current_adv_steps = 0;
#endif
@ -1357,8 +1381,6 @@ void quickStop()
}
#ifdef BABYSTEPPING
void babystep(const uint8_t axis,const bool direction)
{
//MUST ONLY BE CALLED BY A ISR, it depends on that no other ISR interrupts this
@ -1594,3 +1616,13 @@ void microstep_readings()
#endif
}
#endif //TMC2130
#if defined(FILAMENT_SENSOR) && defined(PAT9125)
void st_reset_fsensor()
{
CRITICAL_SECTION_START;
fsensor_counter = 0;
CRITICAL_SECTION_END;
}
#endif //FILAMENT_SENSOR

View File

@ -92,7 +92,10 @@ void microstep_readings();
#ifdef BABYSTEPPING
void babystep(const uint8_t axis,const bool direction); // perform a short step with a single stepper motor, outside of any convention
#endif
#if defined(FILAMENT_SENSOR) && defined(PAT9125)
// reset the internal filament sensor state
void st_reset_fsensor();
#endif
#endif

View File

@ -11,8 +11,8 @@
#define _millis millis2
#define _micros micros2
#define _delay delay2
#define _tone tone2
#define _noTone noTone2
#define _tone tone
#define _noTone noTone
#define timer02_set_pwm0(pwm0)
@ -20,8 +20,8 @@
#define _millis millis
#define _micros micros
#define _delay delay
#define _tone(x, y) /*tone*/
#define _noTone(x) /*noTone*/
#define _tone tone
#define _noTone noTone
#define timer02_set_pwm0(pwm0)
#endif //SYSTEM_TIMER_2

View File

@ -73,7 +73,7 @@ int current_voltage_raw_pwr = 0;
int current_voltage_raw_bed = 0;
#endif
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
int current_voltage_raw_IR = 0;
#endif //IR_SENSOR_ANALOG
@ -210,6 +210,14 @@ static void temp_runaway_check(int _heater_id, float _target_temperature, float
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);
}
void PID_autotune(float temp, int extruder, int ncycles)
{
pid_number_of_cycles = ncycles;
@ -1403,6 +1411,7 @@ void disable_heater()
target_temperature_bed=0;
soft_pwm_bed=0;
timer02_set_pwm0(soft_pwm_bed << 1);
bedPWMDisabled = 0;
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
//WRITE(HEATER_BED_PIN,LOW);
#endif
@ -1587,7 +1596,7 @@ void adc_ready(void) //callback from adc when sampling finished
#ifdef VOLT_BED_PIN
current_voltage_raw_bed = adc_values[ADC_PIN_IDX(VOLT_BED_PIN)]; // 6->9
#endif
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
current_voltage_raw_IR = adc_values[ADC_PIN_IDX(VOLT_IR_PIN)];
#endif //IR_SENSOR_ANALOG
temp_meas_ready = true;
@ -2002,6 +2011,8 @@ void check_max_temp()
//! number of repeating the same state with consecutive step() calls
//! used to slow down text switching
struct alert_automaton_mintemp {
const char *m2;
alert_automaton_mintemp(const char *m2):m2(m2){}
private:
enum { ALERT_AUTOMATON_SPEED_DIV = 5 };
enum class States : uint8_t { Init = 0, TempAboveMintemp, ShowPleaseRestart, ShowMintemp };
@ -2021,7 +2032,6 @@ public:
//! @param current_temp current hotend/bed temperature (for computing simple hysteresis)
//! @param mintemp minimal temperature including hysteresis to check current_temp against
void step(float current_temp, float mintemp){
static const char m2[] PROGMEM = "MINTEMP fixed";
static const char m1[] PROGMEM = "Please restart";
switch(state){
case States::Init: // initial state - check hysteresis
@ -2049,8 +2059,9 @@ public:
}
}
};
static alert_automaton_mintemp alert_automaton_hotend, alert_automaton_bed;
static const char m2hotend[] PROGMEM = "MINTEMP HOTEND fixed";
static const char m2bed[] PROGMEM = "MINTEMP BED fixed";
static alert_automaton_mintemp alert_automaton_hotend(m2hotend), alert_automaton_bed(m2bed);
void check_min_temp_heater0()
{

View File

@ -47,6 +47,8 @@
void tp_init(); //initialize the heating
void manage_heater(); //it is critical that this is called periodically.
extern bool checkAllHotends(void);
// low level conversion routines
// do not use these routines and variables outside of temperature.cpp
extern int target_temperature[EXTRUDERS];
@ -76,7 +78,7 @@ extern int current_voltage_raw_pwr;
extern int current_voltage_raw_bed;
#endif
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
extern int current_voltage_raw_IR;
#endif //IR_SENSOR_ANALOG
@ -84,6 +86,8 @@ extern int current_voltage_raw_IR;
extern unsigned char soft_pwm_bed;
#endif
extern bool bedPWMDisabled;
#ifdef PIDTEMP
extern int pid_cycle, pid_number_of_cycles;
extern float Kc,_Kp,_Ki,_Kd;
@ -220,6 +224,9 @@ FORCE_INLINE bool isCoolingBed() {
#error Invalid number of extruders
#endif
// return "false", if all heaters are 'off' (ie. "true", if any heater is 'on')
#define CHECK_ALL_HEATERS (checkAllHotends()||(target_temperature_bed!=0))
int getHeaterPower(int heater);
void disable_heater();
void updatePID();

View File

@ -136,14 +136,4 @@ void delay2(unsigned long ms)
}
}
void tone2(__attribute__((unused)) uint8_t _pin, __attribute__((unused)) unsigned int frequency/*, unsigned long duration*/)
{
PIN_SET(BEEPER);
}
void noTone2(__attribute__((unused)) uint8_t _pin)
{
PIN_CLR(BEEPER);
}
#endif //SYSTEM_TIMER_2

View File

@ -23,13 +23,6 @@ extern unsigned long micros2(void);
///! Reimplemented original delay() using timer2
extern void delay2(unsigned long ms);
///! Reimplemented original tone() using timer2
///! Does not perform any PWM tone generation, it just sets the beeper pin to 1
extern void tone2(uint8_t _pin, unsigned int frequency/*, unsigned long duration*/);
///! Turn off beeping - set beeper pin to 0
extern void noTone2(uint8_t _pin);
#if defined(__cplusplus)
}
#endif //defined(__cplusplus)

View File

@ -68,6 +68,10 @@ uint8_t SilentModeMenu_MMU = 1; //activate mmu unit stealth mode
int8_t FSensorStateMenu = 1;
#ifdef IR_SENSOR_ANALOG
bool bMenuFSDetect=false;
#endif //IR_SENSOR_ANALOG
#ifdef SDCARD_SORT_ALPHA
bool presort_flag = false;
@ -114,7 +118,7 @@ static const char* lcd_display_message_fullscreen_nonBlocking_P(const char *msg,
// void copy_and_scalePID_d();
/* Different menus */
static void lcd_status_screen();
//static void lcd_status_screen(); // NOT static due to using inside "Marlin_main" module ("manage_inactivity()")
#if (LANG_MODE != 0)
static void lcd_language_menu();
#endif
@ -164,10 +168,10 @@ static void reset_crash_det(unsigned char axis);
static bool lcd_selfcheck_axis_sg(unsigned char axis);
static bool lcd_selfcheck_axis(int _axis, int _travel);
#else
static bool lcd_selfcheck_endstops();
static bool lcd_selfcheck_axis(int _axis, int _travel);
static bool lcd_selfcheck_pulleys(int axis);
#endif //TMC2130
static bool lcd_selfcheck_endstops();
static bool lcd_selfcheck_check_heater(bool _isbed);
enum class TestScreen : uint_least8_t
@ -235,8 +239,9 @@ static FanCheck lcd_selftest_fan_auto(int _fan);
static bool lcd_selftest_fsensor();
#endif //PAT9125
static bool selftest_irsensor();
#if IR_SENSOR_ANALOG
static bool lcd_selftest_IRsensor();
#ifdef IR_SENSOR_ANALOG
static bool lcd_selftest_IRsensor(bool bStandalone=false);
static void lcd_detect_IRsensor();
#endif //IR_SENSOR_ANALOG
static void lcd_selftest_error(TestError error, const char *_error_1, const char *_error_2);
static void lcd_colorprint_change();
@ -975,7 +980,7 @@ void lcdui_print_status_screen(void)
}
// Main status screen. It's up to the implementation specific part to show what is needed. As this is very display dependent
static void lcd_status_screen()
void lcd_status_screen() // NOT static due to using inside "Marlin_main" module ("manage_inactivity()")
{
if (firstrun == 1)
{
@ -1796,11 +1801,23 @@ static void lcd_menu_fails_stats_print()
uint8_t crashX = eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_X);
uint8_t crashY = eeprom_read_byte((uint8_t*)EEPROM_CRASH_COUNT_Y);
lcd_home();
#ifndef PAT9125
lcd_printf_P(failStatsFmt,
_i("Last print failures"), ////c=20 r=1
_i("Power failures"), power, ////c=14 r=1
_i("Filam. runouts"), filam, ////c=14 r=1
_i("Crash"), crashX, crashY); ////c=7 r=1
#else
// On the MK3 include detailed PAT9125 statistics about soft failures
lcd_printf_P(PSTR("%S\n"
" %-16.16S%-3d\n"
" %-7.7S H %-3d S %-3d\n"
" %-7.7S X %-3d Y %-3d"),
_i("Last print failures"), ////c=20 r=1
_i("Power failures"), power, ////c=14 r=1
_i("Runouts"), filam, fsensor_softfail, //c=7 r=1
_i("Crash"), crashX, crashY); ////c=7 r=1
#endif
menu_back_if_clicked_fb();
}
@ -1940,7 +1957,7 @@ static void lcd_menu_temperatures()
menu_back_if_clicked();
}
#if defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN) || IR_SENSOR_ANALOG
#if defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN) || defined(IR_SENSOR_ANALOG)
#define VOLT_DIV_R1 10000
#define VOLT_DIV_R2 2370
#define VOLT_DIV_FAC ((float)VOLT_DIV_R2 / (VOLT_DIV_R2 + VOLT_DIV_R1))
@ -1952,27 +1969,24 @@ static void lcd_menu_temperatures()
//! | |
//! | PWR: 00.0V | c=12 r=1
//! | Bed: 00.0V | c=12 r=1
//! | |
//! | IR : 00.0V | c=12 r=1 optional
//! ----------------------
//! @endcode
//! @todo Positioning of the messages and values on LCD aren't fixed to their exact place. This causes issues with translations.
static void lcd_menu_voltages()
{
lcd_timeoutToStatus.stop(); //infinite timeout
float volt_pwr = VOLT_DIV_REF * ((float)current_voltage_raw_pwr / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC;
float volt_bed = VOLT_DIV_REF * ((float)current_voltage_raw_bed / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC;
lcd_home();
#if !IR_SENSOR_ANALOG
lcd_printf_P(PSTR("\n"));
#endif //!IR_SENSOR_ANALOG
lcd_printf_P(PSTR(" PWR: %4.1fV\n" " BED: %4.1fV"), volt_pwr, volt_bed);
#if IR_SENSOR_ANALOG
float volt_IR = VOLT_DIV_REF * ((float)current_voltage_raw_IR / (1023 * OVERSAMPLENR));
lcd_printf_P(PSTR("\n IR : %3.1fV"),volt_IR);
lcd_timeoutToStatus.stop(); //infinite timeout
float volt_pwr = VOLT_DIV_REF * ((float)current_voltage_raw_pwr / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC;
float volt_bed = VOLT_DIV_REF * ((float)current_voltage_raw_bed / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC;
lcd_home();
lcd_printf_P(PSTR(" PWR: %4.1fV\n" " BED: %4.1fV"), volt_pwr, volt_bed);
#ifdef IR_SENSOR_ANALOG
float volt_IR = VOLT_DIV_REF * ((float)current_voltage_raw_IR / (1023 * OVERSAMPLENR));
lcd_printf_P(PSTR("\n IR : %3.1fV"),volt_IR);
#endif //IR_SENSOR_ANALOG
menu_back_if_clicked();
menu_back_if_clicked();
}
#endif //defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN) || IR_SENSOR_ANALOG
#endif //defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN) || defined(IR_SENSOR_ANALOG)
#ifdef TMC2130
//! @brief Show Belt Status
@ -2149,6 +2163,23 @@ static void lcd_support_menu()
MENU_ITEM_BACK_P(_i("Date:"));////MSG_DATE c=17 r=1
MENU_ITEM_BACK_P(PSTR(__DATE__));
#ifdef IR_SENSOR_ANALOG
MENU_ITEM_BACK_P(STR_SEPARATOR);
MENU_ITEM_BACK_P(PSTR("Fil. sensor v.:"));
switch(oFsensorPCB)
{
case ClFsensorPCB::_Old:
MENU_ITEM_BACK_P(MSG_03_OR_OLDER);
break;
case ClFsensorPCB::_Rev04:
MENU_ITEM_BACK_P(MSG_04_OR_NEWER);
break;
case ClFsensorPCB::_Undef:
default:
MENU_ITEM_BACK_P(PSTR(" unknown state"));
}
#endif // IR_SENSOR_ANALOG
MENU_ITEM_BACK_P(STR_SEPARATOR);
if (mmu_enabled)
{
@ -2238,10 +2269,12 @@ void lcd_set_filament_autoload() {
fsensor_autoload_set(!fsensor_autoload_enabled);
}
#if defined(FILAMENT_SENSOR) && defined(PAT9125)
void lcd_set_filament_oq_meass()
{
fsensor_oq_meassure_set(!fsensor_oq_meassure_enabled);
}
#endif
FilamentAction eFilamentAction=FilamentAction::None; // must be initialized as 'non-autoLoad'
@ -2801,9 +2834,9 @@ static void lcd_LoadFilament()
//!
//! @code{.unparsed}
//! |01234567890123456789|
//! |Filament used: | c=18 r=1
//! | 00.00m |
//! |Print time: | c=18 r=1
//! |Filament used: | c=19 r=1
//! | 0000.00m |
//! |Print time: | c=19 r=1
//! | 00h 00m 00s |
//! ----------------------
//! @endcode
@ -2812,32 +2845,33 @@ static void lcd_LoadFilament()
//!
//! @code{.unparsed}
//! |01234567890123456789|
//! |Total filament : | c=18 r=1
//! | 000.00 m |
//! |Total print time : | c=18 r=1
//! | 00d :00h :00 m |
//! |Total filament: | c=19 r=1
//! | 0000.00m |
//! |Total print time: | c=19 r=1
//! | 00d 00h 00m |
//! ----------------------
//! @endcode
//! @todo Positioning of the messages and values on LCD aren't fixed to their exact place. This causes issues with translations. Translations missing for "d"days, "h"ours, "m"inutes", "s"seconds".
void lcd_menu_statistics()
{
lcd_timeoutToStatus.stop(); //infinite timeout
if (IS_SD_PRINTING)
{
const float _met = ((float)total_filament_used) / (100000.f);
const uint32_t _t = (_millis() - starttime) / 1000ul;
const int _h = _t / 3600;
const int _m = (_t - (_h * 3600ul)) / 60ul;
const int _s = _t - ((_h * 3600ul) + (_m * 60ul));
const uint32_t _h = _t / 3600;
const uint8_t _m = (_t - (_h * 3600ul)) / 60ul;
const uint8_t _s = _t - ((_h * 3600ul) + (_m * 60ul));
lcd_clear();
lcd_home();
lcd_printf_P(_N(
"%S:\n"
"%17.2fm \n"
"%18.2fm \n"
"%S:\n"
"%2dh %02dm %02ds"
"%10ldh %02hhdm %02hhds"
),
_i("Filament used"), _met, ////c=18 r=1
_i("Print time"), _h, _m, _s); ////c=18 r=1
_i("Filament used"), _met, ////c=19 r=1
_i("Print time"), _h, _m, _s); ////c=19 r=1
menu_back_if_clicked_fb();
}
else
@ -2847,29 +2881,20 @@ void lcd_menu_statistics()
uint8_t _hours, _minutes;
uint32_t _days;
float _filament_m = (float)_filament/100;
// int _filament_km = (_filament >= 100000) ? _filament / 100000 : 0;
// if (_filament_km > 0) _filament_m = _filament - (_filament_km * 100000);
_days = _time / 1440;
_hours = (_time - (_days * 1440)) / 60;
_minutes = _time - ((_days * 1440) + (_hours * 60));
lcd_clear();
lcd_home();
lcd_printf_P(_N(
"%S:\n"
"%17.2fm \n"
"%18.2fm \n"
"%S:\n"
"%7ldd :%2hhdh :%02hhdm"
), _i("Total filament"), _filament_m, _i("Total print time"), _days, _hours, _minutes);
KEEPALIVE_STATE(PAUSED_FOR_USER);
while (!lcd_clicked())
{
manage_heater();
manage_inactivity(true);
_delay(100);
}
KEEPALIVE_STATE(NOT_BUSY);
lcd_quick_feedback();
menu_back();
"%10ldd %02hhdh %02hhdm"
),
_i("Total filament"), _filament_m, ////c=19 r=1
_i("Total print time"), _days, _hours, _minutes); ////c=19 r=1
menu_back_if_clicked_fb();
}
}
@ -5636,7 +5661,7 @@ SETTINGS_VERSION;
MENU_END();
}
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
static void lcd_fsensor_actionNA_set(void)
{
switch(oFsensorActionNA)
@ -5702,8 +5727,9 @@ void lcd_hw_setup_menu(void) // can not be "static"
SETTINGS_NOZZLE;
MENU_ITEM_SUBMENU_P(_i("Checks"), lcd_checking_menu);
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
FSENSOR_ACTION_NA;
MENU_ITEM_FUNCTION_P(PSTR("Fsensor Detection"), lcd_detect_IRsensor);
#endif //IR_SENSOR_ANALOG
MENU_END();
}
@ -7122,7 +7148,7 @@ static void lcd_tune_menu()
else {
MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR), _T(MSG_ON), lcd_fsensor_state_set);
}
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
FSENSOR_ACTION_NA;
#endif //IR_SENSOR_ANALOG
#endif //FILAMENT_SENSOR
@ -7350,10 +7376,7 @@ void lcd_print_stop()
planner_abort_hard(); //needs to be done since plan_buffer_line resets waiting_inside_plan_buffer_line_print_aborted to false. Also copies current to destination.
axis_relative_modes[X_AXIS] = false;
axis_relative_modes[Y_AXIS] = false;
axis_relative_modes[Z_AXIS] = false;
axis_relative_modes[E_AXIS] = true;
axis_relative_modes = E_AXIS_MASK; //XYZ absolute, E relative
isPrintPaused = false; //clear isPrintPaused flag to allow starting next print after pause->stop scenario.
}
@ -7451,90 +7474,95 @@ static void lcd_belttest_v()
lcd_belttest();
menu_back_if_clicked();
}
void lcd_belttest_print(const char* msg, uint16_t X, uint16_t Y)
{
lcd_clear();
lcd_printf_P(
_N(
"%S:\n"
"%S\n"
"X:%d\n"
"Y:%d"
),
_i("Belt status"),
msg,
X,Y
);
}
void lcd_belttest()
{
int _progress = 0;
bool _result = true;
lcd_clear();
// Belttest requires high power mode. Enable it.
FORCE_HIGH_POWER_START;
uint16_t X = eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_X));
uint16_t Y = eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_Y));
lcd_belttest_print(_i("Checking X..."), X, Y);
_delay(2000);
lcd_printf_P(_i("Checking X axis ")); // share message with selftest
lcd_set_cursor(0,1), lcd_printf_P(PSTR("X: %u -> ..."),X);
KEEPALIVE_STATE(IN_HANDLER);
_result = lcd_selfcheck_axis_sg(X_AXIS);
X = eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_X));
if (!_result){
lcd_belttest_print(_i("Error"), X, Y);
return;
// N.B: it doesn't make sense to handle !lcd_selfcheck...() because selftest_sg throws its own error screen
// that clobbers ours, with more info than we could provide. So on fail we just fall through to take us back to status.
if (lcd_selfcheck_axis_sg(X_AXIS)){
X = eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_X));
lcd_set_cursor(10,1), lcd_printf_P(PSTR("%u"),X); // Show new X value next to old one.
lcd_puts_at_P(0,2,_i("Checking Y axis "));
lcd_set_cursor(0,3), lcd_printf_P(PSTR("Y: %u -> ..."),Y);
if (lcd_selfcheck_axis_sg(Y_AXIS))
{
Y = eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_Y));
lcd_set_cursor(10,3),lcd_printf_P(PSTR("%u"),Y);
lcd_set_cursor(19, 3);
lcd_print(LCD_STR_UPLEVEL);
lcd_wait_for_click_delay(10);
}
}
lcd_belttest_print(_i("Checking Y..."), X, Y);
_result = lcd_selfcheck_axis_sg(Y_AXIS);
Y = eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_Y));
if (!_result){
lcd_belttest_print(_i("Error"), X, Y);
lcd_clear();
return;
}
lcd_belttest_print(_i("Done"), X, Y);
FORCE_HIGH_POWER_END;
KEEPALIVE_STATE(NOT_BUSY);
_delay(3000);
}
#endif //TMC2130
#if IR_SENSOR_ANALOG
static bool lcd_selftest_IRsensor()
{
bool bAction;
bool bPCBrev03b;
uint16_t volt_IR_int;
float volt_IR;
#ifdef IR_SENSOR_ANALOG
// called also from marlin_main.cpp
void printf_IRSensorAnalogBoardChange(bool bPCBrev04){
printf_P(PSTR("Filament sensor board change detected: revision %S\n"), bPCBrev04 ? MSG_04_OR_NEWER : MSG_03_OR_OLDER);
}
volt_IR_int=current_voltage_raw_IR;
bPCBrev03b=(volt_IR_int<((int)IRsensor_Hopen_TRESHOLD));
volt_IR=VOLT_DIV_REF*((float)volt_IR_int/(1023*OVERSAMPLENR));
printf_P(PSTR("Measured filament sensor high level: %4.2fV\n"),volt_IR);
if(volt_IR_int<((int)IRsensor_Hmin_TRESHOLD))
{
lcd_selftest_error(TestError::FsensorLevel,"HIGH","");
return(false);
}
lcd_show_fullscreen_message_and_wait_P(_i("Please insert filament (but not load them!) into extruder and then press the knob."));
volt_IR_int=current_voltage_raw_IR;
volt_IR=VOLT_DIV_REF*((float)volt_IR_int/(1023*OVERSAMPLENR));
printf_P(PSTR("Measured filament sensor low level: %4.2fV\n"),volt_IR);
if(volt_IR_int>((int)IRsensor_Lmax_TRESHOLD))
{
lcd_selftest_error(TestError::FsensorLevel,"LOW","");
return(false);
}
if((bPCBrev03b?1:0)!=(uint8_t)oFsensorPCB) // safer then "(uint8_t)bPCBrev03b"
{
printf_P(PSTR("Filament sensor board change detected: revision %S\n"),bPCBrev03b?PSTR("03b or newer"):PSTR("03 or older"));
oFsensorPCB=bPCBrev03b?ClFsensorPCB::_Rev03b:ClFsensorPCB::_Old;
eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,(uint8_t)oFsensorPCB);
}
return(true);
static bool lcd_selftest_IRsensor(bool bStandalone)
{
bool bAction;
bool bPCBrev04;
uint16_t volt_IR_int;
float volt_IR;
volt_IR_int=current_voltage_raw_IR;
bPCBrev04=(volt_IR_int<((int)IRsensor_Hopen_TRESHOLD));
volt_IR=VOLT_DIV_REF*((float)volt_IR_int/(1023*OVERSAMPLENR));
printf_P(PSTR("Measured filament sensor high level: %4.2fV\n"),volt_IR);
if(volt_IR_int < ((int)IRsensor_Hmin_TRESHOLD)){
if(!bStandalone)
lcd_selftest_error(TestError::FsensorLevel,"HIGH","");
return(false);
}
lcd_show_fullscreen_message_and_wait_P(_i("Insert the filament (do not load it) into the extruder and then press the knob."));
volt_IR_int=current_voltage_raw_IR;
volt_IR=VOLT_DIV_REF*((float)volt_IR_int/(1023*OVERSAMPLENR));
printf_P(PSTR("Measured filament sensor low level: %4.2fV\n"),volt_IR);
if(volt_IR_int > ((int)IRsensor_Lmax_TRESHOLD)){
if(!bStandalone)
lcd_selftest_error(TestError::FsensorLevel,"LOW","");
return(false);
}
if((bPCBrev04?1:0)!=(uint8_t)oFsensorPCB){ // safer then "(uint8_t)bPCBrev04"
printf_IRSensorAnalogBoardChange(bPCBrev04);
oFsensorPCB=bPCBrev04?ClFsensorPCB::_Rev04:ClFsensorPCB::_Old;
eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,(uint8_t)oFsensorPCB);
}
return(true);
}
static void lcd_detect_IRsensor(){
bool bAction;
bMenuFSDetect = true; // inhibits some code inside "manage_inactivity()"
bAction = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Is filament loaded?"), false, false);
if(bAction){
lcd_show_fullscreen_message_and_wait_P(_i("Please unload the filament first, then repeat this action."));
return;
}
bAction = lcd_selftest_IRsensor(true);
if(bAction)
lcd_show_fullscreen_message_and_wait_P(_i("Sensor verified, remove the filament now."));
else
lcd_show_fullscreen_message_and_wait_P(_i("Verification failed, remove the filament and try again."));
bMenuFSDetect=false; // de-inhibits some code inside "manage_inactivity()"
}
#endif //IR_SENSOR_ANALOG
@ -7548,26 +7576,22 @@ bool lcd_selftest()
int _progress = 0;
bool _result = true;
bool _swapped_fan = false;
//#ifdef IR_SENSOR_ANALOG
#if (0)
bool bAction;
bAction=lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Is the filament unloaded?"),false,true);
if(!bAction)
return(false);
#endif //IR_SENSOR_ANALOG
lcd_wait_for_cool_down();
lcd_clear();
lcd_set_cursor(0, 0); lcd_puts_P(_i("Self test start "));////MSG_SELFTEST_START c=20
#ifdef TMC2130
FORCE_HIGH_POWER_START;
#endif // TMC2130
#if !IR_SENSOR_ANALOG
_delay(2000);
#endif //!IR_SENSOR_ANALOG
FORCE_BL_ON_START;
FORCE_BL_ON_START;
_delay(2000);
KEEPALIVE_STATE(IN_HANDLER);
#if IR_SENSOR_ANALOG
bool bAction;
bAction=lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Is filament unloaded?"),false,true);
if(!bAction)
return(false);
#endif //IR_SENSOR_ANALOG
_progress = lcd_selftest_screen(TestScreen::ExtruderFan, _progress, 3, true, 2000);
#if (defined(FANCHECK) && defined(TACH_0))
@ -7633,11 +7657,7 @@ bool lcd_selftest()
if (_result)
{
_progress = lcd_selftest_screen(TestScreen::FansOk, _progress, 3, true, 2000);
#ifndef TMC2130
_result = lcd_selfcheck_endstops();
#else
_result = true;
#endif
_result = lcd_selfcheck_endstops(); //With TMC2130, only the Z probe is tested.
}
if (_result)
@ -7688,21 +7708,31 @@ bool lcd_selftest()
#ifdef TMC2130
tmc2130_home_exit();
enable_endstops(false);
current_position[X_AXIS] = current_position[X_AXIS] + 14;
current_position[Y_AXIS] = current_position[Y_AXIS] + 12;
#endif
//homeaxis(X_AXIS);
//homeaxis(Y_AXIS);
current_position[X_AXIS] = pgm_read_float(bed_ref_points_4);
current_position[Y_AXIS] = pgm_read_float(bed_ref_points_4+1);
#ifdef TMC2130
//current_position[X_AXIS] += 0;
current_position[Y_AXIS] += 4;
#endif //TMC2130
current_position[Z_AXIS] = current_position[Z_AXIS] + 10;
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
st_synchronize();
set_destination_to_current();
_progress = lcd_selftest_screen(TestScreen::AxisZ, _progress, 3, true, 1500);
_result = lcd_selfcheck_axis(2, Z_MAX_POS);
if (eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE) != 1) {
enquecommand_P(PSTR("G28 W"));
enquecommand_P(PSTR("G1 Z15 F1000"));
}
#ifdef TMC2130
homeaxis(Z_AXIS); //In case of failure, the code gets stuck in this function.
#else
_result = lcd_selfcheck_axis(Z_AXIS, Z_MAX_POS);
#endif //TMC2130
//raise Z to not damage the bed during and hotend testing
current_position[Z_AXIS] += 20;
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
st_synchronize();
}
#ifdef TMC2130
@ -7759,7 +7789,8 @@ bool lcd_selftest()
_progress = lcd_selftest_screen(TestScreen::FsensorOk, _progress, 3, true, 2000); //fil sensor OK
}
#endif //PAT9125
#if IR_SENSOR_ANALOG
//#ifdef IR_SENSOR_ANALOG
#if (0)
_progress = lcd_selftest_screen(TestScreen::Fsensor, _progress, 3, true, 2000); //check filament sensor
_result = lcd_selftest_IRsensor();
if (_result)
@ -7825,14 +7856,10 @@ static bool lcd_selfcheck_axis_sg(unsigned char axis) {
tmc2130_home_exit();
enable_endstops(true);
if (axis == X_AXIS) { //there is collision between cables and PSU cover in X axis if Z coordinate is too low
current_position[Z_AXIS] += 17;
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
tmc2130_home_enter(Z_AXIS_MASK);
st_synchronize();
tmc2130_home_exit();
}
raise_z_above(MESH_HOME_Z_SEARCH);
st_synchronize();
tmc2130_home_enter(1 << axis);
// first axis length measurement begin
@ -7879,6 +7906,7 @@ static bool lcd_selfcheck_axis_sg(unsigned char axis) {
measured_axis_length[1] = abs(current_position_final - current_position_init);
tmc2130_home_exit();
//end of second measurement, now check for possible errors:
@ -7897,6 +7925,8 @@ static bool lcd_selfcheck_axis_sg(unsigned char axis) {
current_position[axis] = 0;
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
reset_crash_det(axis);
enable_endstops(true);
endstops_hit_on_purpose();
return false;
}
}
@ -7915,17 +7945,18 @@ static bool lcd_selfcheck_axis_sg(unsigned char axis) {
current_position[axis] = 0;
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
reset_crash_det(axis);
endstops_hit_on_purpose();
return false;
}
current_position[axis] = 0;
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
reset_crash_det(axis);
endstops_hit_on_purpose();
return true;
}
#endif //TMC2130
//#ifndef TMC2130
#ifndef TMC2130
static bool lcd_selfcheck_axis(int _axis, int _travel)
{
@ -8024,12 +8055,13 @@ static bool lcd_selfcheck_axis(int _axis, int _travel)
{
lcd_selftest_error(TestError::Motor, _error_1, _error_2);
}
}
}
current_position[_axis] = 0; //simulate axis home to avoid negative numbers for axis position, especially Z.
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
return _stepresult;
}
#ifndef TMC2130
static bool lcd_selfcheck_pulleys(int axis)
{
float tmp_motor_loud[3] = DEFAULT_PWM_MOTOR_CURRENT_LOUD;
@ -8074,7 +8106,7 @@ static bool lcd_selfcheck_pulleys(int axis)
((READ(Y_MIN_PIN) ^ Y_MIN_ENDSTOP_INVERTING) == 1)) {
endstop_triggered = true;
if (current_position_init - 1 <= current_position[axis] && current_position_init + 1 >= current_position[axis]) {
current_position[axis] += (axis == X_AXIS) ? 13 : 9;
current_position[axis] += 10;
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
st_synchronize();
return(true);
@ -8096,31 +8128,42 @@ static bool lcd_selfcheck_pulleys(int axis)
}
return(true);
}
#endif //not defined TMC2130
static bool lcd_selfcheck_endstops()
{
bool _result = true;
if (((READ(X_MIN_PIN) ^ X_MIN_ENDSTOP_INVERTING) == 1) ||
if (
#ifndef TMC2130
((READ(X_MIN_PIN) ^ X_MIN_ENDSTOP_INVERTING) == 1) ||
((READ(Y_MIN_PIN) ^ Y_MIN_ENDSTOP_INVERTING) == 1) ||
#endif //!TMC2130
((READ(Z_MIN_PIN) ^ Z_MIN_ENDSTOP_INVERTING) == 1))
{
#ifndef TMC2130
if ((READ(X_MIN_PIN) ^ X_MIN_ENDSTOP_INVERTING) == 1) current_position[0] += 10;
if ((READ(Y_MIN_PIN) ^ Y_MIN_ENDSTOP_INVERTING) == 1) current_position[1] += 10;
#endif //!TMC2130
if ((READ(Z_MIN_PIN) ^ Z_MIN_ENDSTOP_INVERTING) == 1) current_position[2] += 10;
}
plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder);
_delay(500);
st_synchronize();
if (((READ(X_MIN_PIN) ^ X_MIN_ENDSTOP_INVERTING) == 1) ||
if (
#ifndef TMC2130
((READ(X_MIN_PIN) ^ X_MIN_ENDSTOP_INVERTING) == 1) ||
((READ(Y_MIN_PIN) ^ Y_MIN_ENDSTOP_INVERTING) == 1) ||
#endif //!TMC2130
((READ(Z_MIN_PIN) ^ Z_MIN_ENDSTOP_INVERTING) == 1))
{
_result = false;
char _error[4] = "";
#ifndef TMC2130
if ((READ(X_MIN_PIN) ^ X_MIN_ENDSTOP_INVERTING) == 1) strcat(_error, "X");
if ((READ(Y_MIN_PIN) ^ Y_MIN_ENDSTOP_INVERTING) == 1) strcat(_error, "Y");
#endif //!TMC2130
if ((READ(Z_MIN_PIN) ^ Z_MIN_ENDSTOP_INVERTING) == 1) strcat(_error, "Z");
lcd_selftest_error(TestError::Endstops, _error, "");
}
@ -8128,7 +8171,6 @@ static bool lcd_selfcheck_endstops()
manage_inactivity(true);
return _result;
}
#endif //not defined TMC2130
static bool lcd_selfcheck_check_heater(bool _isbed)
{

View File

@ -55,8 +55,10 @@ extern bool lcd_selftest();
void lcd_menu_statistics();
void lcd_status_screen(); // NOT static due to using inside "Marlin_main" module ("manage_inactivity()")
void lcd_menu_extruder_info(); // NOT static due to using inside "Marlin_main" module ("manage_inactivity()")
void lcd_menu_show_sensors_state(); // NOT static due to using inside "Marlin_main" module ("manage_inactivity()")
#ifdef TMC2130
bool lcd_crash_detect_enabled();
void lcd_crash_detect_enable();
@ -138,6 +140,11 @@ extern uint8_t farm_status;
#define SILENT_MODE_OFF SILENT_MODE_POWER
#endif
#ifdef IR_SENSOR_ANALOG
extern bool bMenuFSDetect;
void printf_IRSensorAnalogBoardChange(bool bPCBrev04);
#endif //IR_SENSOR_ANALOG
extern int8_t SilentModeMenu;
extern uint8_t SilentModeMenu_MMU;
@ -251,7 +258,7 @@ enum class WizState : uint8_t
void lcd_wizard(WizState state);
#define VOLT_DIV_REF 5
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
#define IRsensor_Hmin_TRESHOLD (3.0*1023*OVERSAMPLENR/VOLT_DIV_REF) // ~3.0V (0.6*Vcc)
#define IRsensor_Lmax_TRESHOLD (1.5*1023*OVERSAMPLENR/VOLT_DIV_REF) // ~1.5V (0.3*Vcc)
#define IRsensor_Hopen_TRESHOLD (4.6*1023*OVERSAMPLENR/VOLT_DIV_REF) // ~4.6V (N.C. @ Ru~20-50k, Rd'=56k, Ru'=10k)

View File

@ -151,8 +151,8 @@
// this value is litlebit higher that real limit, because ambient termistor is on the board and is temperated from it,
// temperature inside the case is around 31C for ambient temperature 25C, when the printer is powered on long time and idle
// the real limit is 15C (same as MINTEMP limit), this is because 15C is end of scale for both used thermistors (bed, heater)
#define MINTEMP_MINAMBIENT 25
#define MINTEMP_MINAMBIENT_RAW 978
#define MINTEMP_MINAMBIENT 10
#define MINTEMP_MINAMBIENT_RAW 1002
#define DEBUG_DCODE3
@ -282,14 +282,14 @@
*------------------------------------*/
// Mintemps
#define HEATER_0_MINTEMP 15
#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)"
#endif
#define BED_MINTEMP 15
#define BED_MINTEMP 10
#define BED_MINTEMP_DELAY 50000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if BED_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)"
@ -618,6 +618,10 @@
// The following example, 12 * (4 * 16 / 400) = 12 * 0.16mm = 1.92mm.
//#define UVLO_Z_AXIS_SHIFT 1.92
#define UVLO_Z_AXIS_SHIFT 0.64
// When powered off during PP recovery, the Z axis position can still be re-adjusted. In this case
// we just need to shift to the nearest fullstep, but we need a move which is at least
// "dropsegments" steps long. All the above rules still need to apply.
#define UVLO_TINY_Z_AXIS_SHIFT 0.16
// If power panic occured, and the current temperature is higher then target temperature before interrupt minus this offset, print will be recovered automatically.
#define AUTOMATIC_UVLO_BED_TEMP_OFFSET 5

View File

@ -153,8 +153,8 @@
// this value is litlebit higher that real limit, because ambient termistor is on the board and is temperated from it,
// temperature inside the case is around 31C for ambient temperature 25C, when the printer is powered on long time and idle
// the real limit is 15C (same as MINTEMP limit), this is because 15C is end of scale for both used thermistors (bed, heater)
#define MINTEMP_MINAMBIENT 25
#define MINTEMP_MINAMBIENT_RAW 978
#define MINTEMP_MINAMBIENT 10
#define MINTEMP_MINAMBIENT_RAW 1002
#define DEBUG_DCODE3
@ -284,14 +284,14 @@
*------------------------------------*/
// Mintemps
#define HEATER_0_MINTEMP 15
#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)"
#endif
#define BED_MINTEMP 15
#define BED_MINTEMP 10
#define BED_MINTEMP_DELAY 50000 // [ms] ! if changed, check maximal allowed value @ ShortTimer
#if BED_MINTEMP_DELAY>USHRT_MAX
#error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)"
@ -620,7 +620,11 @@
// The following example, 12 * (4 * 16 / 400) = 12 * 0.16mm = 1.92mm.
//#define UVLO_Z_AXIS_SHIFT 1.92
#define UVLO_Z_AXIS_SHIFT 0.64
// If power panic occured, and the current temperature is higher then target temperature before interrupt minus this offset, print will be recovered automatically.
// When powered off during PP recovery, the Z axis position can still be re-adjusted. In this case
// we just need to shift to the nearest fullstep, but we need a move which is at least
// "dropsegments" steps long. All the above rules still need to apply.
#define UVLO_TINY_Z_AXIS_SHIFT 0.16
// If power panic occured, and the current temperature is higher then target temperature before interrupt minus this offset, print will be recovered automatically.
#define AUTOMATIC_UVLO_BED_TEMP_OFFSET 5
#define HEATBED_V2

View File

@ -56,7 +56,7 @@
# Some may argue that this is only used by a script, BUT as soon someone accidentally or on purpose starts Arduino IDE
# it will use the default Arduino IDE folders and so can corrupt the build environment.
#
# Version: 1.0.6-Build_10
# Version: 1.0.6-Build_13
# Change log:
# 12 Jan 2019, 3d-gussner, Fixed "compiler.c.elf.flags=-w -Os -Wl,-u,vfprintf -lprintf_flt -lm -Wl,--gc-sections" in 'platform.txt'
# 16 Jan 2019, 3d-gussner, Build_2, Added development check to modify 'Configuration.h' to prevent unwanted LCD messages that Firmware is unknown
@ -114,7 +114,10 @@
# 26 Jul 2019, 3d-gussner, Change JSON repository to prusa3d after PR https://github.com/prusa3d/Arduino_Boards/pull/1 was merged
# 23 Sep 2019, 3d-gussner, Prepare PF-build.sh for comming Prusa3d/Arduino_Boards version 1.0.2 Pull Request
# 17 Oct 2019, 3d-gussner, Changed folder and check file names to have seperated build enviroments depening on Arduino IDE version and
# board-versions.
# board-versions.
# 15 Dec 2019, 3d-gussner, Prepare for switch to Prusa3d/PF-build-env repository
# 15 Dec 2019, 3d-gussner, Fix Audrino user preferences for the chosen board.
# 17 Dec 2019, 3d-gussner, Fix "timer0_fract = 0" warning by using Arduino_boards v1.0.3
#### Start check if OSTYPE is supported
OS_FOUND=$( command -v uname)
@ -207,19 +210,22 @@ if ! type python > /dev/null; then
fi
fi
#### End prepare bash environment
#### End prepare bash / Linux environment
#### Set build environment
ARDUINO_ENV="1.8.5"
BUILD_ENV="1.0.6"
BOARD="rambo"
BOARD_PACKAGE_NAME="PrusaResearchRambo"
BOARD_VERSION="1.0.1"
BOARD="prusa_einsy_rambo"
BOARD_PACKAGE_NAME="PrusaResearch"
BOARD_VERSION="1.0.3"
#BOARD_URL="https://raw.githubusercontent.com/3d-gussner/Arduino_Boards/Prusa_Merge_v1.0.3/IDE_Board_Manager/package_prusa3d_index.json"
BOARD_URL="https://raw.githubusercontent.com/prusa3d/Arduino_Boards/master/IDE_Board_Manager/package_prusa3d_index.json"
BOARD_FILENAME="prusa3drambo"
BOARD_FILE_URL="https://raw.githubusercontent.com/prusa3d/Arduino_Boards/master/IDE_Board_Manager/prusa3drambo-1.0.1.tar.bz2"
PF_BUILD_FILE_URL="https://github.com/3d-gussner/PF-build-env/releases/download/$BUILD_ENV/PF-build-env-$BUILD_ENV.zip"
BOARD_FILENAME="prusa3dboards"
#BOARD_FILE_URL="https://raw.githubusercontent.com/3d-gussner/Arduino_Boards/Prusa_Merge_v1.0.3/IDE_Board_Manager/prusa3dboards-1.0.3.tar.bz2"
BOARD_FILE_URL="https://raw.githubusercontent.com/prusa3d/Arduino_Boards/master/IDE_Board_Manager/prusa3dboards-1.0.3.tar.bz2"
#PF_BUILD_FILE_URL="https://github.com/3d-gussner/PF-build-env-1/releases/download/$BUILD_ENV-WinLin/PF-build-env-WinLin-$BUILD_ENV.zip"
PF_BUILD_FILE_URL="https://github.com/prusa3d/PF-build-env/releases/download/$BUILD_ENV-WinLin/PF-build-env-WinLin-$BUILD_ENV.zip"
LIB="PrusaLibrary"
SCRIPT_PATH="$( cd "$(dirname "$0")" ; pwd -P )"
@ -233,6 +239,7 @@ echo "Ardunio IDE :" $ARDUINO_ENV
echo "Build env :" $BUILD_ENV
echo "Board :" $BOARD
echo "Package name:" $BOARD_PACKAGE_NAME
echo "Board v. :" $BOARD_VERSION
echo "Specific Lib:" $LIB
echo ""
@ -321,7 +328,7 @@ if [ ! -e ../PF-build-env-$BUILD_ENV/Preferences-$ARDUINO_ENV-$BOARD_VERSION-$TA
echo "update.check"
sed -i 's/update.check = true/update.check = false/g' ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/lib/preferences.txt
echo "board"
sed -i 's/board = uno/board = $BOARD/g' ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/lib/preferences.txt
sed -i "s/board = uno/board = $BOARD/g" ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/lib/preferences.txt
echo "editor.linenumbers"
sed -i 's/editor.linenumbers = false/editor.linenumbers = true/g' ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/lib/preferences.txt
echo "boardsmanager.additional.urls"
@ -364,7 +371,7 @@ if [[ ! -d "../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$P
fi
# Download and extract Prusa Firmware specific library files
if [ ! -f "PF-build-env-$BUILD_ENV.zip" ]; then
if [ ! -f "PF-build-env-WinLin-$BUILD_ENV.zip" ]; then
echo "$(tput setaf 6)Downloading Prusa Firmware build environment...$(tput setaf 2)"
sleep 2
wget $PF_BUILD_FILE_URL || exit 11
@ -373,7 +380,7 @@ fi
if [ ! -e "../PF-build-env-$BUILD_ENV/PF-build-env-$BUILD_ENV-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt" ]; then
echo "$(tput setaf 6)Unzipping Prusa Firmware build environment...$(tput setaf 2)"
sleep 2
unzip -o PF-build-env-$BUILD_ENV.zip -d ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor || exit 12
unzip -o PF-build-env-WinLin-$BUILD_ENV.zip -d ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor || exit 12
echo "# PF-build-env-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor-$BUILD_ENV" >> ../PF-build-env-$BUILD_ENV/PF-build-env-$BUILD_ENV-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt
echo "$(tput sgr0)"
fi

View File

@ -21,7 +21,7 @@
- For MK3 --> skip to step 3.
- If you have a different printer model, follow step [2.b](#2b) from Windows build
3. Run `sudo ./build.sh`
3. Run `./build.sh`
- Output hex file is at `"PrusaFirmware/lang/firmware.hex"` . In the same folder you can hex files for other languages as well.
4. Connect your printer and flash with PrusaSlicer ( Configuration --> Flash printer firmware ) or Slic3r PE.
@ -46,7 +46,7 @@ _Note: Multi language build is not supported._
* Open Arduino and navigate to File -> Preferences -> Settings
* To the text field `"Additional Boards Manager URLSs"` add `https://raw.githubusercontent.com/prusa3d/Arduino_Boards/master/IDE_Board_Manager/package_prusa3d_index.json`
* Open Board manager (`Tools->Board->Board manager`), and install `Prusa Research AVR MK3 RAMBo EINSy board`
* Open Board manager (`Tools->Board->Board manager`), and install `Prusa Research AVR Boards by Prusa Research`
**c.** Modify compiler flags in `platform.txt` file

View File

@ -1,5 +1,5 @@
#!/bin/bash
BUILD_ENV="1.0.6"
BUILD_ENV="1.0.6.1"
SCRIPT_PATH="$( cd "$(dirname "$0")" ; pwd -P )"
if [ ! -d "build-env" ]; then
@ -8,7 +8,8 @@ fi
cd build-env || exit 2
if [ ! -f "PF-build-env-Linux64-$BUILD_ENV.zip" ]; then
wget https://github.com/mkbel/PF-build-env/releases/download/$BUILD_ENV/PF-build-env-Linux64-$BUILD_ENV.zip || exit 3
#wget https://github.com/3d-gussner/PF-build-env-1/releases/download/$BUILD_ENV-Linux64/PF-build-env-Linux64-$BUILD_ENV.zip || exit 3
wget https://github.com/prusa3d/PF-build-env/releases/download/$BUILD_ENV-Linux64/PF-build-env-Linux64-$BUILD_ENV.zip || exit 3
fi
if [ ! -d "../../PF-build-env-$BUILD_ENV" ]; then

View File

@ -20,7 +20,7 @@
#MSG_CRASH_DET_STEALTH_FORCE_OFF c=20 r=4
"WARNING:\x0aCrash detection\x0adisabled in\x0aStealth mode"
"ATTENTION:\x0aDetection de crash\x0adesactivee en\x0amode feutre"
"ATTENTION:\x0aDetection de crash\x0adesactivee en\x0amode furtif"
#
">Cancel"
@ -550,7 +550,7 @@
#MSG_SILENT
"Silent"
"Feutre"
"Furtif"
#
"MMU needs user attention."