/** \brief Print command on serial console */ void gcode_print_command(GCode *code) { if(GCODE_HAS_M(code)) { out.print('M'); out.print((int)code->M); out.print(' '); } if(GCODE_HAS_G(code)) { out.print('G'); out.print((int)code->G); out.print(' '); } if(GCODE_HAS_T(code)) { out.print('T'); out.print((int)code->T); out.print(' '); } if(GCODE_HAS_X(code)) { out.print_float_P(PSTR(" X"),code->X); } if(GCODE_HAS_Y(code)) { out.print_float_P(PSTR(" Y"),code->Y); } if(GCODE_HAS_Z(code)) { out.print_float_P(PSTR(" Z"),code->Z); } if(GCODE_HAS_E(code)) { out.print_float_P(PSTR(" E"),code->E,4); } if(GCODE_HAS_F(code)) { out.print_float_P(PSTR(" F"),code->F); } if(GCODE_HAS_S(code)) { out.print_long_P(PSTR(" S"),code->S); } if(GCODE_HAS_P(code)) { out.print_long_P(PSTR(" P"),code->P); } if(GCODE_HAS_I(code)) { out.print_float_P(PSTR(" I"),code->I); } if(GCODE_HAS_J(code)) { out.print_float_P(PSTR(" J"),code->J); } if(GCODE_HAS_R(code)) { out.print_float_P(PSTR(" R"),code->R); } if(GCODE_HAS_STRING(code)) { out.print(code->text); } }
/** \brief Execute the command stored in com. */ void process_command(GCode *com) { unsigned long codenum; //throw away variable #ifdef INCLUDE_DEBUG_COMMUNICATION if(DEBUG_COMMUNICATION) { if(GCODE_HAS_G(com) || (GCODE_HAS_M(com) && com->M!=111)) { gcode_command_finished(); // free command cache previous_millis_cmd = millis(); return; } } #endif if(GCODE_HAS_G(com)) { switch(com->G) { case 0: // G0 -> G1 case 1: // G1 if(get_coordinates(com)) // For X Y Z E F queue_move(ALWAYS_CHECK_ENDSTOPS); break; case 4: // G4 dwell codenum = 0; if(GCODE_HAS_P(com)) codenum = com->P; // milliseconds to wait if(GCODE_HAS_S(com)) codenum = (long)com->S * 1000; // seconds to wait codenum += millis(); // keep track of when we started waiting while(millis() < codenum ) { gcode_read_serial(); manage_temperatures(false); } break; case 20: // Units to inches unit_inches = 1; break; case 21: // Units to mm unit_inches = 0; break; case 28: {//G28 Home all Axis one at a time wait_until_end_of_move(); float saved_feedrate = printer_state.feedrate; for(byte i=0; i < 4; i++) { printer_state.destinationSteps[i] = printer_state.currentPositionSteps[i]; } byte home_all_axis = !(GCODE_HAS_X(com) || GCODE_HAS_Y(com) || GCODE_HAS_Z(com)); if(home_all_axis || GCODE_HAS_X(com)) { if ((X_MIN_PIN > -1 && X_HOME_DIR==-1) || (X_MAX_PIN > -1 && X_HOME_DIR==1)) { printer_state.destinationSteps[0] = 1.5 * printer_state.xMaxSteps * X_HOME_DIR; printer_state.currentPositionSteps[0] = -printer_state.destinationSteps[0]; printer_state.feedrate = homing_feedrate[0]; queue_move(true); wait_until_end_of_move(); printer_state.currentPositionSteps[0] = 0; printer_state.destinationSteps[0] = axis_steps_per_unit[0]*-5 * X_HOME_DIR; queue_move(true); wait_until_end_of_move(); printer_state.destinationSteps[0] = axis_steps_per_unit[0]*10 * X_HOME_DIR; queue_move(true); wait_until_end_of_move(); printer_state.currentPositionSteps[0] = (X_HOME_DIR == -1) ? 0 : printer_state.xMaxSteps; printer_state.destinationSteps[0] = printer_state.currentPositionSteps[0]; } } if(home_all_axis || GCODE_HAS_Y(com)) { if ((Y_MIN_PIN > -1 && Y_HOME_DIR==-1) || (Y_MAX_PIN > -1 && Y_HOME_DIR==1)) { printer_state.currentPositionSteps[1] = 0; printer_state.destinationSteps[1] = 1.5 * printer_state.yMaxSteps * Y_HOME_DIR; printer_state.currentPositionSteps[1] = -printer_state.destinationSteps[1]; printer_state.feedrate = homing_feedrate[1]; queue_move(true); wait_until_end_of_move(); printer_state.currentPositionSteps[1] = 0; printer_state.destinationSteps[1] = axis_steps_per_unit[1]*-5 * Y_HOME_DIR; queue_move(true); wait_until_end_of_move(); printer_state.destinationSteps[1] = axis_steps_per_unit[1]*10 * Y_HOME_DIR; queue_move(true); wait_until_end_of_move(); printer_state.currentPositionSteps[1] = (Y_HOME_DIR == -1) ? 0 : printer_state.yMaxSteps; printer_state.destinationSteps[1] = printer_state.currentPositionSteps[1]; } } if(home_all_axis || GCODE_HAS_Z(com)) { if ((Z_MIN_PIN > -1 && Z_HOME_DIR==-1) || (Z_MAX_PIN > -1 && Z_HOME_DIR==1)) { printer_state.currentPositionSteps[2] = 0; printer_state.destinationSteps[2] = 1.5 * printer_state.zMaxSteps * Z_HOME_DIR; printer_state.currentPositionSteps[2] = -printer_state.destinationSteps[2]; printer_state.feedrate = homing_feedrate[2]; queue_move(true); wait_until_end_of_move(); printer_state.currentPositionSteps[2] = 0; printer_state.destinationSteps[2] = axis_steps_per_unit[2]*-2 * Z_HOME_DIR; queue_move(true); wait_until_end_of_move(); printer_state.destinationSteps[2] = axis_steps_per_unit[2]*10 * Z_HOME_DIR; queue_move(true); wait_until_end_of_move(); printer_state.currentPositionSteps[2] = (Z_HOME_DIR == -1) ? 0 : printer_state.zMaxSteps; printer_state.destinationSteps[2] = printer_state.currentPositionSteps[2]; } } printer_state.feedrate = saved_feedrate; } break; case 90: // G90 relative_mode = false; break; case 91: // G91 relative_mode = true; break; case 92: // G92 if(GCODE_HAS_X(com)) printer_state.currentPositionSteps[0] = com->X*axis_steps_per_unit[0]*(unit_inches?25.4:1.0)-printer_state.offsetX; if(GCODE_HAS_Y(com)) printer_state.currentPositionSteps[1] = com->Y*axis_steps_per_unit[1]*(unit_inches?25.4:1.0)-printer_state.offsetY; if(GCODE_HAS_Z(com)) printer_state.currentPositionSteps[2] = com->Z*axis_steps_per_unit[2]*(unit_inches?25.4:1.0); if(GCODE_HAS_E(com)) { printer_state.currentPositionSteps[3] = com->E*axis_steps_per_unit[3]*(unit_inches?25.4:1.0); } break; } previous_millis_cmd = millis(); } else if(GCODE_HAS_M(com)) { // Process M Code switch( com->M ) { #ifdef SDSUPPORT case 20: // M20 - list SD card out.println_P(PSTR("Begin file list")); root.ls(); out.println_P(PSTR("End file list")); break; case 21: // M21 - init SD card sdmode = false; initsd(); break; case 22: //M22 - release SD card sdmode = false; sdactive = false; break; case 23: //M23 - Select file if(sdactive) { sdmode = false; file.close(); if (file.open(&root, com->text, O_READ)) { out.print_P(PSTR("File opened:")); out.print(com->text); out.print_P(PSTR(" Size:")); out.println(file.fileSize()); sdpos = 0; filesize = file.fileSize(); out.println_P(PSTR("File selected")); } else { out.println_P(PSTR("file.open failed")); } } break; case 24: //M24 - Start SD print if(sdactive) { sdmode = true; } break; case 25: //M25 - Pause SD print if(sdmode) { sdmode = false; } break; case 26: //M26 - Set SD index if(sdactive && GCODE_HAS_S(com)) { sdpos = com->S; file.seekSet(sdpos); } break; case 27: //M27 - Get SD status if(sdactive) { out.print_P(PSTR("SD printing byte ")); out.print(sdpos); out.print("/"); out.println(filesize); } else { out.println_P(PSTR("Not SD printing")); } break; case 28: //M28 - Start SD write if(sdactive) { char* npos = 0; file.close(); sdmode = false; if (!file.open(&root,com->text, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) { out.print_P(PSTR("open failed, File: ")); out.print(com->text); out.print_P(PSTR(".")); } else { savetosd = true; out.print_P(PSTR("Writing to file: ")); out.println(com->text); } } break; case 29: //M29 - Stop SD write //processed in write to file routine above //savetosd = false; break; case 30: // M30 filename - Delete file if(sdactive) { sdmode = false; file.close(); if(SdFile::remove(&root, com->text)) { out.println_P(PSTR("File deleted")); } else { out.println_P(PSTR("Deletion failed")); } } break; #endif case 104: // M104 if(DEBUG_DRYRUN) break; wait_until_end_of_move(); if (GCODE_HAS_S(com)) extruder_set_temperature(com->S); break; case 140: // M140 set bed temp if(DEBUG_DRYRUN) break; if (GCODE_HAS_S(com)) heated_bed_set_temperature(com->S); break; case 105: // M105 get temperature. Always returns the current temperature, doesn't wait until move stopped print_temperatures(); break; case 109: // M109 - Wait for extruder heater to reach target. { if(DEBUG_DRYRUN) break; wait_until_end_of_move(); if (GCODE_HAS_S(com)) extruder_set_temperature(com->S); if(current_extruder->currentTemperatureC >= current_extruder->targetTemperature) break; codenum = millis(); long waituntil = 0; while(waituntil==0 || (waituntil!=0 && waituntil>millis())) { if( (millis() - codenum) > 1000 ) { //Print Temp Reading every 1 second while heating up. print_temperatures(); codenum = millis(); } manage_temperatures(false); gcode_read_serial(); if(waituntil==0 && current_extruder->currentTemperatureC >= current_extruder->targetTemperatureC) waituntil = millis()+1000*(long)current_extruder->watchPeriod; // now wait for temp. to stabalize } } break; case 190: // M190 - Wait bed for heater to reach target. if(DEBUG_DRYRUN) break; wait_until_end_of_move(); #if HEATED_BED_SENSOR_TYPE!=0 if (GCODE_HAS_S(com)) heated_bed_set_temperature(com->S); codenum = millis(); while(current_bed_raw < target_bed_raw) { if( (millis()-codenum) > 1000 ) { //Print Temp Reading every 1 second while heating up. print_temperatures(); codenum = millis(); } manage_temperatures(false); } #endif break; case 106: //M106 Fan On wait_until_end_of_move(); if (GCODE_HAS_S(com)) { digitalWrite(FAN_PIN, HIGH); analogWrite(FAN_PIN, constrain(com->S,0,255) ); } else digitalWrite(FAN_PIN, HIGH); break; case 107: //M107 Fan Off wait_until_end_of_move(); analogWrite(FAN_PIN, 0); digitalWrite(FAN_PIN, LOW); break; case 80: // M81 - ATX Power On wait_until_end_of_move(); if(PS_ON_PIN > -1) pinMode(PS_ON_PIN,OUTPUT); //GND break; case 81: // M81 - ATX Power Off wait_until_end_of_move(); if(PS_ON_PIN > -1) pinMode(PS_ON_PIN,INPUT); //Floating break; case 82: relative_mode_e = false; break; case 83: relative_mode_e = true; break; case 84: if(GCODE_HAS_S(com)) { stepper_inactive_time = com->S * 1000; } else { wait_until_end_of_move(); kill(true); } break; case 85: // M85 if(GCODE_HAS_S(com)) max_inactive_time = (long)com->S * 1000; else max_inactive_time = 0; break; case 92: // M92 if(GCODE_HAS_X(com)) axis_steps_per_unit[0] = com->X; if(GCODE_HAS_Y(com)) axis_steps_per_unit[1] = com->Y; if(GCODE_HAS_Z(com)) axis_steps_per_unit[2] = com->Z; if(GCODE_HAS_E(com)) current_extruder->stepsPerMM = com->E; update_ramps_parameter(); break; case 111: if(GCODE_HAS_S(com)) debug_level = com->S; if(DEBUG_DRYRUN) { // simulate movements without printing extruder_set_temperature(0); #if HEATED_BED_TYPE!=0 target_bed_raw = 0; #endif } break; case 115: // M115 out.println_P(PSTR("FIRMWARE_NAME:Repetier FIRMWARE_URL:https://github.com/repetier/Repetier-Firmware/ PROTOCOL_VERSION:1.0 MACHINE_TYPE:Mendel EXTRUDER_COUNT:1 REPETIER_PROTOCOL:1")); break; case 114: // M114 out.print_float_P(PSTR("X:"),printer_state.currentPositionSteps[0]*inv_axis_steps_per_unit[0]*(unit_inches?0.03937:1)); out.print_float_P(PSTR(" Y:"),printer_state.currentPositionSteps[1]*inv_axis_steps_per_unit[1]*(unit_inches?0.03937:1)); out.print_float_P(PSTR(" Z:"),printer_state.currentPositionSteps[2]*inv_axis_steps_per_unit[2]*(unit_inches?0.03937:1)); out.println_float_P(PSTR(" E:"),printer_state.currentPositionSteps[3]*inv_axis_steps_per_unit[3]*(unit_inches?0.03937:1)); break; case 119: // M119 wait_until_end_of_move(); #if (X_MIN_PIN > -1) out.print_P(PSTR("x_min:")); out.print_P((digitalRead(X_MIN_PIN)^ENDSTOPS_INVERTING)?PSTR("H "):PSTR("L ")); #endif #if (X_MAX_PIN > -1) out.print_P(PSTR("x_max:")); out.print_P((digitalRead(X_MAX_PIN)^ENDSTOPS_INVERTING)?PSTR("H "):PSTR("L ")); #endif #if (Y_MIN_PIN > -1) out.print_P(PSTR("y_min:")); out.print_P((digitalRead(Y_MIN_PIN)^ENDSTOPS_INVERTING)?PSTR("H "):PSTR("L ")); #endif #if (Y_MAX_PIN > -1) out.print_P(PSTR("y_max:")); out.print_P((digitalRead(Y_MAX_PIN)^ENDSTOPS_INVERTING)?PSTR("H "):PSTR("L ")); #endif #if (Z_MIN_PIN > -1) out.print_P(PSTR("z_min:")); out.print_P((digitalRead(Z_MIN_PIN)^ENDSTOPS_INVERTING)?PSTR("H "):PSTR("L ")); #endif #if (Z_MAX_PIN > -1) out.print_P(PSTR("z_max:")); out.print_P((digitalRead(Z_MAX_PIN)^ENDSTOPS_INVERTING)?PSTR("H "):PSTR("L ")); #endif out.println(); break; #ifdef RAMP_ACCELERATION case 201: // M201 if(GCODE_HAS_X(com)) axis_steps_per_sqr_second[0] = com->X * axis_steps_per_unit[0]; if(GCODE_HAS_Y(com)) axis_steps_per_sqr_second[1] = com->Y * axis_steps_per_unit[1]; if(GCODE_HAS_Z(com)) axis_steps_per_sqr_second[2] = com->Z * axis_steps_per_unit[2]; if(GCODE_HAS_E(com)) axis_steps_per_sqr_second[3] = com->E * axis_steps_per_unit[3]; break; case 202: // M202 if(GCODE_HAS_X(com)) axis_travel_steps_per_sqr_second[0] = com->X * axis_steps_per_unit[0]; if(GCODE_HAS_Y(com)) axis_travel_steps_per_sqr_second[1] = com->Y * axis_steps_per_unit[1]; if(GCODE_HAS_Z(com)) axis_travel_steps_per_sqr_second[2] = com->Z * axis_steps_per_unit[2]; if(GCODE_HAS_E(com)) axis_travel_steps_per_sqr_second[3] = com->E * axis_steps_per_unit[3]; break; #endif case 203: // M203 Temperature monitor if(GCODE_HAS_S(com)) manage_monitor = com->S; if(manage_monitor==100) manage_monitor=NUM_EXTRUDER; // Set 100 to heated bed break; case 205: // M205 Show EEPROM settings epr_output_settings(); break; case 206: // M206 T[type] P[pos] [Sint(long] [Xfloat] Set eeprom value #if EEPROM_MODE!=0 epr_update(com); #else out.println_P(PSTR("Error: No EEPROM support compiled.")); #endif break; case 222: //M222 F_CPU / S if(GCODE_HAS_S(com)) out.println_long_P(PSTR("F_CPU/x="),CPUDivU2(com->S)); break; case 223: if(GCODE_HAS_S(com)) { extruder_enable(); printer_state.extruderStepsNeeded+=(int)com->S; out.println_int_P(PSTR("Added to:"),printer_state.extruderStepsNeeded); } break; #ifdef USE_ADVANCE case 232: out.print_int_P(PSTR("Max advance="),maxadv); if(maxadv>0) out.println_float_P(PSTR(", speed="),maxadvspeed); else out.println(); maxadv=0; maxadvspeed=0; break; #endif #if USE_OPS==1 case 231: // M231 S<OPS_MODE> X<Min_Distance> Y<Retract> Z<Backslash> F<ReatrctMove> if(GCODE_HAS_S(com) && com->S>=0 && com->S<3) printer_state.opsMode = com->S; if(GCODE_HAS_X(com) && com->X>=0) printer_state.opsMinDistance = com->X; if(GCODE_HAS_Y(com) && com->Y>=0) printer_state.opsRetractDistance = com->Y; if(GCODE_HAS_Z(com) && com->Z>=-printer_state.opsRetractDistance) printer_state.opsRetractBackslash = com->Z; if(GCODE_HAS_F(com) && com->F>=0 && com->F<=100) printer_state.opsMoveAfter = com->F; extruder_select(current_extruder->id); if(printer_state.opsMode==0) { out.println_P(PSTR("OPS disabled")); } else { if(printer_state.opsMode==1) out.print_P(PSTR("OPS classic mode:")); else out.print_P(PSTR("OPS fast mode:")); out.print_float_P(PSTR("min distance = "),printer_state.opsMinDistance); out.print_float_P(PSTR(", retract = "),printer_state.opsRetractDistance); out.print_float_P(PSTR(", backslash = "),printer_state.opsRetractDistance); if(printer_state.opsMode==2) out.print_float_P(PSTR(", move after = "),printer_state.opsMoveAfter); out.println(); } #ifdef DEBUG_OPS out.println_int_P(PSTR("Timer diff"),printer_state.timer0Interval); out.println_int_P(PSTR("Ret. steps:"),printer_state.opsRetractSteps); out.println_int_P(PSTR("PushBack Steps:"),printer_state.opsPushbackSteps); out.println_int_P(PSTR("Move after steps:"),printer_state.opsMoveAfterSteps); #endif break; #endif } } else if(GCODE_HAS_T(com)) { // Process T code wait_until_end_of_move(); extruder_select(com->T); } else { if(DEBUG_ERRORS) { out.print_P(PSTR("Unknown command:")); gcode_print_command(com); out.println(); } } #ifdef ECHO_ON_EXECUTE if(DEBUG_ECHO) { out.print_P(PSTR("Echo:")); gcode_print_command(com); out.println(); } #endif gcode_command_finished(); // free command cache }