Robot: add M220 speed override percentage, ala Marlin et al.
authorMichael Moon <triffid.hunter@gmail.com>
Tue, 15 Jan 2013 08:20:39 +0000 (19:20 +1100)
committerMichael Moon <triffid.hunter@gmail.com>
Tue, 15 Jan 2013 08:20:39 +0000 (19:20 +1100)
M220 S100 = normal speed, M220 S200 = double speed, M220 S50 = half speed, etc.

Axis limits are still obeyed to avoid skipped steps with ludicrous numbers, and a 1% minimum is enforced in case of accidental mis-keying and also to prevent the block queue locking up.

There is no maximum ;)

src/modules/robot/Robot.cpp
src/modules/robot/Robot.h
src/modules/tools/extruder/Extruder.cpp

index cc37431..d2855d0 100644 (file)
@@ -28,6 +28,7 @@ Robot::Robot(){
     clear_vector(this->current_position);
     clear_vector(this->last_milestone);
     this->arm_solution = NULL;
+    seconds_per_minute = 60.0;
 }
 
 //Called when the module has just been loaded
@@ -136,10 +137,12 @@ void Robot::execute_gcode(Gcode* gcode){
                     steps[1] = this->to_millimeters(gcode->get_value('Y'));
                 if (gcode->has_letter('Z'))
                     steps[2] = this->to_millimeters(gcode->get_value('Z'));
+                if (gcode->has_letter('F'))
+                    seconds_per_minute = gcode->get_value('F');
                 this->arm_solution->set_steps_per_millimeter(steps);
                 // update current position in steps
                 this->arm_solution->millimeters_to_steps(this->current_position, this->kernel->planner->position);
-                gcode->stream->printf("X:%g Y:%g Z:%g ", steps[0], steps[1], steps[2]);
+                gcode->stream->printf("X:%g Y:%g Z:%g F:%g ", steps[0], steps[1], steps[2], seconds_per_minute);
                 gcode->add_nl = true;
                 return;
             case 114: gcode->stream->printf("C: X:%1.3f Y:%1.3f Z:%1.3f ",
@@ -148,6 +151,15 @@ void Robot::execute_gcode(Gcode* gcode){
                                                  this->current_position[2]);
                 gcode->add_nl = true;
                 return;
+            case 220: // M220 - speed override percentage
+                if (gcode->has_letter('S'))
+                {
+                    double factor = gcode->get_value('S');
+                    // enforce minimum 1% speed
+                    if (factor < 1.0)
+                        factor = 1.0;
+                    seconds_per_minute = factor * 0.6;
+                }
         }
    }
     if( this->motion_mode < 0)
@@ -162,7 +174,13 @@ void Robot::execute_gcode(Gcode* gcode){
     for(char letter = 'I'; letter <= 'K'; letter++){ if( gcode->has_letter(letter) ){ offset[letter-'I'] = this->to_millimeters(gcode->get_value(letter));                                                    } }
     for(char letter = 'X'; letter <= 'Z'; letter++){ if( gcode->has_letter(letter) ){ target[letter-'X'] = this->to_millimeters(gcode->get_value(letter)) + ( this->absolute_mode ? 0 : target[letter-'X']);  } }
 
-    if( gcode->has_letter('F') ){ if( this->motion_mode == MOTION_MODE_SEEK ){ this->seek_rate = this->to_millimeters( gcode->get_value('F') ) / 60; }else{ this->feed_rate = this->to_millimeters( gcode->get_value('F') ) / 60; } }
+    if( gcode->has_letter('F') )
+    {
+        if( this->motion_mode == MOTION_MODE_SEEK )
+            this->seek_rate = this->to_millimeters( gcode->get_value('F') ) / 60.0;
+        else
+            this->feed_rate = this->to_millimeters( gcode->get_value('F') ) / 60.0;
+    }
 
     //Perform any physical actions
     switch( next_action ){
@@ -200,14 +218,14 @@ void Robot::append_milestone( double target[], double rate ){
 
     for(int axis=X_AXIS;axis<=Z_AXIS;axis++){
         if( this->max_speeds[axis] > 0 ){
-            double axis_speed = ( fabs(deltas[axis]) / ( millimeters_of_travel / rate )) * 60;
+            double axis_speed = ( fabs(deltas[axis]) / ( millimeters_of_travel / rate )) * seconds_per_minute;
             if( axis_speed > this->max_speeds[axis] ){
                 rate = rate * ( this->max_speeds[axis] / axis_speed );
             }
         }
     }
 
-    this->kernel->planner->append_block( steps, rate*60, millimeters_of_travel, deltas );
+    this->kernel->planner->append_block( steps, rate * seconds_per_minute, millimeters_of_travel, deltas );
 
     memcpy(this->last_milestone, target, sizeof(double)*3); // this->last_milestone[] = target[];
 
index a20cd0f..44dd130 100644 (file)
@@ -82,7 +82,7 @@ class Robot : public Module {
         BaseSolution* arm_solution;                           // Selected Arm solution ( millimeters to step calculation )
         double mm_per_line_segment;                           // Setting : Used to split lines into segments
         double mm_per_arc_segment;                            // Setting : Used to split arcs into segmentrs
-        
+
         // Number of arc generation iterations by small angle approximation before exact arc trajectory
         // correction. This parameter maybe decreased if there are issues with the accuracy of the arc
         // generations. In general, the default value is more than enough for the intended CNC applications
@@ -102,12 +102,12 @@ class Robot : public Module {
         Pin* alpha_en_pin;
         Pin* beta_en_pin;
         Pin* gamma_en_pin;
+
         StepperMotor* alpha_stepper_motor;
         StepperMotor* beta_stepper_motor;
         StepperMotor* gamma_stepper_motor;
 
-
+        double seconds_per_minute;                            // for realtime speed change
 };
 
 #endif
index 5d08078..5babe1f 100644 (file)
@@ -99,6 +99,14 @@ void Extruder::on_gcode_received(void *argument)
             gcode->stream->printf("E:%4.1f ", this->current_position);
             gcode->add_nl = true;
         }
+        if (gcode->m == 92 )
+        {
+            double spm = this->steps_per_millimeter;
+            if (gcode->has_letter('E'))
+                spm = gcode->get_value('E');
+            gcode->stream->printf("E:%g ", spm);
+            gcode->add_nl = true;
+        }
     }
 }
 
@@ -118,8 +126,6 @@ void Extruder::on_gcode_execute(void* argument){
                 this->steps_per_millimeter = gcode->get_value('E');
                 this->current_steps = int(floor(this->steps_per_millimeter * this->current_position));
             }
-            gcode->stream->printf("E:%g ", this->steps_per_millimeter);
-            gcode->add_nl = true;
         }
     }