#include "Gcode.h"
#include "libs/StreamOutput.h"
#include "PublicDataRequest.h"
+#include "StreamOutputPool.h"
+#include "ExtruderPublicAccess.h"
#include <mri.h>
#define extruder_default_feed_rate_checksum CHECKSUM("extruder_default_feed_rate")
// NEW config names
-#define extruder_checksum CHECKSUM("extruder")
#define default_feed_rate_checksum CHECKSUM("default_feed_rate")
#define steps_per_mm_checksum CHECKSUM("steps_per_mm")
#define retract_zlift_length_checksum CHECKSUM("retract_zlift_length")
#define retract_zlift_feedrate_checksum CHECKSUM("retract_zlift_feedrate")
-#define save_state_checksum CHECKSUM("save_state")
-#define restore_state_checksum CHECKSUM("restore_state")
-
#define X_AXIS 0
#define Y_AXIS 1
#define Z_AXIS 2
Extruder::Extruder( uint16_t config_identifier, bool single )
{
this->absolute_mode = true;
+ this->milestone_absolute_mode = true;
this->enabled = false;
this->paused = false;
this->single_config = single;
this->volumetric_multiplier = 1.0F;
this->extruder_multiplier = 1.0F;
this->stepper_motor= nullptr;
+ this->milestone_last_position= 0;
+ this->max_volumetric_rate= 0;
memset(this->offset, 0, sizeof(this->offset));
}
if(!pdr->starts_with(extruder_checksum)) return;
+ // handle extrude rates request from robot
+ // TODO if not in volumetric mode then limit speed based on max_speed
+ if(pdr->second_element_is(target_checksum)) {
+ if(!this->enabled || this->max_volumetric_rate == 0 || this->filament_diameter == 0) return;
+
+ float *d= static_cast<float*>(pdr->get_data_ptr());
+ float target= d[0]; // the E passed in on Gcode is in mm³ (maybe absolute or relative)
+ float isecs= d[1]; // inverted secs
+ float delta;
+
+ if(milestone_absolute_mode) {
+ delta= fabsf(target - milestone_last_position); // delta move
+ milestone_last_position= target;
+
+ }else{
+ delta= target;
+ milestone_last_position += target;
+ }
+
+ // return the rate change needed to stay within the max rate
+ float v= delta * isecs; // the flow rate in mm³/sec
+
+ // TODO need to take filament diameter into account for limiting to mm/sec of stepper
+ if(v > max_volumetric_rate) {
+ d[1] = max_volumetric_rate / v;
+ }else{
+ d[1]= 1.0F;
+ }
+ //THEKERNEL->streams->printf("requested flow rate: %f, corrected flow rate: %f\n", v, v * d[1]);
+ pdr->set_taken();
+ return;
+ }
+
// save or restore state
if(pdr->second_element_is(save_state_checksum)) {
this->saved_current_position= this->current_position;
}
gcode->mark_as_taken();
+ } else if (gcode->m == 203 && ( (this->enabled && !gcode->has_letter('P')) || (gcode->has_letter('P') && gcode->get_value('P') == this->identifier)) ) {
+ // M203 Exxx Vyyy Set maximum feedrates xxx mm/sec and/or yyy mm³/sec
+ if(gcode->get_num_args() == 0) {
+ gcode->stream->printf("E:%g V:%g", this->stepper_motor->get_max_rate(), this->max_volumetric_rate);
+ gcode->add_nl = true;
+
+ }else{
+ if(gcode->has_letter('E')){
+ this->stepper_motor->set_max_rate(gcode->get_value('E'));
+ }
+ if(gcode->has_letter('V')){
+ this->max_volumetric_rate= gcode->get_value('V');
+ }
+ }
+
+ gcode->mark_as_taken();
+
} else if (gcode->m == 204 && gcode->has_letter('E') &&
( (this->enabled && !gcode->has_letter('P')) || (gcode->has_letter('P') && gcode->get_value('P') == this->identifier)) ) {
// extruder acceleration M204 Ennn mm/sec^2 (Pnnn sets the specific extruder for M500)
gcode->stream->printf(";E retract length, feedrate, zlift length, feedrate:\nM207 S%1.4f F%1.4f Z%1.4f Q%1.4f\n", this->retract_length, this->retract_feedrate*60.0F, this->retract_zlift_length, this->retract_zlift_feedrate);
gcode->stream->printf(";E retract recover length, feedrate:\nM208 S%1.4f F%1.4f\n", this->retract_recover_length, this->retract_recover_feedrate*60.0F);
gcode->stream->printf(";E acceleration mm/sec^2:\nM204 E%1.4f\n", this->acceleration);
+ gcode->stream->printf(";E max feed rate mm/sec:\nM203 E%1.4f\n", this->stepper_motor->get_max_rate());
+ if(this->max_volumetric_rate > 0) {
+ gcode->stream->printf(";E max volumetric rate mm³/sec:\nM203 V%1.4f\n", this->max_volumetric_rate);
+ }
} else {
gcode->stream->printf(";E Steps per mm:\nM92 E%1.4f P%d\n", this->steps_per_millimeter, this->identifier);
gcode->stream->printf(";E retract length, feedrate:\nM207 S%1.4f F%1.4f Z%1.4f Q%1.4f P%d\n", this->retract_length, this->retract_feedrate*60.0F, this->retract_zlift_length, this->retract_zlift_feedrate, this->identifier);
gcode->stream->printf(";E retract recover length, feedrate:\nM208 S%1.4f F%1.4f P%d\n", this->retract_recover_length, this->retract_recover_feedrate*60.0F, this->identifier);
gcode->stream->printf(";E acceleration mm/sec^2:\nM204 E%1.4f P%d\n", this->acceleration, this->identifier);
+ gcode->stream->printf(";E max feed rate mm/sec:\nM203 E%1.4f P%d\n", this->stepper_motor->get_max_rate(), this->identifier);
+ if(this->max_volumetric_rate > 0) {
+ gcode->stream->printf(";E max volumetric rate mm³/sec:\nM203 V%1.4f P%d\n", this->max_volumetric_rate, this->identifier);
+ }
}
gcode->mark_as_taken();
+
} else if( gcode->m == 17 || gcode->m == 18 || gcode->m == 82 || gcode->m == 83 || gcode->m == 84 ) {
// Mcodes to pass along to on_gcode_execute
THEKERNEL->conveyor->append_gcode(gcode);
this->cancel_zlift_restore= true;
}
}
+
+ // handle some codes now for the volumetric rate limiting
+ // G90 G91 G92 M82 M83
+ if(gcode->has_m) {
+ switch(gcode->m) {
+ case 82: this->milestone_absolute_mode = true; break;
+ case 83: this->milestone_absolute_mode = false; break;
+ }
+
+ }else if(gcode->has_g) {
+ switch(gcode->g) {
+ case 90: this->milestone_absolute_mode = true; break;
+ case 91: this->milestone_absolute_mode = false; break;
+ case 92:
+ if(gcode->has_letter('E')) { this->milestone_last_position= gcode->get_value('E'); }
+ else if(gcode->get_num_args() == 0) { this->milestone_last_position= 0; }
+ break;
+ }
+ }
}
// Compute extrusion speed based on parameters and gcode distance of travel
} else if (gcode->g == 0 || gcode->g == 1) {
// Extrusion length from 'G' Gcode
if( gcode->has_letter('E' )) {
- // Get relative extrusion distance depending on mode ( in absolute mode we must substract target_position )
+ // Get relative extrusion distance depending on mode ( in absolute mode we must subtract target_position )
float extrusion_distance = gcode->get_value('E');
float relative_extrusion_distance = extrusion_distance;
if (this->absolute_mode) {