void unified_bed_leveling::report_state() { echo_name(); SERIAL_PROTOCOLPGM(" System v" UBL_VERSION " "); if (!planner.leveling_active) SERIAL_PROTOCOLPGM("in"); SERIAL_PROTOCOLLNPGM("active."); safe_delay(50); }
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 report_current_position_detail() { stepper.synchronize(); SERIAL_PROTOCOLPGM("\nLogical:"); report_xyze(current_position); SERIAL_PROTOCOLPGM("Raw: "); const float raw[XYZ] = { RAW_X_POSITION(current_position[X_AXIS]), RAW_Y_POSITION(current_position[Y_AXIS]), RAW_Z_POSITION(current_position[Z_AXIS]) }; report_xyz(raw); SERIAL_PROTOCOLPGM("Leveled:"); float leveled[XYZ] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] }; planner.apply_leveling(leveled); report_xyz(leveled); SERIAL_PROTOCOLPGM("UnLevel:"); float unleveled[XYZ] = { leveled[X_AXIS], leveled[Y_AXIS], leveled[Z_AXIS] }; planner.unapply_leveling(unleveled); report_xyz(unleveled); #if IS_KINEMATIC #if IS_SCARA SERIAL_PROTOCOLPGM("ScaraK: "); #else SERIAL_PROTOCOLPGM("DeltaK: "); #endif inverse_kinematics(leveled); // writes delta[] report_xyz(delta); #endif SERIAL_PROTOCOLPGM("Stepper:"); const float step_count[XYZE] = { stepper.position(X_AXIS), stepper.position(Y_AXIS), stepper.position(Z_AXIS), stepper.position(E_AXIS) }; report_xyze(step_count, 4, 0); #if IS_SCARA const float deg[XYZ] = { stepper.get_axis_position_degrees(A_AXIS), stepper.get_axis_position_degrees(B_AXIS) }; SERIAL_PROTOCOLPGM("Degrees:"); report_xyze(deg, 2); #endif SERIAL_PROTOCOLPGM("FromStp:"); get_cartesian_from_steppers(); // writes cartes[XYZ] (with forward kinematics) const float from_steppers[XYZE] = { cartes[X_AXIS], cartes[Y_AXIS], cartes[Z_AXIS], stepper.get_axis_position_mm(E_AXIS) }; report_xyze(from_steppers); const float diff[XYZE] = { from_steppers[X_AXIS] - leveled[X_AXIS], from_steppers[Y_AXIS] - leveled[Y_AXIS], from_steppers[Z_AXIS] - leveled[Z_AXIS], from_steppers[E_AXIS] - current_position[E_AXIS] }; SERIAL_PROTOCOLPGM("Differ: "); report_xyze(diff); }
void vector_3::debug(const char title[]) { SERIAL_PROTOCOL(title); SERIAL_PROTOCOLPGM(" x: "); SERIAL_PROTOCOL_F(x, 6); SERIAL_PROTOCOLPGM(" y: "); SERIAL_PROTOCOL_F(y, 6); SERIAL_PROTOCOLPGM(" z: "); SERIAL_PROTOCOL_F(z, 6); SERIAL_EOL; }
void vector_3::debug(char* title) { SERIAL_PROTOCOL(title); SERIAL_PROTOCOLPGM(" x: "); SERIAL_PROTOCOL(x); SERIAL_PROTOCOLPGM(" y: "); SERIAL_PROTOCOL(y); SERIAL_PROTOCOLPGM(" z: "); SERIAL_PROTOCOL(z); SERIAL_PROTOCOLPGM("\n"); }
void CardReader::getStatus() { if (cardOK) { SERIAL_PROTOCOLPGM(MSG_SD_PRINTING_BYTE); SERIAL_PROTOCOL(sdpos); SERIAL_PROTOCOLPGM("/"); SERIAL_PROTOCOLLN(filesize); } else { SERIAL_PROTOCOLLNPGM(MSG_SD_NOT_PRINTING); } }
/* ??? Check se serve */ void MemReader::getStatus() { if(isprinting){ SERIAL_PROTOCOLPGM(MSG_SD_PRINTING_BYTE); SERIAL_PROTOCOL(pos); SERIAL_PROTOCOLPGM("/"); SERIAL_PROTOCOLLN(ScriptLength[program]); } else{ SERIAL_PROTOCOLLNPGM(MSG_SD_NOT_PRINTING); } }
void PrintCounter::showStats() { char buffer[21]; duration_t elapsed; SERIAL_PROTOCOLPGM(MSG_STATS); SERIAL_ECHOPGM("Prints: "); SERIAL_ECHO(this->data.totalPrints); SERIAL_ECHOPGM(", Finished: "); SERIAL_ECHO(this->data.finishedPrints); SERIAL_ECHOPGM(", Failed: "); // Note: Removes 1 from failures with an active counter SERIAL_ECHO(this->data.totalPrints - this->data.finishedPrints - ((this->isRunning() || this->isPaused()) ? 1 : 0)); SERIAL_EOL; SERIAL_PROTOCOLPGM(MSG_STATS); elapsed = this->data.printTime; elapsed.toString(buffer); SERIAL_ECHOPGM("Total time: "); SERIAL_ECHO(buffer); #if ENABLED(DEBUG_PRINTCOUNTER) SERIAL_ECHOPGM(" ("); SERIAL_ECHO(this->data.printTime); SERIAL_ECHOPGM(")"); #endif elapsed = this->data.longestPrint; elapsed.toString(buffer); SERIAL_ECHOPGM(", Longest job: "); SERIAL_ECHO(buffer); #if ENABLED(DEBUG_PRINTCOUNTER) SERIAL_ECHOPGM(" ("); SERIAL_ECHO(this->data.longestPrint); SERIAL_ECHOPGM(")"); #endif SERIAL_EOL; SERIAL_PROTOCOLPGM(MSG_STATS); SERIAL_ECHOPGM("Filament used: "); SERIAL_ECHO(this->data.filamentUsed / 1000); SERIAL_ECHOPGM("m"); SERIAL_EOL; }
void matrix_3x3::debug(const char title[]) { SERIAL_PROTOCOLLN(title); int count = 0; for(int i=0; i<3; i++) { for(int j=0; j<3; j++) { if (matrix[count] >= 0.0) SERIAL_PROTOCOLPGM("+"); SERIAL_PROTOCOL_F(matrix[count], 6); SERIAL_PROTOCOLPGM(" "); count++; } SERIAL_EOL; } }
void Endstops::M119() { SERIAL_PROTOCOLLNPGM(MSG_M119_REPORT); #if HAS_X_MIN SERIAL_PROTOCOLPGM(MSG_X_MIN); SERIAL_PROTOCOLLN(((READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); #endif #if HAS_X_MAX SERIAL_PROTOCOLPGM(MSG_X_MAX); SERIAL_PROTOCOLLN(((READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); #endif #if HAS_Y_MIN SERIAL_PROTOCOLPGM(MSG_Y_MIN); SERIAL_PROTOCOLLN(((READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); #endif #if HAS_Y_MAX SERIAL_PROTOCOLPGM(MSG_Y_MAX); SERIAL_PROTOCOLLN(((READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); #endif #if HAS_Z_MIN SERIAL_PROTOCOLPGM(MSG_Z_MIN); SERIAL_PROTOCOLLN(((READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); #endif #if HAS_Z_MAX SERIAL_PROTOCOLPGM(MSG_Z_MAX); SERIAL_PROTOCOLLN(((READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); #endif #if HAS_Z2_MAX SERIAL_PROTOCOLPGM(MSG_Z2_MAX); SERIAL_PROTOCOLLN(((READ(Z2_MAX_PIN)^Z2_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); #endif #if HAS_Z_MIN_PROBE_PIN SERIAL_PROTOCOLPGM(MSG_Z_PROBE); SERIAL_PROTOCOLLN(((READ(Z_MIN_PROBE_PIN)^Z_MIN_PROBE_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); #endif } // Endstops::M119
void matrix_3x3::debug(char* title) { SERIAL_PROTOCOL(title); SERIAL_PROTOCOL("\n"); int count = 0; for(int i=0; i<3; i++) { for(int j=0; j<3; j++) { SERIAL_PROTOCOL(matrix[count]); SERIAL_PROTOCOLPGM(" "); count++; } SERIAL_PROTOCOLPGM("\n"); } }
void checkHitEndstops() { if( endstop_x_hit || endstop_y_hit || endstop_z_hit || endstop_j_hit) { SERIAL_ECHO_START; snprintf(json_str,JSONSIZE,"{%s:[",MSG_ENDSTOPS_HIT); SERIAL_PROTOCOL(json_str); comma = false; if(endstop_x_hit) { SERIAL_PROTOCOLPGM("\"x\""); LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT "X"); comma = true; } if(endstop_y_hit) { if (comma) SERIAL_PROTOCOLPGM(","); SERIAL_PROTOCOLPGM("\"y\""); LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT "Y"); comma = true; } if(endstop_z_hit) { if (comma) SERIAL_PROTOCOLPGM(","); SERIAL_PROTOCOLPGM("\"z\""); LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT "Z"); comma = true; } if(endstop_j_hit) { if (comma) SERIAL_PROTOCOLPGM(","); SERIAL_PROTOCOLPGM("\"j\""); LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT "J"); } SERIAL_PROTOCOL("]}"); SERIAL_MSG_END; endstop_x_hit=false; endstop_y_hit=false; endstop_z_hit=false; endstop_j_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 Hysteresis::ReportToSerial() { SERIAL_PROTOCOLPGM("H=X"); SERIAL_PROTOCOL(m_hysteresis_mm[X_AXIS]); SERIAL_PROTOCOLPGM(" Y"); SERIAL_PROTOCOL(m_hysteresis_mm[Y_AXIS]); SERIAL_PROTOCOLPGM(" Z"); SERIAL_PROTOCOL(m_hysteresis_mm[Z_AXIS]); SERIAL_PROTOCOLPGM(" E"); SERIAL_PROTOCOL(m_hysteresis_mm[E_AXIS]); SERIAL_PROTOCOLPGM(" SHIFTS:x="); SERIAL_PROTOCOL(axis_shift[X_AXIS]); SERIAL_PROTOCOLPGM(" y="); SERIAL_PROTOCOL(axis_shift[Y_AXIS]); SERIAL_PROTOCOLPGM(" z="); SERIAL_PROTOCOL(axis_shift[Z_AXIS]); SERIAL_PROTOCOLPGM(" e="); SERIAL_PROTOCOL(axis_shift[E_AXIS]); SERIAL_PROTOCOLLN(""); }
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 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; 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 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; } }
void unified_bed_leveling::display_map(const int map_type) { constexpr uint8_t spaces = 8 * (GRID_MAX_POINTS_X - 2); SERIAL_PROTOCOLPGM("\nBed Topography Report"); if (map_type == 0) { SERIAL_PROTOCOLPGM(":\n\n"); serial_echo_xy(0, GRID_MAX_POINTS_Y - 1); SERIAL_ECHO_SP(spaces + 3); serial_echo_xy(GRID_MAX_POINTS_X - 1, GRID_MAX_POINTS_Y - 1); SERIAL_EOL(); serial_echo_xy(MESH_MIN_X, MESH_MAX_Y); SERIAL_ECHO_SP(spaces); serial_echo_xy(MESH_MAX_X, MESH_MAX_Y); SERIAL_EOL(); } else { SERIAL_PROTOCOLPGM(" for "); serialprintPGM(map_type == 1 ? PSTR("CSV:\n\n") : PSTR("LCD:\n\n")); } const float current_xi = get_cell_index_x(current_position[X_AXIS] + (MESH_X_DIST) / 2.0), current_yi = get_cell_index_y(current_position[Y_AXIS] + (MESH_Y_DIST) / 2.0); for (int8_t j = GRID_MAX_POINTS_Y - 1; j >= 0; j--) { for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) { const bool is_current = i == current_xi && j == current_yi; // is the nozzle here? then mark the number if (map_type == 0) SERIAL_CHAR(is_current ? '[' : ' '); const float f = z_values[i][j]; if (isnan(f)) { serialprintPGM(map_type == 0 ? PSTR(" . ") : PSTR("NAN")); } else if (map_type <= 1) { // if we don't do this, the columns won't line up nicely if (map_type == 0 && f >= 0.0) SERIAL_CHAR(' '); SERIAL_PROTOCOL_F(f, 3); } idle(); if (map_type == 1 && i < GRID_MAX_POINTS_X - 1) SERIAL_CHAR(','); #if TX_BUFFER_SIZE > 0 MYSERIAL.flushTX(); #endif safe_delay(15); if (map_type == 0) { SERIAL_CHAR(is_current ? ']' : ' '); SERIAL_CHAR(' '); } } SERIAL_EOL(); if (j && map_type == 0) { // we want the (0,0) up tight against the block of numbers SERIAL_CHAR(' '); SERIAL_EOL(); } } if (map_type == 0) { serial_echo_xy(MESH_MIN_X, MESH_MIN_Y); SERIAL_ECHO_SP(spaces + 4); serial_echo_xy(MESH_MAX_X, MESH_MIN_Y); SERIAL_EOL(); serial_echo_xy(0, 0); SERIAL_ECHO_SP(spaces + 5); serial_echo_xy(GRID_MAX_POINTS_X - 1, 0); SERIAL_EOL(); } }
/** * - Move to the given XY * - Deploy the probe, if not already deployed * - Probe the bed, get the Z position * - Depending on the 'stow' flag * - Stow the probe, or * - Raise to the BETWEEN height * - Return the probed Z position */ float probe_pt(const float &lx, const float &ly, const bool stow, const uint8_t verbose_level, const bool printable/*=true*/) { #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) { SERIAL_ECHOPAIR(">>> probe_pt(", lx); SERIAL_ECHOPAIR(", ", ly); SERIAL_ECHOPAIR(", ", stow ? "" : "no "); SERIAL_ECHOLNPGM("stow)"); DEBUG_POS("", current_position); } #endif const float nx = lx - (X_PROBE_OFFSET_FROM_EXTRUDER), ny = ly - (Y_PROBE_OFFSET_FROM_EXTRUDER); if (printable ? !position_is_reachable_xy(nx, ny) : !position_is_reachable_by_probe_xy(lx, ly) ) return NAN; const float old_feedrate_mm_s = feedrate_mm_s; #if ENABLED(DELTA) if (current_position[Z_AXIS] > delta_clip_start_height) do_blocking_move_to_z(delta_clip_start_height); #endif #if HAS_SOFTWARE_ENDSTOPS // Store the status of the soft endstops and disable if we're probing a non-printable location static bool enable_soft_endstops = soft_endstops_enabled; if (!printable) soft_endstops_enabled = false; #endif feedrate_mm_s = XY_PROBE_FEEDRATE_MM_S; // Move the probe to the given XY do_blocking_move_to_xy(nx, ny); float measured_z = NAN; if (!DEPLOY_PROBE()) { measured_z = run_z_probe(printable); if (!stow) do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST)); else if (STOW_PROBE()) measured_z = NAN; } #if HAS_SOFTWARE_ENDSTOPS // Restore the soft endstop status soft_endstops_enabled = enable_soft_endstops; #endif if (verbose_level > 2) { SERIAL_PROTOCOLPGM("Bed X: "); SERIAL_PROTOCOL_F(lx, 3); SERIAL_PROTOCOLPGM(" Y: "); SERIAL_PROTOCOL_F(ly, 3); SERIAL_PROTOCOLPGM(" Z: "); SERIAL_PROTOCOL_F(measured_z, 3); SERIAL_EOL(); } #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< probe_pt"); #endif feedrate_mm_s = old_feedrate_mm_s; if (isnan(measured_z)) { LCD_MESSAGEPGM(MSG_ERR_PROBING_FAILED); SERIAL_ERROR_START(); SERIAL_ERRORLNPGM(MSG_ERR_PROBING_FAILED); } return measured_z; }
void unified_bed_leveling::echo_name() { SERIAL_PROTOCOLPGM("Unified Bed Leveling"); }