reworking the extruder module to work with the new stepper subsystem
authorArthur Wolf <wolf.arthur@gmail.com>
Wed, 19 Sep 2012 19:46:28 +0000 (21:46 +0200)
committerArthur Wolf <wolf.arthur@gmail.com>
Wed, 19 Sep 2012 19:46:28 +0000 (21:46 +0200)
src/main.cpp
src/modules/tools/extruder/Extruder.cpp
src/modules/tools/extruder/Extruder.h

index afc1026..785c5f3 100644 (file)
@@ -7,7 +7,7 @@
 
 #include "libs/Kernel.h"
 #include "modules/tools/laser/Laser.h"
-//#include "modules/tools/extruder/Extruder.h"
+#include "modules/tools/extruder/Extruder.h"
 #include "modules/tools/temperaturecontrol/TemperatureControlPool.h"
 #include "modules/tools/endstops/Endstops.h"
 #include "modules/tools/switch/SwitchPool.h"
@@ -33,7 +33,7 @@ int main() {
     kernel->streams->printf("Smoothie ( grbl port ) version 0.6.1 \r\n");
 
     //kernel->add_module( new Laser(p21) );
-    //kernel->add_module( new Extruder() );
+    kernel->add_module( new Extruder() );
     kernel->add_module( new SimpleShell() );
     kernel->add_module( new Configurator() );
     kernel->add_module( new CurrentControl() );
index aaa5a93..c25a213 100644 (file)
@@ -5,7 +5,6 @@
       You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
 */
 
-/*
 #include "libs/Module.h"
 #include "libs/Kernel.h"
 #include "modules/robot/Player.h"
@@ -18,8 +17,6 @@
 
 Extruder::Extruder() {
     this->absolute_mode = true;
-    this->direction     = 1;
-    this->acceleration_lock = false;
     this->step_counter = 0;
     this->counter_increment = 0;
     this->paused = false;
@@ -41,9 +38,9 @@ void Extruder::on_module_loaded() {
     this->register_for_event(ON_GCODE_EXECUTE);
     this->register_for_event(ON_PLAY);
     this->register_for_event(ON_PAUSE);
+    this->register_for_event(ON_SPEED_CHANGE);
 
     // Start values
-    this->start_position = 0;
     this->target_position = 0;
     this->current_position = 0;
     this->current_block = NULL;
@@ -53,18 +50,18 @@ void Extruder::on_module_loaded() {
     // TODO: Make this an independent setting
     this->kernel->slow_ticker->attach( this->kernel->stepper->acceleration_ticks_per_second , this, &Extruder::acceleration_tick );
 
-    // Initiate main_interrupt timer and step reset timer
-    this->kernel->step_ticker->attach( this, &Extruder::stepping_tick );
-    this->kernel->step_ticker->reset_attach( this, &Extruder::reset_step_pin );
+    // Stepper motor object for the extruder
+    this->stepper_motor  = this->kernel->step_ticker->add_stepper_motor( new StepperMotor(this->step_pin,this->dir_pin,this->en_pin) );   
+    this->stepper_motor->attach(this, &Extruder::stepper_motor_finished_move ); 
 
 }
 
 // Get config
 void Extruder::on_config_reload(void* argument){
        this->microseconds_per_step_pulse = this->kernel->config->value(microseconds_per_step_pulse_checksum)->by_default(5)->as_number();
-       this->steps_per_millimeter        = this->kernel->config->value(extruder_steps_per_mm_checksum       )->by_default(1)->as_number();
-       this->feed_rate                   = this->kernel->config->value(default_feed_rate_checksum          )->by_default(1)->as_number();
-       this->acceleration                = this->kernel->config->value(acceleration_checksum               )->by_default(1)->as_number();
+       this->steps_per_millimeter        = this->kernel->config->value(extruder_steps_per_mm_checksum      )->by_default(1)->as_number();
+       this->feed_rate                   = this->kernel->config->value(default_feed_rate_checksum          )->by_default(1000)->as_number();
+       this->acceleration                = this->kernel->config->value(extruder_acceleration_checksum      )->by_default(1000)->as_number();
 
        this->step_pin                    = this->kernel->config->value(extruder_step_pin_checksum          )->by_default("nc" )->as_pin()->as_output();
        this->dir_pin                     = this->kernel->config->value(extruder_dir_pin_checksum           )->by_default("nc" )->as_pin()->as_output();
@@ -105,7 +102,6 @@ void Extruder::on_gcode_execute(void* argument){
             if( gcode->has_letter('E') ){
                 this->current_position = gcode->get_value('E');
                 this->target_position  = this->current_position;
-                this->start_position   = this->current_position;
             }
         }else{
             // Extrusion length from 'G' Gcode
@@ -137,20 +133,27 @@ void Extruder::on_block_begin(void* argument){
     Block* block = static_cast<Block*>(argument);
     if( this->mode == SOLO ){
         // In solo mode we take the block so we can move even if the stepper has nothing to do
+        
         block->take();
         this->current_block = block;
-        this->start_position = this->target_position;
-        this->target_position = this->start_position + this->travel_distance ;
-        this->travel_ratio = 0.2;   // TODO : Make a real acceleration thing
-        if( this->target_position > this->current_position ){ this->direction = 1; }else if( this->target_position < this->current_position ){ this->direction = -1; }
-        this->set_speed(int(floor((this->feed_rate/60)*this->steps_per_millimeter)));//Speed in steps per second
+        this->target_position = this->current_position + this->travel_distance ;
+        
+        this->stepper_motor->move( ( this->travel_distance > 0 ), int(floor(this->steps_per_millimeter * fabs(this->travel_distance)))); 
+
     }else if( this->mode == FOLLOW ){
         // In non-solo mode, we just follow the stepper module
+        
+        block->take();
         this->current_block = block;
-        this->start_position = this->target_position;
-        this->target_position =  this->start_position + ( this->current_block->millimeters * this->travel_ratio );
-        if( this->target_position > this->current_position ){ this->direction = 1; }else if( this->target_position < this->current_position ){ this->direction = -1; }
-        this->acceleration_tick(0);
+        this->target_position =  this->current_position + ( this->current_block->millimeters * this->travel_ratio );
+       
+        this->stepper_motor->move( ( this->travel_distance > 0 ), int(floor(this->steps_per_millimeter * fabs(this->travel_distance)))); 
+
+    }else if( this->mode == OFF ){
+        // No movement means we must reset our speed
+        
+        this->stepper_motor->set_speed(0);
+    
     }
 
 }
@@ -165,18 +168,21 @@ void Extruder::on_block_end(void* argument){
 uint32_t Extruder::acceleration_tick(uint32_t dummy){
 
     // Avoid trying to work when we really shouldn't ( between blocks or re-entry )
-    if( this->current_block == NULL || this->acceleration_lock || this->paused ){ return 0; }
-    this->acceleration_lock = true;
-
-    // In solo mode, we mode independently from the robot
-    if( this->mode == SOLO ){
-        // TODO : Do real acceleration here
-        this->travel_ratio += 0.03;
-        if( this->travel_ratio > 1 ){ this->travel_ratio = 1; }
-        this->set_speed( int(floor(((this->feed_rate/60)*this->steps_per_millimeter)*this->travel_ratio)) );  // Speed in steps per second
+    if( this->current_block == NULL ||  this->paused || this->mode != SOLO ){ return 0; }
+
+    uint32_t current_rate = this->stepper_motor->steps_per_second;
+    uint32_t target_rate = int(floor((this->feed_rate/60)*this->steps_per_millimeter));
+    
+    if( current_rate < target_rate ){
+        uint32_t rate_increase = int(floor((this->acceleration/this->kernel->stepper->acceleration_ticks_per_second)*this->steps_per_millimeter));
+        uint32_t new_rate = min( target_rate, current_rate + rate_increase );
+        this->stepper_motor->set_speed(new_rate); 
+    }
 
         // In follow mode we match the speed of the robot, + eventually advance
-    }else if( this->mode == FOLLOW ){
+    
+       /* 
+        //}else if( this->mode == FOLLOW ){
         Stepper* stepper = this->kernel->stepper; // Just for convenience
 
         // Strategy :
@@ -189,9 +195,9 @@ uint32_t Extruder::acceleration_tick(uint32_t dummy){
         int ticks_forward = 3;
         // We need to take those values here, and then use those instead of the live values, because using the live values inside the loop can break things ( infinite loops etc ... )
         double next_stepper_rate = stepper->trapezoid_adjusted_rate;
-        double step_events_completed =   (double(double(stepper->step_events_completed)/double(1<<16)));
-        double position = ( this->current_position - this->start_position ) * this->direction ;
-        double length = fabs( this->start_position - this->target_position );
+        double step_events_completed = 0;//  (double(double(stepper->step_events_completed)/double(1<<16)));
+        double position = 0; //( this->current_position - this->start_position ) * this->direction ;
+        double length = 0; //fabs( this->start_position - this->target_position );
         double last_ratio = -1;
 
         // Do the startegy above, but if it does not work, look a bit further and try again, and again ...
@@ -208,9 +214,9 @@ uint32_t Extruder::acceleration_tick(uint32_t dummy){
             next_relative_position += ( advance );
 
             // TODO : all of those "if->return" is very hacky, we should do the math in a way where most of those don't happen, but that requires doing tons of drawing ...
-            if( last_ratio == next_ratio ){ this->acceleration_lock = false; return 0; }else{ last_ratio = next_ratio; }
-            if( next_ratio == 0 || next_ratio > 1 ){ this->acceleration_lock = false; return 0; }
-            if( ticks_forward > 1000 ){ this->acceleration_lock = false; return 0; } // This is very ugly
+            if( last_ratio == next_ratio ){ return 0; }else{ last_ratio = next_ratio; }
+            if( next_ratio == 0 || next_ratio > 1 ){ return 0; }
+            if( ticks_forward > 1000 ){ return 0; } // This is very ugly
 
             // Hack : We have not looked far enough, we compute how far ahead we must look to get a relevant value
             if( position > next_relative_position ){
@@ -222,71 +228,45 @@ uint32_t Extruder::acceleration_tick(uint32_t dummy){
                 double ticks_to_equilibrium = ceil(far_back_ratio / ratio_per_tick) + 1;
                 ticks_forward += ticks_to_equilibrium;
                 // Because this is a loop, and we can be interrupted by the stepping interrupt, if that interrupt changes block, the new block may not be solo, and we may get trapped into an infinite loop
-                if( this->mode != FOLLOW ){ this->acceleration_lock = false; return 0; }
+                if( this->mode != FOLLOW ){ return 0; }
                 continue;
             }
 
             // Finally, compute the speed to get to that next position
-            double next_absolute_position = this->start_position + ( this->direction * next_relative_position );
-            double steps_to_next_tick = ( next_relative_position - position ) * this->steps_per_millimeter;
-            double speed_to_next_tick = steps_to_next_tick / ( 1 / double(double(this->kernel->stepper->acceleration_ticks_per_second) / ticks_forward) );
+            //double next_absolute_position = this->start_position + ( this->direction * next_relative_position );
+            //double steps_to_next_tick = ( next_relative_position - position ) * this->steps_per_millimeter;
+            //double speed_to_next_tick = steps_to_next_tick / ( 1 / double(double(this->kernel->stepper->acceleration_ticks_per_second) / ticks_forward) );
 
             // Change stepping speed
-            this->set_speed( speed_to_next_tick );
+            //this->set_speed( speed_to_next_tick );
 
-            this->acceleration_lock = false;
             return 0;
         }
     }
+    */
+
 
-    this->acceleration_lock = false;
-       return 0;
+    return 0;
 }
 
-// Convenience function to set stepping speed
-void Extruder::set_speed( int steps_per_second ){
+// Speed has been updated for the robot's stepper, we must update accordingly
+void Extruder::on_speed_change( void* argument ){
 
-    if( steps_per_second < 10 ){ steps_per_second = 10; }
+    // Avoid trying to work when we really shouldn't ( between blocks or re-entry )
+    if( this->current_block == NULL ||  this->paused || this->mode != FOLLOW ){ return; }
 
-    // TODO : Proper limit config value
-    if( steps_per_second > (this->feed_rate*double(this->steps_per_millimeter))/60 ){
-        steps_per_second = (this->feed_rate*double(this->steps_per_millimeter))/60;
-    }
 
-    this->counter_increment = int(floor(double(1<<16)/double(this->kernel->stepper->base_stepping_frequency / steps_per_second)));
 
 }
 
-inline uint32_t Extruder::stepping_tick(uint32_t dummy){
-    if( this->paused ){ return 0; }
 
-    this->step_counter += this->counter_increment;
-    if( this->step_counter > 1<<16 ){
-        this->step_counter -= 1<<16;
 
-        // If we still have steps to do
-        // TODO: Step using the same timer as the robot, and count steps instead of absolute float position
-        if( ( this->current_position < this->target_position && this->direction == 1 ) || ( this->current_position > this->target_position && this->direction == -1 ) ){
-            this->current_position += (double(double(1)/double(this->steps_per_millimeter)))*double(this->direction);
-            this->dir_pin->set((this->direction > 0) ? 1 : 0);
-            this->step_pin->set(1);
-        }else{
-            // Move finished
-            if( this->mode == SOLO && this->current_block != NULL ){
-                // In follow mode, the robot takes and releases the block, in solo mode we do
-                this->current_block->release();
-            }
-        }
-    }
-    return 0;
-}
+// When the stepper has finished it's move
+uint32_t Extruder::stepper_motor_finished_move(uint32_t dummy){
 
-uint32_t Extruder::reset_step_pin(uint32_t dummy){
-    this->step_pin->set(0);
-       return 0;
-}
-
-*/
+    this->current_position = this->target_position;
 
+    this->current_block->release();
 
+}
 
index 952f104..65f83ad 100644 (file)
@@ -18,7 +18,7 @@
 #define extruder_module_enable_checksum      6183
 #define extruder_steps_per_mm_checksum       58088
 #define default_feed_rate_checksum           53183
-#define acceleration_checksum                60356
+#define extruder_acceleration_checksum       60356
 
 #define OFF 0
 #define SOLO 1
@@ -34,16 +34,14 @@ class Extruder : public Module{
         void on_block_end(void* argument);
         void on_play(void* argument);
         void on_pause(void* argument);
-        void set_speed(int steps_per_second);
+        void on_speed_change(void* argument);
         uint32_t acceleration_tick(uint32_t dummy);
-        uint32_t stepping_tick(uint32_t dummy);
-        uint32_t reset_step_pin(uint32_t dummy);
+        uint32_t stepper_motor_finished_move(uint32_t dummy);
 
         Pin*            step_pin;                     // Step pin for the stepper driver
         Pin*            dir_pin;                      // Dir pin for the stepper driver
         Pin*            en_pin;
 
-        double          start_position;               // Start point ( in steps ) for the current move
         double          target_position;              // End point ( in steps ) for the current move
         double          current_position;             // Current point ( in steps ) for the current move, incremented every time a step is outputed
         Block*          current_block;                // Current block we are stepping, same as Stepper's one
@@ -60,15 +58,15 @@ class Extruder : public Module{
         double          travel_distance;
         bool            absolute_mode;
 
-        int             direction;
-
         bool            debug;
         int debug_count;
 
         char mode;
-        bool acceleration_lock;
 
         bool paused;
+
+        StepperMotor* stepper_motor;
+
 };
 
 #endif