repaired Pause subsystem, added M109 ( wait for temp ) gcode to
authorArthur Wolf <wolf.arthur@gmail.com>
Sun, 19 Feb 2012 22:37:13 +0000 (23:37 +0100)
committerArthur Wolf <wolf.arthur@gmail.com>
Sun, 19 Feb 2012 22:37:13 +0000 (23:37 +0100)
temperaturecontrol

15 files changed:
src/libs/Config.h
src/libs/Kernel.cpp
src/libs/Kernel.h
src/libs/Pin.h
src/main.cpp
src/modules/robot/Block.cpp
src/modules/robot/Stepper.cpp
src/modules/robot/Stepper.h
src/modules/tools/extruder/Extruder.cpp
src/modules/tools/extruder/Extruder.h
src/modules/tools/temperaturecontrol/TemperatureControl.cpp
src/modules/tools/temperaturecontrol/TemperatureControl.h
src/modules/utils/pausebutton/PauseButton.cpp [new file with mode: 0644]
src/modules/utils/pausebutton/PauseButton.h [moved from src/modules/utils/pauser/Pauser.h with 58% similarity]
src/modules/utils/pauser/Pauser.cpp [deleted file]

index c89df1d..fd9b7c1 100644 (file)
@@ -71,7 +71,7 @@ class ConfigValue{
 
         Pin* as_pin(){
             Pin* pin = new Pin();
-            pin->from_string(this->value);
+            pin->from_string(this->as_string());
             return pin;
         }
 
index 1d3601c..20e5059 100644 (file)
@@ -14,6 +14,7 @@ using namespace std;
 #include "libs/nuts_bolts.h"
 #include "libs/SlowTicker.h"
 #include "libs/Adc.h"
+#include "libs/Pauser.h"
 
 #include "modules/communication/SerialConsole.h"
 #include "modules/communication/GcodeDispatch.h"
@@ -63,18 +64,12 @@ Kernel::Kernel(){
     NVIC_SetPriority(TIMER2_IRQn, 2); 
 
     // Core modules 
-    this->gcode_dispatch = new GcodeDispatch();
-    this->robot          = new Robot();
-    this->stepper        = new Stepper();
-    this->planner        = new Planner();
-    this->player         = new Player();
-
-    this->add_module( this->gcode_dispatch );
-    this->add_module( this->robot );
-    this->add_module( this->stepper );
-    this->add_module( this->planner );
-    this->add_module( this->player );
-
+    this->add_module( this->gcode_dispatch = new GcodeDispatch() );
+    this->add_module( this->robot          = new Robot()         );
+    this->add_module( this->stepper        = new Stepper()       );
+    this->add_module( this->planner        = new Planner()       );
+    this->add_module( this->player         = new Player()        );
+    this->add_module( this->pauser         = new Pauser()        );
 }
 
 void Kernel::add_module(Module* module){
index 74b24bc..33c92dd 100644 (file)
@@ -12,6 +12,7 @@
 #include "libs/SlowTicker.h"
 #include "libs/StepTicker.h"
 #include "libs/Adc.h"
+#include "libs/Pauser.h"
 #include "modules/communication/SerialConsole.h"
 #include "modules/communication/GcodeDispatch.h"
 #include "modules/robot/Planner.h"
@@ -59,6 +60,7 @@ class Kernel {
         Planner*          planner;
         Config*           config;
         Player*           player;
+        Pauser*           pauser;
 
         int debug;
         SlowTicker*       slow_ticker;
index c9a3bda..9d9b6ca 100644 (file)
@@ -23,7 +23,21 @@ class Pin{
             return this;
         }  
 
+        inline Pin*  as_input(){
+            this->port->FIODIR &= ~(1<<this->pin);
+            return this;
+        }  
+
+        inline bool get(){
+            if( this->inverting ){
+               return ~(( this->port->FIOPIN >> this->pin ) & 1);
+            }else{
+               return  (( this->port->FIOPIN >> this->pin ) & 1);
+            }
+        }
+
         inline void set(bool value){
+            // TODO : This should be bitmath 
             if( this->inverting ){ value = !value; }
             if( value ){
                 this->port->FIOSET = 1 << this->pin;
index 613aadc..6f8b603 100644 (file)
@@ -12,7 +12,7 @@
 #include "modules/tools/temperaturecontrol/TemperatureControlPool.h"
 #include "modules/robot/Player.h"
 #include "modules/utils/simpleshell/SimpleShell.h"
-#include "modules/utils/pauser/Pauser.h"
+#include "modules/utils/pausebutton/PauseButton.h"
 #include "libs/ChaNFSSD/SDFileSystem.h"
 #include "libs/Config.h"
 #include "libs/nuts_bolts.h"
@@ -33,15 +33,10 @@ int main() {
     kernel->add_module( new Extruder(p26,p27) );
     kernel->add_module( new SimpleShell() );
     kernel->add_module( new TemperatureControlPool() );
-    
+    kernel->add_module( new PauseButton() );   
+
     kernel->add_module( &cdcmsc );
  
-    wait(0.1); 
-    Pin* pin = new Pin(); 
-    kernel->adc->enable_pin(pin->from_string("0.23"));
-    wait(0.1);
-    kernel->serial->printf("value: %u \r\n", kernel->adc->read(pin));
-
     while(1){
         kernel->call_event(ON_MAIN_LOOP);
     }
index ee03642..057886a 100644 (file)
@@ -161,8 +161,6 @@ void Block::forward_pass(Block* previous, Block* next){
 
 // Gcodes are attached to their respective blocks so that on_gcode_execute can be called with it
 void Block::append_gcode(Gcode* gcode){
-   //this->commands.push_back(gcode->command);
-   //this->travel_distances.push_back(gcode->millimeters_of_travel);
    __disable_irq();
    this->gcodes.push_back(*gcode);
    __enable_irq();
@@ -171,16 +169,7 @@ void Block::append_gcode(Gcode* gcode){
 // The attached gcodes are then poped and the on_gcode_execute event is called with them as a parameter
 void Block::pop_and_execute_gcode(Kernel* &kernel){
     Block* block = const_cast<Block*>(this);
-    //for(unsigned short index=0; index<block->commands.size(); index++){
-    //    Gcode gcode = Gcode();
-    //    gcode.command = block->commands.at(index);
-    //    gcode.millimeters_of_travel = block->travel_distances.at(index);
-    //    kernel->call_event(ON_GCODE_EXECUTE, &gcode ); 
-    //}
     for(unsigned short index=0; index<block->gcodes.size(); index++){
-        //this->player->kernel->serial->printf("exec: block:%p gcode:%p command:%p \r\n", block, &(block->gcodes[index]), &(block->gcodes[index].command) );
-        //this->player->kernel->serial->printf("                        str:%s \r\n", block->gcodes[index].command.c_str() );
-        //wait(0.1);
         kernel->call_event(ON_GCODE_EXECUTE, &(block->gcodes[index]));
     }
 }
@@ -204,20 +193,14 @@ void Block::release(){
         this->pop_and_execute_gcode(this->player->kernel);
         Player* player = this->player;
 
-        //this->player->kernel->serial->printf("a %d\r\n", this->player->queue.size() );
         if( player->queue.size() > 0 ){ 
             player->queue.delete_first();
         } 
 
-        //this->player->kernel->serial->printf("b %d %d\r\n", this->player->queue.size(), player->looking_for_new_block );
-        
         if( player->looking_for_new_block == false ){
-            //player->pop_and_process_new_block(123);
             if( player->queue.size() > 0 ){
                 Block* candidate =  player->queue.get_ref(0);
                 if( candidate->is_ready ){
-                    //candidate->debug(player->kernel);
-                    //this->player->kernel->serial->printf("c %d %d\r\n", this->player->queue.size(), player->looking_for_new_block );
                     player->current_block = candidate;
                     player->kernel->call_event(ON_BLOCK_BEGIN, player->current_block);
                     if( player->current_block->times_taken < 1 ){
@@ -229,9 +212,6 @@ void Block::release(){
 
                 } 
             }else{
-                //player->current_block->debug(player->kernel);
-                //this->player->kernel->serial->printf("d %d %d\r\n", this->player->queue.size(), player->looking_for_new_block );
-                //wait(0.1);
                 player->current_block = NULL;
             }
         }
index 5d250dd..f1a59e7 100644 (file)
@@ -21,6 +21,7 @@ Stepper::Stepper(){
     this->current_block = NULL;
     this->step_events_completed = 0; 
     this->divider = 0;
+    this->paused = false;
 }
 
 //Called when the module has just been loaded
@@ -65,12 +66,13 @@ void Stepper::on_config_reload(void* argument){
 
 // When the play/pause button is set to pause, or a module calls the ON_PAUSE event
 void Stepper::on_pause(void* argument){
-    //TODO: reImplement pause here
+    this->paused = true;
 }
 
 // When the play/pause button is set to play, or a module calls the ON_PLAY event
 void Stepper::on_play(void* argument){
-    //TODO: reImplement pause here
+    // TODO: Re-compute the whole queue for a cold-start
+    this->paused = false;
 }
 
 // A new block is popped from the queue
@@ -83,10 +85,6 @@ void Stepper::on_block_begin(void* argument){
     // Mark the new block as of interrest to us
     block->take();
    
-    if( block->final_rate < 0.1 ){
-        //block->debug(this->kernel);
-    }
-
     // Setup
     for( int stpr=ALPHA_STEPPER; stpr<=GAMMA_STEPPER; stpr++){ this->counters[stpr] = 0; this->stepped[stpr] = 0; } 
     this->step_events_completed = 0; 
@@ -110,7 +108,8 @@ void Stepper::on_block_end(void* argument){
 // "The Stepper Driver Interrupt" - This timer interrupt is the workhorse of Smoothie. It is executed at the rate set with
 // config_step_timer. It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately.
 inline void Stepper::main_interrupt(){
-   
+    if( this->paused ){ return; } 
+
     // Step dir pins first, then step pinse, stepper drivers like to know the direction before the step signal comes in
     this->alpha_dir_pin->set(  ( this->out_bits >> 0  ) & 1 );
     this->beta_dir_pin->set(   ( this->out_bits >> 1  ) & 1 );
@@ -156,7 +155,7 @@ void Stepper::update_offsets(){
 // interrupt. It can be assumed that the trapezoid-generator-parameters and the
 // current_block stays untouched by outside handlers for the duration of this function call.
 void Stepper::trapezoid_generator_tick() {
-    if(this->current_block && !this->trapezoid_generator_busy ) {
+    if(this->current_block && !this->trapezoid_generator_busy && !this->paused ) {
           if(this->step_events_completed < this->current_block->accelerate_until<<16) {
               this->trapezoid_adjusted_rate += this->current_block->rate_delta;
               if (this->trapezoid_adjusted_rate > this->current_block->nominal_rate ) {
index 0cf0cbf..05c8029 100644 (file)
@@ -66,6 +66,7 @@ class Stepper : public Module {
         Pin* gamma_dir_pin;
         unsigned short step_bits[3];
         int counter_increment;
+        bool paused;
 };
 
 
index 80277e8..5133de2 100644 (file)
@@ -19,6 +19,7 @@ Extruder::Extruder(PinName stppin, PinName dirpin) : step_pin(stppin), dir_pin(d
     this->acceleration_lock = false;
     this->step_counter = 0;
     this->counter_increment = 0;
+    this->paused = false;
 }
 
 void Extruder::on_module_loaded() {
@@ -33,7 +34,9 @@ void Extruder::on_module_loaded() {
     this->register_for_event(ON_BLOCK_BEGIN);
     this->register_for_event(ON_BLOCK_END);
     this->register_for_event(ON_GCODE_EXECUTE);
-
+    this->register_for_event(ON_PLAY);
+    this->register_for_event(ON_PAUSE);
     // Start values
     this->start_position = 0;
     this->target_position = 0;
@@ -59,6 +62,19 @@ void Extruder::on_config_reload(void* argument){
     this->acceleration                = this->kernel->config->value(acceleration_checksum               )->by_default(1)->as_number();
 }
 
+
+// When the play/pause button is set to pause, or a module calls the ON_PAUSE event
+void Extruder::on_pause(void* argument){
+    this->paused = true;
+}
+
+// When the play/pause button is set to play, or a module calls the ON_PLAY event
+void Extruder::on_play(void* argument){
+    this->paused = false;
+}
+
+
+
 // Compute extrusion speed based on parameters and gcode distance of travel
 void Extruder::on_gcode_execute(void* argument){
     Gcode* gcode = static_cast<Gcode*>(argument);
@@ -137,7 +153,7 @@ void Extruder::on_block_end(void* argument){
 void Extruder::acceleration_tick(){
 
     // Avoid trying to work when we really shouldn't ( between blocks or re-entry ) 
-    if( this->current_block == NULL || this->acceleration_lock ){ return; }
+    if( this->current_block == NULL || this->acceleration_lock || this->paused ){ return; }
     this->acceleration_lock = true;
    
     // In solo mode, we mode independently from the robot
@@ -229,6 +245,7 @@ void Extruder::set_speed( int steps_per_second ){
 }
 
 inline void Extruder::stepping_tick(){
+    if( this->paused ){ return; }
 
     this->step_counter += this->counter_increment;
     if( this->step_counter > 1<<16 ){
index 671783f..18e81ae 100644 (file)
@@ -33,6 +33,8 @@ class Extruder : public Module{
         void on_gcode_execute(void* argument);
         void on_block_begin(void* argument);
         void on_block_end(void* argument);
+        void on_play(void* argument);
+        void on_pause(void* argument); 
         void set_speed(int steps_per_second);
         void acceleration_tick();
         void stepping_tick();
@@ -64,6 +66,8 @@ class Extruder : public Module{
 
         char mode;
         bool acceleration_lock;
+
+        bool paused;
 };
 
 #endif
index 7b7c4f3..8e8fc8d 100644 (file)
@@ -23,7 +23,7 @@ TemperatureControl::TemperatureControl(uint16_t name){
 
 void TemperatureControl::on_module_loaded(){
     
-    // We start now desiring any temp
+    // We start not desiring any temp
     this->desired_adc_value = UNDEFINED;
 
     // Settings
@@ -99,11 +99,21 @@ void TemperatureControl::on_config_reload(void* argument){
 void TemperatureControl::on_gcode_execute(void* argument){
     Gcode* gcode = static_cast<Gcode*>(argument);
 
-    // Set temperature
+    // Set temperature without waiting
     if( gcode->has_letter('M') && gcode->get_value('M') == 104 && gcode->has_letter('S') ){
         this->set_desired_temperature(gcode->get_value('S')); 
     } 
 
+    // Set temperature and wait
+    if( gcode->has_letter('M') && gcode->get_value('M') == 109 && gcode->has_letter('S') ){
+        this->set_desired_temperature(gcode->get_value('S'));
+        
+        // Pause 
+        this->kernel->pauser->take(); 
+        this->waiting = true; 
+    
+    } 
+
     // Get temperature
     if( gcode->has_letter('M') && gcode->get_value('M') == 105 ){
         gcode->stream->printf("get temperature: %f current:%f target:%f \r\n", this->get_temperature(), this->new_thermistor_reading(), this->desired_adc_value );
@@ -137,6 +147,10 @@ void TemperatureControl::thermistor_read_tick(){
             this->heater_pin->set(1); 
         }else{
             this->heater_pin->set(0); 
+            if( this->waiting ){ 
+                this->kernel->pauser->release();
+                this->waiting = false; 
+            }
         }
     }
 }
index 1a7a61f..380ccc4 100644 (file)
@@ -70,6 +70,8 @@ class TemperatureControl : public Module {
 
         Pin* thermistor_pin;
         Pin* heater_pin;
+    
+        bool waiting;
 
 };
 
diff --git a/src/modules/utils/pausebutton/PauseButton.cpp b/src/modules/utils/pausebutton/PauseButton.cpp
new file mode 100644 (file)
index 0000000..f363b1f
--- /dev/null
@@ -0,0 +1,49 @@
+#include "mbed.h"
+#include "libs/Kernel.h"
+#include "PauseButton.h"
+#include "libs/nuts_bolts.h"
+#include "libs/utils.h"
+#include <string>
+using namespace std;
+
+PauseButton::PauseButton(){}
+
+void PauseButton::on_module_loaded(){
+    this->button_state = true;
+    this->play_state   = true;
+    this->register_for_event(ON_PLAY);
+    this->register_for_event(ON_PAUSE);
+
+    this->button     =  this->kernel->config->value( pause_button_pin_checksum )->by_default("0.0")->as_pin()->as_input();
+    this->led        =  this->kernel->config->value( pause_led_pin_checksum    )->by_default("0.1")->as_pin()->as_output();
+
+    this->kernel->slow_ticker->attach( 100, this, &PauseButton::button_tick );
+}
+
+//TODO: Make this use InterruptIn
+//Check the state of the button and act accordingly
+void PauseButton::button_tick(){
+    // If button changed 
+    if(this->button_state != this->button->get()){ 
+        this->button_state = this->button->get();
+        // If button pressed 
+        if( this->button_state ){
+            if( this->play_state ){
+                this->play_state = false;
+                this->kernel->pauser->take(); 
+            }else{
+                this->play_state = true;
+                this->kernel->pauser->release(); 
+            } 
+        } 
+    }
+}
+
+void PauseButton::on_play( void* argument ){
+    this->led->set(0);
+}
+
+void PauseButton::on_pause( void* argument ){
+    this->led->set(1);
+}
+
similarity index 58%
rename from src/modules/utils/pauser/Pauser.h
rename to src/modules/utils/pausebutton/PauseButton.h
index 05d99a2..fc46455 100644 (file)
@@ -1,24 +1,26 @@
-#ifndef pauser_h
-#define pauser_h
+#ifndef PAUSEBUTTON_H
+#define PAUSEBUTTON_H
 
 #include "mbed.h"
 #include "libs/Kernel.h"
 #include "libs/nuts_bolts.h"
 #include "libs/utils.h"
+#include "libs/Pin.h"
 
+#define pause_button_pin_checksum 32709
+#define pause_led_pin_checksum    48477
 
-class Pauser : public Module {
+class PauseButton : public Module {
     public:
-        Pauser(PinName ButtonPin, PinName LedPin);
+        PauseButton();
        
         void on_module_loaded();
         void button_tick();
         void on_play( void* argument );
         void on_pause( void* argument );
         
-        DigitalIn  button;
-        DigitalOut led; 
-        Ticker     button_ticker;
+        Pin*       button;
+        Pin*       led; 
         bool       button_state;
         bool       play_state;
 };
diff --git a/src/modules/utils/pauser/Pauser.cpp b/src/modules/utils/pauser/Pauser.cpp
deleted file mode 100644 (file)
index 8f55937..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "mbed.h"
-#include "libs/Kernel.h"
-#include "Pauser.h"
-#include "libs/nuts_bolts.h"
-#include "libs/utils.h"
-
-Pauser::Pauser(PinName ButtonPin, PinName LedPin) : button(ButtonPin), led(LedPin) {}
-
-void Pauser::on_module_loaded(){
-    this->button_state = false;
-    this->led = false;
-    this->play_state   = true;
-    this->register_for_event(ON_PLAY);
-    this->register_for_event(ON_PAUSE);
-    this->button_ticker.attach_us(this, &Pauser::button_tick, 1000000/100);
-}
-
-//TODO: Make this use InterruptIn
-//Check the state of the button and ask accordingly
-void Pauser::button_tick(){
-    if(this->button_state != this->button){ 
-        this->button_state = this->button; 
-        if( this->button_state ){
-            if( this->play_state ){
-                this->play_state = false;
-                this->kernel->call_event(ON_PAUSE, this);
-            }else{
-                this->play_state = true;
-                this->kernel->call_event(ON_PLAY, this);
-            } 
-        } 
-    }
-}
-
-void Pauser::on_play( void* argument ){
-    this->play_state = true;
-    this->led = false;
-}
-
-void Pauser::on_pause( void* argument ){
-    this->play_state = false;
-    this->led = true;
-}
-