merge changes from upstream
This commit is contained in:
commit
7e3a1c7d45
20 changed files with 808 additions and 218 deletions
11
.travis.yml
11
.travis.yml
|
@ -3,16 +3,17 @@ before_install:
|
|||
- sudo apt-get install -y ninja-build
|
||||
script:
|
||||
- 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
|
||||
- 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
|
||||
- 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
|
||||
- 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
|
||||
- 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/Example_test.cpp
|
||||
Tests/Timer_test.cpp
|
||||
Tests/AutoDeplete_test.cpp
|
||||
Firmware/Timer.cpp
|
||||
Firmware/AutoDeplete.cpp
|
||||
)
|
||||
add_executable(tests ${TEST_SOURCES})
|
||||
target_include_directories(tests PRIVATE Tests)
|
||||
|
|
79
Firmware/AutoDeplete.cpp
Normal file
79
Firmware/AutoDeplete.cpp
Normal file
|
@ -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;
|
||||
}
|
17
Firmware/AutoDeplete.h
Normal file
17
Firmware/AutoDeplete.h
Normal file
|
@ -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.
|
||||
#define PIDTEMP
|
||||
#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
|
||||
//#define PID_DEBUG // Sends debug data to the serial port.
|
||||
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
|
||||
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
|
||||
#define PID_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 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
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
#include <avr/pgmspace.h>
|
||||
|
||||
#include "Dcodes.h"
|
||||
#include "AutoDeplete.h"
|
||||
|
||||
|
||||
#ifdef SWSPI
|
||||
|
@ -6947,6 +6948,10 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
|
|||
}
|
||||
else {
|
||||
tmp_extruder = code_value();
|
||||
if (mmu_enabled && lcd_autoDepleteEnabled())
|
||||
{
|
||||
tmp_extruder = ad_getAlternative(tmp_extruder);
|
||||
}
|
||||
}
|
||||
st_synchronize();
|
||||
snmm_filaments_used |= (1 << tmp_extruder); //for stop print
|
||||
|
@ -7641,6 +7646,7 @@ void Stop()
|
|||
disable_heater();
|
||||
if(Stopped == false) {
|
||||
Stopped = true;
|
||||
lcd_print_stop();
|
||||
Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart
|
||||
SERIAL_ERROR_START;
|
||||
SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED);
|
||||
|
|
182
Firmware/mmu.cpp
182
Firmware/mmu.cpp
|
@ -1,4 +1,4 @@
|
|||
//mmu.cpp
|
||||
//! @file
|
||||
|
||||
#include "mmu.h"
|
||||
#include "planner.h"
|
||||
|
@ -14,6 +14,7 @@
|
|||
#include "printers.h"
|
||||
#include <avr/pgmspace.h>
|
||||
#include "io_atmega2560.h"
|
||||
#include "AutoDeplete.h"
|
||||
|
||||
#ifdef TMC2130
|
||||
#include "tmc2130.h"
|
||||
|
@ -245,7 +246,7 @@ void mmu_loop(void)
|
|||
mmu_printf_P(PSTR("T%d\n"), filament);
|
||||
mmu_state = 3; // wait for response
|
||||
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))
|
||||
{
|
||||
|
@ -263,7 +264,7 @@ void mmu_loop(void)
|
|||
#endif //MMU_DEBUG
|
||||
mmu_puts_P(PSTR("C0\n")); //send 'continue loading'
|
||||
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)
|
||||
{
|
||||
|
@ -326,8 +327,15 @@ void mmu_loop(void)
|
|||
if (!mmu_finda && CHECK_FSENSOR && fsensor_enabled) {
|
||||
fsensor_stop_and_save_print();
|
||||
enquecommand_front_P(PSTR("FSENSOR_RECOVER")); //then recover
|
||||
if (lcd_autoDepleteEnabled()) enquecommand_front_P(PSTR("M600 AUTO")); //save print and run M600 command
|
||||
else enquecommand_front_P(PSTR("M600")); //save print and run M600 command
|
||||
ad_markDepleted(mmu_extruder);
|
||||
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;
|
||||
if (mmu_cmd == 0)
|
||||
|
@ -339,19 +347,20 @@ void mmu_loop(void)
|
|||
}
|
||||
return;
|
||||
case 3: //response to mmu commands
|
||||
if (mmu_idl_sens && ir_sensor_detected) {
|
||||
if (PIN_GET(IR_SENSOR_PIN) == 0 && mmu_loading_flag)
|
||||
{
|
||||
if (mmu_idl_sens)
|
||||
{
|
||||
if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0 && mmu_loading_flag)
|
||||
{
|
||||
#ifdef MMU_DEBUG
|
||||
printf_P(PSTR("MMU <= 'A'\n"));
|
||||
printf_P(PSTR("MMU <= 'A'\n"));
|
||||
#endif //MMU_DEBUG
|
||||
mmu_puts_P(PSTR("A\n")); //send 'abort' request
|
||||
mmu_idl_sens = 0;
|
||||
//printf_P(PSTR("MMU IDLER_SENSOR = 0 - ABORT\n"));
|
||||
}
|
||||
//else
|
||||
//printf_P(PSTR("MMU IDLER_SENSOR = 1 - WAIT\n"));
|
||||
}
|
||||
mmu_puts_P(PSTR("A\n")); //send 'abort' request
|
||||
mmu_idl_sens = 0;
|
||||
//printf_P(PSTR("MMU IDLER_SENSOR = 0 - ABORT\n"));
|
||||
}
|
||||
//else
|
||||
//printf_P(PSTR("MMU IDLER_SENSOR = 1 - WAIT\n"));
|
||||
}
|
||||
if (mmu_rx_ok() > 0)
|
||||
{
|
||||
#ifdef MMU_DEBUG
|
||||
|
@ -420,69 +429,96 @@ int8_t mmu_set_filament_type(uint8_t extruder, uint8_t filament)
|
|||
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)
|
||||
{
|
||||
#ifdef TMC2130
|
||||
if ((cmd >= MMU_CMD_T0) && (cmd <= MMU_CMD_T4))
|
||||
{
|
||||
//disable extruder motor
|
||||
#ifdef TMC2130
|
||||
tmc2130_set_pwr(E_AXIS, 0);
|
||||
//printf_P(PSTR("E-axis disabled\n"));
|
||||
}
|
||||
#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_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;
|
||||
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)
|
||||
{
|
||||
mmu_loading_flag = false;
|
||||
if (!ir_sensor_detected) move = MMU_NO_MOVE;
|
||||
mmu_loading_flag = false;
|
||||
|
||||
printf_P(PSTR("mmu_get_response - begin move:%d\n"), move);
|
||||
KEEPALIVE_STATE(IN_PROCESS);
|
||||
while (mmu_cmd != 0)
|
||||
{
|
||||
// mmu_loop();
|
||||
delay_keep_alive(100);
|
||||
}
|
||||
|
||||
while (!mmu_ready)
|
||||
{
|
||||
// mmu_loop();
|
||||
|
||||
if ((mmu_state != 3) && (mmu_last_cmd == 0))
|
||||
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) {
|
||||
case MMU_LOAD_MOVE:
|
||||
mmu_loading_flag = true;
|
||||
mmu_load_step();
|
||||
case MMU_LOAD_MOVE:
|
||||
mmu_loading_flag = true;
|
||||
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
|
||||
if (PIN_GET(IR_SENSOR_PIN) == 0) move = MMU_NO_MOVE;
|
||||
break;
|
||||
case MMU_UNLOAD_MOVE:
|
||||
if (PIN_GET(IR_SENSOR_PIN) == 0) //filament is still detected by idler sensor, printer helps with unlading
|
||||
{
|
||||
printf_P(PSTR("Unload 1\n"));
|
||||
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();
|
||||
if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) //filament is still detected by idler sensor, printer helps with unlading
|
||||
{
|
||||
if (can_extrude())
|
||||
{
|
||||
printf_P(PSTR("Unload 1\n"));
|
||||
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
|
||||
{
|
||||
|
@ -492,12 +528,15 @@ bool mmu_get_response(uint8_t move)
|
|||
}
|
||||
break;
|
||||
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
|
||||
{
|
||||
printf_P(PSTR("Unload 2\n"));
|
||||
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();
|
||||
if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) //filament detected by idler sensor, we must unload first
|
||||
{
|
||||
if (can_extrude())
|
||||
{
|
||||
printf_P(PSTR("Unload 2\n"));
|
||||
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
|
||||
{
|
||||
|
@ -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
|
||||
delay_keep_alive(MMU_LOAD_TIME_MS);
|
||||
move = MMU_LOAD_MOVE;
|
||||
printf_P(PSTR("mmu_get_response - begin move:%d\n"), move);
|
||||
}
|
||||
break;
|
||||
case MMU_NO_MOVE:
|
||||
|
@ -518,27 +558,20 @@ bool mmu_get_response(uint8_t move)
|
|||
mmu_ready = false;
|
||||
// printf_P(PSTR("mmu_get_response - end %d\n"), ret?1:0);
|
||||
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)
|
||||
{
|
||||
|
@ -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..."));
|
||||
delay_keep_alive(3000);
|
||||
}
|
||||
while ((degTargetHotend(active_extruder) - degHotend(active_extruder)) > 5)
|
||||
{
|
||||
delay_keep_alive(1000);
|
||||
lcd_wait_for_heater();
|
||||
}
|
||||
mmu_wait_for_heater_blocking();
|
||||
}
|
||||
if (move_axes) {
|
||||
lcd_clear();
|
||||
|
@ -751,7 +780,7 @@ void mmu_M600_load_filament(bool automatic)
|
|||
#endif //MMU_M600_SWITCH_EXTRUDER
|
||||
}
|
||||
else {
|
||||
tmp_extruder = (tmp_extruder+1)%5;
|
||||
tmp_extruder = ad_getAlternative(tmp_extruder);
|
||||
}
|
||||
lcd_update_enable(false);
|
||||
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
|
||||
static void filament_ramming()
|
||||
void mmu_filament_ramming()
|
||||
{
|
||||
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(" ");
|
||||
else lcd_print(mmu_extruder + 1);
|
||||
|
||||
filament_ramming();
|
||||
mmu_filament_ramming();
|
||||
|
||||
mmu_command(MMU_CMD_U0);
|
||||
// get response
|
||||
|
@ -1366,6 +1395,7 @@ void mmu_continue_loading()
|
|||
setAllTargetHotends(0);
|
||||
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
|
||||
isPrintPaused = true;
|
||||
}
|
||||
}
|
||||
else { //mmu_ir_sensor_detected == false
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
//mmu.h
|
||||
//! @file
|
||||
|
||||
#ifndef MMU_H
|
||||
#define MMU_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 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();
|
||||
|
||||
|
@ -119,3 +122,8 @@ extern void mmu_eject_fil_2();
|
|||
extern void mmu_eject_fil_3();
|
||||
extern void mmu_eject_fil_4();
|
||||
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 "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============================
|
||||
|
@ -103,15 +112,15 @@ static volatile bool temp_meas_ready = false;
|
|||
|
||||
#ifdef PIDTEMP
|
||||
//static cannot be external:
|
||||
static float temp_iState[EXTRUDERS] = { 0 };
|
||||
static float temp_dState[EXTRUDERS] = { 0 };
|
||||
static float iState_sum[EXTRUDERS] = { 0 };
|
||||
static float dState_last[EXTRUDERS] = { 0 };
|
||||
static float pTerm[EXTRUDERS];
|
||||
static float iTerm[EXTRUDERS];
|
||||
static float dTerm[EXTRUDERS];
|
||||
//int output;
|
||||
static float pid_error[EXTRUDERS];
|
||||
static float temp_iState_min[EXTRUDERS];
|
||||
static float temp_iState_max[EXTRUDERS];
|
||||
static float iState_sum_min[EXTRUDERS];
|
||||
static float iState_sum_max[EXTRUDERS];
|
||||
// static float pid_input[EXTRUDERS];
|
||||
// static float pid_output[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 }
|
||||
#endif
|
||||
|
||||
static ShortTimer oTimer4minTempHeater,oTimer4minTempBed;
|
||||
|
||||
// Init min and max temp with extreme values to prevent false errors during startup
|
||||
static int minttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP );
|
||||
static int maxttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP );
|
||||
|
@ -252,6 +263,7 @@ static void temp_runaway_stop(bool isPreheat, bool isBed);
|
|||
if (extruder<0)
|
||||
{
|
||||
soft_pwm_bed = (MAX_BED_POWER)/2;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
bias = d = (MAX_BED_POWER)/2;
|
||||
}
|
||||
else
|
||||
|
@ -288,7 +300,10 @@ static void temp_runaway_stop(bool isPreheat, bool isBed);
|
|||
if(millis() - t2 > 5000) {
|
||||
heating=false;
|
||||
if (extruder<0)
|
||||
{
|
||||
soft_pwm_bed = (bias - d) >> 1;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
else
|
||||
soft_pwm[extruder] = (bias - d) >> 1;
|
||||
t1=millis();
|
||||
|
@ -342,7 +357,10 @@ static void temp_runaway_stop(bool isPreheat, bool isBed);
|
|||
}
|
||||
}
|
||||
if (extruder<0)
|
||||
{
|
||||
soft_pwm_bed = (bias + d) >> 1;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
else
|
||||
soft_pwm[extruder] = (bias + d) >> 1;
|
||||
pid_cycle++;
|
||||
|
@ -413,7 +431,7 @@ void updatePID()
|
|||
{
|
||||
#ifdef PIDTEMP
|
||||
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
|
||||
#ifdef PIDTEMPBED
|
||||
|
@ -582,6 +600,12 @@ void checkExtruderAutoFans()
|
|||
|
||||
#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()
|
||||
{
|
||||
#ifdef WATCHDOG
|
||||
|
@ -593,9 +617,13 @@ void manage_heater()
|
|||
|
||||
if(temp_meas_ready != true) //better readability
|
||||
return;
|
||||
// more precisely - this condition partially stabilizes time interval for regulation values evaluation (@ ~ 230ms)
|
||||
|
||||
updateTemperaturesFromRawValues();
|
||||
|
||||
check_max_temp();
|
||||
check_min_temp();
|
||||
|
||||
#ifdef TEMP_RUNAWAY_BED_HYSTERESIS
|
||||
temp_runaway_check(0, target_temperature_bed, current_temperature_bed, (int)soft_pwm_bed, true);
|
||||
#endif
|
||||
|
@ -611,38 +639,42 @@ void manage_heater()
|
|||
pid_input = current_temperature[e];
|
||||
|
||||
#ifndef PID_OPENLOOP
|
||||
pid_error[e] = target_temperature[e] - pid_input;
|
||||
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) {
|
||||
if(target_temperature[e] == 0) {
|
||||
pid_output = 0;
|
||||
pid_reset[e] = true;
|
||||
}
|
||||
else {
|
||||
if(pid_reset[e] == true) {
|
||||
temp_iState[e] = 0.0;
|
||||
} else {
|
||||
pid_error[e] = target_temperature[e] - pid_input;
|
||||
if(pid_reset[e]) {
|
||||
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;
|
||||
}
|
||||
#ifndef PonM
|
||||
pTerm[e] = cs.Kp * pid_error[e];
|
||||
temp_iState[e] += pid_error[e];
|
||||
temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
|
||||
iTerm[e] = cs.Ki * temp_iState[e];
|
||||
|
||||
//K1 defined in Configuration.h in the PID settings
|
||||
iState_sum[e] += pid_error[e];
|
||||
iState_sum[e] = constrain(iState_sum[e], iState_sum_min[e], iState_sum_max[e]);
|
||||
iTerm[e] = cs.Ki * iState_sum[e];
|
||||
// K1 defined in Configuration.h in the PID settings
|
||||
#define K2 (1.0-K1)
|
||||
dTerm[e] = (cs.Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
|
||||
pid_output = pTerm[e] + iTerm[e] - 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]; // 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_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;
|
||||
} else if (pid_output < 0){
|
||||
if (pid_error[e] < 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration
|
||||
} else if (pid_output < 0) {
|
||||
if (pid_error[e] < 0 ) iState_sum[e] -= pid_error[e]; // conditional un-integration
|
||||
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
|
||||
pid_output = constrain(target_temperature[e], 0, PID_MAX);
|
||||
#endif //PID_OPENLOOP
|
||||
|
@ -659,7 +691,7 @@ void manage_heater()
|
|||
SERIAL_ECHO(" iTerm ");
|
||||
SERIAL_ECHO(iTerm[e]);
|
||||
SERIAL_ECHO(" dTerm ");
|
||||
SERIAL_ECHOLN(dTerm[e]);
|
||||
SERIAL_ECHOLN(-dTerm[e]);
|
||||
#endif //PID_DEBUG
|
||||
#else /* PID off */
|
||||
pid_output = 0;
|
||||
|
@ -669,16 +701,12 @@ void manage_heater()
|
|||
#endif
|
||||
|
||||
// Check if temperature is within the correct range
|
||||
#ifdef AMBIENT_THERMISTOR
|
||||
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
|
||||
if((current_temperature[e] < maxttemp[e]) && (target_temperature[e] != 0))
|
||||
{
|
||||
soft_pwm[e] = (int)pid_output >> 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
soft_pwm[e] = 0;
|
||||
}
|
||||
|
||||
|
@ -763,55 +791,61 @@ void manage_heater()
|
|||
pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
|
||||
#endif //PID_OPENLOOP
|
||||
|
||||
#ifdef AMBIENT_THERMISTOR
|
||||
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
|
||||
if(current_temperature_bed < BED_MAXTEMP)
|
||||
{
|
||||
soft_pwm_bed = (int)pid_output >> 1;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
else {
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
|
||||
#elif !defined(BED_LIMIT_SWITCHING)
|
||||
// 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)
|
||||
{
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
soft_pwm_bed = MAX_BED_POWER>>1;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
WRITE(HEATER_BED_PIN,LOW);
|
||||
}
|
||||
#else //#ifdef BED_LIMIT_SWITCHING
|
||||
// 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)
|
||||
{
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
else if(current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS)
|
||||
{
|
||||
soft_pwm_bed = MAX_BED_POWER>>1;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
WRITE(HEATER_BED_PIN,LOW);
|
||||
}
|
||||
#endif
|
||||
if(target_temperature_bed==0)
|
||||
soft_pwm_bed = 0;
|
||||
#endif
|
||||
|
||||
#ifdef HOST_KEEPALIVE_FEATURE
|
||||
|
@ -983,7 +1017,6 @@ static void updateTemperaturesFromRawValues()
|
|||
CRITICAL_SECTION_END;
|
||||
}
|
||||
|
||||
|
||||
void tp_init()
|
||||
{
|
||||
#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
|
||||
maxttemp[e] = maxttemp[0];
|
||||
#ifdef PIDTEMP
|
||||
temp_iState_min[e] = 0.0;
|
||||
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki;
|
||||
iState_sum_min[e] = 0.0;
|
||||
iState_sum_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki;
|
||||
#endif //PIDTEMP
|
||||
#ifdef PIDTEMPBED
|
||||
temp_iState_min_bed = 0.0;
|
||||
|
@ -1050,10 +1083,12 @@ void tp_init()
|
|||
|
||||
adc_init();
|
||||
|
||||
timer02_init();
|
||||
|
||||
// Use timer0 for temperature measurement
|
||||
// Interleave temperature interrupt with millies interrupt
|
||||
OCR0B = 128;
|
||||
TIMSK0 |= (1<<OCIE0B);
|
||||
OCR2B = 128;
|
||||
TIMSK2 |= (1<<OCIE2B);
|
||||
|
||||
// Wait for temperature measurement to settle
|
||||
delay(250);
|
||||
|
@ -1361,6 +1396,7 @@ void disable_heater()
|
|||
#if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
|
||||
target_temperature_bed=0;
|
||||
soft_pwm_bed=0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
|
||||
WRITE(HEATER_BED_PIN,LOW);
|
||||
#endif
|
||||
|
@ -1525,8 +1561,8 @@ void adc_ready(void) //callback from adc when sampling finished
|
|||
} // extern "C"
|
||||
|
||||
|
||||
// Timer 0 is shared with millies
|
||||
ISR(TIMER0_COMPB_vect)
|
||||
// Timer2 (originaly timer0) is shared with millies
|
||||
ISR(TIMER2_COMPB_vect)
|
||||
{
|
||||
static bool _lock = false;
|
||||
if (_lock) return;
|
||||
|
@ -1534,11 +1570,6 @@ ISR(TIMER0_COMPB_vect)
|
|||
asm("sei");
|
||||
|
||||
if (!temp_meas_ready) adc_cycle();
|
||||
else
|
||||
{
|
||||
check_max_temp();
|
||||
check_min_temp();
|
||||
}
|
||||
lcd_buttons_update();
|
||||
|
||||
static unsigned char pwm_count = (1 << SOFT_PWM_SCALE);
|
||||
|
@ -1598,7 +1629,7 @@ ISR(TIMER0_COMPB_vect)
|
|||
#endif
|
||||
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
|
||||
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
|
||||
}
|
||||
#ifdef FAN_SOFT_PWM
|
||||
|
@ -1735,7 +1766,7 @@ ISR(TIMER0_COMPB_vect)
|
|||
state_timer_heater_b = MIN_STATE_TIME;
|
||||
}
|
||||
state_heater_b = 1;
|
||||
WRITE(HEATER_BED_PIN, 1);
|
||||
//WRITE(HEATER_BED_PIN, 1);
|
||||
}
|
||||
} else {
|
||||
// turn OFF heather only if the minimum time is up
|
||||
|
@ -1934,26 +1965,49 @@ void check_min_temp_bed()
|
|||
|
||||
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
|
||||
static uint8_t heat_cycles = 0;
|
||||
if (current_temperature_raw_ambient > OVERSAMPLENR*MINTEMP_MINAMBIENT_RAW)
|
||||
{
|
||||
if (READ(HEATER_0_PIN) == HIGH)
|
||||
{
|
||||
// if ((heat_cycles % 10) == 0)
|
||||
// printf_P(PSTR("X%d\n"), heat_cycles);
|
||||
if (heat_cycles > 50) //reaction time 5-10s
|
||||
check_min_temp_heater0();
|
||||
else
|
||||
heat_cycles++;
|
||||
}
|
||||
else
|
||||
heat_cycles = 0;
|
||||
return;
|
||||
}
|
||||
if(current_temperature_raw_ambient>(OVERSAMPLENR*MINTEMP_MINAMBIENT_RAW)) // thermistor is NTC type, so operator is ">" ;-)
|
||||
{ // ambient temperature is low
|
||||
#endif //AMBIENT_THERMISTOR
|
||||
// *** 'common' part of code for MK2.5 & MK3
|
||||
// * nozzle checking
|
||||
if(target_temperature[active_extruder]>minttemp[active_extruder])
|
||||
{ // ~ nozzle heating is on
|
||||
bCheckingOnHeater=bCheckingOnHeater||(current_temperature[active_extruder]>=minttemp[active_extruder]); // for eventually delay cutting
|
||||
if(oTimer4minTempHeater.expired(HEATER_MINTEMP_DELAY)||(!oTimer4minTempHeater.running())||bCheckingOnHeater)
|
||||
{
|
||||
bCheckingOnHeater=true; // not necessary
|
||||
check_min_temp_heater0(); // delay is elapsed or temperature is/was over minTemp => periodical checking is active
|
||||
}
|
||||
}
|
||||
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
|
||||
check_min_temp_heater0();
|
||||
check_min_temp_bed();
|
||||
}
|
||||
|
||||
#if (defined(FANCHECK) && defined(TACH_0) && (TACH_0 > -1))
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
#include "stepper.h"
|
||||
#endif
|
||||
|
||||
#define ENABLE_TEMPERATURE_INTERRUPT() TIMSK0 |= (1<<OCIE0B)
|
||||
#define DISABLE_TEMPERATURE_INTERRUPT() TIMSK0 &= ~(1<<OCIE0B)
|
||||
#define ENABLE_TEMPERATURE_INTERRUPT() TIMSK2 |= (1<<OCIE2B)
|
||||
#define DISABLE_TEMPERATURE_INTERRUPT() TIMSK2 &= ~(1<<OCIE2B)
|
||||
|
||||
// public functions
|
||||
void tp_init(); //initialize the heating
|
||||
|
@ -87,6 +87,8 @@ extern int current_voltage_raw_bed;
|
|||
extern volatile int babystepsTodo[3];
|
||||
#endif
|
||||
|
||||
void resetPID(uint8_t extruder);
|
||||
|
||||
inline void babystepsTodoZadd(int n)
|
||||
{
|
||||
if (n != 0) {
|
||||
|
@ -137,11 +139,15 @@ FORCE_INLINE float degTargetBed() {
|
|||
|
||||
FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t extruder) {
|
||||
target_temperature[extruder] = celsius;
|
||||
resetPID(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)
|
||||
|
|
103
Firmware/timer02.c
Normal file
103
Firmware/timer02.c
Normal file
|
@ -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_fan_dialog(int _fan);
|
||||
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_colorprint_change();
|
||||
#ifdef SNMM
|
||||
|
@ -237,6 +238,8 @@ bool wait_for_unclick;
|
|||
// float raw_Ki, raw_Kd;
|
||||
#endif
|
||||
|
||||
bool bMain; // flag (i.e. 'fake parameter') for 'lcd_sdcard_menu()' function
|
||||
|
||||
|
||||
|
||||
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 (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
|
||||
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
|
||||
{
|
||||
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
|
||||
#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
|
||||
|
@ -6227,7 +6234,10 @@ void lcd_sdcard_menu()
|
|||
|
||||
|
||||
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();
|
||||
if (card.filename[0] == '/')
|
||||
{
|
||||
|
@ -6323,28 +6333,24 @@ bool lcd_selftest()
|
|||
_result = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (_result)
|
||||
{
|
||||
_progress = lcd_selftest_screen(3, _progress, 3, true, 1000);
|
||||
_result = lcd_selfcheck_check_heater(false);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
_progress = lcd_selftest_screen(4, _progress, 3, true, 2000);
|
||||
_progress = lcd_selftest_screen(3, _progress, 3, true, 2000);
|
||||
#ifdef TMC2130
|
||||
_result = lcd_selfcheck_axis_sg(X_AXIS);
|
||||
_result = lcd_selfcheck_axis_sg(X_AXIS);
|
||||
#else
|
||||
_result = lcd_selfcheck_axis(X_AXIS, X_MAX_POS);
|
||||
_result = lcd_selfcheck_axis(X_AXIS, X_MAX_POS);
|
||||
#endif //TMC2130
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (_result)
|
||||
{
|
||||
_progress = lcd_selftest_screen(4, _progress, 3, true, 0);
|
||||
_progress = lcd_selftest_screen(3, _progress, 3, true, 0);
|
||||
|
||||
#ifndef TMC2130
|
||||
_result = lcd_selfcheck_pulleys(X_AXIS);
|
||||
|
@ -6354,7 +6360,7 @@ bool lcd_selftest()
|
|||
|
||||
if (_result)
|
||||
{
|
||||
_progress = lcd_selftest_screen(5, _progress, 3, true, 1500);
|
||||
_progress = lcd_selftest_screen(4, _progress, 3, true, 1500);
|
||||
#ifdef TMC2130
|
||||
_result = lcd_selfcheck_axis_sg(Y_AXIS);
|
||||
#else
|
||||
|
@ -6364,7 +6370,7 @@ bool lcd_selftest()
|
|||
|
||||
if (_result)
|
||||
{
|
||||
_progress = lcd_selftest_screen(5, _progress, 3, true, 0);
|
||||
_progress = lcd_selftest_screen(4, _progress, 3, true, 0);
|
||||
#ifndef TMC2130
|
||||
_result = lcd_selfcheck_pulleys(Y_AXIS);
|
||||
#endif // TMC2130
|
||||
|
@ -6385,7 +6391,7 @@ bool lcd_selftest()
|
|||
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);
|
||||
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);
|
||||
if (eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE) != 1) {
|
||||
enquecommand_P(PSTR("G28 W"));
|
||||
|
@ -6412,25 +6418,46 @@ bool lcd_selftest()
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
if (_result)
|
||||
{
|
||||
_progress = lcd_selftest_screen(7, _progress, 3, true, 1000); //check nozzle
|
||||
_result = lcd_selfcheck_check_heater(false);
|
||||
}
|
||||
if (_result)
|
||||
{
|
||||
_progress = lcd_selftest_screen(8, _progress, 3, true, 2000); //bed ok
|
||||
#ifdef PAT9125
|
||||
if (mmu_enabled == false) {
|
||||
_progress = lcd_selftest_screen(9, _progress, 3, true, 2000); //check filaments sensor
|
||||
_result = lcd_selftest_fsensor();
|
||||
}
|
||||
_progress = lcd_selftest_screen(8, _progress, 3, true, 2000); //nozzle ok
|
||||
}
|
||||
#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 (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
|
||||
}
|
||||
else
|
||||
|
@ -6642,7 +6669,7 @@ static bool lcd_selfcheck_axis(int _axis, int _travel)
|
|||
}
|
||||
else
|
||||
{
|
||||
_progress = lcd_selftest_screen(4 + _axis, _progress, 3, false, 0);
|
||||
_progress = lcd_selftest_screen(3 + _axis, _progress, 3, false, 0);
|
||||
_lcd_refresh = 0;
|
||||
}
|
||||
|
||||
|
@ -6809,7 +6836,7 @@ static bool lcd_selfcheck_check_heater(bool _isbed)
|
|||
|
||||
manage_heater();
|
||||
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) {
|
||||
MYSERIAL.print("Bed temp:");
|
||||
MYSERIAL.println(degBed());
|
||||
|
@ -6835,9 +6862,10 @@ static bool lcd_selfcheck_check_heater(bool _isbed)
|
|||
MYSERIAL.print("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;
|
||||
}
|
||||
|
@ -6985,6 +7013,70 @@ static bool lcd_selftest_fsensor(void)
|
|||
}
|
||||
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
|
||||
|
||||
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);
|
||||
|
||||
int _step_block = 0;
|
||||
const char *_indicator = (_progress > _progress_scale) ? "-" : "|";
|
||||
const char *_indicator = (_progress >= _progress_scale) ? "-" : "|";
|
||||
|
||||
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 == 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 == 3) lcd_puts_P(_i("Checking hotend "));////MSG_SELFTEST_CHECK_HOTEND c=20 r=0
|
||||
if (_step == 4) lcd_puts_P(_i("Checking X axis "));////MSG_SELFTEST_CHECK_X c=20 r=0
|
||||
if (_step == 5) lcd_puts_P(_i("Checking Y axis "));////MSG_SELFTEST_CHECK_Y c=20 r=0
|
||||
if (_step == 6) lcd_puts_P(_i("Checking Z axis "));////MSG_SELFTEST_CHECK_Z c=20 r=0
|
||||
if (_step == 7) lcd_puts_P(_T(MSG_SELFTEST_CHECK_BED));
|
||||
if (_step == 8) lcd_puts_P(_T(MSG_SELFTEST_CHECK_BED));
|
||||
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 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(_T(MSG_SELFTEST_CHECK_BED));
|
||||
if (_step == 7
|
||||
|| _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 == 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
|
||||
|
@ -7191,26 +7283,27 @@ static int lcd_selftest_screen(int _step, int _progress, int _progress_scale, bo
|
|||
else if (_step < 9)
|
||||
{
|
||||
//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);
|
||||
|
||||
_step_block = 5;
|
||||
_step_block = 4;
|
||||
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);
|
||||
|
||||
_step_block = 7;
|
||||
_step_block = 6;
|
||||
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);
|
||||
_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)
|
||||
|
@ -7517,7 +7610,9 @@ void menu_lcd_lcdupdate_func(void)
|
|||
if (lcd_oldcardstatus)
|
||||
{
|
||||
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();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef CONFIGURATION_PRUSA_H
|
||||
#define CONFIGURATION_PRUSA_H
|
||||
|
||||
#include <limits.h>
|
||||
/*------------------------------------
|
||||
GENERAL SETTINGS
|
||||
*------------------------------------*/
|
||||
|
@ -102,10 +103,18 @@ EXTRUDER SETTINGS
|
|||
*------------------------------------*/
|
||||
|
||||
// Mintemps
|
||||
#define HEATER_0_MINTEMP 15
|
||||
#define HEATER_0_MINTEMP 30
|
||||
#define HEATER_1_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
|
||||
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef CONFIGURATION_PRUSA_H
|
||||
#define CONFIGURATION_PRUSA_H
|
||||
|
||||
#include <limits.h>
|
||||
/*------------------------------------
|
||||
GENERAL SETTINGS
|
||||
*------------------------------------*/
|
||||
|
@ -102,10 +103,18 @@ EXTRUDER SETTINGS
|
|||
*------------------------------------*/
|
||||
|
||||
// Mintemps
|
||||
#define HEATER_0_MINTEMP 15
|
||||
#define HEATER_0_MINTEMP 30
|
||||
#define HEATER_1_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
|
||||
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef CONFIGURATION_PRUSA_H
|
||||
#define CONFIGURATION_PRUSA_H
|
||||
|
||||
#include <limits.h>
|
||||
/*------------------------------------
|
||||
GENERAL SETTINGS
|
||||
*------------------------------------*/
|
||||
|
@ -155,10 +156,18 @@
|
|||
*------------------------------------*/
|
||||
|
||||
// Mintemps
|
||||
#define HEATER_0_MINTEMP 15
|
||||
#define HEATER_0_MINTEMP 30
|
||||
#define HEATER_1_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
|
||||
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef CONFIGURATION_PRUSA_H
|
||||
#define CONFIGURATION_PRUSA_H
|
||||
|
||||
#include <limits.h>
|
||||
/*------------------------------------
|
||||
GENERAL SETTINGS
|
||||
*------------------------------------*/
|
||||
|
@ -156,10 +157,18 @@
|
|||
*------------------------------------*/
|
||||
|
||||
// Mintemps
|
||||
#define HEATER_0_MINTEMP 15
|
||||
#define HEATER_0_MINTEMP 30
|
||||
#define HEATER_1_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
|
||||
#if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef CONFIGURATION_PRUSA_H
|
||||
#define CONFIGURATION_PRUSA_H
|
||||
|
||||
#include <limits.h>
|
||||
/*------------------------------------
|
||||
GENERAL SETTINGS
|
||||
*------------------------------------*/
|
||||
|
@ -276,7 +277,15 @@
|
|||
#define HEATER_0_MINTEMP 15
|
||||
#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_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
|
||||
#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
|
||||
`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
|
||||
`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_
|
||||
|
|
146
Tests/AutoDeplete_test.cpp
Normal file
146
Tests/AutoDeplete_test.cpp
Normal file
|
@ -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
|
||||
|
||||
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
|
||||
|
||||
cd ../../PF-build-env-$BUILD_ENV || exit 5
|
||||
|
|
Loading…
Reference in a new issue