void probe_1point() { float Point; Point = Probe_Bed(-1,-1,PROBE_N); //destination[2] = Point +1; //feedrate = homing_feedrate[Z_AXIS]; //prepare_move(); SERIAL_ECHOLN("**************************************"); SERIAL_ECHO("Probed Z="); SERIAL_ECHOLN(Point); }
void checkHitEndstops() { if( endstop_x_hit || endstop_y_hit || endstop_z_hit) { SERIAL_ECHO_START; SERIAL_ECHO(MSG_ENDSTOPS_HIT); if(endstop_x_hit) { SERIAL_ECHOPAIR(" X:",(float)endstops_trigsteps[X_AXIS]/axis_steps_per_unit[X_AXIS]); } if(endstop_y_hit) { SERIAL_ECHOPAIR(" Y:",(float)endstops_trigsteps[Y_AXIS]/axis_steps_per_unit[Y_AXIS]); } if(endstop_z_hit) { SERIAL_ECHOPAIR(" Z:",(float)endstops_trigsteps[Z_AXIS]/axis_steps_per_unit[Z_AXIS]); } SERIAL_ECHOLN(""); endstop_x_hit=false; endstop_y_hit=false; endstop_z_hit=false; if (abort_on_endstop_hit){ quickStop(); Jawsboard::getBoard().setTargetDegExtruder(0,0); Jawsboard::getBoard().setTargetDegExtruder(0,1); Jawsboard::getBoard().setTargetDegExtruder(0,2); } } }
void CardReader::chdir(const char* relpath) { SdFile newfile; SdFile* parent=&root; if(workDir.isOpen()) { parent=&workDir; } if(!newfile.open(*parent,relpath, O_READ)) { SERIAL_ECHO_START; SERIAL_ECHOPGM(MSG_SD_CANT_ENTER_SUBDIR); SERIAL_ECHOLN(relpath); } else { if(workDirDepth < MAX_DIR_DEPTH) { for(int d = ++workDirDepth; d--;) { workDirParents[d+1] = workDirParents[d]; } workDirParents[0]=*parent; } workDir=newfile; } }
void checkHitEndstops() { if( endstop_x_hit || endstop_y_hit || endstop_z_hit) { SERIAL_ECHO_START; SERIAL_ECHOPGM(MSG_ENDSTOPS_HIT); if(endstop_x_hit) { SERIAL_ECHOPAIR(" X:",(float)endstops_trigsteps[X_AXIS]/axis_steps_per_unit[X_AXIS]); LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT "X"); } if(endstop_y_hit) { SERIAL_ECHOPAIR(" Y:",(float)endstops_trigsteps[Y_AXIS]/axis_steps_per_unit[Y_AXIS]); LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT "Y"); } if(endstop_z_hit) { SERIAL_ECHOPAIR(" Z:",(float)endstops_trigsteps[Z_AXIS]/axis_steps_per_unit[Z_AXIS]); LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT "Z"); } SERIAL_ECHOLN(""); endstop_x_hit=false; endstop_y_hit=false; endstop_z_hit=false; #ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED if (abort_on_endstop_hit) { card.sdprinting = false; card.closefile(); quickStop(); setTargetHotend0(0); setTargetHotend1(0); setTargetHotend2(0); } #endif } }
void checkHitEndstops() { if( endstop_x_hit || endstop_y_hit || endstop_z_hit || endstop_p_hit || endstop_v_hit) { SERIAL_ECHO_START; SERIAL_ECHOPGM(MSG_ENDSTOPS_HIT); if(endstop_x_hit) { SERIAL_ECHOPAIR(" X:",(float)endstops_trigsteps[X_AXIS]/axis_steps_per_unit[X_AXIS]); } if(endstop_y_hit) { SERIAL_ECHOPAIR(" Y:",(float)endstops_trigsteps[Y_AXIS]/axis_steps_per_unit[Y_AXIS]); } if(endstop_z_hit) { SERIAL_ECHOPAIR(" Z:",(float)endstops_trigsteps[Z_AXIS]/axis_steps_per_unit[Z_AXIS]); } if(endstop_p_hit) { SERIAL_ECHOPAIR(" P:",(float)endstops_trigsteps[P_AXIS]/axis_steps_per_unit[P_AXIS]); } if(endstop_v_hit) { SERIAL_ECHOPAIR(" V:",(float)endstops_trigsteps[V_AXIS]/axis_steps_per_unit[V_AXIS]); } SERIAL_ECHOLN(""); endstop_x_hit=false; endstop_y_hit=false; endstop_z_hit=false; endstop_p_hit=false; endstop_v_hit=false; } }
void ScreenSerial::draw() { if ( !m_text || m_needs_drawing) { m_needs_drawing = false; //Start painting sequence painter.firstPage(); do { painter.setColorIndex(1); //Paint title on top of screen painter.title(MSG_SCREEN_SERIAL_TITLE()); //Paint bitmap on the left uint8_t x_init = painter.coordinateXInit(); uint8_t y_init = painter.coordinateYInit(); uint8_t x_end = painter.coordinateXEnd(); uint8_t y_end = painter.coordinateYEnd(); uint8_t x_offset = 6; uint8_t y_offset = 4; painter.setColorIndex(1); painter.drawBitmap(x_init + x_offset, y_init + y_offset, serial_width, serial_height, bits_serial); //Print state Area text_area(x_init + x_offset + serial_width, y_init, 127, 63); painter.setWorkingArea(text_area); SERIAL_ECHOLN(m_text); painter.multiText(m_text); } while( painter.nextPage() ); } }
/** * M0: Unconditional stop - Wait for user button press on LCD * M1: Conditional stop - Wait for user button press on LCD */ void GcodeSuite::M0_M1() { const char * const args = parser.string_arg; millis_t ms = 0; bool hasP = false, hasS = false; if (parser.seenval('P')) { ms = parser.value_millis(); // milliseconds to wait hasP = ms > 0; } if (parser.seenval('S')) { ms = parser.value_millis_from_seconds(); // seconds to wait hasS = ms > 0; } #if ENABLED(ULTIPANEL) if (!hasP && !hasS && args && *args) lcd_setstatus(args, true); else { LCD_MESSAGEPGM(MSG_USERWAIT); #if ENABLED(LCD_PROGRESS_BAR) && PROGRESS_MSG_EXPIRE > 0 dontExpireStatus(); #endif } #else if (!hasP && !hasS && args && *args) { SERIAL_ECHO_START(); SERIAL_ECHOLN(args); } #endif KEEPALIVE_STATE(PAUSED_FOR_USER); wait_for_user = true; stepper.synchronize(); refresh_cmd_timeout(); if (ms > 0) { ms += previous_cmd_ms; // wait until this time for a click while (PENDING(millis(), ms) && wait_for_user) idle(); } else { #if ENABLED(ULTIPANEL) if (lcd_detected()) { while (wait_for_user) idle(); IS_SD_PRINTING ? LCD_MESSAGEPGM(MSG_RESUMING) : LCD_MESSAGEPGM(WELCOME_MSG); } #else while (wait_for_user) idle(); #endif } wait_for_user = false; KEEPALIVE_STATE(IN_HANDLER); }
void CardReader::removeFile(char* name) { if (!cardOK) return; file.close(); sdprinting = false; SdFile myDir; curDir = &root; char *fname = name; char *dirname_start, *dirname_end; if (name[0] == '/') { dirname_start = strchr(name, '/') + 1; while (dirname_start > 0) { dirname_end = strchr(dirname_start, '/'); //SERIAL_ECHO("start:");SERIAL_ECHOLN((int)(dirname_start - name)); //SERIAL_ECHO("end :");SERIAL_ECHOLN((int)(dirname_end - name)); if (dirname_end > 0 && dirname_end > dirname_start) { char subdirname[FILENAME_LENGTH]; strncpy(subdirname, dirname_start, dirname_end - dirname_start); subdirname[dirname_end - dirname_start] = 0; SERIAL_ECHOLN(subdirname); if (!myDir.open(curDir, subdirname, O_READ)) { SERIAL_PROTOCOLPGM("open failed, File: "); SERIAL_PROTOCOL(subdirname); SERIAL_PROTOCOLCHAR('.'); return; } else { //SERIAL_ECHOLN("dive ok"); } curDir = &myDir; dirname_start = dirname_end + 1; } else { // the remainder after all /fsa/fdsa/ is the filename fname = dirname_start; //SERIAL_ECHOLN("remainder"); //SERIAL_ECHOLN(fname); break; } } } else { // relative path curDir = &workDir; } if (file.remove(curDir, fname)) { SERIAL_PROTOCOLPGM("File deleted:"); SERIAL_PROTOCOLLN(fname); sdpos = 0; } else { SERIAL_PROTOCOLPGM("Deletion failed, File: "); SERIAL_PROTOCOL(fname); SERIAL_PROTOCOLCHAR('.'); } }
void M100_dump_routine(const char * const title, const char *start, const char *end) { SERIAL_ECHOLN(title); // // Round the start and end locations to produce full lines of output // start = (char*)((uint16_t) start & 0xFFF0); end = (char*)((uint16_t) end | 0x000F); dump_free_memory(start, end); }
void StorageManager::InitilializeStats() { SERIAL_ECHOLN("Initializing stats to zero"); StorageManager::single::instance().writeByte(ADDR_STAT_FLAG, 0x00); StorageManager::single::instance().setStatHours(0); StorageManager::single::instance().setStatMinutes(0); StorageManager::single::instance().setStatTotalPrints(0); StorageManager::single::instance().setStatSucceded(0); }
void laser_extinguish(){ if (laser.firing == LASER_ON) { laser.firing = LASER_OFF; // Engage the pullup resistor for TTL laser controllers which don't turn off entirely without it. pinMode(LASER_FIRING_PIN, INPUT); laser.time += millis() - (laser.last_firing / 1000); if (laser.diagnostics) { SERIAL_ECHOLN("Laser extinguished"); } } }
void Config_RetrieveSettings() { int i=EEPROM_OFFSET; char stored_ver[4]; char ver[4]=EEPROM_VERSION; EEPROM_READ_VAR(i,stored_ver); //read stored version // SERIAL_ECHOLN("Version: [" << ver << "] Stored version: [" << stored_ver << "]"); if (strncmp(ver,stored_ver,3) == 0) { // version number match EEPROM_READ_VAR(i,axis_steps_per_unit); EEPROM_READ_VAR(i,max_feedrate); EEPROM_READ_VAR(i,max_acceleration_units_per_sq_second); EEPROM_READ_VAR(i,acceleration); EEPROM_READ_VAR(i,retract_acceleration); EEPROM_READ_VAR(i,minimumfeedrate); EEPROM_READ_VAR(i,mintravelfeedrate); EEPROM_READ_VAR(i,minsegmenttime); EEPROM_READ_VAR(i,max_xy_jerk); EEPROM_READ_VAR(i,max_z_jerk); EEPROM_READ_VAR(i,max_e_jerk); EEPROM_READ_VAR(i,add_homeing); #ifndef ULTIPANEL int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed; int absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed; #endif EEPROM_READ_VAR(i,plaPreheatHotendTemp); EEPROM_READ_VAR(i,plaPreheatHPBTemp); EEPROM_READ_VAR(i,plaPreheatFanSpeed); EEPROM_READ_VAR(i,absPreheatHotendTemp); EEPROM_READ_VAR(i,absPreheatHPBTemp); EEPROM_READ_VAR(i,absPreheatFanSpeed); #ifndef PIDTEMP float Kp,Ki,Kd; #endif EEPROM_READ_VAR(i,Kp); EEPROM_READ_VAR(i,Ki); EEPROM_READ_VAR(i,Kd); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Stored settings retreived:"); } else { Config_ResetDefault(); SERIAL_ECHO_START; SERIAL_ECHOLN("Using Default settings:"); } Config_PrintSettings(); }
void dac_print_values() { if (!dac_present) return; SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("Stepper current values in % (Amps):"); SERIAL_ECHO_START(); SERIAL_ECHOPAIR(" X:", dac_perc(X_AXIS)); SERIAL_ECHOPAIR(" (", dac_amps(X_AXIS)); SERIAL_ECHOPAIR(") Y:", dac_perc(Y_AXIS)); SERIAL_ECHOPAIR(" (", dac_amps(Y_AXIS)); SERIAL_ECHOPAIR(") Z:", dac_perc(Z_AXIS)); SERIAL_ECHOPAIR(" (", dac_amps(Z_AXIS)); SERIAL_ECHOPAIR(") E:", dac_perc(E_AXIS)); SERIAL_ECHOPAIR(" (", dac_amps(E_AXIS)); SERIAL_ECHOLN(")"); }
void CardReader::chdir(const char * relpath) { SdFile newfile; SdFile *parent = &root; if (workDir.isOpen()) parent = &workDir; if (!newfile.open(*parent, relpath, O_READ)) { SERIAL_ECHO_START; SERIAL_ECHOPGM(MSG_SD_CANT_ENTER_SUBDIR); SERIAL_ECHOLN(relpath); } else { if (workDirDepth < MAX_DIR_DEPTH) workDirParents[workDirDepth++] = *parent; workDir = newfile; } }
void laser_fire(int intensity = 100.0){ laser.firing = LASER_ON; laser.last_firing = micros(); // microseconds of last laser firing if (intensity > 100.0) intensity = 100.0; // restrict intensity between 0 and 100 if (intensity < 0) intensity = 0; pinMode(LASER_FIRING_PIN, OUTPUT); #if LASER_CONTROL == 1 analogWrite(LASER_FIRING_PIN, labs((intensity / 100.0)*(F_CPU / LASER_PWM))); #endif #if LASER_CONTROL == 2 analogWrite(LASER_INTENSITY_PIN, labs((intensity / 100.0)*(F_CPU / LASER_PWM))); digitalWrite(LASER_FIRING_PIN, HIGH); #endif if (laser.diagnostics) { SERIAL_ECHOLN("Laser fired"); } }
bool lcd_material_verify_material_settings() { SERIAL_ECHO_START; uint8_t max_mats = eeprom_read_byte(EEPROM_MATERIAL_COUNT_OFFSET()); SERIAL_ECHOPAIR("Checking ", (unsigned long) max_mats); SERIAL_ECHOPAIR(" presets and ", (unsigned long) EXTRUDERS); SERIAL_ECHOLNPGM (" extruder settings:"); if (max_mats < 2 || max_mats > EEPROM_MATERIAL_SETTINGS_MAX_COUNT) return false; byte cnt =0; while(cnt < max_mats+EXTRUDERS) { SERIAL_ECHOPAIR("Checking preset # ",(unsigned long) cnt); if (eeprom_read_word(EEPROM_MATERIAL_TEMPERATURE_OFFSET(cnt)) > HEATER_0_MAXTEMP) return false; if (eeprom_read_word(EEPROM_MATERIAL_BED_TEMPERATURE_OFFSET(cnt)) > BED_MAXTEMP) return false; if (eeprom_read_byte(EEPROM_MATERIAL_FAN_SPEED_OFFSET(cnt)) > 100) return false; if (eeprom_read_word(EEPROM_MATERIAL_FLOW_OFFSET(cnt)) > 1000) return false; if (eeprom_read_float(EEPROM_MATERIAL_DIAMETER_OFFSET(cnt)) > 10.0) return false; if (eeprom_read_float(EEPROM_MATERIAL_DIAMETER_OFFSET(cnt)) < 0.1) return false; strcpy_P (material_name_buf,"???"); eeprom_read_block(material_name_buf, EEPROM_MATERIAL_NAME_OFFSET(cnt), MATERIAL_NAME_LENGTH); material_name_buf[MATERIAL_NAME_LENGTH] = '\0'; if (cnt >= max_mats ) { SERIAL_ECHOPAIR(".....verified extruder setting # ",(unsigned long) cnt-max_mats);} else { SERIAL_ECHOPAIR(".....verified preset # ",(unsigned long) cnt);} SERIAL_ECHO(" ("); SERIAL_ECHO(material_name_buf); SERIAL_ECHO(")"); SERIAL_ECHOLN(""); cnt++; } return true; }
void CardReader::initsd() { cardOK = false; if(root.isOpen()) root.close(); #ifdef SDSLOW if (!card.init(SPI_HALF_SPEED,SDSS)) #else if (!card.init(SPI_FULL_SPEED,SDSS)) #endif { //if (!card.init(SPI_HALF_SPEED,SDSS)) SERIAL_ECHO_START; SERIAL_ECHOLNPGM(MSG_SD_INIT_FAIL); SERIAL_ECHOLN(errorCode()); } else if (!volume.init(&card)) { SERIAL_ERROR_START; SERIAL_ERRORLNPGM(MSG_SD_VOL_INIT_FAIL); } else if (!root.openRoot(&volume)) { SERIAL_ERROR_START; SERIAL_ERRORLNPGM(MSG_SD_OPENROOT_FAIL); } else { cardOK = true; SERIAL_ECHO_START; SERIAL_ECHOLNPGM(MSG_SD_CARD_OK); } workDir=root; curDir=&root; /* if(!workDir.openRoot(&volume)) { SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL); } */ }
/*Crash1 - G29 to Probe and stop on Bed G29 will probe bed at least twice at 3 points and take an average. G30 will probe bed at it's current location. Z stop should be set slightly below bed height. Solder stub wire to each hole in huxley bed and attach a ring terminal under spring. Wire bed probe to A2 on Melzi and duplicate cap/resistor circuit in schematic. Use something like this in the start.gcode file: G29 ;Probe bed for Z height G92 Z0 ;Set Z to Probed Depth G1 Z5 F200 ;Lift Z out of way */ void probe_3points() { float Probe_Avg, Point1, Point2, Point3; Point1 = Probe_Bed(15,15,PROBE_N); Point2 = Probe_Bed(X_MAX_LENGTH - 20,15,PROBE_N) ; Point3 = Probe_Bed(X_MAX_LENGTH/2,Y_MAX_LENGTH - 5,PROBE_N); Probe_Avg = (Point1 + Point2 + Point3) / 3; //destination[2] = Probe_Avg; //feedrate = homing_feedrate[Z_AXIS]; //prepare_move(); SERIAL_ECHOLN("**************************************"); SERIAL_ECHO("Point1 ="); SERIAL_ECHOLN(Point1); SERIAL_ECHO("Point2 ="); SERIAL_ECHOLN(Point2); SERIAL_ECHO("Point3 ="); SERIAL_ECHOLN(Point3); SERIAL_ECHO("Probed Average="); SERIAL_ECHOLN(Probe_Avg); SERIAL_ECHOLN("**************************************"); }
/** * Dive into a folder and recurse depth-first to perform a pre-set operation lsAction: * LS_Count - Add +1 to nrFiles for every file within the parent * LS_GetFilename - Get the filename of the file indexed by nrFiles * LS_SerialPrint - Print the full path of each file to serial output */ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/) { dir_t p; uint8_t cnt = 0; // Read the next entry from a directory while (parent.readDir(p, longFilename) > 0) { // If the entry is a directory and the action is LS_SerialPrint if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { // Get the short name for the item, which we know is a folder char lfilename[FILENAME_LENGTH]; createFilename(lfilename, p); // Allocate enough stack space for the full path to a folder, trailing slash, and nul boolean prepend_is_empty = (prepend[0] == '\0'); int len = (prepend_is_empty ? 1 : strlen(prepend)) + strlen(lfilename) + 1 + 1; char path[len]; // Append the FOLDERNAME12/ to the passed string. // It contains the full path to the "parent" argument. // We now have the full path to the item in this folder. strcpy(path, prepend_is_empty ? "/" : prepend); // root slash if prepend is empty strcat(path, lfilename); // FILENAME_LENGTH-1 characters maximum strcat(path, "/"); // 1 character // Serial.print(path); // Get a new directory object using the full path // and dive recursively into it. SdFile dir; if (!dir.open(parent, lfilename, O_READ)) { if (lsAction == LS_SerialPrint) { SERIAL_ECHO_START; SERIAL_ECHOPGM(MSG_SD_CANT_OPEN_SUBDIR); SERIAL_ECHOLN(lfilename); } } lsDive(path, dir); // close() is done automatically by destructor of SdFile } else { uint8_t pn0 = p.name[0]; if (pn0 == DIR_NAME_FREE) break; if (pn0 == DIR_NAME_DELETED || pn0 == '.') continue; if (longFilename[0] == '.') continue; if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue; filenameIsDir = DIR_IS_SUBDIR(&p); if (!filenameIsDir && (p.name[8] != 'G' || p.name[9] == '~')) continue; switch (lsAction) { case LS_Count: nrFiles++; break; case LS_SerialPrint: createFilename(filename, p); SERIAL_PROTOCOL(prepend); SERIAL_PROTOCOLLN(filename); break; case LS_GetFilename: createFilename(filename, p); if (match != NULL) { if (strcasecmp(match, filename) == 0) return; } else if (cnt == nrFiles) return; cnt++; break; } } } // while readDir }
void CardReader::openFile(char* name, bool read, bool replace_current/*=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++; } else { SERIAL_ECHO_START; SERIAL_ECHOPGM("Now doing file: "); SERIAL_ECHOLN(name); } file.close(); } else { //opening fresh file file_subcall_ctr = 0; //resetting procedure depth in case user cancels print while in procedure SERIAL_ECHO_START; SERIAL_ECHOPGM("Now fresh file: "); SERIAL_ECHOLN(name); } sdprinting = false; SdFile myDir; curDir = &root; char *fname = name; char *dirname_start, *dirname_end; if (name[0] == '/') { dirname_start = &name[1]; while(dirname_start > 0) { dirname_end = strchr(dirname_start, '/'); //SERIAL_ECHO("start:");SERIAL_ECHOLN((int)(dirname_start - name)); //SERIAL_ECHO("end :");SERIAL_ECHOLN((int)(dirname_end - name)); if (dirname_end > 0 && dirname_end > dirname_start) { char subdirname[FILENAME_LENGTH]; strncpy(subdirname, dirname_start, dirname_end - dirname_start); subdirname[dirname_end - dirname_start] = 0; SERIAL_ECHOLN(subdirname); if (!myDir.open(curDir, subdirname, O_READ)) { SERIAL_PROTOCOLPGM(MSG_SD_OPEN_FILE_FAIL); SERIAL_PROTOCOL(subdirname); SERIAL_PROTOCOLCHAR('.'); return; } else { //SERIAL_ECHOLN("dive ok"); } curDir = &myDir; dirname_start = dirname_end + 1; } else { // the remainder after all /fsa/fdsa/ is the filename fname = dirname_start; //SERIAL_ECHOLN("remainder"); //SERIAL_ECHOLN(fname); break; } } } else { //relative path curDir = &workDir; } if (read) { if (file.open(curDir, fname, O_READ)) { filesize = file.fileSize(); SERIAL_PROTOCOLPGM(MSG_SD_FILE_OPENED); SERIAL_PROTOCOL(fname); SERIAL_PROTOCOLPGM(MSG_SD_SIZE); SERIAL_PROTOCOLLN(filesize); sdpos = 0; SERIAL_PROTOCOLLNPGM(MSG_SD_FILE_SELECTED); getfilename(0, fname); lcd_setstatus(longFilename[0] ? longFilename : fname); } else { SERIAL_PROTOCOLPGM(MSG_SD_OPEN_FILE_FAIL); SERIAL_PROTOCOL(fname); SERIAL_PROTOCOLCHAR('.'); } } 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 { saving = true; SERIAL_PROTOCOLPGM(MSG_SD_WRITE_TO_FILE); SERIAL_PROTOCOLLN(name); lcd_setstatus(fname); } } }
void PID_autotune(float temp, int extruder, int ncycles) { float input = 0.0; int cycles=0; bool heating = true; unsigned long temp_millis = millis(); unsigned long t1=temp_millis; unsigned long t2=temp_millis; long t_high = 0; long t_low = 0; long bias, d; float Ku, Tu; float Kp, Ki, Kd; float max = 0, min = 10000; if ((extruder > EXTRUDERS) #if (TEMP_BED_PIN <= -1) ||(extruder < 0) #endif ){ SERIAL_ECHOLN("PID Autotune failed. Bad extruder number."); return; } SERIAL_ECHOLN("PID Autotune start"); disable_heater(); // switch off all heaters. if (extruder<0) { soft_pwm_bed = (MAX_BED_POWER)/2; bias = d = (MAX_BED_POWER)/2; } else { soft_pwm[extruder] = (PID_MAX)/2; bias = d = (PID_MAX)/2; } for(;;) { if(temp_meas_ready == true) { // temp sample ready updateTemperaturesFromRawValues(); input = (extruder<0)?current_temperature_bed:current_temperature[extruder]; max=max(max,input); min=min(min,input); if(heating == true && input > temp) { if(millis() - t2 > 5000) { heating=false; if (extruder<0) soft_pwm_bed = (bias - d) >> 1; else soft_pwm[extruder] = (bias - d) >> 1; t1=millis(); t_high=t1 - t2; max=temp; } }
void Config_PrintSettings() { // Always have this function, even with EEPROM_SETTINGS disabled, the current values will be shown SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Steps per unit:"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M92 X",axis_steps_per_unit[X_AXIS]); SERIAL_ECHOPAIR(" Y",axis_steps_per_unit[Y_AXIS]); SERIAL_ECHOPAIR(" Z",axis_steps_per_unit[Z_AXIS]); SERIAL_ECHOPAIR(" E",axis_steps_per_unit[E_AXIS]); SERIAL_ECHOLN(""); SERIAL_ECHO_START; #ifdef SCARA SERIAL_ECHOLNPGM("Scaling factors:"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M365 X",axis_scaling[X_AXIS]); SERIAL_ECHOPAIR(" Y",axis_scaling[Y_AXIS]); SERIAL_ECHOPAIR(" Z",axis_scaling[Z_AXIS]); SERIAL_ECHOLN(""); SERIAL_ECHO_START; #endif SERIAL_ECHOLNPGM("Maximum feedrates (mm/s):"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M203 X", max_feedrate[X_AXIS]); SERIAL_ECHOPAIR(" Y", max_feedrate[Y_AXIS]); SERIAL_ECHOPAIR(" Z", max_feedrate[Z_AXIS]); SERIAL_ECHOPAIR(" E", max_feedrate[E_AXIS]); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Maximum Acceleration (mm/s2):"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M201 X" ,max_acceleration_units_per_sq_second[X_AXIS] ); SERIAL_ECHOPAIR(" Y" , max_acceleration_units_per_sq_second[Y_AXIS] ); SERIAL_ECHOPAIR(" Z" ,max_acceleration_units_per_sq_second[Z_AXIS] ); SERIAL_ECHOPAIR(" E" ,max_acceleration_units_per_sq_second[E_AXIS]); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Acceleration: S=acceleration, T=retract acceleration"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M204 S",acceleration ); SERIAL_ECHOPAIR(" T" ,retract_acceleration); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum XY jerk (mm/s), Z=maximum Z jerk (mm/s), E=maximum E jerk (mm/s)"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M205 S",minimumfeedrate ); SERIAL_ECHOPAIR(" T" ,mintravelfeedrate ); SERIAL_ECHOPAIR(" B" ,minsegmenttime ); SERIAL_ECHOPAIR(" X" ,max_xy_jerk ); SERIAL_ECHOPAIR(" Z" ,max_z_jerk); SERIAL_ECHOPAIR(" E" ,max_e_jerk); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Home offset (mm):"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M206 X",add_homing[X_AXIS] ); SERIAL_ECHOPAIR(" Y" ,add_homing[Y_AXIS] ); SERIAL_ECHOPAIR(" Z" ,add_homing[Z_AXIS] ); SERIAL_ECHOLN(""); #ifdef DELTA SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Endstop adjustement (mm):"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M666 X",endstop_adj[X_AXIS] ); SERIAL_ECHOPAIR(" Y" ,endstop_adj[Y_AXIS] ); SERIAL_ECHOPAIR(" Z" ,endstop_adj[Z_AXIS] ); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Delta settings: L=delta_diagonal_rod, R=delta_radius, S=delta_segments_per_second"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M665 L",delta_diagonal_rod ); SERIAL_ECHOPAIR(" R" ,delta_radius ); SERIAL_ECHOPAIR(" S" ,delta_segments_per_second ); SERIAL_ECHOLN(""); #endif #ifdef PIDTEMP SERIAL_ECHO_START; SERIAL_ECHOLNPGM("PID settings:"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M301 P",Kp); SERIAL_ECHOPAIR(" I" ,unscalePID_i(Ki)); SERIAL_ECHOPAIR(" D" ,unscalePID_d(Kd)); SERIAL_ECHOLN(""); #endif #ifdef FWRETRACT SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Retract: S=Length (mm) F:Speed (mm/m) Z: ZLift (mm)"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M207 S",retract_length); SERIAL_ECHOPAIR(" F" ,retract_feedrate*60); SERIAL_ECHOPAIR(" Z" ,retract_zlift); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Recover: S=Extra length (mm) F:Speed (mm/m)"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M208 S",retract_recover_length); SERIAL_ECHOPAIR(" F" ,retract_recover_feedrate*60); SERIAL_ECHOLN(""); #endif }
void PID_autotune(float temp, int extruder, int ncycles) { float input = 0.0; int cycles = 0; bool heating = true; millis_t temp_ms = millis(), t1 = temp_ms, t2 = temp_ms; long t_high = 0, t_low = 0; long bias, d; float Ku, Tu; float Kp, Ki, Kd; float max = 0, min = 10000; #if HAS_AUTO_FAN millis_t next_auto_fan_check_ms = temp_ms + 2500; #endif if (extruder >= EXTRUDERS #if !HAS_TEMP_BED || extruder < 0 #endif ) { SERIAL_ECHOLN(MSG_PID_BAD_EXTRUDER_NUM); return; } SERIAL_ECHOLN(MSG_PID_AUTOTUNE_START); disable_heater(); // switch off all heaters. if (extruder < 0) soft_pwm_bed = bias = d = MAX_BED_POWER / 2; else soft_pwm[extruder] = bias = d = PID_MAX / 2; // PID Tuning loop for (;;) { millis_t ms = millis(); if (temp_meas_ready) { // temp sample ready updateTemperaturesFromRawValues(); input = (extruder<0)?current_temperature_bed:current_temperature[extruder]; max = max(max, input); min = min(min, input); #if HAS_AUTO_FAN if (ms > next_auto_fan_check_ms) { checkExtruderAutoFans(); next_auto_fan_check_ms = ms + 2500; } #endif if (heating == true && input > temp) { if (ms - t2 > 5000) { heating = false; if (extruder < 0) soft_pwm_bed = (bias - d) >> 1; else soft_pwm[extruder] = (bias - d) >> 1; t1 = ms; t_high = t1 - t2; max = temp; } } if (heating == false && input < temp) { if (ms - t1 > 5000) { heating = true; t2 = ms; t_low = t2 - t1; if (cycles > 0) { long max_pow = extruder < 0 ? MAX_BED_POWER : PID_MAX; bias += (d*(t_high - t_low))/(t_low + t_high); bias = constrain(bias, 20, max_pow - 20); d = (bias > max_pow / 2) ? max_pow - 1 - bias : bias; SERIAL_PROTOCOLPGM(MSG_BIAS); SERIAL_PROTOCOL(bias); SERIAL_PROTOCOLPGM(MSG_D); SERIAL_PROTOCOL(d); SERIAL_PROTOCOLPGM(MSG_T_MIN); SERIAL_PROTOCOL(min); SERIAL_PROTOCOLPGM(MSG_T_MAX); SERIAL_PROTOCOLLN(max); if (cycles > 2) { Ku = (4.0 * d) / (3.14159265 * (max - min) / 2.0); Tu = ((float)(t_low + t_high) / 1000.0); SERIAL_PROTOCOLPGM(MSG_KU); SERIAL_PROTOCOL(Ku); SERIAL_PROTOCOLPGM(MSG_TU); SERIAL_PROTOCOLLN(Tu); Kp = 0.6 * Ku; Ki = 2 * Kp / Tu; Kd = Kp * Tu / 8; SERIAL_PROTOCOLLNPGM(MSG_CLASSIC_PID); SERIAL_PROTOCOLPGM(MSG_KP); SERIAL_PROTOCOLLN(Kp); SERIAL_PROTOCOLPGM(MSG_KI); SERIAL_PROTOCOLLN(Ki); SERIAL_PROTOCOLPGM(MSG_KD); SERIAL_PROTOCOLLN(Kd); /* Kp = 0.33*Ku; Ki = Kp/Tu; Kd = Kp*Tu/3; SERIAL_PROTOCOLLNPGM(" Some overshoot "); SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp); SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki); SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd); Kp = 0.2*Ku; Ki = 2*Kp/Tu; Kd = Kp*Tu/3; SERIAL_PROTOCOLLNPGM(" No overshoot "); SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp); SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki); SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd); */ } } if (extruder < 0) soft_pwm_bed = (bias + d) >> 1; else soft_pwm[extruder] = (bias + d) >> 1; cycles++; min = temp; }
void Config_PrintSettings() { // Always have this function, even with EEPROM_SETTINGS disabled, the current values will be shown SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Steps per unit:"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M92 X",axis_steps_per_unit[0]); SERIAL_ECHOPAIR(" Y",axis_steps_per_unit[1]); SERIAL_ECHOPAIR(" Z",axis_steps_per_unit[2]); SERIAL_ECHOPAIR(" E",axis_steps_per_unit[3]); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Maximum feedrates (mm/s):"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M203 X",max_feedrate[0]); SERIAL_ECHOPAIR(" Y",max_feedrate[1] ); SERIAL_ECHOPAIR(" Z", max_feedrate[2] ); SERIAL_ECHOPAIR(" E", max_feedrate[3]); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Maximum Acceleration (mm/s2):"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M201 X" ,max_acceleration_units_per_sq_second[0] ); SERIAL_ECHOPAIR(" Y" , max_acceleration_units_per_sq_second[1] ); SERIAL_ECHOPAIR(" Z" ,max_acceleration_units_per_sq_second[2] ); SERIAL_ECHOPAIR(" E" ,max_acceleration_units_per_sq_second[3]); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Acceleration: S=acceleration, T=retract acceleration"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M204 S",acceleration ); SERIAL_ECHOPAIR(" T" ,retract_acceleration); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum XY jerk (mm/s), Z=maximum Z jerk (mm/s), E=maximum E jerk (mm/s)"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M205 S",minimumfeedrate ); SERIAL_ECHOPAIR(" T" ,mintravelfeedrate ); SERIAL_ECHOPAIR(" B" ,minsegmenttime ); SERIAL_ECHOPAIR(" X" ,max_xy_jerk ); SERIAL_ECHOPAIR(" Z" ,max_z_jerk); SERIAL_ECHOPAIR(" E" ,max_e_jerk); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Home offset (mm):"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M206 X",add_homeing[0] ); SERIAL_ECHOPAIR(" Y" ,add_homeing[1] ); SERIAL_ECHOPAIR(" Z" ,add_homeing[2] ); SERIAL_ECHOLN(""); #ifdef DELTA SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Endstop adjustment (mm):"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M666 X",endstop_adj[0]); SERIAL_ECHOPAIR(" Y" ,endstop_adj[1]); SERIAL_ECHOPAIR(" Z" ,endstop_adj[2]); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Delta Geometry adjustment:"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M666 A",tower_adj[0]); SERIAL_ECHOPAIR(" B" ,tower_adj[1]); SERIAL_ECHOPAIR(" C" ,tower_adj[2]); SERIAL_ECHOPAIR(" I" ,tower_adj[3]); SERIAL_ECHOPAIR(" J" ,tower_adj[4]); SERIAL_ECHOPAIR(" K" ,tower_adj[5]); SERIAL_ECHOPAIR(" R" ,delta_radius); SERIAL_ECHOPAIR(" D" ,delta_diagonal_rod); SERIAL_ECHOPAIR(" H" ,max_pos[Z_AXIS]); SERIAL_ECHOPAIR(" P" ,z_probe_offset[Z_AXIS]); SERIAL_ECHOPAIR(" S" ,delta_segments_per_second ); SERIAL_ECHOLN(""); /* SERIAL_ECHOLN("Tower Positions"); SERIAL_ECHOPAIR("Tower1 X:",delta_tower1_x); SERIAL_ECHOPAIR(" Y:",delta_tower1_y); SERIAL_ECHOLN(""); SERIAL_ECHOPAIR("Tower2 X:",delta_tower2_x); SERIAL_ECHOPAIR(" Y:",delta_tower2_y); SERIAL_ECHOLN(""); SERIAL_ECHOPAIR("Tower3 X:",delta_tower3_x); SERIAL_ECHOPAIR(" Y:",delta_tower3_y); SERIAL_ECHOLN(""); */ #endif #ifdef PIDTEMP SERIAL_ECHO_START; SERIAL_ECHOLNPGM("PID settings:"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M301 P",Kp); SERIAL_ECHOPAIR(" I" ,unscalePID_i(Ki)); SERIAL_ECHOPAIR(" D" ,unscalePID_d(Kd)); SERIAL_ECHOLN(""); #endif }
/** * M420: Enable/Disable Bed Leveling and/or set the Z fade height. * * S[bool] Turns leveling on or off * Z[height] Sets the Z fade height (0 or none to disable) * V[bool] Verbose - Print the leveling grid * * With AUTO_BED_LEVELING_UBL only: * * L[index] Load UBL mesh from index (0 is default) * T[map] 0:Human-readable 1:CSV 2:"LCD" 4:Compact * * With mesh-based leveling only: * * C Center mesh on the mean of the lowest and highest * * With MARLIN_DEV_MODE: * S2 Create a simple random mesh and enable */ void GcodeSuite::M420() { const bool seen_S = parser.seen('S'), to_enable = seen_S ? parser.value_bool() : planner.leveling_active; #if ENABLED(MARLIN_DEV_MODE) if (parser.intval('S') == 2) { #if ENABLED(AUTO_BED_LEVELING_BILINEAR) bilinear_start[X_AXIS] = MIN_PROBE_X; bilinear_start[Y_AXIS] = MIN_PROBE_Y; bilinear_grid_spacing[X_AXIS] = (MAX_PROBE_X - (MIN_PROBE_X)) / (GRID_MAX_POINTS_X - 1); bilinear_grid_spacing[Y_AXIS] = (MAX_PROBE_Y - (MIN_PROBE_Y)) / (GRID_MAX_POINTS_Y - 1); #endif for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++) for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++) Z_VALUES(x, y) = 0.001 * random(-200, 200); SERIAL_ECHOPGM("Simulated " STRINGIFY(GRID_MAX_POINTS_X) "x" STRINGIFY(GRID_MAX_POINTS_X) " mesh "); SERIAL_ECHOPAIR(" (", MIN_PROBE_X); SERIAL_CHAR(','); SERIAL_ECHO(MIN_PROBE_Y); SERIAL_ECHOPAIR(")-(", MAX_PROBE_X); SERIAL_CHAR(','); SERIAL_ECHO(MAX_PROBE_Y); SERIAL_ECHOLNPGM(")"); } #endif // If disabling leveling do it right away // (Don't disable for just M420 or M420 V) if (seen_S && !to_enable) set_bed_leveling_enabled(false); const float oldpos[] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] }; #if ENABLED(AUTO_BED_LEVELING_UBL) // L to load a mesh from the EEPROM if (parser.seen('L')) { set_bed_leveling_enabled(false); #if ENABLED(EEPROM_SETTINGS) const int8_t storage_slot = parser.has_value() ? parser.value_int() : ubl.storage_slot; const int16_t a = settings.calc_num_meshes(); if (!a) { SERIAL_ECHOLNPGM("?EEPROM storage not available."); return; } if (!WITHIN(storage_slot, 0, a - 1)) { SERIAL_ECHOLNPGM("?Invalid storage slot."); SERIAL_ECHOLNPAIR("?Use 0 to ", a - 1); return; } settings.load_mesh(storage_slot); ubl.storage_slot = storage_slot; #else SERIAL_ECHOLNPGM("?EEPROM storage not available."); return; #endif } // L or V display the map info if (parser.seen('L') || parser.seen('V')) { ubl.display_map(parser.byteval('T')); SERIAL_ECHOPGM("Mesh is "); if (!ubl.mesh_is_valid()) SERIAL_ECHOPGM("in"); SERIAL_ECHOLNPAIR("valid\nStorage slot: ", ubl.storage_slot); } #endif // AUTO_BED_LEVELING_UBL const bool seenV = parser.seen('V'); #if HAS_MESH if (leveling_is_valid()) { // Subtract the given value or the mean from all mesh values if (parser.seen('C')) { const float cval = parser.value_float(); #if ENABLED(AUTO_BED_LEVELING_UBL) set_bed_leveling_enabled(false); ubl.adjust_mesh_to_mean(true, cval); #else #if ENABLED(M420_C_USE_MEAN) // Get the sum and average of all mesh values float mesh_sum = 0; for (uint8_t x = GRID_MAX_POINTS_X; x--;) for (uint8_t y = GRID_MAX_POINTS_Y; y--;) mesh_sum += Z_VALUES(x, y); const float zmean = mesh_sum / float(GRID_MAX_POINTS); #else // Find the low and high mesh values float lo_val = 100, hi_val = -100; for (uint8_t x = GRID_MAX_POINTS_X; x--;) for (uint8_t y = GRID_MAX_POINTS_Y; y--;) { const float z = Z_VALUES(x, y); NOMORE(lo_val, z); NOLESS(hi_val, z); } // Take the mean of the lowest and highest const float zmean = (lo_val + hi_val) / 2.0 + cval; #endif // If not very close to 0, adjust the mesh if (!NEAR_ZERO(zmean)) { set_bed_leveling_enabled(false); // Subtract the mean from all values for (uint8_t x = GRID_MAX_POINTS_X; x--;) for (uint8_t y = GRID_MAX_POINTS_Y; y--;) Z_VALUES(x, y) -= zmean; #if ENABLED(ABL_BILINEAR_SUBDIVISION) bed_level_virt_interpolate(); #endif } #endif } } else if (to_enable || seenV) { SERIAL_ECHO_MSG("Invalid mesh."); goto EXIT_M420; } #endif // HAS_MESH // V to print the matrix or mesh if (seenV) { #if ABL_PLANAR planner.bed_level_matrix.debug(PSTR("Bed Level Correction Matrix:")); #else if (leveling_is_valid()) { #if ENABLED(AUTO_BED_LEVELING_BILINEAR) print_bilinear_leveling_grid(); #if ENABLED(ABL_BILINEAR_SUBDIVISION) print_bilinear_leveling_grid_virt(); #endif #elif ENABLED(MESH_BED_LEVELING) SERIAL_ECHOLNPGM("Mesh Bed Level data:"); mbl.report_mesh(); #endif } #endif } #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) if (parser.seen('Z')) set_z_fade_height(parser.value_linear_units(), false); #endif // Enable leveling if specified, or if previously active set_bed_leveling_enabled(to_enable); #if HAS_MESH EXIT_M420: #endif // Error if leveling failed to enable or reenable if (to_enable && !planner.leveling_active) SERIAL_ERROR_MSG(MSG_ERR_M420_FAILED); SERIAL_ECHO_START(); SERIAL_ECHOPGM("Bed Leveling "); serialprintln_onoff(planner.leveling_active); #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) SERIAL_ECHO_START(); SERIAL_ECHOPGM("Fade Height "); if (planner.z_fade_height > 0.0) SERIAL_ECHOLN(planner.z_fade_height); else SERIAL_ECHOLNPGM(MSG_OFF); #endif // Report change in position if (memcmp(oldpos, current_position, sizeof(oldpos))) report_current_position(); }
void PID_autotune(float temp, int extruder, int ncycles) { float input = 0.0; int cycles=0; bool heating = true; unsigned long temp_millis = millis(); unsigned long t1=temp_millis; unsigned long t2=temp_millis; long t_high = 0; long t_low = 0; long bias, d; float Ku, Tu; float Kp, Ki, Kd; float max = 0, min = 10000; if ((extruder > EXTRUDERS) #if (TEMP_BED_PIN <= -1) ||(extruder < 0) #endif ){ SERIAL_ECHOLN("PID Autotune failed. Bad extruder number."); return; } SERIAL_ECHOLN("PID Autotune start"); disable_heater(); // switch off all heaters. if (extruder<0) { soft_pwm_bed = (MAX_BED_POWER)/2; bias = d = (MAX_BED_POWER)/2; } else { soft_pwm[extruder] = (PID_MAX)/2; bias = d = (PID_MAX)/2; } for(;;) { if(temp_meas_ready == true) { // temp sample ready //Reset the watchdog after we know we have a temperature measurement. watchdog_reset(); CRITICAL_SECTION_START; temp_meas_ready = false; CRITICAL_SECTION_END; input = (extruder<0)?analog2tempBed(current_raw_bed):analog2temp(current_raw[extruder], extruder); max=max(max,input); min=min(min,input); if(heating == true && input > temp) { if(millis() - t2 > 5000) { heating=false; if (extruder<0) soft_pwm_bed = (bias - d) >> 1; else soft_pwm[extruder] = (bias - d) >> 1; t1=millis(); t_high=t1 - t2; max=temp; } }
void CardReader::openFile(char* name,bool read) { if(!cardOK) return; file.close(); sdprinting = false; SdFile myDir; curDir=&root; char *fname=name; char *dirname_start,*dirname_end; if(name[0]=='/') { dirname_start=strchr(name,'/')+1; while(dirname_start>0) { dirname_end=strchr(dirname_start,'/'); //SERIAL_ECHO("start:");SERIAL_ECHOLN((int)(dirname_start-name)); //SERIAL_ECHO("end :");SERIAL_ECHOLN((int)(dirname_end-name)); if(dirname_end>0 && dirname_end>dirname_start) { char subdirname[13]; strncpy(subdirname, dirname_start, dirname_end-dirname_start); subdirname[dirname_end-dirname_start]=0; SERIAL_ECHOLN(subdirname); if(!myDir.open(curDir,subdirname,O_READ)) { SERIAL_PROTOCOLPGM(MSG_SD_OPEN_FILE_FAIL); SERIAL_PROTOCOL(subdirname); SERIAL_PROTOCOLLNPGM("."); return; } else { //SERIAL_ECHOLN("dive ok"); } curDir=&myDir; dirname_start=dirname_end+1; } else // the reminder after all /fsa/fdsa/ is the filename { fname=dirname_start; //SERIAL_ECHOLN("remaider"); //SERIAL_ECHOLN(fname); break; } } } else //relative path { curDir=&workDir; } if(read) { if (file.open(curDir, fname, O_READ)) { filesize = file.fileSize(); SERIAL_PROTOCOLPGM(MSG_SD_FILE_OPENED); SERIAL_PROTOCOL(fname); SERIAL_PROTOCOLPGM(MSG_SD_SIZE); SERIAL_PROTOCOLLN(filesize); sdpos = 0; SERIAL_PROTOCOLLNPGM(MSG_SD_FILE_SELECTED); LCD_MESSAGE(fname); } else { SERIAL_PROTOCOLPGM(MSG_SD_OPEN_FILE_FAIL); SERIAL_PROTOCOL(fname); SERIAL_PROTOCOLLNPGM("."); } } 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_PROTOCOLLNPGM("."); } else { saving = true; SERIAL_PROTOCOLPGM(MSG_SD_WRITE_TO_FILE); SERIAL_PROTOCOLLN(name); LCD_MESSAGE(fname); } } }
void Config_PrintSettings() { // Always have this function, even with EEPROM_SETTINGS disabled, the current values will be shown SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Steps per unit:"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M92 X",axis_steps_per_unit[0]); SERIAL_ECHOPAIR(" Y",axis_steps_per_unit[1]); SERIAL_ECHOPAIR(" Z",axis_steps_per_unit[2]); SERIAL_ECHOPAIR(" E",axis_steps_per_unit[3]); SERIAL_ECHOPAIR(" E1",e1_steps_per_unit); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Maximum feedrates (mm/s):"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M203 X",max_feedrate[0]); SERIAL_ECHOPAIR(" Y",max_feedrate[1] ); SERIAL_ECHOPAIR(" Z", max_feedrate[2] ); SERIAL_ECHOPAIR(" E", max_feedrate[3]); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Maximum Acceleration (mm/s2):"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M201 X" ,max_acceleration_units_per_sq_second[0] ); SERIAL_ECHOPAIR(" Y" , max_acceleration_units_per_sq_second[1] ); SERIAL_ECHOPAIR(" Z" ,max_acceleration_units_per_sq_second[2] ); SERIAL_ECHOPAIR(" E" ,max_acceleration_units_per_sq_second[3]); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Acceleration: S=acceleration, T=retract acceleration"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M204 S",acceleration ); SERIAL_ECHOPAIR(" T" ,retract_acceleration); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum XY jerk (mm/s), Z=maximum Z jerk (mm/s), E=maximum E jerk (mm/s)"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M205 S",minimumfeedrate ); SERIAL_ECHOPAIR(" T" ,mintravelfeedrate ); SERIAL_ECHOPAIR(" B" ,minsegmenttime ); SERIAL_ECHOPAIR(" X" ,max_xy_jerk ); SERIAL_ECHOPAIR(" Z" ,max_z_jerk); SERIAL_ECHOPAIR(" E" ,max_e_jerk); SERIAL_ECHOLN(""); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Home offset (mm):"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M206 X",add_homeing[0] ); SERIAL_ECHOPAIR(" Y" ,add_homeing[1] ); SERIAL_ECHOPAIR(" Z" ,add_homeing[2] ); SERIAL_ECHOLN(""); #ifdef DELTA SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Endstop adjustement (mm):"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M666 X",endstop_adj[0] ); SERIAL_ECHOPAIR(" Y" ,endstop_adj[1] ); SERIAL_ECHOPAIR(" Z" ,endstop_adj[2] ); SERIAL_ECHOLN(""); #endif #ifdef PIDTEMP SERIAL_ECHO_START; SERIAL_ECHOLNPGM("PID settings:"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M301 P",Kp); SERIAL_ECHOPAIR(" I" ,unscalePID_i(Ki)); SERIAL_ECHOPAIR(" D" ,unscalePID_d(Kd)); SERIAL_ECHOLN(""); #endif }
void CardReader::lsDive(const char *prepend,SdFile parent) { dir_t p; uint8_t cnt=0; while (parent.readDir(p, longFilename) > 0) { if( DIR_IS_SUBDIR(&p) && lsAction!=LS_Count && lsAction!=LS_GetFilename) // hence LS_SerialPrint { char path[13*2]; char lfilename[13]; createFilename(lfilename,p); path[0]=0; if(strlen(prepend)==0) //avoid leading / if already in prepend { strcat(path,"/"); } strcat(path,prepend); strcat(path,lfilename); strcat(path,"/"); //Serial.print(path); SdFile dir; if(!dir.open(parent,lfilename, O_READ)) { if(lsAction==LS_SerialPrint) { SERIAL_ECHO_START; SERIAL_ECHOLN(MSG_SD_CANT_OPEN_SUBDIR); SERIAL_ECHOLN(lfilename); } } lsDive(path,dir); //close done automatically by destructor of SdFile } else { if (p.name[0] == DIR_NAME_FREE) break; if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.'|| p.name[0] == '_') continue; if ( p.name[0] == '.') { if ( p.name[1] != '.') continue; } if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue; filenameIsDir=DIR_IS_SUBDIR(&p); if(!filenameIsDir) { if(p.name[8]!='G') continue; if(p.name[9]=='~') continue; } //if(cnt++!=nr) continue; createFilename(filename,p); if(lsAction==LS_SerialPrint) { SERIAL_PROTOCOL(prepend); SERIAL_PROTOCOLLN(filename); } else if(lsAction==LS_Count) { nrFiles++; } else if(lsAction==LS_GetFilename) { if(cnt==nrFiles) return; cnt++; } } } }
void PID_autotune(float temp) { float input; int cycles=0; bool heating = true; unsigned long temp_millis = millis(); unsigned long t1=temp_millis; unsigned long t2=temp_millis; long t_high; long t_low; long bias=127; long d = 127; float Ku, Tu; float Kp, Ki, Kd; float max, min; SERIAL_ECHOLN("PID Autotune start"); disable_heater(); // switch off all heaters. soft_pwm[0] = 255>>1; for(;;) { if(temp_meas_ready == true) { // temp sample ready CRITICAL_SECTION_START; temp_meas_ready = false; CRITICAL_SECTION_END; input = analog2temp(current_raw[0], 0); max=max(max,input); min=min(min,input); if(heating == true && input > temp) { if(millis() - t2 > 5000) { heating=false; soft_pwm[0] = (bias - d) >> 1; t1=millis(); t_high=t1 - t2; max=temp; } } if(heating == false && input < temp) { if(millis() - t1 > 5000) { heating=true; t2=millis(); t_low=t2 - t1; if(cycles > 0) { bias += (d*(t_high - t_low))/(t_low + t_high); bias = constrain(bias, 20 ,235); if(bias > 127) d = 254 - bias; else d = bias; SERIAL_PROTOCOLPGM(" bias: "); SERIAL_PROTOCOL(bias); SERIAL_PROTOCOLPGM(" d: "); SERIAL_PROTOCOL(d); SERIAL_PROTOCOLPGM(" min: "); SERIAL_PROTOCOL(min); SERIAL_PROTOCOLPGM(" max: "); SERIAL_PROTOCOLLN(max); if(cycles > 2) { Ku = (4.0*d)/(3.14159*(max-min)/2.0); Tu = ((float)(t_low + t_high)/1000.0); SERIAL_PROTOCOLPGM(" Ku: "); SERIAL_PROTOCOL(Ku); SERIAL_PROTOCOLPGM(" Tu: "); SERIAL_PROTOCOLLN(Tu); Kp = 0.6*Ku; Ki = 2*Kp/Tu; Kd = Kp*Tu/8; SERIAL_PROTOCOLLNPGM(" Clasic PID ") SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp); SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki); SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd); /* Kp = 0.33*Ku; Ki = Kp/Tu; Kd = Kp*Tu/3; SERIAL_PROTOCOLLNPGM(" Some overshoot ") SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp); SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki); SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd); Kp = 0.2*Ku; Ki = 2*Kp/Tu; Kd = Kp*Tu/3; SERIAL_PROTOCOLLNPGM(" No overshoot ") SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp); SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki); SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd); */ } } soft_pwm[0] = (bias + d) >> 1; cycles++; min=temp; } }