merge changes from upstream
This commit is contained in:
commit
7e3a1c7d45
11
.travis.yml
11
.travis.yml
|
|
@ -3,16 +3,17 @@ before_install:
|
||||||
- sudo apt-get install -y ninja-build
|
- sudo apt-get install -y ninja-build
|
||||||
script:
|
script:
|
||||||
- bash -x test.sh
|
- bash -x test.sh
|
||||||
- bash -x build.sh
|
- cp Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h Firmware/Configuration_prusa.h
|
||||||
|
- bash -x build.sh || { echo "1_75mm_MK3-EINSy10a-E3Dv6full variant failed" && false; }
|
||||||
- rm Firmware/Configuration_prusa.h
|
- rm Firmware/Configuration_prusa.h
|
||||||
- cp Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h Firmware/Configuration_prusa.h
|
- cp Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h Firmware/Configuration_prusa.h
|
||||||
- bash -x build.sh
|
- bash -x build.sh || { echo "1_75mm_MK25-RAMBo13a-E3Dv6full variant failed" && false; }
|
||||||
- rm Firmware/Configuration_prusa.h
|
- rm Firmware/Configuration_prusa.h
|
||||||
- cp Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h Firmware/Configuration_prusa.h
|
- cp Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h Firmware/Configuration_prusa.h
|
||||||
- bash -x build.sh
|
- bash -x build.sh || { echo "1_75mm_MK25-RAMBo10a-E3Dv6full variant failed" && false; }
|
||||||
- rm Firmware/Configuration_prusa.h
|
- rm Firmware/Configuration_prusa.h
|
||||||
- cp Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h Firmware/Configuration_prusa.h
|
- cp Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h Firmware/Configuration_prusa.h
|
||||||
- bash -x build.sh
|
- bash -x build.sh || { echo "1_75mm_MK2-RAMBo13a-E3Dv6full variant failed" && false; }
|
||||||
- rm Firmware/Configuration_prusa.h
|
- rm Firmware/Configuration_prusa.h
|
||||||
- cp Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h Firmware/Configuration_prusa.h
|
- cp Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h Firmware/Configuration_prusa.h
|
||||||
- bash -x build.sh
|
- bash -x build.sh || { echo "1_75mm_MK2-RAMBo10a-E3Dv6full variant failed" && false; }
|
||||||
|
|
@ -14,7 +14,9 @@ set(TEST_SOURCES
|
||||||
Tests/tests.cpp
|
Tests/tests.cpp
|
||||||
Tests/Example_test.cpp
|
Tests/Example_test.cpp
|
||||||
Tests/Timer_test.cpp
|
Tests/Timer_test.cpp
|
||||||
|
Tests/AutoDeplete_test.cpp
|
||||||
Firmware/Timer.cpp
|
Firmware/Timer.cpp
|
||||||
|
Firmware/AutoDeplete.cpp
|
||||||
)
|
)
|
||||||
add_executable(tests ${TEST_SOURCES})
|
add_executable(tests ${TEST_SOURCES})
|
||||||
target_include_directories(tests PRIVATE Tests)
|
target_include_directories(tests PRIVATE Tests)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
//! @file
|
||||||
|
//! @author: Marek Bel
|
||||||
|
//! @date Jan 3, 2019
|
||||||
|
|
||||||
|
#include "AutoDeplete.h"
|
||||||
|
#include "assert.h"
|
||||||
|
|
||||||
|
//! @brief bit field marking depleted filaments
|
||||||
|
//!
|
||||||
|
//! binary 1 marks filament as depleted
|
||||||
|
//! Zero initialized value means, that no filament is depleted.
|
||||||
|
static uint8_t depleted;
|
||||||
|
static const uint8_t filamentCount = 5;
|
||||||
|
|
||||||
|
//! @return binary 1 for all filaments
|
||||||
|
//! @par fCount number of filaments
|
||||||
|
static constexpr uint8_t allDepleted(uint8_t fCount)
|
||||||
|
{
|
||||||
|
return fCount == 1 ? 1 : ((1 << (fCount - 1)) | allDepleted(fCount - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Is filament available for printing?
|
||||||
|
//! @par filament Filament number to be checked
|
||||||
|
//! @retval true Filament is available for printing.
|
||||||
|
//! @retval false Filament is not available for printing.
|
||||||
|
static bool loaded(uint8_t filament)
|
||||||
|
{
|
||||||
|
if (depleted & (1 << filament)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Mark filament as not available for printing.
|
||||||
|
//! @par filament filament to be marked
|
||||||
|
void ad_markDepleted(uint8_t filament)
|
||||||
|
{
|
||||||
|
assert(filament < filamentCount);
|
||||||
|
if (filament < filamentCount)
|
||||||
|
{
|
||||||
|
depleted |= 1 << filament;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Mark filament as available for printing.
|
||||||
|
//! @par filament filament to be marked
|
||||||
|
void ad_markLoaded(uint8_t filament)
|
||||||
|
{
|
||||||
|
assert(filament < filamentCount);
|
||||||
|
if (filament < filamentCount)
|
||||||
|
{
|
||||||
|
depleted &= ~(1 << filament);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Get alternative filament, which is not depleted
|
||||||
|
//! @par filament filament
|
||||||
|
//! @return Filament, if it is depleted, returns next available,
|
||||||
|
//! if all filaments are depleted, returns filament function parameter.
|
||||||
|
uint8_t ad_getAlternative(uint8_t filament)
|
||||||
|
{
|
||||||
|
assert(filament < filamentCount);
|
||||||
|
for (uint8_t i = 0; i<filamentCount; ++i)
|
||||||
|
{
|
||||||
|
uint8_t nextFilament = (filament + i) % filamentCount;
|
||||||
|
if (loaded(nextFilament)) return nextFilament;
|
||||||
|
}
|
||||||
|
return filament;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Are all filaments depleted?
|
||||||
|
//! @retval true All filaments are depleted.
|
||||||
|
//! @retval false All filaments are not depleted.
|
||||||
|
bool ad_allDepleted()
|
||||||
|
{
|
||||||
|
if (allDepleted(filamentCount) == depleted)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
//! @file
|
||||||
|
//! @author: Marek Bel
|
||||||
|
//! @brief Filament auto deplete engine for multi-material prints with MMUv2 (Now marketed as SpoolJoin)
|
||||||
|
//!
|
||||||
|
//! Interface for marking MMUv2 filaments as depleted and getting alternative filament for printing.
|
||||||
|
|
||||||
|
#ifndef AUTODEPLETE_H
|
||||||
|
#define AUTODEPLETE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void ad_markDepleted(uint8_t filament);
|
||||||
|
void ad_markLoaded(uint8_t filament);
|
||||||
|
uint8_t ad_getAlternative(uint8_t filament);
|
||||||
|
bool ad_allDepleted();
|
||||||
|
|
||||||
|
#endif /* AUTODEPLETE_H */
|
||||||
|
|
@ -126,13 +126,11 @@
|
||||||
// Comment the following line to disable PID and enable bang-bang.
|
// Comment the following line to disable PID and enable bang-bang.
|
||||||
#define PIDTEMP
|
#define PIDTEMP
|
||||||
#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current
|
#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current
|
||||||
#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current
|
#define PID_MAX BANG_MAX // limits current to nozzle while PID is active; 255=full current
|
||||||
#ifdef PIDTEMP
|
#ifdef PIDTEMP
|
||||||
//#define PID_DEBUG // Sends debug data to the serial port.
|
//#define PID_DEBUG // Sends debug data to the serial port.
|
||||||
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
|
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
|
||||||
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
|
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
|
||||||
#define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature
|
|
||||||
// is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
|
|
||||||
#define PID_INTEGRAL_DRIVE_MAX PID_MAX //limit for the integral term
|
#define PID_INTEGRAL_DRIVE_MAX PID_MAX //limit for the integral term
|
||||||
#define K1 0.95 //smoothing factor within the PID
|
#define K1 0.95 //smoothing factor within the PID
|
||||||
#define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
|
#define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
#include "Dcodes.h"
|
#include "Dcodes.h"
|
||||||
|
#include "AutoDeplete.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef SWSPI
|
#ifdef SWSPI
|
||||||
|
|
@ -6947,6 +6948,10 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tmp_extruder = code_value();
|
tmp_extruder = code_value();
|
||||||
|
if (mmu_enabled && lcd_autoDepleteEnabled())
|
||||||
|
{
|
||||||
|
tmp_extruder = ad_getAlternative(tmp_extruder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
st_synchronize();
|
st_synchronize();
|
||||||
snmm_filaments_used |= (1 << tmp_extruder); //for stop print
|
snmm_filaments_used |= (1 << tmp_extruder); //for stop print
|
||||||
|
|
@ -7641,6 +7646,7 @@ void Stop()
|
||||||
disable_heater();
|
disable_heater();
|
||||||
if(Stopped == false) {
|
if(Stopped == false) {
|
||||||
Stopped = true;
|
Stopped = true;
|
||||||
|
lcd_print_stop();
|
||||||
Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart
|
Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart
|
||||||
SERIAL_ERROR_START;
|
SERIAL_ERROR_START;
|
||||||
SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED);
|
SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED);
|
||||||
|
|
|
||||||
182
Firmware/mmu.cpp
182
Firmware/mmu.cpp
|
|
@ -1,4 +1,4 @@
|
||||||
//mmu.cpp
|
//! @file
|
||||||
|
|
||||||
#include "mmu.h"
|
#include "mmu.h"
|
||||||
#include "planner.h"
|
#include "planner.h"
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include "printers.h"
|
#include "printers.h"
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include "io_atmega2560.h"
|
#include "io_atmega2560.h"
|
||||||
|
#include "AutoDeplete.h"
|
||||||
|
|
||||||
#ifdef TMC2130
|
#ifdef TMC2130
|
||||||
#include "tmc2130.h"
|
#include "tmc2130.h"
|
||||||
|
|
@ -245,7 +246,7 @@ void mmu_loop(void)
|
||||||
mmu_printf_P(PSTR("T%d\n"), filament);
|
mmu_printf_P(PSTR("T%d\n"), filament);
|
||||||
mmu_state = 3; // wait for response
|
mmu_state = 3; // wait for response
|
||||||
mmu_fil_loaded = true;
|
mmu_fil_loaded = true;
|
||||||
if(ir_sensor_detected) mmu_idl_sens = 1; //if idler sensor detected, use it for T-code
|
mmu_idl_sens = 1;
|
||||||
}
|
}
|
||||||
else if ((mmu_cmd >= MMU_CMD_L0) && (mmu_cmd <= MMU_CMD_L4))
|
else if ((mmu_cmd >= MMU_CMD_L0) && (mmu_cmd <= MMU_CMD_L4))
|
||||||
{
|
{
|
||||||
|
|
@ -263,7 +264,7 @@ void mmu_loop(void)
|
||||||
#endif //MMU_DEBUG
|
#endif //MMU_DEBUG
|
||||||
mmu_puts_P(PSTR("C0\n")); //send 'continue loading'
|
mmu_puts_P(PSTR("C0\n")); //send 'continue loading'
|
||||||
mmu_state = 3;
|
mmu_state = 3;
|
||||||
if(ir_sensor_detected) mmu_idl_sens = 1; //if idler sensor detected use it for C0 code
|
mmu_idl_sens = 1;
|
||||||
}
|
}
|
||||||
else if (mmu_cmd == MMU_CMD_U0)
|
else if (mmu_cmd == MMU_CMD_U0)
|
||||||
{
|
{
|
||||||
|
|
@ -326,8 +327,15 @@ void mmu_loop(void)
|
||||||
if (!mmu_finda && CHECK_FSENSOR && fsensor_enabled) {
|
if (!mmu_finda && CHECK_FSENSOR && fsensor_enabled) {
|
||||||
fsensor_stop_and_save_print();
|
fsensor_stop_and_save_print();
|
||||||
enquecommand_front_P(PSTR("FSENSOR_RECOVER")); //then recover
|
enquecommand_front_P(PSTR("FSENSOR_RECOVER")); //then recover
|
||||||
if (lcd_autoDepleteEnabled()) enquecommand_front_P(PSTR("M600 AUTO")); //save print and run M600 command
|
ad_markDepleted(mmu_extruder);
|
||||||
else enquecommand_front_P(PSTR("M600")); //save print and run M600 command
|
if (lcd_autoDepleteEnabled() && !ad_allDepleted())
|
||||||
|
{
|
||||||
|
enquecommand_front_P(PSTR("M600 AUTO")); //save print and run M600 command
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enquecommand_front_P(PSTR("M600")); //save print and run M600 command
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mmu_state = 1;
|
mmu_state = 1;
|
||||||
if (mmu_cmd == 0)
|
if (mmu_cmd == 0)
|
||||||
|
|
@ -339,19 +347,20 @@ void mmu_loop(void)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 3: //response to mmu commands
|
case 3: //response to mmu commands
|
||||||
if (mmu_idl_sens && ir_sensor_detected) {
|
if (mmu_idl_sens)
|
||||||
if (PIN_GET(IR_SENSOR_PIN) == 0 && mmu_loading_flag)
|
{
|
||||||
{
|
if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0 && mmu_loading_flag)
|
||||||
|
{
|
||||||
#ifdef MMU_DEBUG
|
#ifdef MMU_DEBUG
|
||||||
printf_P(PSTR("MMU <= 'A'\n"));
|
printf_P(PSTR("MMU <= 'A'\n"));
|
||||||
#endif //MMU_DEBUG
|
#endif //MMU_DEBUG
|
||||||
mmu_puts_P(PSTR("A\n")); //send 'abort' request
|
mmu_puts_P(PSTR("A\n")); //send 'abort' request
|
||||||
mmu_idl_sens = 0;
|
mmu_idl_sens = 0;
|
||||||
//printf_P(PSTR("MMU IDLER_SENSOR = 0 - ABORT\n"));
|
//printf_P(PSTR("MMU IDLER_SENSOR = 0 - ABORT\n"));
|
||||||
}
|
}
|
||||||
//else
|
//else
|
||||||
//printf_P(PSTR("MMU IDLER_SENSOR = 1 - WAIT\n"));
|
//printf_P(PSTR("MMU IDLER_SENSOR = 1 - WAIT\n"));
|
||||||
}
|
}
|
||||||
if (mmu_rx_ok() > 0)
|
if (mmu_rx_ok() > 0)
|
||||||
{
|
{
|
||||||
#ifdef MMU_DEBUG
|
#ifdef MMU_DEBUG
|
||||||
|
|
@ -420,69 +429,96 @@ int8_t mmu_set_filament_type(uint8_t extruder, uint8_t filament)
|
||||||
return timeout?1:0;
|
return timeout?1:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! @brief Enqueue MMUv2 command
|
||||||
|
//!
|
||||||
|
//! Call manage_response() after enqueuing to process command.
|
||||||
|
//! If T command is enqueued, it disables current for extruder motor if TMC2130 driver present.
|
||||||
|
//! If T or L command is enqueued, it marks filament loaded in AutoDeplete module.
|
||||||
void mmu_command(uint8_t cmd)
|
void mmu_command(uint8_t cmd)
|
||||||
{
|
{
|
||||||
#ifdef TMC2130
|
|
||||||
if ((cmd >= MMU_CMD_T0) && (cmd <= MMU_CMD_T4))
|
if ((cmd >= MMU_CMD_T0) && (cmd <= MMU_CMD_T4))
|
||||||
{
|
{
|
||||||
//disable extruder motor
|
//disable extruder motor
|
||||||
|
#ifdef TMC2130
|
||||||
tmc2130_set_pwr(E_AXIS, 0);
|
tmc2130_set_pwr(E_AXIS, 0);
|
||||||
//printf_P(PSTR("E-axis disabled\n"));
|
|
||||||
}
|
|
||||||
#endif //TMC2130
|
#endif //TMC2130
|
||||||
|
//printf_P(PSTR("E-axis disabled\n"));
|
||||||
|
ad_markLoaded(cmd - MMU_CMD_T0);
|
||||||
|
}
|
||||||
|
if ((cmd >= MMU_CMD_L0) && (cmd <= MMU_CMD_L4))
|
||||||
|
{
|
||||||
|
ad_markLoaded(cmd - MMU_CMD_L0);
|
||||||
|
}
|
||||||
|
|
||||||
mmu_cmd = cmd;
|
mmu_cmd = cmd;
|
||||||
mmu_ready = false;
|
mmu_ready = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mmu_load_step() {
|
//! @brief Rotate extruder idler to catch filament
|
||||||
|
//! @par synchronize
|
||||||
|
//! * true blocking call
|
||||||
|
//! * false non-blocking call
|
||||||
|
void mmu_load_step(bool synchronize)
|
||||||
|
{
|
||||||
current_position[E_AXIS] = current_position[E_AXIS] + MMU_LOAD_FEEDRATE * 0.1;
|
current_position[E_AXIS] = current_position[E_AXIS] + MMU_LOAD_FEEDRATE * 0.1;
|
||||||
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder);
|
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder);
|
||||||
st_synchronize();
|
if (synchronize) st_synchronize();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @brief Is nozzle hot enough to move extruder wheels and do we have idler sensor?
|
||||||
|
//!
|
||||||
|
//! Do load steps only if temperature is higher then min. temp for safe extrusion and
|
||||||
|
//! idler sensor present.
|
||||||
|
//! Otherwise "cold extrusion prevented" would be send to serial line periodically
|
||||||
|
//! and watchdog reset will be triggered by lack of keep_alive processing.
|
||||||
|
//!
|
||||||
|
//! @retval true temperature is high enough to move extruder
|
||||||
|
//! @retval false temperature is not high enough to move extruder, turned
|
||||||
|
//! off E-stepper to prevent over-heating and allow filament pull-out if necessary
|
||||||
|
bool can_extrude()
|
||||||
|
{
|
||||||
|
if ((degHotend(active_extruder) < EXTRUDE_MINTEMP) || !mmu_idler_sensor_detected)
|
||||||
|
{
|
||||||
|
disable_e0();
|
||||||
|
delay_keep_alive(100);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mmu_get_response(uint8_t move)
|
bool mmu_get_response(uint8_t move)
|
||||||
{
|
{
|
||||||
mmu_loading_flag = false;
|
mmu_loading_flag = false;
|
||||||
if (!ir_sensor_detected) move = MMU_NO_MOVE;
|
|
||||||
|
|
||||||
printf_P(PSTR("mmu_get_response - begin move:%d\n"), move);
|
printf_P(PSTR("mmu_get_response - begin move:%d\n"), move);
|
||||||
KEEPALIVE_STATE(IN_PROCESS);
|
KEEPALIVE_STATE(IN_PROCESS);
|
||||||
while (mmu_cmd != 0)
|
while (mmu_cmd != 0)
|
||||||
{
|
{
|
||||||
// mmu_loop();
|
|
||||||
delay_keep_alive(100);
|
delay_keep_alive(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!mmu_ready)
|
while (!mmu_ready)
|
||||||
{
|
{
|
||||||
// mmu_loop();
|
|
||||||
|
|
||||||
if ((mmu_state != 3) && (mmu_last_cmd == 0))
|
if ((mmu_state != 3) && (mmu_last_cmd == 0))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Do load steps only if temperature is higher then min. temp for safe extrusion.
|
|
||||||
//Otherwise "cold extrusion prevented" would be send to serial line periodically
|
|
||||||
if (degHotend(active_extruder) < EXTRUDE_MINTEMP) {
|
|
||||||
disable_e0(); //turn off E-stepper to prevent overheating and alow filament pull-out if necessary
|
|
||||||
delay_keep_alive(100);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (move) {
|
switch (move) {
|
||||||
case MMU_LOAD_MOVE:
|
case MMU_LOAD_MOVE:
|
||||||
mmu_loading_flag = true;
|
mmu_loading_flag = true;
|
||||||
mmu_load_step();
|
if (can_extrude()) mmu_load_step();
|
||||||
//don't rely on "ok" signal from mmu unit; if filament detected by idler sensor during loading stop loading movements to prevent infinite loading
|
//don't rely on "ok" signal from mmu unit; if filament detected by idler sensor during loading stop loading movements to prevent infinite loading
|
||||||
if (PIN_GET(IR_SENSOR_PIN) == 0) move = MMU_NO_MOVE;
|
if (PIN_GET(IR_SENSOR_PIN) == 0) move = MMU_NO_MOVE;
|
||||||
break;
|
break;
|
||||||
case MMU_UNLOAD_MOVE:
|
case MMU_UNLOAD_MOVE:
|
||||||
if (PIN_GET(IR_SENSOR_PIN) == 0) //filament is still detected by idler sensor, printer helps with unlading
|
if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) //filament is still detected by idler sensor, printer helps with unlading
|
||||||
{
|
{
|
||||||
printf_P(PSTR("Unload 1\n"));
|
if (can_extrude())
|
||||||
current_position[E_AXIS] = current_position[E_AXIS] - MMU_LOAD_FEEDRATE * MMU_LOAD_TIME_MS*0.001;
|
{
|
||||||
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder);
|
printf_P(PSTR("Unload 1\n"));
|
||||||
st_synchronize();
|
current_position[E_AXIS] = current_position[E_AXIS] - MMU_LOAD_FEEDRATE * MMU_LOAD_TIME_MS*0.001;
|
||||||
|
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder);
|
||||||
|
st_synchronize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else //filament was unloaded from idler, no additional movements needed
|
else //filament was unloaded from idler, no additional movements needed
|
||||||
{
|
{
|
||||||
|
|
@ -492,12 +528,15 @@ bool mmu_get_response(uint8_t move)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MMU_TCODE_MOVE: //first do unload and then continue with infinite loading movements
|
case MMU_TCODE_MOVE: //first do unload and then continue with infinite loading movements
|
||||||
if (PIN_GET(IR_SENSOR_PIN) == 0) //filament detected by idler sensor, we must unload first
|
if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) //filament detected by idler sensor, we must unload first
|
||||||
{
|
{
|
||||||
printf_P(PSTR("Unload 2\n"));
|
if (can_extrude())
|
||||||
current_position[E_AXIS] = current_position[E_AXIS] - MMU_LOAD_FEEDRATE * MMU_LOAD_TIME_MS*0.001;
|
{
|
||||||
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder);
|
printf_P(PSTR("Unload 2\n"));
|
||||||
st_synchronize();
|
current_position[E_AXIS] = current_position[E_AXIS] - MMU_LOAD_FEEDRATE * MMU_LOAD_TIME_MS*0.001;
|
||||||
|
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder);
|
||||||
|
st_synchronize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else //delay to allow mmu unit to pull out filament from bondtech gears and then start with infinite loading
|
else //delay to allow mmu unit to pull out filament from bondtech gears and then start with infinite loading
|
||||||
{
|
{
|
||||||
|
|
@ -505,6 +544,7 @@ bool mmu_get_response(uint8_t move)
|
||||||
disable_e0(); //turn off E-stepper to prevent overheating and alow filament pull-out if necessary
|
disable_e0(); //turn off E-stepper to prevent overheating and alow filament pull-out if necessary
|
||||||
delay_keep_alive(MMU_LOAD_TIME_MS);
|
delay_keep_alive(MMU_LOAD_TIME_MS);
|
||||||
move = MMU_LOAD_MOVE;
|
move = MMU_LOAD_MOVE;
|
||||||
|
printf_P(PSTR("mmu_get_response - begin move:%d\n"), move);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MMU_NO_MOVE:
|
case MMU_NO_MOVE:
|
||||||
|
|
@ -518,27 +558,20 @@ bool mmu_get_response(uint8_t move)
|
||||||
mmu_ready = false;
|
mmu_ready = false;
|
||||||
// printf_P(PSTR("mmu_get_response - end %d\n"), ret?1:0);
|
// printf_P(PSTR("mmu_get_response - end %d\n"), ret?1:0);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* //waits for "ok" from mmu
|
|
||||||
//function returns true if "ok" was received
|
|
||||||
//if timeout is set to true function return false if there is no "ok" received before timeout
|
|
||||||
bool response = true;
|
|
||||||
LongTimer mmu_get_reponse_timeout;
|
|
||||||
KEEPALIVE_STATE(IN_PROCESS);
|
|
||||||
mmu_get_reponse_timeout.start();
|
|
||||||
while (mmu_rx_ok() <= 0)
|
|
||||||
{
|
|
||||||
delay_keep_alive(100);
|
|
||||||
if (timeout && mmu_get_reponse_timeout.expired(5 * 60 * 1000ul))
|
|
||||||
{ //5 minutes timeout
|
|
||||||
response = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf_P(PSTR("mmu_get_response - end %d\n"), response?1:0);
|
|
||||||
return response;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! @brief Wait for active extruder to reach temperature set
|
||||||
|
//!
|
||||||
|
//! This function is blocking and showing lcd_wait_for_heater() screen
|
||||||
|
//! which is constantly updated with nozzle temperature.
|
||||||
|
void mmu_wait_for_heater_blocking()
|
||||||
|
{
|
||||||
|
while ((degTargetHotend(active_extruder) - degHotend(active_extruder)) > 5)
|
||||||
|
{
|
||||||
|
delay_keep_alive(1000);
|
||||||
|
lcd_wait_for_heater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move)
|
void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move)
|
||||||
{
|
{
|
||||||
|
|
@ -633,11 +666,7 @@ void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move)
|
||||||
lcd_display_message_fullscreen_P(_i("MMU OK. Resuming temperature..."));
|
lcd_display_message_fullscreen_P(_i("MMU OK. Resuming temperature..."));
|
||||||
delay_keep_alive(3000);
|
delay_keep_alive(3000);
|
||||||
}
|
}
|
||||||
while ((degTargetHotend(active_extruder) - degHotend(active_extruder)) > 5)
|
mmu_wait_for_heater_blocking();
|
||||||
{
|
|
||||||
delay_keep_alive(1000);
|
|
||||||
lcd_wait_for_heater();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (move_axes) {
|
if (move_axes) {
|
||||||
lcd_clear();
|
lcd_clear();
|
||||||
|
|
@ -751,7 +780,7 @@ void mmu_M600_load_filament(bool automatic)
|
||||||
#endif //MMU_M600_SWITCH_EXTRUDER
|
#endif //MMU_M600_SWITCH_EXTRUDER
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tmp_extruder = (tmp_extruder+1)%5;
|
tmp_extruder = ad_getAlternative(tmp_extruder);
|
||||||
}
|
}
|
||||||
lcd_update_enable(false);
|
lcd_update_enable(false);
|
||||||
lcd_clear();
|
lcd_clear();
|
||||||
|
|
@ -940,7 +969,7 @@ static const E_step ramming_sequence[] PROGMEM =
|
||||||
};
|
};
|
||||||
|
|
||||||
//! @brief Unload sequence to optimize shape of the tip of the unloaded filament
|
//! @brief Unload sequence to optimize shape of the tip of the unloaded filament
|
||||||
static void filament_ramming()
|
void mmu_filament_ramming()
|
||||||
{
|
{
|
||||||
for(uint8_t i = 0; i < (sizeof(ramming_sequence)/sizeof(E_step));++i)
|
for(uint8_t i = 0; i < (sizeof(ramming_sequence)/sizeof(E_step));++i)
|
||||||
{
|
{
|
||||||
|
|
@ -972,7 +1001,7 @@ void extr_unload()
|
||||||
if (mmu_extruder == MMU_FILAMENT_UNKNOWN) lcd_print(" ");
|
if (mmu_extruder == MMU_FILAMENT_UNKNOWN) lcd_print(" ");
|
||||||
else lcd_print(mmu_extruder + 1);
|
else lcd_print(mmu_extruder + 1);
|
||||||
|
|
||||||
filament_ramming();
|
mmu_filament_ramming();
|
||||||
|
|
||||||
mmu_command(MMU_CMD_U0);
|
mmu_command(MMU_CMD_U0);
|
||||||
// get response
|
// get response
|
||||||
|
|
@ -1366,6 +1395,7 @@ void mmu_continue_loading()
|
||||||
setAllTargetHotends(0);
|
setAllTargetHotends(0);
|
||||||
lcd_setstatuspgm(_i("MMU load failed "));////MSG_RECOVERING_PRINT c=20 r=1
|
lcd_setstatuspgm(_i("MMU load failed "));////MSG_RECOVERING_PRINT c=20 r=1
|
||||||
mmu_fil_loaded = false; //so we can retry same T-code again
|
mmu_fil_loaded = false; //so we can retry same T-code again
|
||||||
|
isPrintPaused = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { //mmu_ir_sensor_detected == false
|
else { //mmu_ir_sensor_detected == false
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
//mmu.h
|
//! @file
|
||||||
|
|
||||||
|
#ifndef MMU_H
|
||||||
|
#define MMU_H
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
|
@ -71,7 +74,7 @@ extern void mmu_command(uint8_t cmd);
|
||||||
|
|
||||||
extern bool mmu_get_response(uint8_t move = 0);
|
extern bool mmu_get_response(uint8_t move = 0);
|
||||||
|
|
||||||
extern void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move = 0);
|
extern void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move = MMU_NO_MOVE);
|
||||||
|
|
||||||
extern void mmu_load_to_nozzle();
|
extern void mmu_load_to_nozzle();
|
||||||
|
|
||||||
|
|
@ -119,3 +122,8 @@ extern void mmu_eject_fil_2();
|
||||||
extern void mmu_eject_fil_3();
|
extern void mmu_eject_fil_3();
|
||||||
extern void mmu_eject_fil_4();
|
extern void mmu_eject_fil_4();
|
||||||
extern void mmu_continue_loading();
|
extern void mmu_continue_loading();
|
||||||
|
extern void mmu_filament_ramming();
|
||||||
|
extern void mmu_wait_for_heater_blocking();
|
||||||
|
extern void mmu_load_step(bool synchronize = true);
|
||||||
|
|
||||||
|
#endif //MMU_H
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,15 @@
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
#include "ConfigurationStore.h"
|
#include "ConfigurationStore.h"
|
||||||
|
|
||||||
|
#include "Timer.h"
|
||||||
|
#include "Configuration_prusa.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
extern void timer02_init(void);
|
||||||
|
extern void timer02_set_pwm0(uint8_t pwm0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//=============================public variables============================
|
//=============================public variables============================
|
||||||
|
|
@ -103,15 +112,15 @@ static volatile bool temp_meas_ready = false;
|
||||||
|
|
||||||
#ifdef PIDTEMP
|
#ifdef PIDTEMP
|
||||||
//static cannot be external:
|
//static cannot be external:
|
||||||
static float temp_iState[EXTRUDERS] = { 0 };
|
static float iState_sum[EXTRUDERS] = { 0 };
|
||||||
static float temp_dState[EXTRUDERS] = { 0 };
|
static float dState_last[EXTRUDERS] = { 0 };
|
||||||
static float pTerm[EXTRUDERS];
|
static float pTerm[EXTRUDERS];
|
||||||
static float iTerm[EXTRUDERS];
|
static float iTerm[EXTRUDERS];
|
||||||
static float dTerm[EXTRUDERS];
|
static float dTerm[EXTRUDERS];
|
||||||
//int output;
|
//int output;
|
||||||
static float pid_error[EXTRUDERS];
|
static float pid_error[EXTRUDERS];
|
||||||
static float temp_iState_min[EXTRUDERS];
|
static float iState_sum_min[EXTRUDERS];
|
||||||
static float temp_iState_max[EXTRUDERS];
|
static float iState_sum_max[EXTRUDERS];
|
||||||
// static float pid_input[EXTRUDERS];
|
// static float pid_input[EXTRUDERS];
|
||||||
// static float pid_output[EXTRUDERS];
|
// static float pid_output[EXTRUDERS];
|
||||||
static bool pid_reset[EXTRUDERS];
|
static bool pid_reset[EXTRUDERS];
|
||||||
|
|
@ -152,6 +161,8 @@ static volatile bool temp_meas_ready = false;
|
||||||
# define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1 }
|
# define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1 }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static ShortTimer oTimer4minTempHeater,oTimer4minTempBed;
|
||||||
|
|
||||||
// Init min and max temp with extreme values to prevent false errors during startup
|
// Init min and max temp with extreme values to prevent false errors during startup
|
||||||
static int minttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP );
|
static int minttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP );
|
||||||
static int maxttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP );
|
static int maxttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP );
|
||||||
|
|
@ -252,6 +263,7 @@ static void temp_runaway_stop(bool isPreheat, bool isBed);
|
||||||
if (extruder<0)
|
if (extruder<0)
|
||||||
{
|
{
|
||||||
soft_pwm_bed = (MAX_BED_POWER)/2;
|
soft_pwm_bed = (MAX_BED_POWER)/2;
|
||||||
|
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||||
bias = d = (MAX_BED_POWER)/2;
|
bias = d = (MAX_BED_POWER)/2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -288,7 +300,10 @@ static void temp_runaway_stop(bool isPreheat, bool isBed);
|
||||||
if(millis() - t2 > 5000) {
|
if(millis() - t2 > 5000) {
|
||||||
heating=false;
|
heating=false;
|
||||||
if (extruder<0)
|
if (extruder<0)
|
||||||
|
{
|
||||||
soft_pwm_bed = (bias - d) >> 1;
|
soft_pwm_bed = (bias - d) >> 1;
|
||||||
|
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
soft_pwm[extruder] = (bias - d) >> 1;
|
soft_pwm[extruder] = (bias - d) >> 1;
|
||||||
t1=millis();
|
t1=millis();
|
||||||
|
|
@ -342,7 +357,10 @@ static void temp_runaway_stop(bool isPreheat, bool isBed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (extruder<0)
|
if (extruder<0)
|
||||||
|
{
|
||||||
soft_pwm_bed = (bias + d) >> 1;
|
soft_pwm_bed = (bias + d) >> 1;
|
||||||
|
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
soft_pwm[extruder] = (bias + d) >> 1;
|
soft_pwm[extruder] = (bias + d) >> 1;
|
||||||
pid_cycle++;
|
pid_cycle++;
|
||||||
|
|
@ -413,7 +431,7 @@ void updatePID()
|
||||||
{
|
{
|
||||||
#ifdef PIDTEMP
|
#ifdef PIDTEMP
|
||||||
for(int e = 0; e < EXTRUDERS; e++) {
|
for(int e = 0; e < EXTRUDERS; e++) {
|
||||||
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki;
|
iState_sum_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef PIDTEMPBED
|
#ifdef PIDTEMPBED
|
||||||
|
|
@ -582,6 +600,12 @@ void checkExtruderAutoFans()
|
||||||
|
|
||||||
#endif // any extruder auto fan pins set
|
#endif // any extruder auto fan pins set
|
||||||
|
|
||||||
|
// ready for eventually parameters adjusting
|
||||||
|
void resetPID(uint8_t) // only for compiler-warning elimination (if function do nothing)
|
||||||
|
//void resetPID(uint8_t extruder)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void manage_heater()
|
void manage_heater()
|
||||||
{
|
{
|
||||||
#ifdef WATCHDOG
|
#ifdef WATCHDOG
|
||||||
|
|
@ -593,9 +617,13 @@ void manage_heater()
|
||||||
|
|
||||||
if(temp_meas_ready != true) //better readability
|
if(temp_meas_ready != true) //better readability
|
||||||
return;
|
return;
|
||||||
|
// more precisely - this condition partially stabilizes time interval for regulation values evaluation (@ ~ 230ms)
|
||||||
|
|
||||||
updateTemperaturesFromRawValues();
|
updateTemperaturesFromRawValues();
|
||||||
|
|
||||||
|
check_max_temp();
|
||||||
|
check_min_temp();
|
||||||
|
|
||||||
#ifdef TEMP_RUNAWAY_BED_HYSTERESIS
|
#ifdef TEMP_RUNAWAY_BED_HYSTERESIS
|
||||||
temp_runaway_check(0, target_temperature_bed, current_temperature_bed, (int)soft_pwm_bed, true);
|
temp_runaway_check(0, target_temperature_bed, current_temperature_bed, (int)soft_pwm_bed, true);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -611,38 +639,42 @@ void manage_heater()
|
||||||
pid_input = current_temperature[e];
|
pid_input = current_temperature[e];
|
||||||
|
|
||||||
#ifndef PID_OPENLOOP
|
#ifndef PID_OPENLOOP
|
||||||
pid_error[e] = target_temperature[e] - pid_input;
|
if(target_temperature[e] == 0) {
|
||||||
if(pid_error[e] > PID_FUNCTIONAL_RANGE) {
|
|
||||||
pid_output = BANG_MAX;
|
|
||||||
pid_reset[e] = true;
|
|
||||||
}
|
|
||||||
else if(pid_error[e] < -PID_FUNCTIONAL_RANGE || target_temperature[e] == 0) {
|
|
||||||
pid_output = 0;
|
pid_output = 0;
|
||||||
pid_reset[e] = true;
|
pid_reset[e] = true;
|
||||||
}
|
} else {
|
||||||
else {
|
pid_error[e] = target_temperature[e] - pid_input;
|
||||||
if(pid_reset[e] == true) {
|
if(pid_reset[e]) {
|
||||||
temp_iState[e] = 0.0;
|
iState_sum[e] = 0.0;
|
||||||
|
dTerm[e] = 0.0; // 'dState_last[e]' initial setting is not necessary (see end of if-statement)
|
||||||
pid_reset[e] = false;
|
pid_reset[e] = false;
|
||||||
}
|
}
|
||||||
|
#ifndef PonM
|
||||||
pTerm[e] = cs.Kp * pid_error[e];
|
pTerm[e] = cs.Kp * pid_error[e];
|
||||||
temp_iState[e] += pid_error[e];
|
iState_sum[e] += pid_error[e];
|
||||||
temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
|
iState_sum[e] = constrain(iState_sum[e], iState_sum_min[e], iState_sum_max[e]);
|
||||||
iTerm[e] = cs.Ki * temp_iState[e];
|
iTerm[e] = cs.Ki * iState_sum[e];
|
||||||
|
// K1 defined in Configuration.h in the PID settings
|
||||||
//K1 defined in Configuration.h in the PID settings
|
|
||||||
#define K2 (1.0-K1)
|
#define K2 (1.0-K1)
|
||||||
dTerm[e] = (cs.Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
|
dTerm[e] = (cs.Kd * (pid_input - dState_last[e]))*K2 + (K1 * dTerm[e]); // e.g. digital filtration of derivative term changes
|
||||||
pid_output = pTerm[e] + iTerm[e] - dTerm[e];
|
pid_output = pTerm[e] + iTerm[e] - dTerm[e]; // subtraction due to "Derivative on Measurement" method (i.e. derivative of input instead derivative of error is used)
|
||||||
if (pid_output > PID_MAX) {
|
if (pid_output > PID_MAX) {
|
||||||
if (pid_error[e] > 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration
|
if (pid_error[e] > 0 ) iState_sum[e] -= pid_error[e]; // conditional un-integration
|
||||||
pid_output=PID_MAX;
|
pid_output=PID_MAX;
|
||||||
} else if (pid_output < 0){
|
} else if (pid_output < 0) {
|
||||||
if (pid_error[e] < 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration
|
if (pid_error[e] < 0 ) iState_sum[e] -= pid_error[e]; // conditional un-integration
|
||||||
pid_output=0;
|
pid_output=0;
|
||||||
}
|
}
|
||||||
|
#else // PonM ("Proportional on Measurement" method)
|
||||||
|
iState_sum[e] += cs.Ki * pid_error[e];
|
||||||
|
iState_sum[e] -= cs.Kp * (pid_input - dState_last[e]);
|
||||||
|
iState_sum[e] = constrain(iState_sum[e], 0, PID_INTEGRAL_DRIVE_MAX);
|
||||||
|
dTerm[e] = cs.Kd * (pid_input - dState_last[e]);
|
||||||
|
pid_output = iState_sum[e] - dTerm[e]; // subtraction due to "Derivative on Measurement" method (i.e. derivative of input instead derivative of error is used)
|
||||||
|
pid_output = constrain(pid_output, 0, PID_MAX);
|
||||||
|
#endif // PonM
|
||||||
}
|
}
|
||||||
temp_dState[e] = pid_input;
|
dState_last[e] = pid_input;
|
||||||
#else
|
#else
|
||||||
pid_output = constrain(target_temperature[e], 0, PID_MAX);
|
pid_output = constrain(target_temperature[e], 0, PID_MAX);
|
||||||
#endif //PID_OPENLOOP
|
#endif //PID_OPENLOOP
|
||||||
|
|
@ -659,7 +691,7 @@ void manage_heater()
|
||||||
SERIAL_ECHO(" iTerm ");
|
SERIAL_ECHO(" iTerm ");
|
||||||
SERIAL_ECHO(iTerm[e]);
|
SERIAL_ECHO(iTerm[e]);
|
||||||
SERIAL_ECHO(" dTerm ");
|
SERIAL_ECHO(" dTerm ");
|
||||||
SERIAL_ECHOLN(dTerm[e]);
|
SERIAL_ECHOLN(-dTerm[e]);
|
||||||
#endif //PID_DEBUG
|
#endif //PID_DEBUG
|
||||||
#else /* PID off */
|
#else /* PID off */
|
||||||
pid_output = 0;
|
pid_output = 0;
|
||||||
|
|
@ -669,16 +701,12 @@ void manage_heater()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check if temperature is within the correct range
|
// Check if temperature is within the correct range
|
||||||
#ifdef AMBIENT_THERMISTOR
|
if((current_temperature[e] < maxttemp[e]) && (target_temperature[e] != 0))
|
||||||
if(((current_temperature_ambient < MINTEMP_MINAMBIENT) || (current_temperature[e] > minttemp[e])) && (current_temperature[e] < maxttemp[e]))
|
|
||||||
#else //AMBIENT_THERMISTOR
|
|
||||||
if((current_temperature[e] > minttemp[e]) && (current_temperature[e] < maxttemp[e]))
|
|
||||||
#endif //AMBIENT_THERMISTOR
|
|
||||||
{
|
{
|
||||||
soft_pwm[e] = (int)pid_output >> 1;
|
soft_pwm[e] = (int)pid_output >> 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
soft_pwm[e] = 0;
|
soft_pwm[e] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -763,55 +791,61 @@ void manage_heater()
|
||||||
pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
|
pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
|
||||||
#endif //PID_OPENLOOP
|
#endif //PID_OPENLOOP
|
||||||
|
|
||||||
#ifdef AMBIENT_THERMISTOR
|
if(current_temperature_bed < BED_MAXTEMP)
|
||||||
if(((current_temperature_bed > BED_MINTEMP) || (current_temperature_ambient < MINTEMP_MINAMBIENT)) && (current_temperature_bed < BED_MAXTEMP))
|
|
||||||
#else //AMBIENT_THERMISTOR
|
|
||||||
if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
|
|
||||||
#endif //AMBIENT_THERMISTOR
|
|
||||||
{
|
{
|
||||||
soft_pwm_bed = (int)pid_output >> 1;
|
soft_pwm_bed = (int)pid_output >> 1;
|
||||||
|
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
soft_pwm_bed = 0;
|
soft_pwm_bed = 0;
|
||||||
|
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif !defined(BED_LIMIT_SWITCHING)
|
#elif !defined(BED_LIMIT_SWITCHING)
|
||||||
// Check if temperature is within the correct range
|
// Check if temperature is within the correct range
|
||||||
if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
|
if(current_temperature_bed < BED_MAXTEMP)
|
||||||
{
|
{
|
||||||
if(current_temperature_bed >= target_temperature_bed)
|
if(current_temperature_bed >= target_temperature_bed)
|
||||||
{
|
{
|
||||||
soft_pwm_bed = 0;
|
soft_pwm_bed = 0;
|
||||||
|
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
soft_pwm_bed = MAX_BED_POWER>>1;
|
soft_pwm_bed = MAX_BED_POWER>>1;
|
||||||
|
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
soft_pwm_bed = 0;
|
soft_pwm_bed = 0;
|
||||||
|
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||||
WRITE(HEATER_BED_PIN,LOW);
|
WRITE(HEATER_BED_PIN,LOW);
|
||||||
}
|
}
|
||||||
#else //#ifdef BED_LIMIT_SWITCHING
|
#else //#ifdef BED_LIMIT_SWITCHING
|
||||||
// Check if temperature is within the correct band
|
// Check if temperature is within the correct band
|
||||||
if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
|
if(current_temperature_bed < BED_MAXTEMP)
|
||||||
{
|
{
|
||||||
if(current_temperature_bed > target_temperature_bed + BED_HYSTERESIS)
|
if(current_temperature_bed > target_temperature_bed + BED_HYSTERESIS)
|
||||||
{
|
{
|
||||||
soft_pwm_bed = 0;
|
soft_pwm_bed = 0;
|
||||||
|
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||||
}
|
}
|
||||||
else if(current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS)
|
else if(current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS)
|
||||||
{
|
{
|
||||||
soft_pwm_bed = MAX_BED_POWER>>1;
|
soft_pwm_bed = MAX_BED_POWER>>1;
|
||||||
|
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
soft_pwm_bed = 0;
|
soft_pwm_bed = 0;
|
||||||
|
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||||
WRITE(HEATER_BED_PIN,LOW);
|
WRITE(HEATER_BED_PIN,LOW);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if(target_temperature_bed==0)
|
||||||
|
soft_pwm_bed = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HOST_KEEPALIVE_FEATURE
|
#ifdef HOST_KEEPALIVE_FEATURE
|
||||||
|
|
@ -983,7 +1017,6 @@ static void updateTemperaturesFromRawValues()
|
||||||
CRITICAL_SECTION_END;
|
CRITICAL_SECTION_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void tp_init()
|
void tp_init()
|
||||||
{
|
{
|
||||||
#if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))
|
#if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))
|
||||||
|
|
@ -997,8 +1030,8 @@ void tp_init()
|
||||||
// populate with the first value
|
// populate with the first value
|
||||||
maxttemp[e] = maxttemp[0];
|
maxttemp[e] = maxttemp[0];
|
||||||
#ifdef PIDTEMP
|
#ifdef PIDTEMP
|
||||||
temp_iState_min[e] = 0.0;
|
iState_sum_min[e] = 0.0;
|
||||||
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki;
|
iState_sum_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki;
|
||||||
#endif //PIDTEMP
|
#endif //PIDTEMP
|
||||||
#ifdef PIDTEMPBED
|
#ifdef PIDTEMPBED
|
||||||
temp_iState_min_bed = 0.0;
|
temp_iState_min_bed = 0.0;
|
||||||
|
|
@ -1050,10 +1083,12 @@ void tp_init()
|
||||||
|
|
||||||
adc_init();
|
adc_init();
|
||||||
|
|
||||||
|
timer02_init();
|
||||||
|
|
||||||
// Use timer0 for temperature measurement
|
// Use timer0 for temperature measurement
|
||||||
// Interleave temperature interrupt with millies interrupt
|
// Interleave temperature interrupt with millies interrupt
|
||||||
OCR0B = 128;
|
OCR2B = 128;
|
||||||
TIMSK0 |= (1<<OCIE0B);
|
TIMSK2 |= (1<<OCIE2B);
|
||||||
|
|
||||||
// Wait for temperature measurement to settle
|
// Wait for temperature measurement to settle
|
||||||
delay(250);
|
delay(250);
|
||||||
|
|
@ -1361,6 +1396,7 @@ void disable_heater()
|
||||||
#if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
|
#if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
|
||||||
target_temperature_bed=0;
|
target_temperature_bed=0;
|
||||||
soft_pwm_bed=0;
|
soft_pwm_bed=0;
|
||||||
|
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||||
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
|
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
|
||||||
WRITE(HEATER_BED_PIN,LOW);
|
WRITE(HEATER_BED_PIN,LOW);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1525,8 +1561,8 @@ void adc_ready(void) //callback from adc when sampling finished
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
||||||
|
|
||||||
// Timer 0 is shared with millies
|
// Timer2 (originaly timer0) is shared with millies
|
||||||
ISR(TIMER0_COMPB_vect)
|
ISR(TIMER2_COMPB_vect)
|
||||||
{
|
{
|
||||||
static bool _lock = false;
|
static bool _lock = false;
|
||||||
if (_lock) return;
|
if (_lock) return;
|
||||||
|
|
@ -1534,11 +1570,6 @@ ISR(TIMER0_COMPB_vect)
|
||||||
asm("sei");
|
asm("sei");
|
||||||
|
|
||||||
if (!temp_meas_ready) adc_cycle();
|
if (!temp_meas_ready) adc_cycle();
|
||||||
else
|
|
||||||
{
|
|
||||||
check_max_temp();
|
|
||||||
check_min_temp();
|
|
||||||
}
|
|
||||||
lcd_buttons_update();
|
lcd_buttons_update();
|
||||||
|
|
||||||
static unsigned char pwm_count = (1 << SOFT_PWM_SCALE);
|
static unsigned char pwm_count = (1 << SOFT_PWM_SCALE);
|
||||||
|
|
@ -1598,7 +1629,7 @@ ISR(TIMER0_COMPB_vect)
|
||||||
#endif
|
#endif
|
||||||
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
|
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
|
||||||
soft_pwm_b = soft_pwm_bed;
|
soft_pwm_b = soft_pwm_bed;
|
||||||
if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1); else WRITE(HEATER_BED_PIN,0);
|
//if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1); else WRITE(HEATER_BED_PIN,0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef FAN_SOFT_PWM
|
#ifdef FAN_SOFT_PWM
|
||||||
|
|
@ -1735,7 +1766,7 @@ ISR(TIMER0_COMPB_vect)
|
||||||
state_timer_heater_b = MIN_STATE_TIME;
|
state_timer_heater_b = MIN_STATE_TIME;
|
||||||
}
|
}
|
||||||
state_heater_b = 1;
|
state_heater_b = 1;
|
||||||
WRITE(HEATER_BED_PIN, 1);
|
//WRITE(HEATER_BED_PIN, 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// turn OFF heather only if the minimum time is up
|
// turn OFF heather only if the minimum time is up
|
||||||
|
|
@ -1934,26 +1965,49 @@ void check_min_temp_bed()
|
||||||
|
|
||||||
void check_min_temp()
|
void check_min_temp()
|
||||||
{
|
{
|
||||||
|
static bool bCheckingOnHeater=false; // state variable, which allows to short no-checking delay (is set, when temperature is (first time) over heaterMintemp)
|
||||||
|
static bool bCheckingOnBed=false; // state variable, which allows to short no-checking delay (is set, when temperature is (first time) over bedMintemp)
|
||||||
#ifdef AMBIENT_THERMISTOR
|
#ifdef AMBIENT_THERMISTOR
|
||||||
static uint8_t heat_cycles = 0;
|
if(current_temperature_raw_ambient>(OVERSAMPLENR*MINTEMP_MINAMBIENT_RAW)) // thermistor is NTC type, so operator is ">" ;-)
|
||||||
if (current_temperature_raw_ambient > OVERSAMPLENR*MINTEMP_MINAMBIENT_RAW)
|
{ // ambient temperature is low
|
||||||
{
|
#endif //AMBIENT_THERMISTOR
|
||||||
if (READ(HEATER_0_PIN) == HIGH)
|
// *** 'common' part of code for MK2.5 & MK3
|
||||||
{
|
// * nozzle checking
|
||||||
// if ((heat_cycles % 10) == 0)
|
if(target_temperature[active_extruder]>minttemp[active_extruder])
|
||||||
// printf_P(PSTR("X%d\n"), heat_cycles);
|
{ // ~ nozzle heating is on
|
||||||
if (heat_cycles > 50) //reaction time 5-10s
|
bCheckingOnHeater=bCheckingOnHeater||(current_temperature[active_extruder]>=minttemp[active_extruder]); // for eventually delay cutting
|
||||||
check_min_temp_heater0();
|
if(oTimer4minTempHeater.expired(HEATER_MINTEMP_DELAY)||(!oTimer4minTempHeater.running())||bCheckingOnHeater)
|
||||||
else
|
{
|
||||||
heat_cycles++;
|
bCheckingOnHeater=true; // not necessary
|
||||||
}
|
check_min_temp_heater0(); // delay is elapsed or temperature is/was over minTemp => periodical checking is active
|
||||||
else
|
}
|
||||||
heat_cycles = 0;
|
}
|
||||||
return;
|
else { // ~ nozzle heating is off
|
||||||
}
|
oTimer4minTempHeater.start();
|
||||||
|
bCheckingOnHeater=false;
|
||||||
|
}
|
||||||
|
// * bed checking
|
||||||
|
if(target_temperature_bed>BED_MINTEMP)
|
||||||
|
{ // ~ bed heating is on
|
||||||
|
bCheckingOnBed=bCheckingOnBed||(current_temperature_bed>=BED_MINTEMP); // for eventually delay cutting
|
||||||
|
if(oTimer4minTempBed.expired(BED_MINTEMP_DELAY)||(!oTimer4minTempBed.running())||bCheckingOnBed)
|
||||||
|
{
|
||||||
|
bCheckingOnBed=true; // not necessary
|
||||||
|
check_min_temp_bed(); // delay is elapsed or temperature is/was over minTemp => periodical checking is active
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // ~ bed heating is off
|
||||||
|
oTimer4minTempBed.start();
|
||||||
|
bCheckingOnBed=false;
|
||||||
|
}
|
||||||
|
// *** end of 'common' part
|
||||||
|
#ifdef AMBIENT_THERMISTOR
|
||||||
|
}
|
||||||
|
else { // ambient temperature is standard
|
||||||
|
check_min_temp_heater0();
|
||||||
|
check_min_temp_bed();
|
||||||
|
}
|
||||||
#endif //AMBIENT_THERMISTOR
|
#endif //AMBIENT_THERMISTOR
|
||||||
check_min_temp_heater0();
|
|
||||||
check_min_temp_bed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (defined(FANCHECK) && defined(TACH_0) && (TACH_0 > -1))
|
#if (defined(FANCHECK) && defined(TACH_0) && (TACH_0 > -1))
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,8 @@
|
||||||
#include "stepper.h"
|
#include "stepper.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ENABLE_TEMPERATURE_INTERRUPT() TIMSK0 |= (1<<OCIE0B)
|
#define ENABLE_TEMPERATURE_INTERRUPT() TIMSK2 |= (1<<OCIE2B)
|
||||||
#define DISABLE_TEMPERATURE_INTERRUPT() TIMSK0 &= ~(1<<OCIE0B)
|
#define DISABLE_TEMPERATURE_INTERRUPT() TIMSK2 &= ~(1<<OCIE2B)
|
||||||
|
|
||||||
// public functions
|
// public functions
|
||||||
void tp_init(); //initialize the heating
|
void tp_init(); //initialize the heating
|
||||||
|
|
@ -87,6 +87,8 @@ extern int current_voltage_raw_bed;
|
||||||
extern volatile int babystepsTodo[3];
|
extern volatile int babystepsTodo[3];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void resetPID(uint8_t extruder);
|
||||||
|
|
||||||
inline void babystepsTodoZadd(int n)
|
inline void babystepsTodoZadd(int n)
|
||||||
{
|
{
|
||||||
if (n != 0) {
|
if (n != 0) {
|
||||||
|
|
@ -137,11 +139,15 @@ FORCE_INLINE float degTargetBed() {
|
||||||
|
|
||||||
FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t extruder) {
|
FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t extruder) {
|
||||||
target_temperature[extruder] = celsius;
|
target_temperature[extruder] = celsius;
|
||||||
|
resetPID(extruder);
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void setTargetHotendSafe(const float &celsius, uint8_t extruder)
|
static inline void setTargetHotendSafe(const float &celsius, uint8_t extruder)
|
||||||
{
|
{
|
||||||
if (extruder<EXTRUDERS) target_temperature[extruder] = celsius;
|
if (extruder<EXTRUDERS) {
|
||||||
|
target_temperature[extruder] = celsius;
|
||||||
|
resetPID(extruder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void setAllTargetHotends(const float &celsius)
|
static inline void setAllTargetHotends(const float &celsius)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
//timer02.c
|
||||||
|
// use atmega timer2 as main system timer instead of timer0
|
||||||
|
// timer0 is used for fast pwm (OC0B output)
|
||||||
|
// original OVF handler is disabled
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t timer02_pwm0 = 0;
|
||||||
|
|
||||||
|
void timer02_set_pwm0(uint8_t pwm0)
|
||||||
|
{
|
||||||
|
if (timer02_pwm0 == pwm0) return;
|
||||||
|
if (pwm0)
|
||||||
|
{
|
||||||
|
TCCR0A |= (2 << COM0B0);
|
||||||
|
OCR0B = pwm0 - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TCCR0A &= ~(2 << COM0B0);
|
||||||
|
OCR0B = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer02_init(void)
|
||||||
|
{
|
||||||
|
//save sreg
|
||||||
|
uint8_t _sreg = SREG;
|
||||||
|
//disable interrupts for sure
|
||||||
|
cli();
|
||||||
|
//mask timer0 interrupts - disable all
|
||||||
|
TIMSK0 &= ~(1<<TOIE0);
|
||||||
|
TIMSK0 &= ~(1<<OCIE0A);
|
||||||
|
TIMSK0 &= ~(1<<OCIE0B);
|
||||||
|
//setup timer0
|
||||||
|
TCCR0A = 0x00; //COM_A-B=00, WGM_0-1=00
|
||||||
|
TCCR0B = (1 << CS00); //WGM_2=0, CS_0-2=011
|
||||||
|
//switch timer0 to fast pwm mode
|
||||||
|
TCCR0A |= (3 << WGM00); //WGM_0-1=11
|
||||||
|
//set OCR0B register to zero
|
||||||
|
OCR0B = 0;
|
||||||
|
//disable OCR0B output (will be enabled in timer02_set_pwm0)
|
||||||
|
TCCR0A &= ~(2 << COM0B0);
|
||||||
|
//setup timer2
|
||||||
|
TCCR2A = 0x00; //COM_A-B=00, WGM_0-1=00
|
||||||
|
TCCR2B = (3 << CS20); //WGM_2=0, CS_0-2=011
|
||||||
|
//mask timer2 interrupts - enable OVF, disable others
|
||||||
|
TIMSK2 |= (1<<TOIE2);
|
||||||
|
TIMSK2 &= ~(1<<OCIE2A);
|
||||||
|
TIMSK2 &= ~(1<<OCIE2B);
|
||||||
|
//set timer2 OCR registers (OCRB interrupt generated 0.5ms after OVF interrupt)
|
||||||
|
OCR2A = 0;
|
||||||
|
OCR2B = 128;
|
||||||
|
//restore sreg (enable interrupts)
|
||||||
|
SREG = _sreg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//following code is OVF handler for timer 2
|
||||||
|
//it is copy-paste from wiring.c and modified for timer2
|
||||||
|
//variables timer0_overflow_count and timer0_millis are declared in wiring.c
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// the prescaler is set so that timer0 ticks every 64 clock cycles, and the
|
||||||
|
// the overflow handler is called every 256 ticks.
|
||||||
|
#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
|
||||||
|
|
||||||
|
// the whole number of milliseconds per timer0 overflow
|
||||||
|
#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
|
||||||
|
|
||||||
|
// the fractional number of milliseconds per timer0 overflow. we shift right
|
||||||
|
// by three to fit these numbers into a byte. (for the clock speeds we care
|
||||||
|
// about - 8 and 16 MHz - this doesn't lose precision.)
|
||||||
|
#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
|
||||||
|
#define FRACT_MAX (1000 >> 3)
|
||||||
|
|
||||||
|
extern volatile unsigned long timer0_overflow_count;
|
||||||
|
extern volatile unsigned long timer0_millis;
|
||||||
|
unsigned char timer0_fract = 0;
|
||||||
|
|
||||||
|
ISR(TIMER2_OVF_vect)
|
||||||
|
{
|
||||||
|
// copy these to local variables so they can be stored in registers
|
||||||
|
// (volatile variables must be read from memory on every access)
|
||||||
|
unsigned long m = timer0_millis;
|
||||||
|
unsigned char f = timer0_fract;
|
||||||
|
|
||||||
|
m += MILLIS_INC;
|
||||||
|
f += FRACT_INC;
|
||||||
|
if (f >= FRACT_MAX)
|
||||||
|
{
|
||||||
|
f -= FRACT_MAX;
|
||||||
|
m += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer0_fract = f;
|
||||||
|
timer0_millis = m;
|
||||||
|
timer0_overflow_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -163,6 +163,7 @@ static void lcd_selftest_screen_step(int _row, int _col, int _state, const char
|
||||||
static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite);
|
static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite);
|
||||||
static bool lcd_selftest_fan_dialog(int _fan);
|
static bool lcd_selftest_fan_dialog(int _fan);
|
||||||
static bool lcd_selftest_fsensor();
|
static bool lcd_selftest_fsensor();
|
||||||
|
static bool selftest_irsensor();
|
||||||
static void lcd_selftest_error(int _error_no, const char *_error_1, const char *_error_2);
|
static void lcd_selftest_error(int _error_no, const char *_error_1, const char *_error_2);
|
||||||
static void lcd_colorprint_change();
|
static void lcd_colorprint_change();
|
||||||
#ifdef SNMM
|
#ifdef SNMM
|
||||||
|
|
@ -237,6 +238,8 @@ bool wait_for_unclick;
|
||||||
// float raw_Ki, raw_Kd;
|
// float raw_Ki, raw_Kd;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool bMain; // flag (i.e. 'fake parameter') for 'lcd_sdcard_menu()' function
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char STR_SEPARATOR[] PROGMEM = "------------";
|
const char STR_SEPARATOR[] PROGMEM = "------------";
|
||||||
|
|
@ -5886,7 +5889,10 @@ static void lcd_main_menu()
|
||||||
if (!is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL))
|
if (!is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL))
|
||||||
{
|
{
|
||||||
//if (farm_mode) MENU_ITEM_SUBMENU_P(MSG_FARM_CARD_MENU, lcd_farm_sdcard_menu);
|
//if (farm_mode) MENU_ITEM_SUBMENU_P(MSG_FARM_CARD_MENU, lcd_farm_sdcard_menu);
|
||||||
/*else*/ MENU_ITEM_SUBMENU_P(_T(MSG_CARD_MENU), lcd_sdcard_menu);
|
/*else*/ {
|
||||||
|
bMain=true; // flag ('fake parameter') for 'lcd_sdcard_menu()' function
|
||||||
|
MENU_ITEM_SUBMENU_P(_T(MSG_CARD_MENU), lcd_sdcard_menu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#if SDCARDDETECT < 1
|
#if SDCARDDETECT < 1
|
||||||
MENU_ITEM_GCODE_P(_i("Change SD card"), PSTR("M21")); // SD-card changed by user////MSG_CNG_SDCARD c=0 r=0
|
MENU_ITEM_GCODE_P(_i("Change SD card"), PSTR("M21")); // SD-card changed by user////MSG_CNG_SDCARD c=0 r=0
|
||||||
|
|
@ -5895,6 +5901,7 @@ static void lcd_main_menu()
|
||||||
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
|
bMain=true; // flag (i.e. 'fake parameter') for 'lcd_sdcard_menu()' function
|
||||||
MENU_ITEM_SUBMENU_P(_i("No SD card"), lcd_sdcard_menu);////MSG_NO_CARD c=0 r=0
|
MENU_ITEM_SUBMENU_P(_i("No SD card"), lcd_sdcard_menu);////MSG_NO_CARD c=0 r=0
|
||||||
#if SDCARDDETECT < 1
|
#if SDCARDDETECT < 1
|
||||||
MENU_ITEM_GCODE_P(_i("Init. SD card"), PSTR("M21")); // Manually initialize the SD-card via user interface////MSG_INIT_SDCARD c=0 r=0
|
MENU_ITEM_GCODE_P(_i("Init. SD card"), PSTR("M21")); // Manually initialize the SD-card via user interface////MSG_INIT_SDCARD c=0 r=0
|
||||||
|
|
@ -6227,7 +6234,10 @@ void lcd_sdcard_menu()
|
||||||
|
|
||||||
|
|
||||||
MENU_BEGIN();
|
MENU_BEGIN();
|
||||||
MENU_ITEM_BACK_P(_T(MSG_MAIN));
|
if(bMain) // i.e. default menu-item
|
||||||
|
MENU_ITEM_BACK_P(_T(MSG_MAIN));
|
||||||
|
else // i.e. menu-item after card insertion
|
||||||
|
MENU_ITEM_FUNCTION_P(_T(MSG_WATCH),lcd_return_to_status);
|
||||||
card.getWorkDirName();
|
card.getWorkDirName();
|
||||||
if (card.filename[0] == '/')
|
if (card.filename[0] == '/')
|
||||||
{
|
{
|
||||||
|
|
@ -6323,28 +6333,24 @@ bool lcd_selftest()
|
||||||
_result = true;
|
_result = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_result)
|
|
||||||
{
|
|
||||||
_progress = lcd_selftest_screen(3, _progress, 3, true, 1000);
|
|
||||||
_result = lcd_selfcheck_check_heater(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (_result)
|
if (_result)
|
||||||
{
|
{
|
||||||
//current_position[Z_AXIS] += 15; //move Z axis higher to avoid false triggering of Z end stop in case that we are very low - just above heatbed
|
//current_position[Z_AXIS] += 15; //move Z axis higher to avoid false triggering of Z end stop in case that we are very low - just above heatbed
|
||||||
_progress = lcd_selftest_screen(4, _progress, 3, true, 2000);
|
_progress = lcd_selftest_screen(3, _progress, 3, true, 2000);
|
||||||
#ifdef TMC2130
|
#ifdef TMC2130
|
||||||
_result = lcd_selfcheck_axis_sg(X_AXIS);
|
_result = lcd_selfcheck_axis_sg(X_AXIS);
|
||||||
#else
|
#else
|
||||||
_result = lcd_selfcheck_axis(X_AXIS, X_MAX_POS);
|
_result = lcd_selfcheck_axis(X_AXIS, X_MAX_POS);
|
||||||
#endif //TMC2130
|
#endif //TMC2130
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (_result)
|
if (_result)
|
||||||
{
|
{
|
||||||
_progress = lcd_selftest_screen(4, _progress, 3, true, 0);
|
_progress = lcd_selftest_screen(3, _progress, 3, true, 0);
|
||||||
|
|
||||||
#ifndef TMC2130
|
#ifndef TMC2130
|
||||||
_result = lcd_selfcheck_pulleys(X_AXIS);
|
_result = lcd_selfcheck_pulleys(X_AXIS);
|
||||||
|
|
@ -6354,7 +6360,7 @@ bool lcd_selftest()
|
||||||
|
|
||||||
if (_result)
|
if (_result)
|
||||||
{
|
{
|
||||||
_progress = lcd_selftest_screen(5, _progress, 3, true, 1500);
|
_progress = lcd_selftest_screen(4, _progress, 3, true, 1500);
|
||||||
#ifdef TMC2130
|
#ifdef TMC2130
|
||||||
_result = lcd_selfcheck_axis_sg(Y_AXIS);
|
_result = lcd_selfcheck_axis_sg(Y_AXIS);
|
||||||
#else
|
#else
|
||||||
|
|
@ -6364,7 +6370,7 @@ bool lcd_selftest()
|
||||||
|
|
||||||
if (_result)
|
if (_result)
|
||||||
{
|
{
|
||||||
_progress = lcd_selftest_screen(5, _progress, 3, true, 0);
|
_progress = lcd_selftest_screen(4, _progress, 3, true, 0);
|
||||||
#ifndef TMC2130
|
#ifndef TMC2130
|
||||||
_result = lcd_selfcheck_pulleys(Y_AXIS);
|
_result = lcd_selfcheck_pulleys(Y_AXIS);
|
||||||
#endif // TMC2130
|
#endif // TMC2130
|
||||||
|
|
@ -6385,7 +6391,7 @@ bool lcd_selftest()
|
||||||
current_position[Z_AXIS] = current_position[Z_AXIS] + 10;
|
current_position[Z_AXIS] = current_position[Z_AXIS] + 10;
|
||||||
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[3], manual_feedrate[0] / 60, active_extruder);
|
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[3], manual_feedrate[0] / 60, active_extruder);
|
||||||
st_synchronize();
|
st_synchronize();
|
||||||
_progress = lcd_selftest_screen(6, _progress, 3, true, 1500);
|
_progress = lcd_selftest_screen(5, _progress, 3, true, 1500);
|
||||||
_result = lcd_selfcheck_axis(2, Z_MAX_POS);
|
_result = lcd_selfcheck_axis(2, Z_MAX_POS);
|
||||||
if (eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE) != 1) {
|
if (eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE) != 1) {
|
||||||
enquecommand_P(PSTR("G28 W"));
|
enquecommand_P(PSTR("G28 W"));
|
||||||
|
|
@ -6412,25 +6418,46 @@ bool lcd_selftest()
|
||||||
|
|
||||||
if (_result)
|
if (_result)
|
||||||
{
|
{
|
||||||
_progress = lcd_selftest_screen(7, _progress, 3, true, 2000); //check bed
|
_progress = lcd_selftest_screen(6, _progress, 3, true, 2000); //check bed
|
||||||
_result = lcd_selfcheck_check_heater(true);
|
_result = lcd_selfcheck_check_heater(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_result)
|
||||||
|
{
|
||||||
|
_progress = lcd_selftest_screen(7, _progress, 3, true, 1000); //check nozzle
|
||||||
|
_result = lcd_selfcheck_check_heater(false);
|
||||||
|
}
|
||||||
if (_result)
|
if (_result)
|
||||||
{
|
{
|
||||||
_progress = lcd_selftest_screen(8, _progress, 3, true, 2000); //bed ok
|
_progress = lcd_selftest_screen(8, _progress, 3, true, 2000); //nozzle ok
|
||||||
#ifdef PAT9125
|
|
||||||
if (mmu_enabled == false) {
|
|
||||||
_progress = lcd_selftest_screen(9, _progress, 3, true, 2000); //check filaments sensor
|
|
||||||
_result = lcd_selftest_fsensor();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#ifdef FILAMENT_SENSOR
|
||||||
|
if (_result)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (mmu_enabled)
|
||||||
|
{
|
||||||
|
_progress = lcd_selftest_screen(9, _progress, 3, true, 2000); //check filaments sensor
|
||||||
|
_result = selftest_irsensor();
|
||||||
|
if (_result)
|
||||||
|
{
|
||||||
|
_progress = lcd_selftest_screen(10, _progress, 3, true, 2000); //fil sensor OK
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
#ifdef PAT9125
|
||||||
|
_progress = lcd_selftest_screen(9, _progress, 3, true, 2000); //check filaments sensor
|
||||||
|
_result = lcd_selftest_fsensor();
|
||||||
|
if (_result)
|
||||||
|
{
|
||||||
|
_progress = lcd_selftest_screen(10, _progress, 3, true, 2000); //fil sensor OK
|
||||||
|
}
|
||||||
|
#endif //PAT9125
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif //FILAMENT_SENSOR
|
||||||
if (_result)
|
if (_result)
|
||||||
{
|
{
|
||||||
if (mmu_enabled == false)
|
|
||||||
{
|
|
||||||
_progress = lcd_selftest_screen(10, _progress, 3, true, 2000); //fil sensor OK
|
|
||||||
}
|
|
||||||
#endif // PAT9125
|
|
||||||
_progress = lcd_selftest_screen(11, _progress, 3, true, 5000); //all correct
|
_progress = lcd_selftest_screen(11, _progress, 3, true, 5000); //all correct
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -6642,7 +6669,7 @@ static bool lcd_selfcheck_axis(int _axis, int _travel)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_progress = lcd_selftest_screen(4 + _axis, _progress, 3, false, 0);
|
_progress = lcd_selftest_screen(3 + _axis, _progress, 3, false, 0);
|
||||||
_lcd_refresh = 0;
|
_lcd_refresh = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6809,7 +6836,7 @@ static bool lcd_selfcheck_check_heater(bool _isbed)
|
||||||
|
|
||||||
manage_heater();
|
manage_heater();
|
||||||
manage_inactivity(true);
|
manage_inactivity(true);
|
||||||
_progress = (_isbed) ? lcd_selftest_screen(7, _progress, 2, false, 400) : lcd_selftest_screen(3, _progress, 2, false, 400);
|
_progress = (_isbed) ? lcd_selftest_screen(6, _progress, 2, false, 400) : lcd_selftest_screen(7, _progress, 2, false, 400);
|
||||||
/*if (_isbed) {
|
/*if (_isbed) {
|
||||||
MYSERIAL.print("Bed temp:");
|
MYSERIAL.print("Bed temp:");
|
||||||
MYSERIAL.println(degBed());
|
MYSERIAL.println(degBed());
|
||||||
|
|
@ -6835,9 +6862,10 @@ static bool lcd_selfcheck_check_heater(bool _isbed)
|
||||||
MYSERIAL.print("Opposite result:");
|
MYSERIAL.print("Opposite result:");
|
||||||
MYSERIAL.println(_opposite_result);
|
MYSERIAL.println(_opposite_result);
|
||||||
*/
|
*/
|
||||||
if (_opposite_result < ((_isbed) ? 10 : 3))
|
|
||||||
|
if (_opposite_result < ((_isbed) ? 30 : 9))
|
||||||
{
|
{
|
||||||
if (_checked_result >= ((_isbed) ? 3 : 10))
|
if (_checked_result >= ((_isbed) ? 9 : 30))
|
||||||
{
|
{
|
||||||
_stepresult = true;
|
_stepresult = true;
|
||||||
}
|
}
|
||||||
|
|
@ -6985,6 +7013,70 @@ static bool lcd_selftest_fsensor(void)
|
||||||
}
|
}
|
||||||
return (!fsensor_not_responding);
|
return (!fsensor_not_responding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! @brief Self-test of infrared barrier filament sensor mounted on MK3S with MMUv2 printer
|
||||||
|
//!
|
||||||
|
//! Test whether sensor is not triggering filament presence when extruder idler is moving without filament.
|
||||||
|
//!
|
||||||
|
//! Steps:
|
||||||
|
//! * Backup current active extruder temperature
|
||||||
|
//! * Pre-heat to PLA extrude temperature.
|
||||||
|
//! * Unload filament possibly present.
|
||||||
|
//! * Move extruder idler same way as during filament load
|
||||||
|
//! and sample MMU_IDLER_SENSOR_PIN.
|
||||||
|
//! * Check that pin doesn't go low.
|
||||||
|
//!
|
||||||
|
//! @retval true passed
|
||||||
|
//! @retval false failed
|
||||||
|
static bool selftest_irsensor()
|
||||||
|
{
|
||||||
|
class TempBackup
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TempBackup():
|
||||||
|
m_temp(degTargetHotend(active_extruder)),
|
||||||
|
m_extruder(active_extruder){}
|
||||||
|
~TempBackup(){setTargetHotend(m_temp,m_extruder);}
|
||||||
|
private:
|
||||||
|
float m_temp;
|
||||||
|
uint8_t m_extruder;
|
||||||
|
};
|
||||||
|
uint8_t progress;
|
||||||
|
{
|
||||||
|
TempBackup tempBackup;
|
||||||
|
setTargetHotend(ABS_PREHEAT_HOTEND_TEMP,active_extruder);
|
||||||
|
mmu_wait_for_heater_blocking();
|
||||||
|
progress = lcd_selftest_screen(9, 0, 1, true, 0);
|
||||||
|
mmu_filament_ramming();
|
||||||
|
}
|
||||||
|
progress = lcd_selftest_screen(9, progress, 1, true, 0);
|
||||||
|
mmu_command(MMU_CMD_U0);
|
||||||
|
manage_response(false, false);
|
||||||
|
|
||||||
|
for(uint_least8_t i = 0; i < 200; ++i)
|
||||||
|
{
|
||||||
|
if (0 == (i % 32)) progress = lcd_selftest_screen(9, progress, 1, true, 0);
|
||||||
|
|
||||||
|
mmu_load_step(false);
|
||||||
|
while (blocks_queued())
|
||||||
|
{
|
||||||
|
if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) return false;
|
||||||
|
#ifdef TMC2130
|
||||||
|
manage_heater();
|
||||||
|
// Vojtech: Don't disable motors inside the planner!
|
||||||
|
if (!tmc2130_update_sg())
|
||||||
|
{
|
||||||
|
manage_inactivity(true);
|
||||||
|
}
|
||||||
|
#else //TMC2130
|
||||||
|
manage_heater();
|
||||||
|
// Vojtech: Don't disable motors inside the planner!
|
||||||
|
manage_inactivity(true);
|
||||||
|
#endif //TMC2130
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#endif //FILAMENT_SENSOR
|
#endif //FILAMENT_SENSOR
|
||||||
|
|
||||||
static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite)
|
static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite)
|
||||||
|
|
@ -7147,7 +7239,7 @@ static int lcd_selftest_screen(int _step, int _progress, int _progress_scale, bo
|
||||||
lcd_update_enable(false);
|
lcd_update_enable(false);
|
||||||
|
|
||||||
int _step_block = 0;
|
int _step_block = 0;
|
||||||
const char *_indicator = (_progress > _progress_scale) ? "-" : "|";
|
const char *_indicator = (_progress >= _progress_scale) ? "-" : "|";
|
||||||
|
|
||||||
if (_clear) lcd_clear();
|
if (_clear) lcd_clear();
|
||||||
|
|
||||||
|
|
@ -7158,12 +7250,12 @@ static int lcd_selftest_screen(int _step, int _progress, int _progress_scale, bo
|
||||||
if (_step == 0) lcd_puts_P(_T(MSG_SELFTEST_FAN));
|
if (_step == 0) lcd_puts_P(_T(MSG_SELFTEST_FAN));
|
||||||
if (_step == 1) lcd_puts_P(_T(MSG_SELFTEST_FAN));
|
if (_step == 1) lcd_puts_P(_T(MSG_SELFTEST_FAN));
|
||||||
if (_step == 2) lcd_puts_P(_i("Checking endstops"));////MSG_SELFTEST_CHECK_ENDSTOPS c=20 r=0
|
if (_step == 2) lcd_puts_P(_i("Checking endstops"));////MSG_SELFTEST_CHECK_ENDSTOPS c=20 r=0
|
||||||
if (_step == 3) lcd_puts_P(_i("Checking hotend "));////MSG_SELFTEST_CHECK_HOTEND c=20 r=0
|
if (_step == 3) lcd_puts_P(_i("Checking X axis "));////MSG_SELFTEST_CHECK_X c=20 r=0
|
||||||
if (_step == 4) lcd_puts_P(_i("Checking X axis "));////MSG_SELFTEST_CHECK_X c=20 r=0
|
if (_step == 4) lcd_puts_P(_i("Checking Y axis "));////MSG_SELFTEST_CHECK_Y c=20 r=0
|
||||||
if (_step == 5) lcd_puts_P(_i("Checking Y axis "));////MSG_SELFTEST_CHECK_Y c=20 r=0
|
if (_step == 5) lcd_puts_P(_i("Checking Z axis "));////MSG_SELFTEST_CHECK_Z c=20 r=0
|
||||||
if (_step == 6) lcd_puts_P(_i("Checking Z axis "));////MSG_SELFTEST_CHECK_Z c=20 r=0
|
if (_step == 6) lcd_puts_P(_T(MSG_SELFTEST_CHECK_BED));
|
||||||
if (_step == 7) lcd_puts_P(_T(MSG_SELFTEST_CHECK_BED));
|
if (_step == 7
|
||||||
if (_step == 8) lcd_puts_P(_T(MSG_SELFTEST_CHECK_BED));
|
|| _step == 8) lcd_puts_P(_i("Checking hotend "));////MSG_SELFTEST_CHECK_HOTEND c=20 r=0
|
||||||
if (_step == 9) lcd_puts_P(_T(MSG_SELFTEST_CHECK_FSENSOR));
|
if (_step == 9) lcd_puts_P(_T(MSG_SELFTEST_CHECK_FSENSOR));
|
||||||
if (_step == 10) lcd_puts_P(_T(MSG_SELFTEST_CHECK_FSENSOR));
|
if (_step == 10) lcd_puts_P(_T(MSG_SELFTEST_CHECK_FSENSOR));
|
||||||
if (_step == 11) lcd_puts_P(_i("All correct "));////MSG_SELFTEST_CHECK_ALLCORRECT c=20 r=0
|
if (_step == 11) lcd_puts_P(_i("All correct "));////MSG_SELFTEST_CHECK_ALLCORRECT c=20 r=0
|
||||||
|
|
@ -7191,26 +7283,27 @@ static int lcd_selftest_screen(int _step, int _progress, int _progress_scale, bo
|
||||||
else if (_step < 9)
|
else if (_step < 9)
|
||||||
{
|
{
|
||||||
//SERIAL_ECHOLNPGM("Other tests");
|
//SERIAL_ECHOLNPGM("Other tests");
|
||||||
_step_block = 3;
|
|
||||||
lcd_selftest_screen_step(3, 9, ((_step == _step_block) ? 1 : (_step < _step_block) ? 0 : 2), "Hotend", _indicator);
|
|
||||||
|
|
||||||
_step_block = 4;
|
_step_block = 3;
|
||||||
lcd_selftest_screen_step(2, 2, ((_step == _step_block) ? 1 : (_step < _step_block) ? 0 : 2), "X", _indicator);
|
lcd_selftest_screen_step(2, 2, ((_step == _step_block) ? 1 : (_step < _step_block) ? 0 : 2), "X", _indicator);
|
||||||
|
|
||||||
_step_block = 5;
|
_step_block = 4;
|
||||||
lcd_selftest_screen_step(2, 8, ((_step == _step_block) ? 1 : (_step < _step_block) ? 0 : 2), "Y", _indicator);
|
lcd_selftest_screen_step(2, 8, ((_step == _step_block) ? 1 : (_step < _step_block) ? 0 : 2), "Y", _indicator);
|
||||||
|
|
||||||
_step_block = 6;
|
_step_block = 5;
|
||||||
lcd_selftest_screen_step(2, 14, ((_step == _step_block) ? 1 : (_step < _step_block) ? 0 : 2), "Z", _indicator);
|
lcd_selftest_screen_step(2, 14, ((_step == _step_block) ? 1 : (_step < _step_block) ? 0 : 2), "Z", _indicator);
|
||||||
|
|
||||||
_step_block = 7;
|
_step_block = 6;
|
||||||
lcd_selftest_screen_step(3, 0, ((_step == _step_block) ? 1 : (_step < _step_block) ? 0 : 2), "Bed", _indicator);
|
lcd_selftest_screen_step(3, 0, ((_step == _step_block) ? 1 : (_step < _step_block) ? 0 : 2), "Bed", _indicator);
|
||||||
|
|
||||||
|
_step_block = 7;
|
||||||
|
lcd_selftest_screen_step(3, 9, ((_step == _step_block) ? 1 : (_step < _step_block) ? 0 : 2), "Hotend", _indicator);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_delay > 0) delay_keep_alive(_delay);
|
if (_delay > 0) delay_keep_alive(_delay);
|
||||||
_progress++;
|
_progress++;
|
||||||
|
|
||||||
return (_progress > _progress_scale * 2) ? 0 : _progress;
|
return (_progress >= _progress_scale * 2) ? 0 : _progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lcd_selftest_screen_step(int _row, int _col, int _state, const char *_name, const char *_indicator)
|
static void lcd_selftest_screen_step(int _row, int _col, int _state, const char *_name, const char *_indicator)
|
||||||
|
|
@ -7517,7 +7610,9 @@ void menu_lcd_lcdupdate_func(void)
|
||||||
if (lcd_oldcardstatus)
|
if (lcd_oldcardstatus)
|
||||||
{
|
{
|
||||||
card.initsd();
|
card.initsd();
|
||||||
LCD_MESSAGERPGM(_i("Card inserted"));////MSG_SD_INSERTED c=0 r=0
|
LCD_MESSAGERPGM(_T(WELCOME_MSG));
|
||||||
|
bMain=false; // flag (i.e. 'fake parameter') for 'lcd_sdcard_menu()' function
|
||||||
|
menu_submenu(lcd_sdcard_menu);
|
||||||
//get_description();
|
//get_description();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef CONFIGURATION_PRUSA_H
|
#ifndef CONFIGURATION_PRUSA_H
|
||||||
#define CONFIGURATION_PRUSA_H
|
#define CONFIGURATION_PRUSA_H
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
/*------------------------------------
|
/*------------------------------------
|
||||||
GENERAL SETTINGS
|
GENERAL SETTINGS
|
||||||
*------------------------------------*/
|
*------------------------------------*/
|
||||||
|
|
@ -102,10 +103,18 @@ EXTRUDER SETTINGS
|
||||||
*------------------------------------*/
|
*------------------------------------*/
|
||||||
|
|
||||||
// Mintemps
|
// Mintemps
|
||||||
#define HEATER_0_MINTEMP 15
|
#define HEATER_0_MINTEMP 30
|
||||||
#define HEATER_1_MINTEMP 5
|
#define HEATER_1_MINTEMP 5
|
||||||
#define HEATER_2_MINTEMP 5
|
#define HEATER_2_MINTEMP 5
|
||||||
#define BED_MINTEMP 15
|
#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 30
|
||||||
|
#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)"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Maxtemps
|
// Maxtemps
|
||||||
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef CONFIGURATION_PRUSA_H
|
#ifndef CONFIGURATION_PRUSA_H
|
||||||
#define CONFIGURATION_PRUSA_H
|
#define CONFIGURATION_PRUSA_H
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
/*------------------------------------
|
/*------------------------------------
|
||||||
GENERAL SETTINGS
|
GENERAL SETTINGS
|
||||||
*------------------------------------*/
|
*------------------------------------*/
|
||||||
|
|
@ -102,10 +103,18 @@ EXTRUDER SETTINGS
|
||||||
*------------------------------------*/
|
*------------------------------------*/
|
||||||
|
|
||||||
// Mintemps
|
// Mintemps
|
||||||
#define HEATER_0_MINTEMP 15
|
#define HEATER_0_MINTEMP 30
|
||||||
#define HEATER_1_MINTEMP 5
|
#define HEATER_1_MINTEMP 5
|
||||||
#define HEATER_2_MINTEMP 5
|
#define HEATER_2_MINTEMP 5
|
||||||
#define BED_MINTEMP 15
|
#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 30
|
||||||
|
#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)"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Maxtemps
|
// Maxtemps
|
||||||
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef CONFIGURATION_PRUSA_H
|
#ifndef CONFIGURATION_PRUSA_H
|
||||||
#define CONFIGURATION_PRUSA_H
|
#define CONFIGURATION_PRUSA_H
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
/*------------------------------------
|
/*------------------------------------
|
||||||
GENERAL SETTINGS
|
GENERAL SETTINGS
|
||||||
*------------------------------------*/
|
*------------------------------------*/
|
||||||
|
|
@ -155,10 +156,18 @@
|
||||||
*------------------------------------*/
|
*------------------------------------*/
|
||||||
|
|
||||||
// Mintemps
|
// Mintemps
|
||||||
#define HEATER_0_MINTEMP 15
|
#define HEATER_0_MINTEMP 30
|
||||||
#define HEATER_1_MINTEMP 5
|
#define HEATER_1_MINTEMP 5
|
||||||
#define HEATER_2_MINTEMP 5
|
#define HEATER_2_MINTEMP 5
|
||||||
#define BED_MINTEMP 15
|
#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 30
|
||||||
|
#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)"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Maxtemps
|
// Maxtemps
|
||||||
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef CONFIGURATION_PRUSA_H
|
#ifndef CONFIGURATION_PRUSA_H
|
||||||
#define CONFIGURATION_PRUSA_H
|
#define CONFIGURATION_PRUSA_H
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
/*------------------------------------
|
/*------------------------------------
|
||||||
GENERAL SETTINGS
|
GENERAL SETTINGS
|
||||||
*------------------------------------*/
|
*------------------------------------*/
|
||||||
|
|
@ -156,10 +157,18 @@
|
||||||
*------------------------------------*/
|
*------------------------------------*/
|
||||||
|
|
||||||
// Mintemps
|
// Mintemps
|
||||||
#define HEATER_0_MINTEMP 15
|
#define HEATER_0_MINTEMP 30
|
||||||
#define HEATER_1_MINTEMP 5
|
#define HEATER_1_MINTEMP 5
|
||||||
#define HEATER_2_MINTEMP 5
|
#define HEATER_2_MINTEMP 5
|
||||||
#define BED_MINTEMP 15
|
#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 30
|
||||||
|
#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)"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Maxtemps
|
// Maxtemps
|
||||||
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef CONFIGURATION_PRUSA_H
|
#ifndef CONFIGURATION_PRUSA_H
|
||||||
#define CONFIGURATION_PRUSA_H
|
#define CONFIGURATION_PRUSA_H
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
/*------------------------------------
|
/*------------------------------------
|
||||||
GENERAL SETTINGS
|
GENERAL SETTINGS
|
||||||
*------------------------------------*/
|
*------------------------------------*/
|
||||||
|
|
@ -276,7 +277,15 @@
|
||||||
#define HEATER_0_MINTEMP 15
|
#define HEATER_0_MINTEMP 15
|
||||||
#define HEATER_1_MINTEMP 5
|
#define HEATER_1_MINTEMP 5
|
||||||
#define HEATER_2_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 15
|
||||||
|
#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)"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Maxtemps
|
// Maxtemps
|
||||||
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ The script downloads Arduino with our modifications and Rambo board support inst
|
||||||
|
|
||||||
a. install `"Arduino Software IDE"` for your preferred operating system
|
a. install `"Arduino Software IDE"` for your preferred operating system
|
||||||
`https://www.arduino.cc -> Software->Downloads`
|
`https://www.arduino.cc -> Software->Downloads`
|
||||||
it is recommended to use older version `"1.6.9"`, as it is used on out build server to produce official builds.
|
it is recommended to use version `"1.8.5"`, as it is used on out build server to produce official builds.
|
||||||
_note: in the case of persistent compilation problems, check the version of the currently used C/C++ compiler (GCC) - should be `4.8.1`; version can be verified by entering the command
|
_note: in the case of persistent compilation problems, check the version of the currently used C/C++ compiler (GCC) - should be `4.8.1`; version can be verified by entering the command
|
||||||
`avr-gcc --version`
|
`avr-gcc --version`
|
||||||
if you are not sure where the file is placed (depends on how `"Arduino Software IDE"` was installed), you can use the search feature within the file system_
|
if you are not sure where the file is placed (depends on how `"Arduino Software IDE"` was installed), you can use the search feature within the file system_
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,146 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @author Marek Bel
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
#include "../Firmware/AutoDeplete.h"
|
||||||
|
|
||||||
|
TEST_CASE( "AutoDeplete test.", "[AutoDeplete]" )
|
||||||
|
{
|
||||||
|
CHECK(ad_allDepleted() == false);
|
||||||
|
|
||||||
|
CHECK(ad_getAlternative(0) == 0);
|
||||||
|
CHECK(ad_getAlternative(1) == 1);
|
||||||
|
CHECK(ad_getAlternative(2) == 2);
|
||||||
|
CHECK(ad_getAlternative(3) == 3);
|
||||||
|
CHECK(ad_getAlternative(4) == 4);
|
||||||
|
|
||||||
|
ad_markDepleted(1);
|
||||||
|
|
||||||
|
CHECK(ad_getAlternative(0) == 0);
|
||||||
|
CHECK(ad_getAlternative(1) == 2);
|
||||||
|
CHECK(ad_getAlternative(2) == 2);
|
||||||
|
CHECK(ad_getAlternative(3) == 3);
|
||||||
|
CHECK(ad_getAlternative(4) == 4);
|
||||||
|
CHECK(ad_allDepleted() == false);
|
||||||
|
|
||||||
|
ad_markDepleted(3);
|
||||||
|
|
||||||
|
CHECK(ad_getAlternative(0) == 0);
|
||||||
|
CHECK(ad_getAlternative(1) == 2);
|
||||||
|
CHECK(ad_getAlternative(2) == 2);
|
||||||
|
CHECK(ad_getAlternative(3) == 4);
|
||||||
|
CHECK(ad_getAlternative(4) == 4);
|
||||||
|
CHECK(ad_allDepleted() == false);
|
||||||
|
|
||||||
|
ad_markDepleted(4);
|
||||||
|
|
||||||
|
CHECK(ad_getAlternative(0) == 0);
|
||||||
|
CHECK(ad_getAlternative(1) == 2);
|
||||||
|
CHECK(ad_getAlternative(2) == 2);
|
||||||
|
CHECK(ad_getAlternative(3) == 0);
|
||||||
|
CHECK(ad_getAlternative(4) == 0);
|
||||||
|
CHECK(ad_allDepleted() == false);
|
||||||
|
|
||||||
|
ad_markDepleted(4);
|
||||||
|
|
||||||
|
CHECK(ad_getAlternative(0) == 0);
|
||||||
|
CHECK(ad_getAlternative(1) == 2);
|
||||||
|
CHECK(ad_getAlternative(2) == 2);
|
||||||
|
CHECK(ad_getAlternative(3) == 0);
|
||||||
|
CHECK(ad_getAlternative(4) == 0);
|
||||||
|
CHECK(ad_allDepleted() == false);
|
||||||
|
|
||||||
|
ad_markDepleted(0);
|
||||||
|
|
||||||
|
CHECK(ad_getAlternative(0) == 2);
|
||||||
|
CHECK(ad_getAlternative(1) == 2);
|
||||||
|
CHECK(ad_getAlternative(2) == 2);
|
||||||
|
CHECK(ad_getAlternative(3) == 2);
|
||||||
|
CHECK(ad_getAlternative(4) == 2);
|
||||||
|
CHECK(ad_allDepleted() == false);
|
||||||
|
|
||||||
|
ad_markDepleted(2);
|
||||||
|
|
||||||
|
CHECK(ad_getAlternative(0) == 0);
|
||||||
|
CHECK(ad_getAlternative(1) == 1);
|
||||||
|
CHECK(ad_getAlternative(2) == 2);
|
||||||
|
CHECK(ad_getAlternative(3) == 3);
|
||||||
|
CHECK(ad_getAlternative(4) == 4);
|
||||||
|
CHECK(ad_allDepleted() == true);
|
||||||
|
|
||||||
|
ad_markDepleted(2);
|
||||||
|
|
||||||
|
CHECK(ad_getAlternative(0) == 0);
|
||||||
|
CHECK(ad_getAlternative(1) == 1);
|
||||||
|
CHECK(ad_getAlternative(2) == 2);
|
||||||
|
CHECK(ad_getAlternative(3) == 3);
|
||||||
|
CHECK(ad_getAlternative(4) == 4);
|
||||||
|
CHECK(ad_allDepleted() == true);
|
||||||
|
|
||||||
|
ad_markLoaded(4);
|
||||||
|
|
||||||
|
CHECK(ad_getAlternative(0) == 4);
|
||||||
|
CHECK(ad_getAlternative(1) == 4);
|
||||||
|
CHECK(ad_getAlternative(2) == 4);
|
||||||
|
CHECK(ad_getAlternative(3) == 4);
|
||||||
|
CHECK(ad_getAlternative(4) == 4);
|
||||||
|
CHECK(ad_allDepleted() == false);
|
||||||
|
|
||||||
|
ad_markLoaded(0);
|
||||||
|
|
||||||
|
CHECK(ad_getAlternative(0) == 0);
|
||||||
|
CHECK(ad_getAlternative(1) == 4);
|
||||||
|
CHECK(ad_getAlternative(2) == 4);
|
||||||
|
CHECK(ad_getAlternative(3) == 4);
|
||||||
|
CHECK(ad_getAlternative(4) == 4);
|
||||||
|
CHECK(ad_allDepleted() == false);
|
||||||
|
|
||||||
|
ad_markLoaded(3);
|
||||||
|
|
||||||
|
CHECK(ad_getAlternative(0) == 0);
|
||||||
|
CHECK(ad_getAlternative(1) == 3);
|
||||||
|
CHECK(ad_getAlternative(2) == 3);
|
||||||
|
CHECK(ad_getAlternative(3) == 3);
|
||||||
|
CHECK(ad_getAlternative(4) == 4);
|
||||||
|
CHECK(ad_allDepleted() == false);
|
||||||
|
|
||||||
|
ad_markLoaded(3);
|
||||||
|
|
||||||
|
CHECK(ad_getAlternative(0) == 0);
|
||||||
|
CHECK(ad_getAlternative(1) == 3);
|
||||||
|
CHECK(ad_getAlternative(2) == 3);
|
||||||
|
CHECK(ad_getAlternative(3) == 3);
|
||||||
|
CHECK(ad_getAlternative(4) == 4);
|
||||||
|
CHECK(ad_allDepleted() == false);
|
||||||
|
|
||||||
|
ad_markLoaded(2);
|
||||||
|
|
||||||
|
CHECK(ad_getAlternative(0) == 0);
|
||||||
|
CHECK(ad_getAlternative(1) == 2);
|
||||||
|
CHECK(ad_getAlternative(2) == 2);
|
||||||
|
CHECK(ad_getAlternative(3) == 3);
|
||||||
|
CHECK(ad_getAlternative(4) == 4);
|
||||||
|
CHECK(ad_allDepleted() == false);
|
||||||
|
|
||||||
|
ad_markLoaded(1);
|
||||||
|
|
||||||
|
CHECK(ad_getAlternative(0) == 0);
|
||||||
|
CHECK(ad_getAlternative(1) == 1);
|
||||||
|
CHECK(ad_getAlternative(2) == 2);
|
||||||
|
CHECK(ad_getAlternative(3) == 3);
|
||||||
|
CHECK(ad_getAlternative(4) == 4);
|
||||||
|
CHECK(ad_allDepleted() == false);
|
||||||
|
|
||||||
|
ad_markLoaded(1);
|
||||||
|
|
||||||
|
CHECK(ad_getAlternative(0) == 0);
|
||||||
|
CHECK(ad_getAlternative(1) == 1);
|
||||||
|
CHECK(ad_getAlternative(2) == 2);
|
||||||
|
CHECK(ad_getAlternative(3) == 3);
|
||||||
|
CHECK(ad_getAlternative(4) == 4);
|
||||||
|
CHECK(ad_allDepleted() == false);
|
||||||
|
|
||||||
|
}
|
||||||
2
build.sh
2
build.sh
|
|
@ -12,7 +12,7 @@ if [ ! -f "PF-build-env-Linux64-$BUILD_ENV.zip" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -d "../../PF-build-env-$BUILD_ENV" ]; then
|
if [ ! -d "../../PF-build-env-$BUILD_ENV" ]; then
|
||||||
unzip PF-build-env-Linux64-$BUILD_ENV.zip -d ../../PF-build-env-$BUILD_ENV || exit 4
|
unzip -q PF-build-env-Linux64-$BUILD_ENV.zip -d ../../PF-build-env-$BUILD_ENV || exit 4
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd ../../PF-build-env-$BUILD_ENV || exit 5
|
cd ../../PF-build-env-$BUILD_ENV || exit 5
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue