// our point structure to make things nice. struct LongPoint { long x; long y; long z; }; struct FloatPoint { float x; float y; float z; }; FloatPoint current_units; FloatPoint target_units; FloatPoint delta_units; FloatPoint current_steps; FloatPoint target_steps; FloatPoint delta_steps; boolean abs_mode = false; //0 = incremental; 1 = absolute //default to mm for units float x_units = X_STEPS_PER_MM; float y_units = Y_STEPS_PER_MM; float z_units = Z_STEPS_PER_MM; float curve_section = CURVE_SECTION_MM; //our direction vars byte x_direction = 1; byte y_direction = 1; byte z_direction = 1; //init our string processing void init_process_string() { //init our command for (byte i=0; i 0) feedrate_micros = calculate_feedrate_delay(feedrate); //nope, no feedrate else feedrate_micros = getMaxSpeed(); } //use our max for normal moves. else feedrate_micros = getMaxSpeed(); } //nope, just coordinates! else { //do we have a feedrate yet? if (feedrate > 0) feedrate_micros = calculate_feedrate_delay(feedrate); //nope, no feedrate else feedrate_micros = getMaxSpeed(); } //finally move. dda_move(feedrate_micros); break; //Dwell case 4: delay((int)search_string('P', instruction, size)); break; //Inches for Units case 20: x_units = X_STEPS_PER_INCH; y_units = Y_STEPS_PER_INCH; z_units = Z_STEPS_PER_INCH; curve_section = CURVE_SECTION_INCHES; calculate_deltas(); break; //mm for Units case 21: x_units = X_STEPS_PER_MM; y_units = Y_STEPS_PER_MM; z_units = Z_STEPS_PER_MM; curve_section = CURVE_SECTION_MM; calculate_deltas(); break; //go home. case 28: set_target(0.0, 0.0, 0.0); dda_move(getMaxSpeed()); break; //go home via an intermediate point. case 30: fp.x = search_string('X', instruction, size); fp.y = search_string('Y', instruction, size); fp.z = search_string('Z', instruction, size); //set our target. if(abs_mode) { if (!has_command('X', instruction, size)) fp.x = current_units.x; if (!has_command('Y', instruction, size)) fp.y = current_units.y; if (!has_command('Z', instruction, size)) fp.z = current_units.z; set_target(fp.x, fp.y, fp.z); } else set_target(current_units.x + fp.x, current_units.y + fp.y, current_units.z + fp.z); //go there. dda_move(getMaxSpeed()); //go home. set_target(0.0, 0.0, 0.0); dda_move(getMaxSpeed()); break; //Absolute Positioning case 90: abs_mode = true; break; //Incremental Positioning case 91: abs_mode = false; break; //Set as home case 92: set_position(0.0, 0.0, 0.0); break; /* //Inverse Time Feed Mode case 93: break; //TODO: add this //Feed per Minute Mode case 94: break; //TODO: add this */ default: Serial.print("huh? G"); Serial.println(code,DEC); } } //find us an m code. if (has_command('M', instruction, size)) { code = search_string('M', instruction, size); switch (code) { //TODO: this is a bug because search_string returns 0. gotta fix that. case 0: true; break; /* case 0: //todo: stop program break; case 1: //todo: optional stop break; case 2: //todo: program end break; */ //turn extruder on, forward case 101: enableTimer1Interrupt(); enableTimer2Interrupt(); break; //turn extruder on, reverse case 102: //this is not implemented, nor supported break; //turn extruder off case 103: disableTimer1Interrupt(); disableTimer2Interrupt(); analogWrite(EXTRUDER_MOTOR_SPEED_PIN, 0); //extruder_error = 0; break; //custom code for temperature control case 104: extruder_set_temperature((int)search_string('S', instruction, size)); //warmup if we're too cold. while (extruder_get_temperature() < extruder_target_celsius) { extruder_manage_temperature(); Serial.print("T:"); Serial.println(extruder_get_temperature()); delay(1000); } break; //custom code for temperature reading case 105: Serial.print("T:"); Serial.println(extruder_get_temperature()); break; //turn fan on case 106: extruder_set_cooler(255); break; //turn fan off case 107: extruder_set_cooler(0); break; //set max extruder speed, in RPM case 108: extruder_rpm = (int)search_string('R', instruction, size); if (extruder_rpm) { extruder_delay = (960000000UL / EXTRUDER_ENCODER_STEPS) / extruder_rpm; setTimer1Ticks(extruder_delay); } break; //set extruder P gain case 120: extruder_pGain = (int)search_string('S', instruction, size); break; //set extruder I gain case 121: extruder_iGain = (int)search_string('S', instruction, size); break; //set extruder D gain case 122: extruder_dGain = (int)search_string('S', instruction, size); break; //set extruder iMax case 123: iMax = (int)search_string('S', instruction, size); break; //set extruder iMin case 124: iMin = (int)search_string('S', instruction, size); break; //set extruder iMin case 125: Serial.print("P:"); Serial.println(extruder_pGain, DEC); Serial.print("I:"); Serial.println(extruder_iGain, DEC); Serial.print("D:"); Serial.println(extruder_dGain, DEC); break; default: Serial.print("Huh? M"); Serial.println(code); } } //tell our host we're done. Serial.println("ok"); } //look for the number that appears after the char key and return it double search_string(char key, char instruction[], int string_size) { char temp[10] = ""; for (byte i=0; i