Merge branch 'MK3' into prusa3d-DEV_MK3

This commit is contained in:
Marek Bel 2019-01-15 16:58:36 +01:00
commit 052ae323f8
34 changed files with 3650 additions and 3740 deletions

16
.gitignore vendored
View File

@ -1,4 +1,4 @@
.settings
.settings
.project
.cproject
Debug
@ -35,3 +35,17 @@ Firmware/Doc
/Firmware/variants/1_75mm_MK2-EINY01-E3Dv6full.h.bak
/Firmware/variants/1_75mm_MK1-RAMBo13a-E3Dv6full.h
/Firmware/variants/1_75mm_MK1-RAMBo10a-E3Dv6full.h
/lang/*.bin
/lang/*.hex
/lang/*.dat
/lang/*.tmp
/lang/*.out
/lang/not_tran.txt
/lang/not_used.txt
/lang/progmem1.chr
/lang/progmem1.lss
/lang/progmem1.txt
/lang/progmem1.var
/lang/text.sym
/lang/textaddr.txt
/build-env/

18
.travis.yml Normal file
View File

@ -0,0 +1,18 @@
dist: trusty
before_install:
- sudo apt-get install -y ninja-build
script:
- bash -x test.sh
- bash -x build.sh
- rm Firmware/Configuration_prusa.h
- cp Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h Firmware/Configuration_prusa.h
- bash -x build.sh
- rm Firmware/Configuration_prusa.h
- cp Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h Firmware/Configuration_prusa.h
- bash -x build.sh
- rm Firmware/Configuration_prusa.h
- cp Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h Firmware/Configuration_prusa.h
- bash -x build.sh
- rm Firmware/Configuration_prusa.h
- cp Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h Firmware/Configuration_prusa.h
- bash -x build.sh

View File

@ -1,4 +1,6 @@
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.1)
set (CMAKE_CXX_STANDARD 11)
project(cmake_test)

View File

@ -7,8 +7,8 @@
#define STR(x) STR_HELPER(x)
// Firmware version
#define FW_VERSION "3.5.0"
#define FW_COMMIT_NR 1749
#define FW_VERSION "3.5.1"
#define FW_COMMIT_NR 1778
// FW_VERSION_UNKNOWN means this is an unofficial build.
// The firmware should only be checked into github with this symbol.
#define FW_DEV_VERSION FW_VERSION_UNKNOWN

View File

@ -129,6 +129,7 @@
#include "sound.h"
#include "cmdqueue.h"
#include "io_atmega2560.h"
// Macros for bit masks
#define BIT(b) (1<<(b))
@ -394,6 +395,8 @@ static bool saved_extruder_relative_mode = false;
static int saved_fanSpeed = 0; //!< Print fan speed
//! @}
static int saved_feedmultiply_mm = 100;
//===========================================================================
//=============================Routines======================================
//===========================================================================
@ -639,6 +642,8 @@ void failstats_reset_print()
eeprom_update_byte((uint8_t *)EEPROM_CRASH_COUNT_Y, 0);
eeprom_update_byte((uint8_t *)EEPROM_FERROR_COUNT, 0);
eeprom_update_byte((uint8_t *)EEPROM_POWER_COUNT, 0);
eeprom_update_byte((uint8_t *)EEPROM_MMU_FAIL, 0);
eeprom_update_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL, 0);
}
@ -685,6 +690,12 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
eeprom_update_word((uint16_t *)EEPROM_FERROR_COUNT_TOT, 0);
eeprom_update_word((uint16_t *)EEPROM_POWER_COUNT_TOT, 0);
eeprom_update_word((uint16_t *)EEPROM_MMU_FAIL_TOT, 0);
eeprom_update_word((uint16_t *)EEPROM_MMU_LOAD_FAIL_TOT, 0);
eeprom_update_byte((uint8_t *)EEPROM_MMU_FAIL, 0);
eeprom_update_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL, 0);
lcd_menu_statistics();
break;
@ -711,6 +722,11 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
eeprom_update_word((uint16_t *)EEPROM_FERROR_COUNT_TOT, 0);
eeprom_update_word((uint16_t *)EEPROM_POWER_COUNT_TOT, 0);
eeprom_update_word((uint16_t *)EEPROM_MMU_FAIL_TOT, 0);
eeprom_update_word((uint16_t *)EEPROM_MMU_LOAD_FAIL_TOT, 0);
eeprom_update_byte((uint8_t *)EEPROM_MMU_FAIL, 0);
eeprom_update_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL, 0);
#ifdef FILAMENT_SENSOR
fsensor_enable();
fsensor_autoload_set(true);
@ -1389,6 +1405,12 @@ void setup()
if (eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_MMU_FAIL_TOT) == 0xffff) eeprom_update_word((uint16_t *)EEPROM_MMU_FAIL_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT) == 0xffff) eeprom_update_word((uint16_t *)EEPROM_MMU_LOAD_FAIL_TOT, 0);
if (eeprom_read_byte((uint8_t*)EEPROM_MMU_FAIL) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_MMU_FAIL, 0);
if (eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL, 0);
#ifdef SNMM
if (eeprom_read_dword((uint32_t*)EEPROM_BOWDEN_LENGTH) == 0x0ffffffff) { //bowden length used for SNMM
int _z = BOWDEN_LENGTH;
@ -2804,10 +2826,15 @@ bool gcode_M45(bool onlyZ, int8_t verbosity_level)
lcd_puts_P(_T(MSG_FIND_BED_OFFSET_AND_SKEW_LINE2));
}
bool endstops_enabled = enable_endstops(false);
current_position[Z_AXIS] -= 1; //move 1mm down with disabled endstop
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[Z_AXIS] / 40, active_extruder);
st_synchronize();
// Move the print head close to the bed.
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
bool endstops_enabled = enable_endstops(true);
enable_endstops(true);
#ifdef TMC2130
tmc2130_home_enter(Z_AXIS_MASK);
#endif //TMC2130
@ -4537,10 +4564,20 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
lcd_calibrate_z_end_stop_manual(true); // Z-leveling (X-assembly stay up!!!)
#endif // TMC2130
// ~ Z-homing (can not be used "G28", because X & Y-homing would have been done before (Z-homing))
bState=enable_z_endstop(true);
bState=enable_z_endstop(false);
current_position[Z_AXIS] -= 1;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[Z_AXIS] / 40, active_extruder);
st_synchronize();
enable_z_endstop(true);
#ifdef TMC2130
tmc2130_home_enter(Z_AXIS_MASK);
#endif // TMC2130
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[Z_AXIS] / 40, active_extruder);
st_synchronize();
#ifdef TMC2130
tmc2130_home_exit();
#endif // TMC2130
enable_z_endstop(bState);
} while (st_get_position_mm(Z_AXIS) > MESH_HOME_Z_SEARCH); // i.e. Z-leveling not o.k.
// plan_set_z_position(MESH_HOME_Z_SEARCH); // is not necessary ('do-while' loop always ends at the expected Z-position)
@ -6091,12 +6128,20 @@ Sigma_Exit:
SERIAL_ECHOLN("");
}break;
#endif
case 220: // M220 S<factor in percent>- set speed factor override percentage
{
if(code_seen('S'))
if (code_seen('B')) //backup current speed factor
{
saved_feedmultiply_mm = feedmultiply;
}
if(code_seen('S'))
{
feedmultiply = code_value() ;
}
if (code_seen('R')) { //restore previous feedmultiply
feedmultiply = saved_feedmultiply_mm;
}
}
break;
case 221: // M221 S<factor in percent>- set extrude factor override percentage
@ -6506,6 +6551,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
#endif //FILAMENTCHANGEENABLE
case 601: //! M601 - Pause print
{
cmdqueue_pop_front(); //trick because we want skip this command (M601) after restore
lcd_pause_print();
}
break;
@ -6860,8 +6906,10 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
//! if extruder is "?", open menu to let the user select extruder/filament
//!
//! For MMU_V2:
//! @n T<n> Gcode to extrude must follow immediately to load to extruder wheels
//! @n T? Gcode to extrude doesn't have to follow, load to extruder wheels is done automatically
//! @n T<n> Gcode to extrude at least 38.10 mm at feedrate 19.02 mm/s must follow immediately to load to extruder wheels.
//! @n T? Gcode to extrude shouldn't have to follow, load to extruder wheels is done automatically
//! @n Tx Same as T?, except nozzle doesn't have to be preheated. Tc must be placed after extruder nozzle is preheated to finish filament load.
//! @n Tc Load to nozzle after filament was prepared by Tc and extruder nozzle is already heated.
else if(code_seen('T'))
{
int index;
@ -6877,16 +6925,20 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
if (mmu_enabled)
{
tmp_extruder = choose_menu_P(_T(MSG_CHOOSE_FILAMENT), _T(MSG_FILAMENT));
if ((tmp_extruder == mmu_extruder) && mmu_fil_loaded) {
printf_P(PSTR("Duplicit T-code ignored.\n"));
return; //dont execute the same T-code twice in a row
}
st_synchronize();
mmu_command(MMU_CMD_T0 + tmp_extruder);
manage_response(true, true);
manage_response(true, true, MMU_TCODE_MOVE);
}
}
else if (*(strchr_pointer + index) == 'c') { //load to from bondtech gears to nozzle (nozzle should be preheated)
if (mmu_enabled)
{
st_synchronize();
mmu_command(MMU_CMD_C0);
mmu_continue_loading();
mmu_extruder = tmp_extruder; //filament change is finished
mmu_load_to_nozzle();
}
@ -6911,11 +6963,15 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
if (mmu_enabled)
{
if ((tmp_extruder == mmu_extruder) && mmu_fil_loaded) {
printf_P(PSTR("Duplicit T-code ignored.\n"));
return; //dont execute the same T-code twice in a row
}
mmu_command(MMU_CMD_T0 + tmp_extruder);
manage_response(true, true);
mmu_command(MMU_CMD_C0);
mmu_extruder = tmp_extruder; //filament change is finished
manage_response(true, true, MMU_TCODE_MOVE);
mmu_continue_loading();
mmu_extruder = tmp_extruder; //filament change is finished
if (load_to_nozzle)// for single material usage with mmu
{

View File

@ -43,8 +43,8 @@
#define W25X20CL_SPSR SPI_SPSR(W25X20CL_SPI_RATE)
//LANG - Multi-language support
#define LANG_MODE 0 // primary language only
//#define LANG_MODE 1 // sec. language support
//#define LANG_MODE 0 // primary language only
#define LANG_MODE 1 // sec. language support
#define LANG_SIZE_RESERVED 0x2f00 // reserved space for secondary language (12032 bytes)

View File

@ -148,6 +148,12 @@
#define EEPROM_FSENS_OQ_MEASS_ENABLED (EEPROM_AUTO_DEPLETE - 1) //bool
#define EEPROM_MMU_FAIL_TOT (EEPROM_FSENS_OQ_MEASS_ENABLED - 2) //uint16_t
#define EEPROM_MMU_FAIL (EEPROM_MMU_FAIL_TOT - 1) //uint8_t
#define EEPROM_MMU_LOAD_FAIL_TOT (EEPROM_MMU_FAIL - 2) //uint16_t
#define EEPROM_MMU_LOAD_FAIL (EEPROM_MMU_LOAD_FAIL_TOT - 1) //uint8_t
// !!!!!
// !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!!
// !!!!!

View File

@ -13,6 +13,7 @@
#include "sound.h"
#include "printers.h"
#include <avr/pgmspace.h>
#include "io_atmega2560.h"
#ifdef TMC2130
#include "tmc2130.h"
@ -22,25 +23,31 @@
#define MMU_TODELAY 100
#define MMU_TIMEOUT 10
#define MMU_CMD_TIMEOUT 300000ul //5min timeout for mmu commands (except P0)
#define MMU_CMD_TIMEOUT 45000ul //5min timeout for mmu commands (except P0)
#define MMU_P0_TIMEOUT 3000ul //timeout for P0 command: 3seconds
#define MMU_MAX_RESEND_ATTEMPTS 2
#ifdef MMU_HWRESET
#define MMU_RST_PIN 76
#endif //MMU_HWRESET
bool mmu_enabled = false;
bool mmu_ready = false;
bool mmu_fil_loaded = false; //if true: blocks execution of duplicit T-codes
static int8_t mmu_state = 0;
uint8_t mmu_cmd = 0;
uint8_t mmu_extruder = 0;
//idler ir sensor
uint8_t mmu_idl_sens = 0;
bool mmu_idler_sensor_detected = false;
bool mmu_loading_flag = false;
uint8_t mmu_extruder = MMU_FILAMENT_UNKNOWN;
//! This variable probably has no meaning and is planed to be removed
uint8_t tmp_extruder = 0;
uint8_t tmp_extruder = MMU_FILAMENT_UNKNOWN;
int8_t mmu_finda = -1;
@ -51,6 +58,9 @@ int16_t mmu_buildnr = -1;
uint32_t mmu_last_request = 0;
uint32_t mmu_last_response = 0;
uint8_t mmu_last_cmd = 0;
uint16_t mmu_power_failures = 0;
//clear rx buffer
void mmu_clr_rx_buf(void)
@ -106,11 +116,31 @@ void mmu_init(void)
_delay_ms(10); //wait 10ms for sure
mmu_reset(); //reset mmu (HW or SW), do not wait for response
mmu_state = -1;
PIN_INP(MMU_IDLER_SENSOR_PIN); //input mode
PIN_SET(MMU_IDLER_SENSOR_PIN); //pullup
}
//returns true if idler IR sensor was detected, otherwise returns false
bool check_for_idler_sensor()
{
bool detected = false;
//if MMU_IDLER_SENSOR_PIN input is low and pat9125sensor is not present we detected idler sensor
if ((PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) && fsensor_not_responding)
{
detected = true;
//printf_P(PSTR("Idler IR sensor detected\n"));
}
else
{
//printf_P(PSTR("Idler IR sensor not detected\n"));
}
return detected;
}
//mmu main loop - state machine processing
void mmu_loop(void)
{
static uint8_t mmu_attempt_nr = 0;
int filament = 0;
// printf_P(PSTR("MMU loop, state=%d\n"), mmu_state);
switch (mmu_state)
@ -158,9 +188,9 @@ void mmu_loop(void)
if ((PRINTER_TYPE == PRINTER_MK3) || (PRINTER_TYPE == PRINTER_MK3_SNMM))
{
#ifdef MMU_DEBUG
#if defined MMU_DEBUG && defined MMU_FINDA_DEBUG
puts_P(PSTR("MMU <= 'P0'"));
#endif //MMU_DEBUG
#endif //MMU_DEBUG && MMU_FINDA_DEBUG
mmu_puts_P(PSTR("P0\n")); //send 'read finda' request
mmu_state = -4;
}
@ -178,9 +208,9 @@ void mmu_loop(void)
case -5:
if (mmu_rx_ok() > 0)
{
#ifdef MMU_DEBUG
#if defined MMU_DEBUG && defined MMU_FINDA_DEBUG
puts_P(PSTR("MMU <= 'P0'"));
#endif //MMU_DEBUG
#endif //MMU_DEBUG && MMU_FINDA_DEBUG
mmu_puts_P(PSTR("P0\n")); //send 'read finda' request
mmu_state = -4;
}
@ -189,11 +219,13 @@ void mmu_loop(void)
if (mmu_rx_ok() > 0)
{
fscanf_P(uart2io, PSTR("%hhu"), &mmu_finda); //scan finda from buffer
#ifdef MMU_DEBUG
#if defined MMU_DEBUG && defined MMU_FINDA_DEBUG
printf_P(PSTR("MMU => '%dok'\n"), mmu_finda);
#endif //MMU_DEBUG
#endif //MMU_DEBUG && MMU_FINDA_DEBUG
puts_P(PSTR("MMU - ENABLED"));
mmu_enabled = true;
//if we have filament loaded into the nozzle, we can decide if printer has idler sensor right now; otherwise we will will wait till start of T-code so it will be detected on beginning of second T-code
if(check_for_idler_sensor()) mmu_idler_sensor_detected = true;
mmu_state = 1;
}
return;
@ -208,6 +240,8 @@ void mmu_loop(void)
#endif //MMU_DEBUG
mmu_printf_P(PSTR("T%d\n"), filament);
mmu_state = 3; // wait for response
mmu_fil_loaded = true;
if(mmu_idler_sensor_detected) mmu_idl_sens = 1; //if idler sensor detected, use it for T-code
}
else if ((mmu_cmd >= MMU_CMD_L0) && (mmu_cmd <= MMU_CMD_L4))
{
@ -225,6 +259,7 @@ void mmu_loop(void)
#endif //MMU_DEBUG
mmu_puts_P(PSTR("C0\n")); //send 'continue loading'
mmu_state = 3;
if(mmu_idler_sensor_detected) mmu_idl_sens = 1; //if idler sensor detected use it for C0 code
}
else if (mmu_cmd == MMU_CMD_U0)
{
@ -232,6 +267,7 @@ void mmu_loop(void)
printf_P(PSTR("MMU <= 'U0'\n"));
#endif //MMU_DEBUG
mmu_puts_P(PSTR("U0\n")); //send 'unload current filament'
mmu_fil_loaded = false;
mmu_state = 3;
}
else if ((mmu_cmd >= MMU_CMD_E0) && (mmu_cmd <= MMU_CMD_E4))
@ -241,6 +277,7 @@ void mmu_loop(void)
printf_P(PSTR("MMU <= 'E%d'\n"), filament);
#endif //MMU_DEBUG
mmu_printf_P(PSTR("E%d\n"), filament); //send eject filament
mmu_fil_loaded = false;
mmu_state = 3; // wait for response
}
else if (mmu_cmd == MMU_CMD_R0)
@ -251,13 +288,23 @@ void mmu_loop(void)
mmu_puts_P(PSTR("R0\n")); //send recover after eject
mmu_state = 3; // wait for response
}
else if (mmu_cmd == MMU_CMD_S3)
{
#ifdef MMU_DEBUG
printf_P(PSTR("MMU <= 'S3'\n"));
#endif //MMU_DEBUG
mmu_puts_P(PSTR("S3\n")); //send power failures request
mmu_state = 4; // power failures response
}
mmu_last_cmd = mmu_cmd;
mmu_cmd = 0;
}
else if ((mmu_last_response + 300) < millis()) //request every 300ms
{
#ifdef MMU_DEBUG
if(check_for_idler_sensor()) mmu_idler_sensor_detected = true;
#if defined MMU_DEBUG && defined MMU_FINDA_DEBUG
puts_P(PSTR("MMU <= 'P0'"));
#endif //MMU_DEBUG
#endif //MMU_DEBUG && MMU_FINDA_DEBUG
mmu_puts_P(PSTR("P0\n")); //send 'read finda' request
mmu_state = 2;
}
@ -266,9 +313,9 @@ void mmu_loop(void)
if (mmu_rx_ok() > 0)
{
fscanf_P(uart2io, PSTR("%hhu"), &mmu_finda); //scan finda from buffer
#ifdef MMU_DEBUG
#if defined MMU_DEBUG && MMU_FINDA_DEBUG
printf_P(PSTR("MMU => '%dok'\n"), mmu_finda);
#endif //MMU_DEBUG
#endif //MMU_DEBUG && MMU_FINDA_DEBUG
//printf_P(PSTR("Eact: %d\n"), int(e_active()));
if (!mmu_finda && CHECK_FINDA && fsensor_enabled) {
fsensor_stop_and_save_print();
@ -286,11 +333,59 @@ void mmu_loop(void)
}
return;
case 3: //response to mmu commands
if (mmu_idler_sensor_detected) {
if (mmu_idl_sens)
{
if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0 && mmu_loading_flag)
{
#ifdef MMU_DEBUG
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"));
}
}
if (mmu_rx_ok() > 0)
{
#ifdef MMU_DEBUG
printf_P(PSTR("MMU => 'ok'\n"));
#endif //MMU_DEBUG
mmu_attempt_nr = 0;
mmu_last_cmd = 0;
mmu_ready = true;
mmu_state = 1;
}
else if ((mmu_last_request + MMU_CMD_TIMEOUT) < millis())
{ //resend request after timeout (5 min)
if (mmu_last_cmd)
{
if (mmu_attempt_nr++ < MMU_MAX_RESEND_ATTEMPTS) {
#ifdef MMU_DEBUG
printf_P(PSTR("MMU retry attempt nr. %d\n"), mmu_attempt_nr - 1);
#endif //MMU_DEBUG
mmu_cmd = mmu_last_cmd;
}
else {
mmu_cmd = 0;
mmu_last_cmd = 0; //check
mmu_attempt_nr = 0;
}
}
mmu_state = 1;
}
return;
case 4:
if (mmu_rx_ok() > 0)
{
fscanf_P(uart2io, PSTR("%d"), &mmu_power_failures); //scan power failures
#ifdef MMU_DEBUG
printf_P(PSTR("MMU => 'ok'\n"));
#endif //MMU_DEBUG
mmu_last_cmd = 0;
mmu_ready = true;
mmu_state = 1;
}
@ -298,7 +393,6 @@ void mmu_loop(void)
{ //resend request after timeout (5 min)
mmu_state = 1;
}
return;
}
}
@ -338,22 +432,85 @@ void mmu_command(uint8_t cmd)
mmu_ready = false;
}
bool mmu_get_response(void)
void mmu_load_step() {
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();
}
bool mmu_get_response(uint8_t move)
{
// printf_P(PSTR("mmu_get_response - begin\n"));
mmu_loading_flag = false;
if (!mmu_idler_sensor_detected) move = MMU_NO_MOVE;
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)
if ((mmu_state != 3) && (mmu_last_cmd == 0))
break;
delay_keep_alive(100);
//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();
//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(MMU_IDLER_SENSOR_PIN) == 0) move = MMU_NO_MOVE;
break;
case MMU_UNLOAD_MOVE:
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"));
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
{
printf_P(PSTR("Unloading finished 1\n"));
disable_e0(); //turn off E-stepper to prevent overheating and alow filament pull-out if necessary
move = MMU_NO_MOVE;
}
break;
case MMU_TCODE_MOVE: //first do unload and then continue with infinite loading movements
if (PIN_GET(MMU_IDLER_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();
}
else //delay to allow mmu unit to pull out filament from bondtech gears and then start with infinite loading
{
printf_P(PSTR("Unloading finished 2\n"));
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;
}
break;
case MMU_NO_MOVE:
default:
delay_keep_alive(100);
break;
}
}
printf_P(PSTR("mmu_get_response() returning: %d\n"), mmu_ready);
bool ret = mmu_ready;
mmu_ready = false;
// printf_P(PSTR("mmu_get_response - end %d\n"), ret?1:0);
@ -380,7 +537,7 @@ bool mmu_get_response(void)
}
void manage_response(bool move_axes, bool turn_off_nozzle)
void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move)
{
bool response = false;
mmu_print_saved = false;
@ -390,11 +547,18 @@ void manage_response(bool move_axes, bool turn_off_nozzle)
float x_position_bckp = current_position[X_AXIS];
float y_position_bckp = current_position[Y_AXIS];
uint8_t screen = 0; //used for showing multiscreen messages
while(!response)
{
response = mmu_get_response(); //wait for "ok" from mmu
response = mmu_get_response(move); //wait for "ok" from mmu
if (!response) { //no "ok" was received in reserved time frame, user will fix the issue on mmu unit
if (!mmu_print_saved) { //first occurence, we are saving current position, park print head in certain position and disable nozzle heater
uint8_t mmu_fail = eeprom_read_byte((uint8_t*)EEPROM_MMU_FAIL);
uint16_t mmu_fail_tot = eeprom_read_word((uint16_t*)EEPROM_MMU_FAIL_TOT);
if(mmu_fail < 255) eeprom_update_byte((uint8_t*)EEPROM_MMU_FAIL, mmu_fail + 1);
if(mmu_fail_tot < 65535) eeprom_update_word((uint16_t*)EEPROM_MMU_FAIL_TOT, mmu_fail_tot + 1);
if (lcd_update_enabled) {
lcd_update_was_enabled = true;
lcd_update_enable(false);
@ -424,6 +588,7 @@ void manage_response(bool move_axes, bool turn_off_nozzle)
//set nozzle target temperature to 0
setAllTargetHotends(0);
}
disable_e0(); //turn off E-stepper to prevent overheating and alow filament pull-out if necessary
}
//first three lines are used for printing multiscreen message; last line contains measured and target nozzle temperature
@ -438,19 +603,21 @@ void manage_response(bool move_axes, bool turn_off_nozzle)
}
lcd_set_degree();
lcd_set_cursor(0, 4); //line 4
//Print the hotend temperature (9 chars total) and fill rest of the line with space
int chars = lcd_printf_P(_N("%c%3d/%d%c"), LCD_STR_THERMOMETER[0],(int)(degHotend(active_extruder) + 0.5), (int)(degTargetHotend(active_extruder) + 0.5), LCD_STR_DEGREE[0]);
lcd_space(9 - chars);
//5 seconds delay
for (uint8_t i = 0; i < 50; i++) {
for (uint8_t i = 0; i < 5; i++) {
if (lcd_clicked()) {
setTargetHotend(hotend_temp_bckp, active_extruder);
/// mmu_cmd = mmu_last_cmd;
break;
}
delay_keep_alive(100);
}
//Print the hotend temperature (9 chars total) and fill rest of the line with space
lcd_set_cursor(0, 4); //line 4
int chars = lcd_printf_P(_N("%c%3d/%d%c"), LCD_STR_THERMOMETER[0],(int)(degHotend(active_extruder) + 0.5), (int)(degTargetHotend(active_extruder) + 0.5), LCD_STR_DEGREE[0]);
lcd_space(9 - chars);
delay_keep_alive(1000);
}
}
else if (mmu_print_saved) {
@ -507,7 +674,14 @@ void mmu_load_to_nozzle()
bool saved_e_relative_mode = axis_relative_modes[E_AXIS];
if (!saved_e_relative_mode) axis_relative_modes[E_AXIS] = true;
current_position[E_AXIS] += 7.2f;
if (mmu_idler_sensor_detected)
{
current_position[E_AXIS] += 3.0f;
}
else
{
current_position[E_AXIS] += 7.2f;
}
float feedrate = 562;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate / 60, active_extruder);
st_synchronize();
@ -587,9 +761,10 @@ void mmu_M600_load_filament(bool automatic)
// mmu_printf_P(PSTR("T%d\n"), tmp_extruder);
mmu_command(MMU_CMD_T0 + tmp_extruder);
manage_response(false, true);
mmu_command(MMU_CMD_C0);
manage_response(false, true, MMU_LOAD_MOVE);
mmu_continue_loading();
mmu_extruder = tmp_extruder; //filament change is finished
mmu_load_to_nozzle();
load_filament_final_feed();
st_synchronize();
@ -791,13 +966,14 @@ void extr_unload()
lcd_clear();
lcd_set_cursor(0, 1); lcd_puts_P(_T(MSG_UNLOADING_FILAMENT));
lcd_print(" ");
lcd_print(mmu_extruder + 1);
if (mmu_extruder == MMU_FILAMENT_UNKNOWN) lcd_print(" ");
else lcd_print(mmu_extruder + 1);
filament_ramming();
mmu_command(MMU_CMD_U0);
// get response
manage_response(false, true);
manage_response(false, true, MMU_UNLOAD_MOVE);
lcd_update_enable(true);
#else //SNMM
@ -1093,8 +1269,8 @@ void lcd_mmu_load_to_nozzle(uint8_t filament_nr)
lcd_print(" ");
lcd_print(tmp_extruder + 1);
mmu_command(MMU_CMD_T0 + tmp_extruder);
manage_response(true, true);
mmu_command(MMU_CMD_C0);
manage_response(true, true, MMU_TCODE_MOVE);
mmu_continue_loading();
mmu_extruder = tmp_extruder; //filament change is finished
mmu_load_to_nozzle();
load_filament_final_feed();
@ -1130,7 +1306,7 @@ void mmu_eject_filament(uint8_t filament, bool recover)
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 2500 / 60, active_extruder);
st_synchronize();
mmu_command(MMU_CMD_E0 + filament);
manage_response(false, false);
manage_response(false, false, MMU_UNLOAD_MOVE);
if (recover)
{
lcd_show_fullscreen_message_and_wait_P(_i("Please remove filament and then press the knob."));
@ -1150,3 +1326,46 @@ void mmu_eject_filament(uint8_t filament, bool recover)
puts_P(PSTR("Filament nr out of range!"));
}
}
void mmu_continue_loading()
{
if (mmu_idler_sensor_detected) {
for (uint8_t i = 0; i < MMU_IDLER_SENSOR_ATTEMPTS_NR; i++) {
if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) return;
#ifdef MMU_DEBUG
printf_P(PSTR("Additional load attempt nr. %d\n"), i);
#endif // MMU_DEBUG
mmu_command(MMU_CMD_C0);
manage_response(true, true, MMU_LOAD_MOVE);
}
if (PIN_GET(MMU_IDLER_SENSOR_PIN) != 0) {
uint8_t mmu_load_fail = eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL);
uint16_t mmu_load_fail_tot = eeprom_read_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT);
if(mmu_load_fail < 255) eeprom_update_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL, mmu_load_fail + 1);
if(mmu_load_fail_tot < 65535) eeprom_update_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT, mmu_load_fail_tot + 1);
char cmd[3];
//pause print, show error message and then repeat last T-code
stop_and_save_print_to_ram(0, 0);
//lift z
current_position[Z_AXIS] += Z_PAUSE_LIFT;
if (current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 15, active_extruder);
st_synchronize();
//Move XY to side
current_position[X_AXIS] = X_PAUSE_POS;
current_position[Y_AXIS] = Y_PAUSE_POS;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 50, active_extruder);
st_synchronize();
//set nozzle target temperature to 0
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
}
}
else { //mmu_idler_sensor_detected == false
mmu_command(MMU_CMD_C0);
}
}

View File

@ -4,16 +4,30 @@
extern bool mmu_enabled;
extern bool mmu_fil_loaded;
extern uint8_t mmu_extruder;
extern uint8_t tmp_extruder;
extern int8_t mmu_finda;
extern bool mmu_idler_sensor_detected;
extern bool mmu_loading_flag;
extern int16_t mmu_version;
extern int16_t mmu_buildnr;
extern uint16_t mmu_power_failures;
#define MMU_FILAMENT_UNKNOWN 255
#define MMU_NO_MOVE 0
#define MMU_UNLOAD_MOVE 1
#define MMU_LOAD_MOVE 2
#define MMU_TCODE_MOVE 3
#define MMU_LOAD_FEEDRATE 19.02f //mm/s
#define MMU_LOAD_TIME_MS 2000 //should be fine tuned to load time for shortest allowed PTFE tubing and maximum loading speed
#define MMU_CMD_NONE 0
#define MMU_CMD_T0 0x10
@ -34,7 +48,7 @@ extern int16_t mmu_buildnr;
#define MMU_CMD_E3 0x53
#define MMU_CMD_E4 0x54
#define MMU_CMD_R0 0x60
#define MMU_CMD_S3 0x73
extern int mmu_puts_P(const char* str);
@ -42,6 +56,7 @@ extern int mmu_printf_P(const char* format, ...);
extern int8_t mmu_rx_ok(void);
extern bool check_for_idler_sensor();
extern void mmu_init(void);
@ -54,9 +69,9 @@ extern int8_t mmu_set_filament_type(uint8_t extruder, uint8_t filament);
extern void mmu_command(uint8_t cmd);
extern bool mmu_get_response(void);
extern bool mmu_get_response(uint8_t move = 0);
extern void manage_response(bool move_axes, bool turn_off_nozzle);
extern void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move = 0);
extern void mmu_load_to_nozzle();
@ -103,3 +118,4 @@ extern void mmu_eject_fil_1();
extern void mmu_eject_fil_2();
extern void mmu_eject_fil_3();
extern void mmu_eject_fil_4();
extern void mmu_continue_loading();

View File

@ -118,6 +118,7 @@
#define TACH_0 79 // !!! changed from 81 (EINY03)
#define TACH_1 80
#define MMU_IDLER_SENSOR_PIN 62 //idler sensor @PK0 (digital pin 62/A8)
// Support for an 8 bit logic analyzer, for example the Saleae.
// Channels 0-2 are fast, they could generate 2.667Mhz waveform with a software loop.

View File

@ -102,7 +102,7 @@
#define SDCARDDETECT 72
#define MMU_IDLER_SENSOR_PIN 62 //idler sensor @PK0 (digital pin 62/A8)
// Support for an 8 bit logic analyzer, for example the Saleae.
// Channels 0-2 are fast, they could generate 2.667Mhz waveform with a software loop.

View File

@ -102,7 +102,7 @@
#define SDCARDDETECT 15
#define MMU_IDLER_SENSOR_PIN 62 //idler sensor @PK0 (digital pin 62/A8)
// Support for an 8 bit logic analyzer, for example the Saleae.
// Channels 0-2 are fast, they could generate 2.667Mhz waveform with a software loop.

View File

@ -38,7 +38,7 @@
#include "mmu.h"
#include "static_assert.h"
#include "io_atmega2560.h"
extern bool fans_check_enabled;
@ -136,6 +136,11 @@ static void lcd_menu_extruder_info();
static void lcd_menu_xyz_y_min();
static void lcd_menu_xyz_skew();
static void lcd_menu_xyz_offset();
static void lcd_menu_fails_stats_mmu();
static void lcd_menu_fails_stats_mmu_print();
static void lcd_menu_fails_stats_mmu_total();
static void lcd_menu_show_sensors_state();
#if defined(TMC2130) || defined(FILAMENT_SENSOR)
static void lcd_menu_fails_stats();
#endif //TMC2130 or FILAMENT_SENSOR
@ -195,6 +200,9 @@ static void menu_action_sddirectory(const char* filename);
#define ENCODER_FEEDRATE_DEADZONE 10
#define STATE_NA 255
#define STATE_OFF 0
#define STATE_ON 1
/*
#define MENU_ITEM(type, label, args...) do { \
@ -537,10 +545,15 @@ void lcdui_print_percent_done(void)
void lcdui_print_extruder(void)
{
int chars = 0;
if (mmu_extruder == tmp_extruder)
chars = lcd_printf_P(_N(" F%u"), mmu_extruder+1);
if (mmu_extruder == tmp_extruder) {
if (mmu_extruder == MMU_FILAMENT_UNKNOWN) chars = lcd_printf_P(_N(" F?"));
else chars = lcd_printf_P(_N(" F%u"), mmu_extruder + 1);
}
else
chars = lcd_printf_P(_N(" %u>%u"), mmu_extruder+1, tmp_extruder+1);
{
if (mmu_extruder == MMU_FILAMENT_UNKNOWN) chars = lcd_printf_P(_N(" ?>%u"), tmp_extruder + 1);
else chars = lcd_printf_P(_N(" %u>%u"), mmu_extruder + 1, tmp_extruder + 1);
}
lcd_space(5 - chars);
}
@ -1914,6 +1927,48 @@ static void lcd_menu_extruder_info()
menu_back_if_clicked();
}
static void lcd_menu_fails_stats_mmu()
{
MENU_BEGIN();
MENU_ITEM_BACK_P(_T(MSG_MAIN));
MENU_ITEM_SUBMENU_P(_i("Last print"), lcd_menu_fails_stats_mmu_print);
MENU_ITEM_SUBMENU_P(_i("Total"), lcd_menu_fails_stats_mmu_total);
MENU_END();
}
static void lcd_menu_fails_stats_mmu_print()
{
//01234567890123456789
//Last print failures
// MMU fails 000
// MMU load fails 000
//
//////////////////////
lcd_timeoutToStatus.stop(); //infinite timeout
uint8_t fails = eeprom_read_byte((uint8_t*)EEPROM_MMU_FAIL);
uint16_t load_fails = eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL);
// lcd_printf_P(PSTR(ESC_H(0,0) "Last print failures" ESC_H(1,1) "Power failures %-3d" ESC_H(1,2) "Filam. runouts %-3d" ESC_H(1,3) "Crash X %-3d Y %-3d"), power, filam, crashX, crashY);
lcd_printf_P(PSTR(ESC_H(0,0) "%S" ESC_H(1,1) "%S %-3d" ESC_H(1,2) "%S %-3d" ESC_H(1,3)), _i("Last print failures"), _i("MMU fails"), fails, _i("MMU load fails"), load_fails);
menu_back_if_clicked_fb();
}
static void lcd_menu_fails_stats_mmu_total()
{
//01234567890123456789
//Last print failures
// MMU fails 000
// MMU load fails 000
//
//////////////////////
mmu_command(MMU_CMD_S3);
lcd_timeoutToStatus.stop(); //infinite timeout
uint8_t fails = eeprom_read_byte((uint8_t*)EEPROM_MMU_FAIL_TOT);
uint16_t load_fails = eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL_TOT);
// lcd_printf_P(PSTR(ESC_H(0,0) "Last print failures" ESC_H(1,1) "Power failures %-3d" ESC_H(1,2) "Filam. runouts %-3d" ESC_H(1,3) "Crash X %-3d Y %-3d"), power, filam, crashX, crashY);
lcd_printf_P(PSTR(ESC_H(0,0) "%S" ESC_H(1,1) "%S %-3d" ESC_H(1,2) "%S %-3d" ESC_H(1,3) "%S %-3d"), _i("Total failures"), _i("MMU fails"), fails, _i("MMU load fails"), load_fails, _i("MMU power fails"), mmu_power_failures);
menu_back_if_clicked_fb();
}
#if defined(TMC2130) && defined(FILAMENT_SENSOR)
static void lcd_menu_fails_stats_total()
{
@ -1950,6 +2005,7 @@ static void lcd_menu_fails_stats_print()
lcd_printf_P(PSTR(ESC_H(0,0) "%S" ESC_H(1,1) "%S %-3d" ESC_H(1,2) "%S %-3d" ESC_H(1,3) "%S X %-3d Y %-3d"), _i("Last print failures"), _i("Power failures"), power, _i("Filam. runouts"), filam, _i("Crash"), crashX, crashY);
menu_back_if_clicked_fb();
}
/**
* @brief Open fail statistics menu
*
@ -1965,6 +2021,7 @@ static void lcd_menu_fails_stats()
MENU_ITEM_SUBMENU_P(_i("Total"), lcd_menu_fails_stats_total);
MENU_END();
}
#elif defined(FILAMENT_SENSOR)
/**
* @brief Print last print and total filament run outs
@ -2180,16 +2237,17 @@ static void lcd_support_menu()
#ifndef MK1BP
MENU_ITEM_BACK_P(STR_SEPARATOR);
MENU_ITEM_SUBMENU_P(_i("XYZ cal. details"), lcd_menu_xyz_y_min);////MSG_XYZ_DETAILS c=19 r=1
MENU_ITEM_SUBMENU_P(_i("Extruder info"), lcd_menu_extruder_info);////MSG_INFO_EXTRUDER c=15 r=1
MENU_ITEM_SUBMENU_P(_i("Extruder info"), lcd_menu_extruder_info);////MSG_INFO_EXTRUDER c=18 r=1
MENU_ITEM_SUBMENU_P(_i("Show sensors"), lcd_menu_show_sensors_state);////MSG_INFO_SENSORS c=18 r=1
#ifdef TMC2130
MENU_ITEM_SUBMENU_P(_i("Belt status"), lcd_menu_belt_status);////MSG_MENU_BELT_STATUS c=15 r=1
MENU_ITEM_SUBMENU_P(_i("Belt status"), lcd_menu_belt_status);////MSG_MENU_BELT_STATUS c=18 r=1
#endif //TMC2130
MENU_ITEM_SUBMENU_P(_i("Temperatures"), lcd_menu_temperatures);////MSG_MENU_TEMPERATURES c=15 r=1
MENU_ITEM_SUBMENU_P(_i("Temperatures"), lcd_menu_temperatures);////MSG_MENU_TEMPERATURES c=18 r=1
#if defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN)
MENU_ITEM_SUBMENU_P(_i("Voltages"), lcd_menu_voltages);////MSG_MENU_VOLTAGES c=15 r=1
MENU_ITEM_SUBMENU_P(_i("Voltages"), lcd_menu_voltages);////MSG_MENU_VOLTAGES c=18 r=1
#endif //defined VOLT_BED_PIN || defined VOLT_PWR_PIN
#ifdef DEBUG_BUILD
@ -2351,7 +2409,7 @@ void lcd_alright() {
enc_dif = lcd_encoder_diff;
lcd_consume_click();
while (lcd_change_fil_state == 0) {
manage_heater();
@ -3239,6 +3297,7 @@ void lcd_show_fullscreen_message_and_wait_P(const char *msg)
const char *msg_next = lcd_display_message_fullscreen_P(msg);
bool multi_screen = msg_next != NULL;
lcd_set_custom_characters_nextpage();
lcd_consume_click();
KEEPALIVE_STATE(PAUSED_FOR_USER);
// Until confirmed by a button click.
for (;;) {
@ -3283,7 +3342,7 @@ bool lcd_wait_for_click_delay(uint16_t nDelay)
{
bool bDelayed;
long nTime0 = millis()/1000;
lcd_consume_click();
KEEPALIVE_STATE(PAUSED_FOR_USER);
for (;;) {
manage_heater();
@ -3332,6 +3391,7 @@ int8_t lcd_show_multiscreen_message_two_choices_and_wait_P(const char *msg, bool
// Wait for user confirmation or a timeout.
unsigned long previous_millis_cmd = millis();
int8_t enc_dif = lcd_encoder_diff;
lcd_consume_click();
//KEEPALIVE_STATE(PAUSED_FOR_USER);
for (;;) {
for (uint8_t i = 0; i < 100; ++i) {
@ -3421,6 +3481,7 @@ int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, bool allow
// Wait for user confirmation or a timeout.
unsigned long previous_millis_cmd = millis();
int8_t enc_dif = lcd_encoder_diff;
lcd_consume_click();
KEEPALIVE_STATE(PAUSED_FOR_USER);
for (;;) {
if (allow_timeouting && millis() - previous_millis_cmd > LCD_TIMEOUT_TO_STATUS)
@ -3555,6 +3616,7 @@ static void menu_show_end_stops() {
void lcd_diag_show_end_stops()
{
lcd_clear();
lcd_consume_click();
for (;;) {
manage_heater();
manage_inactivity(true);
@ -3567,28 +3629,60 @@ void lcd_diag_show_end_stops()
lcd_return_to_status();
}
#ifdef TMC2130
static void lcd_show_pinda_state()
static void lcd_print_state(uint8_t state)
{
lcd_set_cursor(0, 0);
lcd_puts_P((PSTR("P.I.N.D.A. state")));
lcd_set_cursor(0, 2);
lcd_puts_P(READ(Z_MIN_PIN)?(PSTR("Z1 (LED off)")):(PSTR("Z0 (LED on) "))); // !!! both strings must have same length (due to dynamic refreshing)
switch (state) {
case STATE_ON:
lcd_puts_P(_i("On "));
break;
case STATE_OFF:
lcd_puts_P(_i("Off"));
break;
default:
lcd_puts_P(_i("N/A"));
break;
}
}
static void menu_show_pinda_state()
static void lcd_show_sensors_state()
{
lcd_timeoutToStatus.stop();
lcd_show_pinda_state();
if(LCD_CLICKED)
{
lcd_timeoutToStatus.start();
menu_back();
}
//0: N/A; 1: OFF; 2: ON
uint8_t chars = 0;
uint8_t pinda_state = STATE_NA;
uint8_t finda_state = STATE_NA;
uint8_t idler_state = STATE_NA;
pinda_state = READ(Z_MIN_PIN);
if (mmu_enabled) {
finda_state = mmu_finda;
}
if (mmu_idler_sensor_detected) {
idler_state = !PIN_GET(MMU_IDLER_SENSOR_PIN);
}
lcd_puts_at_P(0, 0, _i("Sensor state"));
lcd_puts_at_P(1, 1, _i("PINDA:"));
lcd_set_cursor(LCD_WIDTH - 4, 1);
lcd_print_state(pinda_state);
lcd_puts_at_P(1, 2, _i("FINDA:"));
lcd_set_cursor(LCD_WIDTH - 4, 2);
lcd_print_state(finda_state);
lcd_puts_at_P(1, 3, _i("IR:"));
lcd_set_cursor(LCD_WIDTH - 4, 3);
lcd_print_state(idler_state);
}
#endif // defined TMC2130
static void lcd_menu_show_sensors_state()
{
lcd_timeoutToStatus.stop();
lcd_show_sensors_state();
if(LCD_CLICKED)
{
lcd_timeoutToStatus.start();
menu_back();
}
}
void prusa_statistics(int _message, uint8_t _fil_nr) {
#ifdef DEBUG_DISABLE_PRUSA_STATISTICS
@ -4313,6 +4407,7 @@ void lcd_v2_calibration()
}
else {
lcd_display_message_fullscreen_P(_i("Please load PLA filament first."));////MSG_PLEASE_LOAD_PLA c=20 r=4
lcd_consume_click();
for (int i = 0; i < 20; i++) { //wait max. 2s
delay_keep_alive(100);
if (lcd_clicked()) {
@ -4944,9 +5039,7 @@ static void lcd_calibration_menu()
MENU_ITEM_SUBMENU_P(_i("Bed level correct"), lcd_adjust_bed);////MSG_BED_CORRECTION_MENU c=0 r=0
MENU_ITEM_SUBMENU_P(_i("PID calibration"), pid_extruder);////MSG_PID_EXTRUDER c=17 r=1
#ifdef TMC2130
MENU_ITEM_SUBMENU_P(_i("Show pinda state"), menu_show_pinda_state);
#else
#ifndef TMC2130
MENU_ITEM_SUBMENU_P(_i("Show end stops"), menu_show_end_stops);////MSG_SHOW_END_STOPS c=17 r=1
#endif
#ifndef MK1BP
@ -4979,7 +5072,7 @@ void bowden_menu() {
}
enc_dif = lcd_encoder_diff;
lcd_consume_click();
while (1) {
manage_heater();
@ -5086,6 +5179,7 @@ static char snmm_stop_print_menu() { //menu for choosing which filaments will be
char cursor_pos = 1;
int enc_dif = 0;
KEEPALIVE_STATE(PAUSED_FOR_USER);
lcd_consume_click();
while (1) {
manage_heater();
manage_inactivity(true);
@ -5241,7 +5335,7 @@ char reset_menu() {
lcd_clear();
lcd_set_cursor(0, 0);
lcd_print(">");
lcd_consume_click();
while (1) {
for (int i = 0; i < 4; i++) {
@ -5517,7 +5611,7 @@ unsigned char lcd_choose_color() {
lcd_print(">");
active_rows = items_no < 3 ? items_no : 3;
lcd_consume_click();
while (1) {
lcd_puts_at_P(0, 0, PSTR("Choose color:"));
for (int i = 0; i < active_rows; i++) {
@ -5852,7 +5946,9 @@ static void lcd_main_menu()
#if defined(TMC2130) || defined(FILAMENT_SENSOR)
MENU_ITEM_SUBMENU_P(_i("Fail stats"), lcd_menu_fails_stats);
#endif
if (mmu_enabled) {
MENU_ITEM_SUBMENU_P(_i("Fail stats MMU"), lcd_menu_fails_stats_mmu);
}
MENU_ITEM_SUBMENU_P(_i("Support"), lcd_support_menu);////MSG_SUPPORT c=0 r=0
#ifdef LCD_TEST
MENU_ITEM_SUBMENU_P(_i("W25x20CL init"), lcd_test_menu);////MSG_SUPPORT c=0 r=0
@ -6052,6 +6148,7 @@ static void lcd_sd_updir()
void lcd_print_stop()
{
saved_printing = false;
cancel_heatup = true;
#ifdef MESH_BED_LEVELING
mbl.active = false;
@ -6085,7 +6182,7 @@ void lcd_print_stop()
void lcd_sdcard_stop()
{
lcd_set_cursor(0, 0);
lcd_puts_P(_T(MSG_STOP_PRINT));
lcd_set_cursor(2, 2);

View File

@ -432,4 +432,6 @@ THERMISTORS SETTINGS
//#define SUPPORT_VERBOSITY
#endif
#define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
#endif //__CONFIGURATION_PRUSA_H

View File

@ -432,4 +432,6 @@ THERMISTORS SETTINGS
//#define SUPPORT_VERBOSITY
#endif
#define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
#endif //__CONFIGURATION_PRUSA_H

View File

@ -487,4 +487,6 @@
#define MMU_REQUIRED_FW_BUILDNR 132
//#define MMU_DEBUG //print communication between MMU2 and printer on serial
#define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
#endif //__CONFIGURATION_PRUSA_H

View File

@ -488,4 +488,6 @@
#define MMU_REQUIRED_FW_BUILDNR 132
//#define MMU_DEBUG //print communication between MMU2 and printer on serial
#define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
#endif //__CONFIGURATION_PRUSA_H

View File

@ -614,6 +614,8 @@
#define MMU_REQUIRED_FW_BUILDNR 83
#define MMU_HWRESET
//#define MMU_DEBUG //print communication between MMU2 and printer on serial
#define MMU_DEBUG //print communication between MMU2 and printer on serial
#define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
#endif //__CONFIGURATION_PRUSA_H

View File

@ -1,15 +1,24 @@
# Table of contents
<!--ts-->
* [Development environment preparation](#1-development-environment-preparation)
* [Source code compilation](#2-source-code-compilation)
* [Linux build](#linux)
* [Windows build](#windows)
* [Automated tests](#3-automated-tests)
* [Documentation](#4-documentation)
<!--te-->
# 1. Development environment preparation
1. install `"Arduino Software IDE"` for your preferred operating system
# Build
## Linux
Run shell script build.sh to build for MK3 and flash with Sli3er.
If you have different printel model, follow step [2.b](#2b) from Windows build first.
If you wish to flash from Arduino, follow step [2.c](#2c) from Windows build first.
The script downloads Arduino with our modifications and Rambo board support installed, unpacks it into folder PF-build-env-\<version\> on the same level, as your Prusa-Firmware folder is located, builds firmware for MK3 using that Arduino in Prusa-Firmware-build folder on the same level as Prusa-Firmware, runs secondary language support scripts. Firmware with secondary language support is generated in lang subfolder. Use firmware.hex for MK3 variant. Use firmware_\<lang\>.hex for other printers. Don't forget to follow step [2.b](#2b) first for non-MK3 printers.
## Windows
### 1. Development environment preparation
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.
_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
@ -17,7 +26,7 @@ _note: in the case of persistent compilation problems, check the version of the
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_
_note: name collision for `"LiquidCrystal"` library known from previous versions is now obsolete (so there is no need to delete or rename original file/-s)_
2. add (`UltiMachine`) `RAMBo` board into the list of Arduino target boards
b. add (`UltiMachine`) `RAMBo` board into the list of Arduino target boards
`File->Preferences->Settings`
into text field `"Additional Boards Manager URLs"`
type location
@ -34,16 +43,19 @@ _note: select this item for any variant of board used in printers `'Prusa i3 MKx
'clicking' the item will display the installation button; select choice `"1.0.1"` from the list(last known version as of the date of issue of this document)
_(after installation, the item is labeled as `"INSTALLED"` and can then be used for target board selection)_
3. modify platform.txt to enable float printf support:
c. modify platform.txt to enable float printf support:
add "-Wl,-u,vfprintf -lprintf_flt -lm" to "compiler.c.elf.flags=" before existing flag "-Wl,--gc-sections"
example:
`"compiler.c.elf.flags=-w -Os -Wl,-u,vfprintf -lprintf_flt -lm -Wl,--gc-sections"`
# 2. Source code compilation
### 2. Source code compilation
place the source codes corresponding to your printer model obtained from the repository into the selected directory on your disk
a. place the source codes corresponding to your printer model obtained from the repository into the selected directory on your disk
`https://github.com/prusa3d/Prusa-Firmware/`
in the subdirectory `"Firmware/variants/"` select the configuration file (`.h`) corresponding to your printer model, make copy named `"Configuration_prusa.h"` (or make simple renaming) and copy them into `"Firmware/"` directory
b.<a name="2b"></a> In the subdirectory `"Firmware/variants/"` select the configuration file (`.h`) corresponding to your printer model, make copy named `"Configuration_prusa.h"` (or make simple renaming) and copy it into `"Firmware/"` directory.
c.<a name="2c"></a> In file `"Firmware/config.h"` set LANG_MODE to 0.
run `"Arduino IDE"`; select the file `"Firmware.ino"` from the subdirectory `"Firmware/"` at the location, where you placed the source codes
`File->Open`

40
build.sh Executable file
View File

@ -0,0 +1,40 @@
#!/bin/bash
BUILD_ENV="1.0.1"
SCRIPT_PATH="$( cd "$(dirname "$0")" ; pwd -P )"
if [ ! -d "build-env" ]; then
mkdir build-env || exit 1
fi
cd build-env || exit 2
if [ ! -f "PF-build-env-Linux64-$BUILD_ENV.zip" ]; then
wget https://github.com/mkbel/PF-build-env/releases/download/$BUILD_ENV/PF-build-env-Linux64-$BUILD_ENV.zip || exit 3
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
fi
cd ../../PF-build-env-$BUILD_ENV || exit 5
BUILD_ENV_PATH="$( pwd -P )"
cd ..
if [ ! -d "Prusa-Firmware-build" ]; then
mkdir Prusa-Firmware-build || exit 6
fi
cd Prusa-Firmware-build || exit 7
BUILD_PATH="$( pwd -P )"
if [ ! -f "$SCRIPT_PATH/Firmware/Configuration_prusa.h" ]; then
cp $SCRIPT_PATH/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h $SCRIPT_PATH/Firmware/Configuration_prusa.h || exit 8
fi
$BUILD_ENV_PATH/arduino $SCRIPT_PATH/Firmware/Firmware.ino --verify --board rambo:avr:rambo --pref build.path=$BUILD_PATH || exit 9
export ARDUINO=$BUILD_ENV_PATH
cd $SCRIPT_PATH/lang
./lang-build.sh || exit 10
./fw-build.sh || exit 11

View File

@ -5,17 +5,19 @@
# This file is 'included' in all scripts.
#
# Arduino main folder:
export ARDUINO=C:/arduino-1.8.5
if [ -z "$ARDUINO" ]; then
export ARDUINO=C:/arduino-1.8.5
fi
#
# Arduino builder:
export BUILDER=$ARDUINO/arduino_debug.exe
export BUILDER=$ARDUINO/arduino-builder
#
# AVR gcc tools:
export OBJCOPY=$ARDUINO/hardware/tools/avr/bin/avr-objcopy.exe
export OBJDUMP=$ARDUINO/hardware/tools/avr/bin/avr-objdump.exe
export OBJCOPY=$ARDUINO/hardware/tools/avr/bin/avr-objcopy
export OBJDUMP=$ARDUINO/hardware/tools/avr/bin/avr-objdump
#
# Output folder:
export OUTDIR="../../output"
export OUTDIR="../../Prusa-Firmware-build"
#
# Objects folder:
export OBJDIR="$OUTDIR/sketch"

0
lang/fw-build.sh Normal file → Executable file
View File

0
lang/lang-build.sh Normal file → Executable file
View File

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

0
lang/progmem.sh Normal file → Executable file
View File

0
lang/textaddr.sh Normal file → Executable file
View File

0
lang/update_lang.sh Normal file → Executable file
View File

12
test.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
cd .. || exit 5
if [ ! -d "Prusa-Firmware-test" ]; then
mkdir Prusa-Firmware-test || exit 10
fi
cd Prusa-Firmware-test || exit 20
cmake -G "Eclipse CDT4 - Ninja" ../Prusa-Firmware || exit 30
cmake --build . || exit 35
./tests || exit 40