Commit 4756724e authored by MagoKimbra's avatar MagoKimbra

Merge branch 'pr/39' into Development

parents b0d0aa70 eb511f3b
......@@ -20,7 +20,7 @@
// User-specified version info of this build to display in [Pronterface, etc] terminal window during
// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this
// build by the user have been successfully uploaded into firmware.
#define STRING_VERSION " 4.0.9"
#define STRING_VERSION " 4.1.1"
#define STRING_URL "reprap.org"
#define STRING_VERSION_CONFIG_H __DATE__ " " __TIME__ // build date and time
#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes.
......@@ -147,7 +147,7 @@
// 10 is 100k RS thermistor 198-961 (4.7k pullup)
// 11 is 100k beta 3950 1% thermistor (4.7k pullup)
// 12 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed)
// 13 is 100k Hisens 3950 1% up to 300C for hotend "Simple ONE " & "Hotend "All In ONE"
// 13 is 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE"
// 20 is the PT100 circuit found in the Ultimainboard V2.x
// 60 is 100k Maker's Tool Works Kapton Bed Thermistor beta=3950
//
......@@ -161,7 +161,7 @@
// 1010 is Pt1000 with 1k pullup (non standard)
// 147 is Pt100 with 4k7 pullup
// 110 is Pt100 with 1k pullup (non standard)
// 998 and 999 are Dummy Tables. They will ALWAYS read 25C or the temperature defined below.
// 998 and 999 are Dummy Tables. They will ALWAYS read 25°C or the temperature defined below.
// Use it for Testing or Development purposes. NEVER for production machine.
// #define DUMMY_THERMISTOR_998_VALUE 25
// #define DUMMY_THERMISTOR_999_VALUE 100
......@@ -228,9 +228,9 @@
#define K1 0.95 // Smoothing factor within the PID
// HotEnd{HE0,HE1,HE2,HE3}
#define DEFAULT_Kp {41,41,41,41} // Kp for E0, E1, E2, E3
#define DEFAULT_Kp {40,40,40,40} // Kp for E0, E1, E2, E3
#define DEFAULT_Ki {07,07,07,07} // Ki for E0, E1, E2, E3
#define DEFAULT_Kd {59,59,59,59} // Kd for E0, E1, E2, E3
#define DEFAULT_Kd {60,60,60,60} // Kd for E0, E1, E2, E3
#endif // PIDTEMP
......@@ -460,6 +460,14 @@ your extruder heater takes 2 minutes to hit the target on heating.
// please keep turned on if you can.
//#define DISABLE_M503
//=================================== EXTRA SETTINGS ON SD ================================
// Uncomment SD_SETTINGS to enable the firmware to write some configuration, that require frequent update, on the SD card.
#define SD_SETTINGS
#define SD_CFG_SECONDS 10 //seconds between update
#define CFG_SD_FILE "config.cfg" //name of the configuration file
#define CFG_SD_MAX_KEY_LEN 3+1 //icrease this if you add key name longer than the actual value.
#define CFG_SD_MAX_VALUE_LEN 12+1 //this should be enought for int, long and float if you need to retrive strings increase this carefully
//========================= Bowden Filament management ======================
//#define EASY_LOAD
#ifdef EASY_LOAD
......
......@@ -14,10 +14,10 @@
*
*/
#define EEPROM_VERSION "V20"
#define EEPROM_VERSION "V21"
/**
* V19 EEPROM Layout:
* V21 EEPROM Layout:
*
* ver
* axis_steps_per_unit (x7)
......@@ -92,7 +92,6 @@
*
* idleoozing_enabled
*
* power_consumption_hour
*
*
*/
......@@ -101,6 +100,7 @@
#include "planner.h"
#include "temperature.h"
#include "ultralcd.h"
#include "cardreader.h"
#include "ConfigurationStore.h"
void _EEPROM_writeData(int &pos, uint8_t* value, uint8_t size) {
......@@ -260,10 +260,6 @@ void Config_StoreSettings() {
EEPROM_WRITE_VAR(i, idleoozing_enabled);
#endif
#if defined(POWER_CONSUMPTION) && defined(STORE_CONSUMPTION)
EEPROM_WRITE_VAR(i, power_consumption_hour);
#endif
char ver2[4] = EEPROM_VERSION;
int j = EEPROM_OFFSET;
EEPROM_WRITE_VAR(j, ver2); // validate data
......@@ -419,10 +415,6 @@ void Config_RetrieveSettings() {
EEPROM_READ_VAR(i, idleoozing_enabled);
#endif
#if defined(POWER_CONSUMPTION) && defined(STORE_CONSUMPTION)
EEPROM_READ_VAR(i, power_consumption_hour);
#endif
// Call updatePID (similar to when we have processed M301)
updatePID();
......@@ -567,14 +559,19 @@ void Config_ResetDefault() {
idleoozing_enabled = true;
#endif
#if defined(POWER_CONSUMPTION) && defined(STORE_CONSUMPTION)
power_consumption_hour = 0;
#endif
SERIAL_ECHO_START;
SERIAL_ECHOLNPGM("Hardcoded Default Settings Loaded");
}
void ConfigSD_ResetDefault() {
#ifdef POWER_CONSUMPTION
power_consumption_hour = 0;
#endif
printer_usage_seconds = 0;
SERIAL_ECHO_START;
SERIAL_ECHOLNPGM("Hardcoded SD Default Settings Loaded");
}
#ifndef DISABLE_M503
void Config_PrintSettings(bool forReplay) {
......@@ -868,16 +865,86 @@ void Config_PrintSettings(bool forReplay) {
SERIAL_ECHOLNPGM("Filament settings: Disabled");
}
}
}
#if defined(POWER_CONSUMPTION) && defined(STORE_CONSUMPTION)
SERIAL_ECHO_START;
void ConfigSD_PrintSettings(bool forReplay) {
// Always have this function, even with SD_SETTINGS disabled, the current values will be shown
#ifdef POWER_CONSUMPTION
if (!forReplay) {
SERIAL_ECHOLNPGM("Power consumation:");
SERIAL_ECHOLNPGM("Watt/h consumed:");
SERIAL_ECHO_START;
}
SERIAL_ECHOPAIR(" W/h:", power_consumption_hour);
SERIAL_ECHOPAIR(" W/h", power_consumption_hour);
SERIAL_EOL;
#endif
if (!forReplay) {
SERIAL_ECHOLNPGM("Power on time:");
SERIAL_ECHO_START;
}
SERIAL_ECHOPAIR(" s", printer_usage_seconds);
SERIAL_EOL;
}
#endif //!DISABLE_M503
#if defined(SDSUPPORT) && defined(SD_SETTINGS)
void ConfigSD_StoreSettings() {
if(!IS_SD_INSERTED || card.isFileOpen() || card.sdprinting) return;
card.openFile(CFG_SD_FILE, false, true, false);
char buff[CFG_SD_MAX_VALUE_LEN];
#ifdef POWER_CONSUMPTION
ltoa(power_consumption_hour,buff,10);
card.unparseKeyLine(cfgSD_KEY[SD_CFG_PWR], buff);
#endif
ltoa(printer_usage_seconds,buff,10);
card.unparseKeyLine(cfgSD_KEY[SD_CFG_TME], buff);
card.closeFile(false);
config_last_update = millis();
}
void ConfigSD_RetrieveSettings(bool addValue) {
if(!IS_SD_INSERTED || card.isFileOpen() || card.sdprinting) return;
char key[CFG_SD_MAX_KEY_LEN], value[CFG_SD_MAX_VALUE_LEN];
int k_idx;
int k_len, v_len;
card.openFile(CFG_SD_FILE, true, true, false);
while(true) {
k_len = CFG_SD_MAX_KEY_LEN;
v_len = CFG_SD_MAX_VALUE_LEN;
card.parseKeyLine(key, value, k_len, v_len);
if(k_len == 0 || v_len == 0) break; //no valid key or value founded
k_idx = ConfigSD_KeyIndex(key);
if(k_idx == -1) continue; //unknow key ignore it
switch(k_idx) {
#ifdef POWER_CONSUMPTION
case SD_CFG_PWR: {
if(addValue) power_consumption_hour += (unsigned long)atol(value);
else power_consumption_hour = (unsigned long)atol(value);
}
break;
#endif
case SD_CFG_TME: {
if(addValue) printer_usage_seconds += (unsigned long)atol(value);
else printer_usage_seconds = (unsigned long)atol(value);
}
break;
}
}
card.closeFile(false);
config_readed = true;
config_last_update = millis();
}
int ConfigSD_KeyIndex(char *key) { //At the moment a binary search algorithm is used for simplicity, if it will be necessary (Eg. tons of key), an hash search algorithm will be implemented.
int begin = 0, end = SD_CFG_END - 1, middle, cond;
while(begin <= end) {
middle = (begin + end) / 2;
cond = strcmp(cfgSD_KEY[middle], key);
if(!cond) return middle;
else if(cond < 0) begin = middle + 1;
else end = middle - 1;
}
return -1;
}
#endif
......@@ -4,11 +4,14 @@
#include "Configuration.h"
void Config_ResetDefault();
void ConfigSD_ResetDefault();
#ifndef DISABLE_M503
void Config_PrintSettings(bool forReplay=false);
void ConfigSD_PrintSettings(bool forReplay=false);
#else
FORCE_INLINE void Config_PrintSettings(bool forReplay=false) {}
FORCE_INLINE void ConfigSD_PrintSettings(bool forReplay=false) {}
#endif
#ifdef EEPROM_SETTINGS
......@@ -19,4 +22,27 @@ void Config_ResetDefault();
FORCE_INLINE void Config_RetrieveSettings() { Config_ResetDefault(); Config_PrintSettings(); }
#endif
#if defined(SDSUPPORT) && defined(SD_SETTINGS)
static const char *cfgSD_KEY[] = { //Keep this in lexicographical order for better search performance(O(Nlog2(N)) insted of O(N*N)) (if you don't keep this sorted, the algorithm for find the key index won't work, keep attention.)
#ifdef POWER_CONSUMPTION
"PWR",
#endif
"TME",
};
enum cfgSD_ENUM { //This need to be in the same order as cfgSD_KEY
#ifdef POWER_CONSUMPTION
SD_CFG_PWR,
#endif
SD_CFG_TME,
SD_CFG_END //Leave this always as the last
};
void ConfigSD_StoreSettings();
void ConfigSD_RetrieveSettings(bool addValue = false);
int ConfigSD_KeyIndex(char *key);
#else
FORCE_INLINE void ConfigSD_RetrieveSettings() { ConfigSD_ResetDefault(); ConfigSD_PrintSettings(); }
#endif
#endif //CONFIGURATIONSTORE_H
......@@ -198,9 +198,9 @@
//Manual homing switch locations:
// For SCARA: Offset between HomingPosition and Bed X=0 / Y=0
#ifdef MANUAL_HOME_POSITIONS
#define MANUAL_X_HOME_POS -22
#define MANUAL_Y_HOME_POS -52
#define MANUAL_Z_HOME_POS 0.1 // Distance between nozzle and print surface after homing.
#define MANUAL_X_HOME_POS -22
#define MANUAL_Y_HOME_POS -52
#define MANUAL_Z_HOME_POS 0.1 // Distance between nozzle and print surface after homing.
#endif
// MOVEMENT SETTINGS
......
......@@ -48,13 +48,12 @@
// extruder idle oozing prevention
//if the extruder motor is idle for more than SECONDS, and the temperature over MINTEMP, some filament is retracted. The filament retracted is re-added before the next extrusion
//or when the target temperature is less than EXTRUDE_MINTEMP and the actual temperature is greater than IDLE_OOZING_MINTEMP and less than IDLE_OOZING_FEEDRATE
//or when the target temperature is less than EXTRUDE_MINTEMP.
//#define IDLE_OOZING_PREVENT
#define IDLE_OOZING_MINTEMP EXTRUDE_MINTEMP + 5
#define IDLE_OOZING_MAXTEMP IDLE_OOZING_MINTEMP + 5
#define IDLE_OOZING_MINTEMP EXTRUDE_MINTEMP + 25
#define IDLE_OOZING_FEEDRATE 45 //default feedrate for retracting (mm/s)
#define IDLE_OOZING_SECONDS 10
#define IDLE_OOZING_LENGTH 15 //default retract length (positive mm)
#define IDLE_OOZING_LENGTH 10 //default retract length (positive mm)
#define IDLE_OOZING_RECOVER_LENGTH 0 //default additional recover length (mm, added to retract length when recovering)
#define IDLE_OOZING_RECOVER_FEEDRATE 50 //default feedrate for recovering from retraction (mm/s)
......
......@@ -35,6 +35,10 @@
#define TEST(n,b) (((n)&BIT(b))!=0)
#define RADIANS(d) ((d)*M_PI/180.0)
#define DEGREES(r) ((d)*180.0/M_PI)
#define NOLESS(v,n) do{ if (v < n) v = n; }while(0)
#define NOMORE(v,n) do{ if (v > n) v = n; }while(0)
typedef unsigned long millis_t;
// Arduino < 1.0.0 does not define this, so we need to do it ourselves
#ifndef analogInputToDigitalPin
......@@ -244,14 +248,14 @@ extern bool Running;
inline bool IsRunning() { return Running; }
inline bool IsStopped() { return !Running; }
bool enquecommand(const char *cmd); //put a single ASCII command at the end of the current buffer or return false when it is full
void enquecommands_P(const char *cmd); //put one or many ASCII commands at the end of the current buffer, read from flash
bool enqueuecommand(const char *cmd); //put a single ASCII command at the end of the current buffer or return false when it is full
void enqueuecommands_P(const char *cmd); //put one or many ASCII commands at the end of the current buffer, read from flash
void prepare_arc_move(char isclockwise);
void clamp_to_software_endstops(float target[3]);
extern unsigned long previous_millis_cmd;
inline void refresh_cmd_timeout() { previous_millis_cmd = millis(); }
extern millis_t previous_cmd_ms;
inline void refresh_cmd_timeout() { previous_cmd_ms = millis(); }
#ifdef FAST_PWM_FAN
void setPwmFrequency(uint8_t pin, int val);
......@@ -264,7 +268,7 @@ inline void refresh_cmd_timeout() { previous_millis_cmd = millis(); }
extern float homing_feedrate[];
extern bool axis_relative_modes[];
extern int feedmultiply;
extern int feedrate_multiplier;
extern bool volumetric_enabled;
extern int extruder_multiply[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually
extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder.
......@@ -307,6 +311,8 @@ extern bool axis_known_position[3];
extern float lastpos[4];
extern float zprobe_zoffset;
extern unsigned long printer_usage_seconds; //this can old about 136 year before go overflow. If you belive that you can live more than this please contact me.
#ifdef PREVENT_DANGEROUS_EXTRUDE
extern float extrude_min_temp;
#endif
......@@ -358,8 +364,13 @@ extern int fanSpeed;
extern int laser_ttl_modulation;
#endif
extern unsigned long starttime;
extern unsigned long stoptime;
#if defined(SDSUPPORT) && defined(SD_SETTINGS)
extern unsigned long config_last_update;
extern bool config_readed;
#endif
extern millis_t print_job_start_ms;
extern millis_t print_job_stop_ms;
// Handling multiple extruders pins
extern uint8_t active_extruder;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -25,7 +25,7 @@ CardReader::CardReader() {
OUT_WRITE(SDPOWER, HIGH);
#endif //SDPOWER
autostart_atmillis = millis() + 5000;
next_autostart_ms = millis() + 5000;
}
char *createFilename(char *buffer, const dir_t &p) { //buffer > 12characters
......@@ -189,36 +189,35 @@ void CardReader::getAbsFilename(char *t) {
t[0] = 0;
}
void CardReader::openFile(char* name, bool read, bool replace_current/*=true*/) {
void CardReader::openFile(char* name, bool read, bool replace_current/*=true*/, bool lcd_status/*=true*/) {
if (!cardOK) return;
if (file.isOpen()) { //replacing current file by new file, or subfile call
if (!replace_current) {
if (file_subcall_ctr > SD_PROCEDURE_DEPTH - 1) {
SERIAL_ERROR_START;
SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:");
SERIAL_ERRORLN(SD_PROCEDURE_DEPTH);
kill();
return;
}
SERIAL_ECHO_START;
SERIAL_ECHOPGM("SUBROUTINE CALL target:\"");
SERIAL_ECHO(name);
SERIAL_ECHOPGM("\" parent:\"");
//store current filename and position
getAbsFilename(filenames[file_subcall_ctr]);
SERIAL_ECHO(filenames[file_subcall_ctr]);
SERIAL_ECHOPGM("\" pos");
SERIAL_ECHOLN(sdpos);
filespos[file_subcall_ctr] = sdpos;
file_subcall_ctr++;
if (file_subcall_ctr > SD_PROCEDURE_DEPTH - 1) {
SERIAL_ERROR_START;
SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:");
SERIAL_ERRORLN(SD_PROCEDURE_DEPTH);
kill();
return;
}
SERIAL_ECHO_START;
SERIAL_ECHOPGM("SUBROUTINE CALL target:\"");
SERIAL_ECHO(name);
SERIAL_ECHOPGM("\" parent:\"");
//store current filename and position
getAbsFilename(filenames[file_subcall_ctr]);
SERIAL_ECHO(filenames[file_subcall_ctr]);
SERIAL_ECHOPGM("\" pos");
SERIAL_ECHOLN(sdpos);
filespos[file_subcall_ctr] = sdpos;
file_subcall_ctr++;
}
else {
SERIAL_ECHO_START;
SERIAL_ECHOPGM("Now doing file: ");
SERIAL_ECHOLN(name);
SERIAL_ECHO_START;
SERIAL_ECHOPGM("Now doing file: ");
SERIAL_ECHOLN(name);
}
file.close();
}
......@@ -282,7 +281,7 @@ void CardReader::openFile(char* name, bool read, bool replace_current/*=true*/)
SERIAL_PROTOCOLLNPGM(MSG_SD_FILE_SELECTED);
getfilename(0, fname);
lcd_setstatus(longFilename[0] ? longFilename : fname);
if(lcd_status) lcd_setstatus(longFilename[0] ? longFilename : fname);
}
else {
SERIAL_PROTOCOLPGM(MSG_SD_OPEN_FILE_FAIL);
......@@ -291,16 +290,16 @@ void CardReader::openFile(char* name, bool read, bool replace_current/*=true*/)
}
}
else { //write
if (!file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
SERIAL_PROTOCOLPGM(MSG_SD_OPEN_FILE_FAIL);
SERIAL_PROTOCOL(fname);
SERIAL_PROTOCOLCHAR('.');
}
else {
if (file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
saving = true;
SERIAL_PROTOCOLPGM(MSG_SD_WRITE_TO_FILE);
SERIAL_PROTOCOLLN(name);
lcd_setstatus(fname);
if(lcd_status) lcd_setstatus(fname);
}
else {
SERIAL_PROTOCOLPGM(MSG_SD_OPEN_FILE_FAIL);
SERIAL_PROTOCOL(fname);
SERIAL_PROTOCOLCHAR('.');
}
}
}
......@@ -397,7 +396,7 @@ void CardReader::write_command(char *buf) {
}
void CardReader::checkautostart(bool force) {
if (!force && (!autostart_stilltocheck || autostart_atmillis < millis()))
if (!force && (!autostart_stilltocheck || next_autostart_ms < millis()))
return;
autostart_stilltocheck = false;
......@@ -421,8 +420,8 @@ void CardReader::checkautostart(bool force) {
if (p.name[9] != '~' && strncmp((char*)p.name, autoname, 5) == 0) {
char cmd[30];
sprintf_P(cmd, PSTR("M23 %s"), autoname);
enquecommand(cmd);
enquecommands_P(PSTR("M24"));
enqueuecommand(cmd);
enqueuecommands_P(PSTR("M24"));
found = true;
}
}
......@@ -432,7 +431,7 @@ void CardReader::checkautostart(bool force) {
autostart_index++;
}
void CardReader::closefile(bool store_location) {
void CardReader::closeFile(bool store_location) {
file.sync();
file.close();
saving = logging = false;
......@@ -443,6 +442,94 @@ void CardReader::closefile(bool store_location) {
}
}
void CardReader::parseKeyLine(char *key, char *value, int &len_k, int &len_v) {
if (!cardOK || !isFileOpen()) return;
int ln_buf = 0;
char ln_char;
bool ln_space = false, ln_ignore = false, key_found = false;
while(!eof()) { //READ KEY
ln_char = (char)get();
if(ln_char == '\n') {
ln_buf = 0;
ln_ignore = false; //We've reached a new line try to find a key again
continue;
}
if(ln_ignore) continue;
if(ln_char == ' ') {
ln_space = true;
continue;
}
if(ln_char == '=') {
key[ln_buf] = '\0';
len_k = ln_buf;
key_found = true;
break; //key finded and buffered
}
if(ln_char == ';' || ln_buf+1 >= len_k || ln_space && ln_buf > 0) { //comments on key is not allowd. Also key len can't be longer than len_k or contain spaces. Stop buffering and try the next line
ln_ignore = true;
continue;
}
ln_space = false;
key[ln_buf] = ln_char;
ln_buf++;
}
if(!key_found) { //definitly there isn't no more key that can be readed in the file
key[0] = '\0';
value[0] = '\0';
len_k = 0;
len_v = 0;
return;
}
ln_buf = 0;
ln_ignore = false;
while(!eof()) { //READ VALUE
ln_char = (char)get();
if(ln_char == '\n') {
value[ln_buf] = '\0';
len_v = ln_buf;
break; //new line reached, we can stop
}
if(ln_ignore|| ln_char == ' ' && ln_buf == 0) continue; //ignore also initial spaces of the value
if(ln_char == ';' || ln_buf+1 >= len_v) { //comments reached or value len longer than len_v. Stop buffering and go to the next line.
ln_ignore = true;
continue;
}
value[ln_buf] = ln_char;
ln_buf++;
}
}
void CardReader::unparseKeyLine(const char *key, char *value) {
if (!cardOK || !isFileOpen()) return;
file.writeError = false;
file.write(key);
if (file.writeError) {
SERIAL_ERROR_START;
SERIAL_ERRORLNPGM(MSG_SD_ERR_WRITE_TO_FILE);
return;
}
file.writeError = false;
file.write("=");
if (file.writeError) {
SERIAL_ERROR_START;
SERIAL_ERRORLNPGM(MSG_SD_ERR_WRITE_TO_FILE);
return;
}
file.writeError = false;
file.write(value);
if (file.writeError) {
SERIAL_ERROR_START;
SERIAL_ERRORLNPGM(MSG_SD_ERR_WRITE_TO_FILE);
return;
}
file.writeError = false;
file.write("\n");
if (file.writeError) {
SERIAL_ERROR_START;
SERIAL_ERRORLNPGM(MSG_SD_ERR_WRITE_TO_FILE);
}
}
/**
* Get the name of a file in the current directory by index
*/
......@@ -508,7 +595,7 @@ void CardReader::printingHasFinished() {
sdprinting = false;
if (SD_FINISHED_STEPPERRELEASE) {
//finishAndDisableSteppers();
enquecommands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
enqueuecommands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
}
autotempShutdown();
}
......
......@@ -18,10 +18,12 @@ public:
//this is to delay autostart and hence the initialisaiton of the sd card to some seconds after the normal init, so the device is available quick after a reset
void checkautostart(bool x);
void openFile(char* name,bool read,bool replace_current=true);
void openFile(char* name,bool read,bool replace_current=true, bool lcd_status=true);
void openLogFile(char* name);
void removeFile(char* name);
void closefile(bool store_location=false);
void closeFile(bool store_location=false);
void parseKeyLine(char *key, char *value, int &len_k, int &len_v);
void unparseKeyLine(const char *key, char *value);
void release();
void startFileprint();
void pauseSDPrint();
......@@ -62,7 +64,7 @@ private:
uint32_t filespos[SD_PROCEDURE_DEPTH];
char filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH];
uint32_t filesize;
unsigned long autostart_atmillis;
millis_t next_autostart_ms;
uint32_t sdpos;
bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware.
......
......@@ -186,11 +186,11 @@ static void lcd_implementation_init() {
// digitalWrite(17, HIGH);
#ifdef LCD_SCREEN_ROT_90
u8g.setRot90(); // Rotate screen by 90
u8g.setRot90(); // Rotate screen by 90°
#elif defined(LCD_SCREEN_ROT_180)
u8g.setRot180(); // Rotate screen by 180
u8g.setRot180(); // Rotate screen by 180°
#elif defined(LCD_SCREEN_ROT_270)
u8g.setRot270(); // Rotate screen by 270
u8g.setRot270(); // Rotate screen by 270°
#endif
// Show splashscreen
......@@ -269,23 +269,23 @@ static void lcd_implementation_status_screen() {
}
u8g.setPrintPos(80,48);
if (starttime != 0) {
if (print_job_start_ms != 0) {
#if HAS_LCD_POWER_SENSOR
if (millis() < print_millis + 1000) {
uint16_t time = (millis() - starttime) / 60000;
lcd_print(itostr2(time/60));
uint16_t time = (millis() - print_job_start_ms) / 60000;
lcd_print(itostr2(time / 60));
lcd_print(':');
lcd_print(itostr2(time%60));
lcd_print(itostr2(time % 60));
}
else {
lcd_print(itostr4(power_consumption_hour-startpower));
lcd_print('Wh');
}
#else
uint16_t time = (millis() - starttime) / 60000;
lcd_print(itostr2(time/60));
uint16_t time = (millis() - print_job_start_ms) / 60000;
lcd_print(itostr2(time / 60));
lcd_print(':');
lcd_print(itostr2(time%60));
lcd_print(itostr2(time % 60));
#endif
}
else {
......@@ -350,7 +350,7 @@ static void lcd_implementation_status_screen() {
lcd_print(LCD_STR_FEEDRATE[0]);
lcd_setFont(FONT_STATUSMENU);
u8g.setPrintPos(12,49);
lcd_print(itostr3(feedmultiply));
lcd_print(itostr3(feedrate_multiplier));
lcd_print('%');
// Status line
......@@ -362,12 +362,12 @@ static void lcd_implementation_status_screen() {
#endif
#if HAS_LCD_FILAMENT_SENSOR || HAS_LCD_POWER_SENSOR
if (millis() < message_millis + 5000) { //Display both Status message line and Filament display on the last line
if (millis() < previous_lcd_status_ms + 5000) { //Display both Status message line and Filament display on the last line
lcd_print(lcd_status_message);
}
#if HAS_LCD_POWER_SENSOR
#if HAS_LCD_FILAMENT_SENSOR
else if (millis() < message_millis + 10000)
else if (millis() < previous_lcd_status_ms + 10000)
#else
else
#endif
......
......@@ -59,6 +59,10 @@
#define MACHINE_NAME CUSTOM_MENDEL_NAME
#endif
#ifndef BUILD_VERSION
#define BUILD_VERSION "V4;"
#endif
#ifndef MACHINE_UUID
#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
#endif
......@@ -77,7 +81,7 @@
// Serial Console Messages (do not translate those!)
#define MSG_Enqueing "enqueing \""
#define MSG_Enqueueing "enqueueing \""
#define MSG_POWERUP "PowerUp"
#define MSG_EXTERNAL_RESET " External Reset"
#define MSG_BROWNOUT_RESET " Brown out Reset"
......@@ -86,8 +90,9 @@
#define MSG_AUTHOR " | Author: "
#define MSG_CONFIGURATION_VER " Last Updated: "
#define MSG_FREE_MEMORY " Free Memory: "
#define MSG_PLANNER_BUFFER_BYTES " PlannerBufferBytes: "
#define MSG_PLANNER_BUFFER_BYTES " PlannerBufferBytes: "
#define MSG_OK "ok"
#define MSG_WAIT "wait"
#define MSG_FILE_SAVED "Done saving file."
#define MSG_ERR_LINE_NO "Line Number is not Last Line Number+1, Last Line: "
#define MSG_ERR_CHECKSUM_MISMATCH "checksum mismatch, Last Line: "
......@@ -107,7 +112,7 @@
#define MSG_HEATING_COMPLETE "Heating done."
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_M115_REPORT "FIRMWARE_NAME:MarlinKimbra V4; FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n"
#define MSG_M115_REPORT "FIRMWARE_NAME:MarlinKimbra " BUILD_VERSION " FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n"
#define MSG_COUNT_X " Count X: "
#define MSG_ERR_KILLED "Printer halted. kill() called!"
#define MSG_ERR_STOPPED "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"
......
......@@ -62,7 +62,7 @@
//============================= public variables ============================
//===========================================================================
unsigned long minsegmenttime;
millis_t minsegmenttime;
float max_feedrate[3 + EXTRUDERS]; // Max speeds in mm per minute
float max_retraction_feedrate[EXTRUDERS]; // set the max speeds for retraction
float axis_steps_per_unit[3 + EXTRUDERS];
......@@ -156,8 +156,8 @@ void calculate_trapezoid_for_block(block_t *block, float entry_factor, float exi
unsigned long final_rate = ceil(block->nominal_rate * exit_factor); // (step/min)
// Limit minimal step rate (Otherwise the timer will overflow.)
if (initial_rate < 120) initial_rate = 120;
if (final_rate < 120) final_rate = 120;
NOLESS(initial_rate, 120);
NOLESS(final_rate, 120);
long acceleration = block->acceleration_st;
int32_t accelerate_steps = ceil(estimate_acceleration_distance(initial_rate, block->nominal_rate, acceleration));
......@@ -378,16 +378,18 @@ void plan_init() {
}
float t = autotemp_min + high * autotemp_factor;
if (t < autotemp_min) t = autotemp_min;
if (t > autotemp_max) t = autotemp_max;
if (oldt > t) t = AUTOTEMP_OLDWEIGHT * oldt + (1 - AUTOTEMP_OLDWEIGHT) * t;
t = constrain(t, autotemp_min, autotemp_max);
if (oldt > t) {
t *= (1 - AUTOTEMP_OLDWEIGHT);
t += AUTOTEMP_OLDWEIGHT * oldt;
}
oldt = t;
setTargetHotend0(t);
}
#endif
void check_axes_activity() {
unsigned char axis_active[NUM_AXIS],
unsigned char axis_active[NUM_AXIS] = { 0 },
tail_fan_speed = fanSpeed;
#ifdef BARICUDA
unsigned char tail_valve_pressure = ValvePressure,
......@@ -428,7 +430,7 @@ void check_axes_activity() {
#if HAS_FAN
#ifdef FAN_KICKSTART_TIME
static unsigned long fan_kick_end;
static millis_t fan_kick_end;
if (tail_fan_speed) {
if (fan_kick_end == 0) {
// Just starting up fan - run at full power.
......@@ -500,7 +502,7 @@ float junction_deviation = 0.1;
target[X_AXIS] = lround(x * axis_steps_per_unit[X_AXIS]);
target[Y_AXIS] = lround(y * axis_steps_per_unit[Y_AXIS]);
target[Z_AXIS] = lround(z * axis_steps_per_unit[Z_AXIS]);
target[E_AXIS] = lround(e * axis_steps_per_unit[E_AXIS + extruder]);
target[E_AXIS] = lround(e * axis_steps_per_unit[E_AXIS + active_extruder]);
float dx = target[X_AXIS] - position[X_AXIS],
dy = target[Y_AXIS] - position[Y_AXIS],
......@@ -693,7 +695,11 @@ float junction_deviation = 0.1;
#endif //!MKR4 && !NPR2
if (feed_rate < minimumfeedrate) feed_rate = minimumfeedrate;
}
else if (feed_rate < mintravelfeedrate) feed_rate = mintravelfeedrate;
if (block->steps[E_AXIS])
NOLESS(feed_rate, minimumfeedrate);
else
NOLESS(feed_rate, mintravelfeedrate);
/**
* This part of the code calculates the total length of the movement.
......
......@@ -114,7 +114,7 @@ FORCE_INLINE uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block
void plan_set_e_position(const float &e);
extern unsigned long minsegmenttime;
extern millis_t minsegmenttime;
extern float max_feedrate[3 + EXTRUDERS]; // set the max speeds
extern float max_retraction_feedrate[EXTRUDERS]; // set the max speeds for retraction
extern float axis_steps_per_unit[3 + EXTRUDERS];
......
......@@ -54,7 +54,7 @@ static unsigned int cleaning_buffer_counter;
locked_z2_motor = false;
#endif
// Counter variables for the bresenham line tracer
// Counter variables for the Bresenham line tracer
static long counter_x, counter_y, counter_z, counter_e;
volatile static unsigned long step_events_completed; // The number of step events executed in the current block
......@@ -66,7 +66,7 @@ volatile static unsigned long step_events_completed; // The number of step event
static long acceleration_time, deceleration_time;
//static unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate;
static unsigned short acc_step_rate; // needed for deccelaration start point
static unsigned short acc_step_rate; // needed for deceleration start point
static char step_loops;
static unsigned short OCR1A_nominal;
static unsigned short step_loops_nominal;
......@@ -210,8 +210,14 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1 };
// intRes = longIn1 * longIn2 >> 24
// uses:
// r26 to store 0
// r27 to store the byte 1 of the 48bit result
#define MultiU24X24toH16(intRes, longIn1, longIn2) \
// r27 to store bits 16-23 of the 48bit result. The top bit is used to round the two byte result.
// note that the lower two bytes and the upper byte of the 48bit result are not calculated.
// this can cause the result to be out by one as the lower bytes may cause carries into the upper ones.
// B0 A0 are bits 24-39 and are the returned value
// C1 B1 A1 is longIn1
// D2 C2 B2 A2 is longIn2
//
#define MultiU24X32toH16(intRes, longIn1, longIn2) \
asm volatile ( \
"clr r26 \n\t" \
"mul %A1, %B2 \n\t" \
......@@ -242,6 +248,11 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1 };
"lsr r27 \n\t" \
"adc %A0, r26 \n\t" \
"adc %B0, r26 \n\t" \
"mul %D2, %A1 \n\t" \
"add %A0, r0 \n\t" \
"adc %B0, r1 \n\t" \
"mul %D2, %B1 \n\t" \
"add %B0, r0 \n\t" \
"clr r1 \n\t" \
: \
"=&r" (intRes) \
......@@ -297,7 +308,7 @@ void checkHitEndstops() {
#if defined(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) && defined(SDSUPPORT)
if (abort_on_endstop_hit) {
card.sdprinting = false;
card.closefile();
card.closeFile();
quickStop();
setTargetHotend0(0);
setTargetHotend1(0);
......@@ -343,7 +354,7 @@ void checkHitEndstops() {
#if defined(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) && defined(SDSUPPORT)
if (abort_on_endstop_hit) {
card.sdprinting = false;
card.closefile();
card.closeFile();
quickStop();
setTargetHotend0(0);
setTargetHotend1(0);
......@@ -372,7 +383,7 @@ void enable_endstops(bool check) { check_endstops = check; }
// The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates
// first block->accelerate_until step_events_completed, then keeps going at constant speed until
// step_events_completed reaches block->decelerate_after after which it decelerates until the trapezoid generator is reset.
// The slope of acceleration is calculated with the lib ramp algorithm.
// The slope of acceleration is calculated using v = u + at where t is the accumulated timer values of the steps so far.
void st_wake_up() {
// TCNT1 = 0;
......@@ -453,7 +464,7 @@ ISR(TIMER1_COMPA_vect) {
current_block = NULL;
plan_discard_current_block();
#ifdef SD_FINISHED_RELEASECOMMAND
if ((cleaning_buffer_counter == 1) && (SD_FINISHED_STEPPERRELEASE)) enquecommands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
if ((cleaning_buffer_counter == 1) && (SD_FINISHED_STEPPERRELEASE)) enqueuecommands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
#endif
cleaning_buffer_counter--;
OCR1A = 200;
......@@ -528,7 +539,7 @@ ISR(TIMER1_COMPA_vect) {
if ((current_block->steps[A_AXIS] != current_block->steps[B_AXIS]) || (TEST(out_bits, A_AXIS) == TEST(out_bits, B_AXIS))) {
if (TEST(out_bits, X_HEAD))
#else
if (TEST(out_bits, X_AXIS)) // stepping along -X axis (regular cartesians bot)
if (TEST(out_bits, X_AXIS)) // stepping along -X axis (regular Cartesian bot)
#endif
{ // -direction
#ifdef DUAL_X_CARRIAGE
......@@ -772,9 +783,9 @@ ISR(TIMER1_COMPA_vect) {
// Calculate new timer value
unsigned short timer;
unsigned short step_rate;
if (step_events_completed <= (unsigned long int)current_block->accelerate_until) {
if (step_events_completed <= (unsigned long)current_block->accelerate_until) {
MultiU24X24toH16(acc_step_rate, acceleration_time, current_block->acceleration_rate);
MultiU24X32toH16(acc_step_rate, acceleration_time, current_block->acceleration_rate);
acc_step_rate += current_block->initial_rate;
// upper limit
......@@ -796,8 +807,8 @@ ISR(TIMER1_COMPA_vect) {
#endif
}
else if (step_events_completed > (unsigned long int)current_block->decelerate_after) {
MultiU24X24toH16(step_rate, deceleration_time, current_block->acceleration_rate);
else if (step_events_completed > (unsigned long)current_block->decelerate_after) {
MultiU24X32toH16(step_rate, deceleration_time, current_block->acceleration_rate);
if (step_rate > acc_step_rate) { // Check step_rate stays positive
step_rate = current_block->final_rate;
......@@ -1236,7 +1247,7 @@ void quickStop() {
uint8_t old_pin = AXIS ##_DIR_READ; \
AXIS ##_APPLY_DIR(INVERT_## AXIS ##_DIR^direction^INVERT, true); \
AXIS ##_APPLY_STEP(!INVERT_## AXIS ##_STEP_PIN, true); \
_delay_us(1U); \
delayMicroseconds(2); \
AXIS ##_APPLY_STEP(INVERT_## AXIS ##_STEP_PIN, true); \
AXIS ##_APPLY_DIR(old_pin, true); \
}
......@@ -1275,7 +1286,7 @@ void quickStop() {
X_STEP_WRITE(!INVERT_X_STEP_PIN);
Y_STEP_WRITE(!INVERT_Y_STEP_PIN);
Z_STEP_WRITE(!INVERT_Z_STEP_PIN);
_delay_us(1U);
delayMicroseconds(2);
X_STEP_WRITE(INVERT_X_STEP_PIN);
Y_STEP_WRITE(INVERT_Y_STEP_PIN);
Z_STEP_WRITE(INVERT_Z_STEP_PIN);
......
......@@ -109,7 +109,7 @@ void microstep_readings();
#ifdef BABYSTEPPING
void babystep(const uint8_t axis,const bool direction); // perform a short step with a single stepper motor, outside of any convention
#endif //BABYSTEPPING
#endif
#ifdef NPR2 //Multiextruder
void colorstep(long csteps,const bool direction);
......
......@@ -77,14 +77,14 @@ unsigned char soft_pwm_bed;
#define HAS_BED_THERMAL_PROTECTION (defined(THERMAL_RUNAWAY_PROTECTION_BED_PERIOD) && THERMAL_RUNAWAY_PROTECTION_BED_PERIOD > 0 && TEMP_SENSOR_BED != 0)
#if HAS_HEATER_THERMAL_PROTECTION || HAS_BED_THERMAL_PROTECTION
enum TRState { TRReset, TRInactive, TRFirstHeating, TRStable, TRRunaway };
void thermal_runaway_protection(TRState *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc);
void thermal_runaway_protection(TRState *state, millis_t *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc);
#if HAS_HEATER_THERMAL_PROTECTION
static TRState thermal_runaway_state_machine[4] = { TRReset, TRReset, TRReset, TRReset };
static unsigned long thermal_runaway_timer[4]; // = {0,0,0,0};
static millis_t thermal_runaway_timer[4]; // = {0,0,0,0};
#endif
#if HAS_BED_THERMAL_PROTECTION
static TRState thermal_runaway_bed_state_machine = TRReset;
static unsigned long thermal_runaway_bed_timer;
static millis_t thermal_runaway_bed_timer;
#endif
#endif
#if HAS_POWER_CONSUMPTION_SENSOR
......@@ -122,7 +122,7 @@ static volatile bool temp_meas_ready = false;
static float temp_iState_min_bed;
static float temp_iState_max_bed;
#else //PIDTEMPBED
static unsigned long previous_millis_bed_heater;
static millis_t next_bed_check_ms;
#endif //PIDTEMPBED
static unsigned char soft_pwm[HOTENDS];
......@@ -131,8 +131,9 @@ static unsigned char soft_pwm[HOTENDS];
static unsigned char soft_pwm_fan;
#endif
#if HAS_AUTO_FAN
static unsigned long extruder_autofan_last_check;
#endif
static millis_t next_auto_fan_check_ms;
#endif
#ifdef PIDTEMP
float Kp[HOTENDS], Ki[HOTENDS], Kd[HOTENDS];
#endif //PIDTEMP
......@@ -160,8 +161,8 @@ static float analog2tempBed(int raw);
static void updateTemperaturesFromRawValues();
#ifdef WATCH_TEMP_PERIOD
int watch_start_temp[HOTENDS] = { 0 };
unsigned long watchmillis[HOTENDS] = { 0 };
int watch_start_temp[HOTENDS] = { 0 };
millis_t watchmillis[HOTENDS] = { 0 };
#endif //WATCH_TEMP_PERIOD
#ifndef SOFT_PWM_SCALE
......@@ -186,7 +187,7 @@ void PID_autotune(float temp, int hotend, int ncycles)
int cycles = 0;
bool heating = true;
unsigned long temp_millis = millis(), t1 = temp_millis, t2 = temp_millis;
millis_t temp_ms = millis(), t1 = temp_ms, t2 = temp_ms;
long t_high = 0, t_low = 0;
long bias, d;
......@@ -195,7 +196,7 @@ void PID_autotune(float temp, int hotend, int ncycles)
float max = 0, min = 10000;
#if HAS_AUTO_FAN
unsigned long extruder_autofan_last_check = temp_millis;
millis_t next_auto_fan_check_ms = temp_ms + 2500;
#endif
if (hotend >= HOTENDS
......@@ -209,7 +210,7 @@ void PID_autotune(float temp, int hotend, int ncycles)
SERIAL_ECHOLN(MSG_PID_AUTOTUNE_START);
disable_heater(); // switch off all heaters.
disable_all_heaters(); // switch off all heaters.
if (hotend < 0)
soft_pwm_bed = bias = d = MAX_BED_POWER / 2;
......@@ -217,9 +218,9 @@ void PID_autotune(float temp, int hotend, int ncycles)
soft_pwm[hotend] = bias = d = PID_MAX / 2;
// PID Tuning loop
for(;;) {
for (;;) {
unsigned long ms = millis();
millis_t ms = millis();
if (temp_meas_ready) { // temp sample ready
updateTemperaturesFromRawValues();
......@@ -230,9 +231,9 @@ void PID_autotune(float temp, int hotend, int ncycles)
min = min(min, input);
#if HAS_AUTO_FAN
if (ms > extruder_autofan_last_check + 2500) {
if (ms > next_auto_fan_check_ms) {
checkExtruderAutoFans();
extruder_autofan_last_check = ms;
next_auto_fan_check_ms = ms + 2500;
}
#endif
......@@ -307,7 +308,7 @@ void PID_autotune(float temp, int hotend, int ncycles)
return;
}
// Every 2 seconds...
if (ms > temp_millis + 2000) {
if (ms > temp_ms + 2000) {
int p;
if (hotend < 0) {
p = soft_pwm_bed;
......@@ -322,7 +323,7 @@ void PID_autotune(float temp, int hotend, int ncycles)
SERIAL_PROTOCOLPGM(MSG_AT);
SERIAL_PROTOCOLLN(p);
temp_millis = ms;
temp_ms = ms;
} // every 2 seconds
// Over 2 minutes?
if (((ms - t1) + (ms - t2)) > (10L*60L*1000L*2L)) {
......@@ -453,11 +454,11 @@ inline void _temp_error(int e, const char *msg1, const char *msg2) {
}
void max_temp_error(uint8_t e) {
disable_heater();
disable_all_heaters();
_temp_error(e, PSTR(MSG_MAXTEMP_EXTRUDER_OFF), PSTR(MSG_ERR_MAXTEMP));
}
void min_temp_error(uint8_t e) {
disable_heater();
disable_all_heaters();
_temp_error(e, PSTR(MSG_MINTEMP_EXTRUDER_OFF), PSTR(MSG_ERR_MINTEMP));
}
void bed_max_temp_error(void) {
......@@ -574,6 +575,14 @@ float get_pid_output(int e) {
}
#endif
/**
* Manage heating activities for extruder hot-ends and a heated bed
* - Acquire updated temperature readings
* - Invoke thermal runaway protection
* - Manage extruder auto-fan
* - Apply filament width to the extrusion rate (may move)
* - Update the heated bed PID output value
*/
void manage_heater() {
if (!temp_meas_ready) return;
......@@ -587,7 +596,7 @@ void manage_heater() {
#endif //HEATER_0_USES_MAX6675
#if defined(WATCH_TEMP_PERIOD) || !defined(PIDTEMPBED) || HAS_AUTO_FAN
unsigned long ms = millis();
millis_t ms = millis();
#endif
// Loop through all hotends
......@@ -618,7 +627,7 @@ void manage_heater() {
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
if (fabs(current_temperature[0] - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) {
disable_heater();
disable_all_heaters();
_temp_error(0, PSTR(MSG_EXTRUDER_SWITCHED_OFF), PSTR(MSG_ERR_REDUNDANT_TEMP));
}
#endif //TEMP_SENSOR_1_AS_REDUNDANT
......@@ -626,16 +635,31 @@ void manage_heater() {
} // Hotends Loop
#if HAS_AUTO_FAN
if (ms > extruder_autofan_last_check + 2500) { // only need to check fan state very infrequently
if (ms > next_auto_fan_check_ms) { // only need to check fan state very infrequently
checkExtruderAutoFans();
extruder_autofan_last_check = ms;
next_auto_fan_check_ms = ms + 2500;
}
#endif
// Control the extruder rate based on the width sensor
#ifdef FILAMENT_SENSOR
if (filament_sensor) {
meas_shift_index = delay_index1 - meas_delay_cm;
if (meas_shift_index < 0) meas_shift_index += MAX_MEASUREMENT_DELAY + 1; //loop around buffer if needed
// Get the delayed info and add 100 to reconstitute to a percent of
// the nominal filament diameter then square it to get an area
meas_shift_index = constrain(meas_shift_index, 0, MAX_MEASUREMENT_DELAY);
float vm = pow((measurement_delay[meas_shift_index] + 100.0) / 100.0, 2);
if (vm < 0.01) vm = 0.01;
volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = vm;
}
#endif //FILAMENT_SENSOR
#ifndef PIDTEMPBED
if (ms < previous_millis_bed_heater + BED_CHECK_INTERVAL) return;
previous_millis_bed_heater = ms;
#endif //PIDTEMPBED
if (ms < next_bed_check_ms) return;
next_bed_check_ms = ms + BED_CHECK_INTERVAL;
#endif
#if TEMP_SENSOR_BED != 0
......@@ -648,22 +672,22 @@ void manage_heater() {
soft_pwm_bed = current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP ? (int)pid_output >> 1 : 0;
#elif !defined(BED_LIMIT_SWITCHING)
// Check if temperature is within the correct range
#elif defined(BED_LIMIT_SWITCHING)
// Check if temperature is within the correct band
if (current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP) {
soft_pwm_bed = current_temperature_bed < target_temperature_bed ? MAX_BED_POWER >> 1 : 0;
if (current_temperature_bed >= target_temperature_bed + BED_HYSTERESIS)
soft_pwm_bed = 0;
else if (current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS)
soft_pwm_bed = MAX_BED_POWER >> 1;
}
else {
soft_pwm_bed = 0;
WRITE_HEATER_BED(LOW);
}
#else //#ifdef BED_LIMIT_SWITCHING
// Check if temperature is within the correct band
#else // 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 >= target_temperature_bed + BED_HYSTERESIS)
soft_pwm_bed = 0;
else if (current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS)
soft_pwm_bed = MAX_BED_POWER >> 1;
soft_pwm_bed = current_temperature_bed < target_temperature_bed ? MAX_BED_POWER >> 1 : 0;
}
else {
soft_pwm_bed = 0;
......@@ -671,56 +695,36 @@ void manage_heater() {
}
#endif
#endif //TEMP_SENSOR_BED != 0
// Control the extruder rate based on the width sensor
#if HAS_FILAMENT_SENSOR
if (filament_sensor) {
meas_shift_index = delay_index1 - meas_delay_cm;
if (meas_shift_index < 0) meas_shift_index += MAX_MEASUREMENT_DELAY + 1; //loop around buffer if needed
// Get the delayed info and add 100 to reconstitute to a percent of
// the nominal filament diameter then square it to get an area
meas_shift_index = constrain(meas_shift_index, 0, MAX_MEASUREMENT_DELAY);
float vm = pow((measurement_delay[meas_shift_index] + 100.0) / 100.0, 2);
if (vm < 0.01) vm = 0.01;
volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = vm;
}
#endif //HAS_FILAMENT_SENSOR
}
#define PGM_RD_W(x) (short)pgm_read_word(&x)
// Derived from RepRap FiveD extruder::getTemperature()
// For hot end temperature measurement.
static float analog2temp(int raw, uint8_t e) {
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
if (e > EXTRUDERS)
#else
if (e >= EXTRUDERS)
#endif
{
SERIAL_ERROR_START;
SERIAL_ERROR((int)e);
SERIAL_ERRORLNPGM(MSG_INVALID_EXTRUDER_NUM);
kill();
return 0.0;
}
#ifdef HEATER_0_USES_MAX6675
if (e == 0)
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
if (e > EXTRUDERS)
#else
if (e >= EXTRUDERS)
#endif
{
return 0.25 * raw;
SERIAL_ERROR_START;
SERIAL_ERROR((int)e);
SERIAL_ERRORLNPGM(MSG_INVALID_EXTRUDER_NUM);
kill();
return 0.0;
}
#ifdef HEATER_0_USES_MAX6675
if (e == 0) return 0.25 * raw;
#endif
if(heater_ttbl_map[e] != NULL)
{
if (heater_ttbl_map[e] != NULL) {
float celsius = 0;
uint8_t i;
short (*tt)[][2] = (short (*)[][2])(heater_ttbl_map[e]);
for (i=1; i<heater_ttbllen_map[e]; i++)
{
if (PGM_RD_W((*tt)[i][0]) > raw)
{
for (i = 1; i < heater_ttbllen_map[e]; i++) {
if (PGM_RD_W((*tt)[i][0]) > raw) {
celsius = PGM_RD_W((*tt)[i-1][1]) +
(raw - PGM_RD_W((*tt)[i-1][0])) *
(float)(PGM_RD_W((*tt)[i][1]) - PGM_RD_W((*tt)[i-1][1])) /
......@@ -749,10 +753,8 @@ static float analog2tempBed(int raw) {
float celsius = 0;
byte i;
for (i=1; i<BEDTEMPTABLE_LEN; i++)
{
if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw)
{
for (i = 1; i < BEDTEMPTABLE_LEN; i++) {
if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw) {
celsius = PGM_RD_W(BEDTEMPTABLE[i-1][1]) +
(raw - PGM_RD_W(BEDTEMPTABLE[i-1][0])) *
(float)(PGM_RD_W(BEDTEMPTABLE[i][1]) - PGM_RD_W(BEDTEMPTABLE[i-1][1])) /
......@@ -773,12 +775,15 @@ static float analog2tempBed(int raw) {
#endif
#else //NO BED_USES_THERMISTOR
return 0;
#endif //BED_USES_THERMISTOR
#endif
}
/* Called to get the raw values into the the actual temperatures. The raw values are created in interrupt context,
and this function is called from normal context as it is too slow to run in interrupts and will block the stepper routine otherwise */
static void updateTemperaturesFromRawValues() {
static millis_t last_update = millis();
millis_t temp_last_update = millis();
millis_t from_last_update = temp_last_update - last_update;
#ifdef HEATER_0_USES_MAX6675
current_temperature_raw[0] = read_max6675();
#endif
......@@ -794,17 +799,22 @@ static void updateTemperaturesFromRawValues() {
#endif
#if HAS_POWER_CONSUMPTION_SENSOR
static float watt_overflow = 0.0;
static unsigned long last_power_update = millis();
unsigned long temp_last_power_update = millis();
power_consumption_meas = analog2power();
//MYSERIAL.println(analog2current(),3);
watt_overflow += (power_consumption_meas * (temp_last_power_update - last_power_update)) / 3600000.0;
watt_overflow += (power_consumption_meas * from_last_update) / 3600000.0;
if (watt_overflow >= 1.0) {
power_consumption_hour++;
watt_overflow--;
}
last_power_update = temp_last_power_update;
#endif
static unsigned int second_overflow = 0;
second_overflow += from_last_update;
if(second_overflow >= 1000) {
printer_usage_seconds++;
second_overflow -= 1000;
}
last_update = temp_last_update;
//Reset the watchdog after we know we have a temperature measurement.
watchdog_reset();
......@@ -844,8 +854,11 @@ static void updateTemperaturesFromRawValues() {
}
#endif
void tp_init()
{
/**
* Initialize the temperature manager
* The manager is implemented by periodic calls to manage_heater()
*/
void tp_init() {
#if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))
//disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector
MCUCR=BIT(JTD);
......@@ -1028,7 +1041,7 @@ void tp_init()
void setWatch() {
#ifdef WATCH_TEMP_PERIOD
unsigned long ms = millis();
millis_t ms = millis();
for (int e = 0; e < HOTENDS; e++) {
if (degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE * 2)) {
watch_start_temp[e] = degHotend(e);
......@@ -1040,7 +1053,7 @@ void setWatch() {
#if HAS_HEATER_THERMAL_PROTECTION || HAS_BED_THERMAL_PROTECTION
void thermal_runaway_protection(TRState *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) {
void thermal_runaway_protection(TRState *state, millis_t *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) {
static float tr_target_temperature[EXTRUDERS+1] = { 0.0 };
......@@ -1095,7 +1108,7 @@ void setWatch() {
SERIAL_ERRORLNPGM(MSG_THERMAL_RUNAWAY_STOP);
if (heater_id < 0) SERIAL_ERRORLNPGM("bed"); else SERIAL_ERRORLN(heater_id);
LCD_ALERTMESSAGEPGM(MSG_THERMAL_RUNAWAY);
disable_heater();
disable_all_heaters();
disable_all_steppers();
for (;;) {
manage_heater();
......@@ -1106,7 +1119,7 @@ void setWatch() {
#endif // HAS_HEATER_THERMAL_PROTECTION || HAS_BED_THERMAL_PROTECTION
void disable_heater() {
void disable_all_heaters() {
for (int i = 0; i < HOTENDS; i++) setTargetHotend(0, i);
setTargetBed(0);
......@@ -1143,16 +1156,18 @@ void disable_heater() {
#ifdef HEATER_0_USES_MAX6675
#define MAX6675_HEAT_INTERVAL 250u
unsigned long max6675_previous_millis = MAX6675_HEAT_INTERVAL;
static millis_t next_max6675_ms = 0;
int max6675_temp = 2000;
static int read_max6675() {
unsigned long ms = millis();
if (ms < max6675_previous_millis + MAX6675_HEAT_INTERVAL)
millis_t ms = millis();
if (ms < next_max6675_ms)
return max6675_temp;
max6675_previous_millis = ms;
next_max6675_ms = ms + MAX6675_HEAT_INTERVAL;
max6675_temp = 0;
#ifdef PRR
......@@ -1251,11 +1266,14 @@ static void set_current_temp_raw() {
temp_meas_ready = true;
}
//
// Timer 0 is shared with millies
//
/**
* Timer 0 is shared with millies
* - Manage PWM to all the heaters and fan
* - Update the raw temperature values
* - Check new temperature values for MIN/MAX errors
* - Step the babysteps value for each axis towards 0
*/
ISR(TIMER0_COMPB_vect) {
//these variables are only accesible from the ISR, but static, so they don't lose their value
static unsigned char temp_count = 0;
static TempState temp_state = StartupDelay;
static unsigned char pwm_count = BIT(SOFT_PWM_SCALE);
......@@ -1646,16 +1664,16 @@ ISR(TIMER0_COMPB_vect) {
} // temp_count >= OVERSAMPLENR
#ifdef BABYSTEPPING
for (uint8_t axis=X_AXIS; axis<=Z_AXIS; axis++) {
int curTodo=babystepsTodo[axis]; //get rid of volatile for performance
for (uint8_t axis = X_AXIS; axis <= Z_AXIS; axis++) {
int curTodo = babystepsTodo[axis]; //get rid of volatile for performance
if (curTodo > 0) {
babystep(axis,/*fwd*/true);
babystepsTodo[axis]--; //less to do next time
babystepsTodo[axis]--; //fewer to do next time
}
else if(curTodo < 0) {
else if (curTodo < 0) {
babystep(axis,/*fwd*/false);
babystepsTodo[axis]++; //less to do next time
babystepsTodo[axis]++; //fewer to do next time
}
}
#endif //BABYSTEPPING
......
......@@ -23,6 +23,7 @@
#include "Marlin.h"
#include "planner.h"
#include "stepper.h"
// public functions
void tp_init(); //initialize the heating
......@@ -133,7 +134,7 @@ HOTEND_ROUTINES(0);
#endif
int getHeaterPower(int heater);
void disable_heater();
void disable_all_heaters();
void setWatch();
void updatePID();
......
......@@ -31,11 +31,11 @@ int gumPreheatHPBTemp;
int gumPreheatFanSpeed;
#if HAS_LCD_FILAMENT_SENSOR || HAS_LCD_POWER_SENSOR
unsigned long message_millis = 0;
millis_t previous_lcd_status_ms = 0;
#endif
#if HAS_LCD_POWER_SENSOR
unsigned long print_millis = 0;
millis_t print_millis = 0;
#endif
/* !Configuration settings */
......@@ -86,8 +86,6 @@ static void lcd_status_screen();
static void lcd_delta_calibrate_menu();
#endif // DELTA
static void lcd_quick_feedback();//Cause an LCD refresh, and give the user visual or audible feedback that something has happened
/* Different types of actions that can be used in menu items. */
static void menu_action_back(menuFunc_t data);
static void menu_action_submenu(menuFunc_t data);
......@@ -163,10 +161,10 @@ static void lcd_status_screen();
* lcd_implementation_drawmenu_function(sel, row, PSTR(MSG_PAUSE_PRINT), lcd_sdcard_pause)
* menu_action_function(lcd_sdcard_pause)
*
* MENU_ITEM_EDIT(int3, MSG_SPEED, &feedmultiply, 10, 999)
* MENU_ITEM(setting_edit_int3, MSG_SPEED, PSTR(MSG_SPEED), &feedmultiply, 10, 999)
* lcd_implementation_drawmenu_setting_edit_int3(sel, row, PSTR(MSG_SPEED), PSTR(MSG_SPEED), &feedmultiply, 10, 999)
* menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedmultiply, 10, 999)
* MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_multiplier, 10, 999)
* MENU_ITEM(setting_edit_int3, MSG_SPEED, PSTR(MSG_SPEED), &feedrate_multiplier, 10, 999)
* lcd_implementation_drawmenu_setting_edit_int3(sel, row, PSTR(MSG_SPEED), PSTR(MSG_SPEED), &feedrate_multiplier, 10, 999)
* menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedrate_multiplier, 10, 999)
*
*/
#define MENU_ITEM(type, label, args...) do { \
......@@ -229,7 +227,7 @@ static void lcd_status_screen();
volatile uint8_t slow_buttons; // Bits of the pressed buttons.
#endif
uint8_t currentMenuViewOffset; /* scroll offset in the current menu */
uint32_t blocking_enc;
millis_t next_button_update_ms;
uint8_t lastEncoderBits;
uint32_t encoderPosition;
#if (SDCARDDETECT > 0)
......@@ -239,7 +237,7 @@ static void lcd_status_screen();
#endif // ULTIPANEL
menuFunc_t currentMenu = lcd_status_screen; /* function pointer to the currently active menu */
uint32_t lcd_next_update_millis;
millis_t next_lcd_update_ms;
uint8_t lcd_status_update_delay;
bool ignore_click = false;
bool wait_for_unclick;
......@@ -257,10 +255,10 @@ menuFunc_t callbackFunc;
// place-holders for Ki and Kd edits
float raw_Ki, raw_Kd;
static void lcd_goto_menu(menuFunc_t menu, const uint32_t encoder=0, const bool feedback=true) {
static void lcd_goto_menu(menuFunc_t menu, const bool feedback=false, const uint32_t encoder=0) {
if (currentMenu != menu) {
currentMenu = menu;
#if defined(NEWPANEL)
#ifdef NEWPANEL
encoderPosition = encoder;
if (feedback) lcd_quick_feedback();
#endif
......@@ -276,7 +274,7 @@ static void lcd_status_screen() {
encoderRateMultiplierEnabled = false;
#ifdef LCD_PROGRESS_BAR
unsigned long ms = millis();
millis_t ms = millis();
#ifndef PROGRESS_MSG_ONCE
if (ms > progressBarTick + PROGRESS_BAR_MSG_TIME + PROGRESS_BAR_BAR_TIME) {
progressBarTick = ms;
......@@ -313,12 +311,12 @@ static void lcd_status_screen() {
#if HAS_LCD_FILAMENT_SENSOR || HAS_LCD_POWER_SENSOR
#if HAS_LCD_FILAMENT_SENSOR && HAS_LCD_POWER_SENSOR
if (millis() > message_millis + 15000)
if (millis() > previous_lcd_status_ms + 15000)
#else
if (millis() > message_millis + 10000)
if (millis() > previous_lcd_status_ms + 10000)
#endif
{
message_millis = millis();
previous_lcd_status_ms = millis();
}
#endif
......@@ -327,70 +325,62 @@ static void lcd_status_screen() {
bool current_click = LCD_CLICKED;
if (ignore_click) {
if (wait_for_unclick) {
if (!current_click) {
ignore_click = wait_for_unclick = false;
}
else {
current_click = false;
}
}
else if (current_click) {
lcd_quick_feedback();
wait_for_unclick = true;
current_click = false;
}
if (wait_for_unclick) {
if (!current_click)
ignore_click = wait_for_unclick = false;
else
current_click = false;
}
else if (current_click) {
lcd_quick_feedback();
wait_for_unclick = true;
current_click = false;
}
}
if (current_click)
{
lcd_goto_menu(lcd_main_menu);
if (current_click) {
lcd_goto_menu(lcd_main_menu, true);
lcd_implementation_init( // to maybe revive the LCD if static electricity killed it.
#ifdef LCD_PROGRESS_BAR
currentMenu == lcd_status_screen
#endif
);
#ifdef FILAMENT_LCD_DISPLAY
message_millis = millis(); // get status message to show up for a while
previous_lcd_status_ms = millis(); // get status message to show up for a while
#endif
}
#ifdef ULTIPANEL_FEEDMULTIPLY
// Dead zone at 100% feedrate
if ((feedmultiply < 100 && (feedmultiply + int(encoderPosition)) > 100) ||
(feedmultiply > 100 && (feedmultiply + int(encoderPosition)) < 100))
{
encoderPosition = 0;
feedmultiply = 100;
}
if (feedmultiply == 100 && int(encoderPosition) > ENCODER_FEEDRATE_DEADZONE)
{
feedmultiply += int(encoderPosition) - ENCODER_FEEDRATE_DEADZONE;
#ifdef ULTIPANEL_FEEDMULTIPLY
// Dead zone at 100% feedrate
if ((feedrate_multiplier < 100 && (feedrate_multiplier + int(encoderPosition)) > 100) ||
(feedrate_multiplier > 100 && (feedrate_multiplier + int(encoderPosition)) < 100)) {
encoderPosition = 0;
}
else if (feedmultiply == 100 && int(encoderPosition) < -ENCODER_FEEDRATE_DEADZONE)
{
feedmultiply += int(encoderPosition) + ENCODER_FEEDRATE_DEADZONE;
encoderPosition = 0;
}
else if (feedmultiply != 100)
{
feedmultiply += int(encoderPosition);
feedrate_multiplier = 100;
}
if (feedrate_multiplier == 100) {
if (int(encoderPosition) > ENCODER_FEEDRATE_DEADZONE) {
feedrate_multiplier += int(encoderPosition) - ENCODER_FEEDRATE_DEADZONE;
encoderPosition = 0;
}
else if (int(encoderPosition) < -ENCODER_FEEDRATE_DEADZONE) {
feedrate_multiplier += int(encoderPosition) + ENCODER_FEEDRATE_DEADZONE;
encoderPosition = 0;
}
}
else {
feedrate_multiplier += int(encoderPosition);
encoderPosition = 0;
}
#endif //ULTIPANEL_FEEDMULTIPLY
}
#endif // ULTIPANEL_FEEDMULTIPLY
if (feedmultiply < 10)
feedmultiply = 10;
else if (feedmultiply > 999)
feedmultiply = 999;
#endif //ULTIPANEL
feedrate_multiplier = constrain(feedrate_multiplier, 10, 999);
#endif //ULTIPANEL
}
#ifdef ULTIPANEL
static void lcd_return_to_status() { lcd_goto_menu(lcd_status_screen, 0, false); }
static void lcd_return_to_status() { lcd_goto_menu(lcd_status_screen); }
static void lcd_sdcard_pause() { card.pauseSDPrint(); }
......@@ -399,7 +389,7 @@ static void lcd_sdcard_resume() { card.startFileprint(); }
static void lcd_sdcard_stop() {
quickStop();
card.sdprinting = false;
card.closefile();
card.closeFile();
autotempShutdown();
cancel_heatup = true;
lcd_setstatus(MSG_PRINT_ABORTED, true);
......@@ -465,7 +455,7 @@ void lcd_set_home_offsets() {
plan_set_position(0.0, 0.0, 0.0, current_position[E_AXIS]);
// Audio feedback
enquecommands_P(PSTR("M300 S659 P200\nM300 S698 P200"));
enqueuecommands_P(PSTR("M300 S659 P200\nM300 S698 P200"));
lcd_return_to_status();
}
......@@ -490,7 +480,7 @@ void lcd_set_home_offsets() {
static void lcd_tune_menu() {
START_MENU();
MENU_ITEM(back, MSG_MAIN, lcd_main_menu);
MENU_ITEM_EDIT(int3, MSG_SPEED, &feedmultiply, 10, 999);
MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_multiplier, 10, 999);
#if TEMP_SENSOR_0 != 0
MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP + LCD_MAX_TEMP_OFFSET);
#endif
......@@ -687,7 +677,7 @@ void config_lcd_level_bed()
SERIAL_ECHOLN("Leveling...");
currentMenu = lcd_level_bed;
enquecommands_P(PSTR("G28 M"));
enqueuecommands_P(PSTR("G28 M"));
pageShowInfo = 0;
}
......@@ -1301,15 +1291,15 @@ menu_edit_type(unsigned long, long5, ftostr5, 0.01)
lcd_move_y();
}
static void reprapworld_keypad_move_home() {
enquecommands_P((PSTR("G28"))); // move all axis home
enqueuecommands_P((PSTR("G28"))); // move all axis home
}
#endif //REPRAPWORLD_KEYPAD
/** End of menus **/
static void lcd_quick_feedback() {
void lcd_quick_feedback() {
lcdDrawUpdate = 2;
blocking_enc = millis() + 500;
next_button_update_ms = millis() + 500;
#ifdef LCD_USE_I2C_BUZZER
#ifndef LCD_FEEDBACK_FREQUENCY_HZ
......@@ -1327,15 +1317,15 @@ static void lcd_quick_feedback() {
#ifndef LCD_FEEDBACK_FREQUENCY_DURATION_MS
#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2
#endif
const unsigned int delay = 1000000 / LCD_FEEDBACK_FREQUENCY_HZ / 2;
int i = LCD_FEEDBACK_FREQUENCY_DURATION_MS * LCD_FEEDBACK_FREQUENCY_HZ / 1000;
const uint16_t delay = 1000000 / LCD_FEEDBACK_FREQUENCY_HZ / 2;
uint16_t i = LCD_FEEDBACK_FREQUENCY_DURATION_MS * LCD_FEEDBACK_FREQUENCY_HZ / 1000;
while (i--) {
WRITE(BEEPER,HIGH);
delayMicroseconds(delay);
WRITE(BEEPER,LOW);
delayMicroseconds(delay);
}
const int j = max(10000 - LCD_FEEDBACK_FREQUENCY_DURATION_MS * 1000, 0);
const uint16_t j = max(10000 - LCD_FEEDBACK_FREQUENCY_DURATION_MS * 1000, 0);
if (j) delayMicroseconds(j);
#endif
}
......@@ -1343,15 +1333,15 @@ static void lcd_quick_feedback() {
/** Menu action functions **/
static void menu_action_back(menuFunc_t data) { lcd_goto_menu(data); }
static void menu_action_submenu(menuFunc_t data) { lcd_goto_menu(data); }
static void menu_action_gcode(const char* pgcode) { enquecommands_P(pgcode); }
static void menu_action_gcode(const char* pgcode) { enqueuecommands_P(pgcode); }
static void menu_action_function(menuFunc_t data) { (*data)(); }
static void menu_action_sdfile(const char* filename, char* longFilename) {
char cmd[30];
char* c;
sprintf_P(cmd, PSTR("M23 %s"), filename);
for(c = &cmd[4]; *c; c++) *c = tolower(*c);
enquecommand(cmd);
enquecommands_P(PSTR("M24"));
enqueuecommand(cmd);
enqueuecommands_P(PSTR("M24"));
lcd_return_to_status();
}
static void menu_action_sddirectory(const char* filename, char* longFilename) {
......@@ -1439,7 +1429,7 @@ int lcd_strlen_P(const char *s) {
void lcd_update() {
#ifdef ULTIPANEL
static unsigned long timeoutToStatus = 0;
static millis_t return_to_status_ms = 0;
#endif
#ifdef LCD_HAS_SLOW_BUTTONS
......@@ -1468,9 +1458,9 @@ void lcd_update() {
}
}
#endif//CARDINSERTED
uint32_t ms = millis();
if (ms > lcd_next_update_millis) {
millis_t ms = millis();
if (ms > next_lcd_update_ms) {
#ifdef ULTIPANEL
......@@ -1522,7 +1512,7 @@ void lcd_update() {
encoderPosition += (encoderDiff * encoderMultiplier) / ENCODER_PULSES_PER_STEP;
encoderDiff = 0;
}
timeoutToStatus = ms + LCD_TIMEOUT_TO_STATUS;
return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS;
lcdDrawUpdate = 1;
}
#endif //ULTIPANEL
......@@ -1558,7 +1548,7 @@ void lcd_update() {
#endif
#ifdef ULTIPANEL
if (currentMenu != lcd_status_screen && millis() > timeoutToStatus) {
if (currentMenu != lcd_status_screen && millis() > return_to_status_ms) {
lcd_return_to_status();
lcdDrawUpdate = 2;
}
......@@ -1566,7 +1556,7 @@ void lcd_update() {
if (lcdDrawUpdate == 2) lcd_implementation_clear();
if (lcdDrawUpdate) lcdDrawUpdate--;
lcd_next_update_millis = millis() + LCD_UPDATE_INTERVAL;
next_lcd_update_ms = millis() + LCD_UPDATE_INTERVAL;
}
}
......@@ -1585,7 +1575,7 @@ void lcd_finishstatus(bool persist=false) {
lcdDrawUpdate = 2;
#ifdef FILAMENT_LCD_DISPLAY
message_millis = millis(); //get status message to show up for a while
previous_lcd_status_ms = millis(); //get status message to show up for a while
#endif
}
......@@ -1659,7 +1649,7 @@ void lcd_buttons_update() {
if (READ(BTN_EN2) == 0) newbutton |= EN_B;
#endif
#if BTN_ENC > 0
if (millis() > blocking_enc && READ(BTN_ENC) == 0) newbutton |= EN_C;
if (millis() > next_button_update_ms && READ(BTN_ENC) == 0) newbutton |= EN_C;
#endif
buttons = newbutton;
#ifdef LCD_HAS_SLOW_BUTTONS
......
......@@ -57,10 +57,11 @@
extern bool cancel_heatup;
#if (HAS_FILAMENT_SENSOR && defined(FILAMENT_LCD_DISPLAY)) || (HAS_POWER_CONSUMPTION_SENSOR && defined(POWER_CONSUMPTION_LCD_DISPLAY))
extern unsigned long message_millis;
extern millis_t previous_lcd_status_ms;
#endif
void lcd_buzz(long duration,uint16_t freq);
void lcd_quick_feedback(); // Audible feedback for a button click - could also be visual
bool lcd_clicked();
void lcd_ignore_click(bool b=true);
......
......@@ -582,7 +582,7 @@ static void lcd_implementation_status_screen() {
lcd.setCursor(0, 2);
lcd.print(LCD_STR_FEEDRATE[0]);
lcd.print(itostr3(feedmultiply));
lcd.print(itostr3(feedrate_multiplier));
lcd.print('%');
#if LCD_WIDTH > 19 && defined(SDSUPPORT)
......@@ -598,11 +598,11 @@ static void lcd_implementation_status_screen() {
#endif // LCD_WIDTH > 19 && SDSUPPORT
lcd.setCursor(LCD_WIDTH - 6, 2);
if(starttime != 0) {
if(print_job_start_ms != 0) {
#if HAS_LCD_POWER_SENSOR
if (millis() < print_millis + 1000) {
lcd.print(LCD_STR_CLOCK[0]);
uint16_t time = millis()/60000 - starttime/60000;
uint16_t time = millis()/60000 - print_job_start_ms/60000;
lcd.print(itostr2(time/60));
lcd.print(':');
lcd.print(itostr2(time%60));
......@@ -613,7 +613,7 @@ static void lcd_implementation_status_screen() {
}
#else
lcd.print(LCD_STR_CLOCK[0]);
uint16_t time = millis()/60000 - starttime/60000;
uint16_t time = millis()/60000 - print_job_start_ms/60000;
lcd.print(itostr2(time/60));
lcd.print(':');
lcd.print(itostr2(time%60));
......@@ -656,12 +656,12 @@ static void lcd_implementation_status_screen() {
//Display both Status message line and Filament display on the last line
#if HAS_LCD_FILAMENT_SENSOR || HAS_LCD_POWER_SENSOR
if (millis() < message_millis + 5000) { //Display both Status message line and Filament display on the last line
if (millis() >= previous_lcd_status_ms + 5000) {
lcd_print(lcd_status_message);
}
#if HAS_LCD_POWER_SENSOR
#if HAS_LCD_FILAMENT_SENSOR
else if (millis() < message_millis + 10000)
else if (millis() < previous_lcd_status_ms + 10000)
#else
else
#endif
......@@ -788,46 +788,45 @@ static void lcd_implementation_drawmenu_sddirectory(bool sel, uint8_t row, const
#define lcd_implementation_drawmenu_function(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ')
#ifdef LCD_HAS_STATUS_INDICATORS
static void lcd_implementation_update_indicators()
{
#if defined(LCD_I2C_PANELOLU2) || defined(LCD_I2C_VIKI)
//set the LEDS - referred to as backlights by the LiquidTWI2 library
static uint8_t ledsprev = 0;
uint8_t leds = 0;
if (target_temperature_bed > 0) leds |= LED_A;
if (target_temperature[0] > 0) leds |= LED_B;
if (fanSpeed) leds |= LED_C;
#if HOTENDS > 1
if (target_temperature[1] > 0) leds |= LED_C;
static void lcd_implementation_update_indicators() {
#if defined(LCD_I2C_PANELOLU2) || defined(LCD_I2C_VIKI)
//set the LEDS - referred to as backlights by the LiquidTWI2 library
static uint8_t ledsprev = 0;
uint8_t leds = 0;
if (target_temperature_bed > 0) leds |= LED_A;
if (target_temperature[0] > 0) leds |= LED_B;
if (fanSpeed) leds |= LED_C;
#if HOTENDS > 1
if (target_temperature[1] > 0) leds |= LED_C;
#endif
if (leds != ledsprev) {
lcd.setBacklight(leds);
ledsprev = leds;
}
#endif
if (leds != ledsprev) {
lcd.setBacklight(leds);
ledsprev = leds;
}
#endif
}
#endif
}
#endif // LCD_HAS_STATUS_INDICATORS
#ifdef LCD_HAS_SLOW_BUTTONS
extern uint32_t blocking_enc;
static uint8_t lcd_implementation_read_slow_buttons()
{
#ifdef LCD_I2C_TYPE_MCP23017
uint8_t slow_buttons;
// Reading these buttons this is likely to be too slow to call inside interrupt context
// so they are called during normal lcd_update
slow_buttons = lcd.readButtons() << B_I2C_BTN_OFFSET;
#if defined(LCD_I2C_VIKI)
if(slow_buttons & (B_MI|B_RI)) { //LCD clicked
if(blocking_enc > millis()) {
slow_buttons &= ~(B_MI|B_RI); // Disable LCD clicked buttons if screen is updated
}
}
extern millis_t next_button_update_ms;
static uint8_t lcd_implementation_read_slow_buttons() {
#ifdef LCD_I2C_TYPE_MCP23017
uint8_t slow_buttons;
// Reading these buttons this is likely to be too slow to call inside interrupt context
// so they are called during normal lcd_update
slow_buttons = lcd.readButtons() << B_I2C_BTN_OFFSET;
#ifdef LCD_I2C_VIKI
if ((slow_buttons & (B_MI|B_RI)) && millis() < next_button_update_ms) // LCD clicked
slow_buttons &= ~(B_MI|B_RI); // Disable LCD clicked buttons if screen is updated
#endif
return slow_buttons;
#endif
return slow_buttons;
#endif
}
#endif
}
#endif // LCD_HAS_SLOW_BUTTONS
#endif //__ULTRALCD_IMPLEMENTATION_HITACHI_HD44780_H
......@@ -39,9 +39,10 @@ The current MarlinKimbra dev team consists of:
More features have been added by:
-
- simone97 (https://github.com/simone97)
-
## License
Marlin is published under the [GPL license](/Documentation/COPYING.md) because I believe in open development.
Please do not use this code in products (3D printers, CNC etc) that are closed source or are crippled by a patent.
\ No newline at end of file
Please do not use this code in products (3D printers, CNC etc) that are closed source or are crippled by a patent.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment