report error message when a command was not taken
[clinton/Smoothieware.git] / src / modules / tools / temperaturecontrol / TemperatureControl.cpp
index 13172dd..07b3fec 100644 (file)
 #include "TemperatureControl.h"
 #include "TemperatureControlPool.h"
 #include "libs/Pin.h"
+#include "libs/Median.h"
+#include "modules/robot/Conveyor.h"
 
-TemperatureControl::TemperatureControl(){}
+#include "MRI_Hooks.h"
 
-TemperatureControl::TemperatureControl(uint16_t name){
-    this->name_checksum = name;
-//     this->error_count = 0;
-    this->waiting = false;
-}
+TemperatureControl::TemperatureControl(uint16_t name) :
+  name_checksum(name), waiting(false), min_temp_violated(false) {}
 
 void TemperatureControl::on_module_loaded(){
 
@@ -32,16 +31,21 @@ void TemperatureControl::on_module_loaded(){
 
     this->acceleration_factor = 10;
 
-    this->kernel->slow_ticker->attach( 20, this, &TemperatureControl::thermistor_read_tick );
-
     // Register for events
+    register_for_event(ON_CONFIG_RELOAD);
     this->register_for_event(ON_GCODE_EXECUTE);
     this->register_for_event(ON_GCODE_RECEIVED);
     this->register_for_event(ON_MAIN_LOOP);
+    this->register_for_event(ON_SECOND_TICK);
 
 }
 
-void TemperatureControl::on_main_loop(void* argument){ }
+void TemperatureControl::on_main_loop(void* argument){
+    if (this->min_temp_violated) {
+        kernel->streams->printf("MINTEMP triggered on P%d.%d! check your thermistors!\n", this->thermistor_pin.port_number, this->thermistor_pin.pin);
+        this->min_temp_violated = false;
+    }
+}
 
 // Get configuration from the config file
 void TemperatureControl::on_config_reload(void* argument){
@@ -50,7 +54,7 @@ void TemperatureControl::on_config_reload(void* argument){
     this->set_m_code          = this->kernel->config->value(temperature_control_checksum, this->name_checksum, set_m_code_checksum)->by_default(104)->as_number();
     this->set_and_wait_m_code = this->kernel->config->value(temperature_control_checksum, this->name_checksum, set_and_wait_m_code_checksum)->by_default(109)->as_number();
     this->get_m_code          = this->kernel->config->value(temperature_control_checksum, this->name_checksum, get_m_code_checksum)->by_default(105)->as_number();
-    this->readings_per_second = this->kernel->config->value(temperature_control_checksum, this->name_checksum, readings_per_second_checksum)->by_default(5)->as_number();
+    this->readings_per_second = this->kernel->config->value(temperature_control_checksum, this->name_checksum, readings_per_second_checksum)->by_default(20)->as_number();
 
     this->designator          = this->kernel->config->value(temperature_control_checksum, this->name_checksum, designator_checksum)->by_default(string("T"))->as_string();
 
@@ -76,39 +80,44 @@ void TemperatureControl::on_config_reload(void* argument){
     this->r1 =                  this->kernel->config->value(temperature_control_checksum, this->name_checksum, r1_checksum  )->by_default(this->r1  )->as_number();
     this->r2 =                  this->kernel->config->value(temperature_control_checksum, this->name_checksum, r2_checksum  )->by_default(this->r2  )->as_number();
 
+    this->preset1 =             this->kernel->config->value(temperature_control_checksum, this->name_checksum, preset1_checksum)->by_default(0)->as_number();
+    this->preset2 =             this->kernel->config->value(temperature_control_checksum, this->name_checksum, preset2_checksum)->by_default(0)->as_number();
+
 
     // Thermistor math
     j = (1.0 / beta);
     k = (1.0 / (t0 + 273.15));
 
-    // ADC smoothing
-    running_total = 0;
-
     // sigma-delta output modulation
     o = 0;
 
     // Thermistor pin for ADC readings
-    this->thermistor_pin = this->kernel->config->value(temperature_control_checksum, this->name_checksum, thermistor_pin_checksum )->required()->as_pin();
-    this->kernel->adc->enable_pin(this->thermistor_pin);
+    this->thermistor_pin.from_string(this->kernel->config->value(temperature_control_checksum, this->name_checksum, thermistor_pin_checksum )->required()->as_string());
+    this->kernel->adc->enable_pin(&thermistor_pin);
 
     // Heater pin
-    this->heater_pin     =  this->kernel->config->value(temperature_control_checksum, this->name_checksum, heater_pin_checksum)->required()->as_pwm()->as_output();
-    this->heater_pin->set(0);
+    this->heater_pin.from_string(    this->kernel->config->value(temperature_control_checksum, this->name_checksum, heater_pin_checksum)->required()->as_string())->as_output();
+    this->heater_pin.max_pwm(        this->kernel->config->value(temperature_control_checksum, this->name_checksum, max_pwm_checksum)->by_default(255)->as_number() );
+    this->heater_pin.set(0);
+
+    set_low_on_debug(heater_pin.port_number, heater_pin.pin);
 
     // activate SD-DAC timer
-    this->kernel->slow_ticker->attach(1000, this->heater_pin, &Pwm::on_tick);
+    this->kernel->slow_ticker->attach(1000, &heater_pin, &Pwm::on_tick);
+
+    // reading tick
+    this->kernel->slow_ticker->attach( this->readings_per_second, this, &TemperatureControl::thermistor_read_tick );
 
     // PID
     this->p_factor = this->kernel->config->value(temperature_control_checksum, this->name_checksum, p_factor_checksum)->by_default(10 )->as_number();
     this->i_factor = this->kernel->config->value(temperature_control_checksum, this->name_checksum, i_factor_checksum)->by_default(0.3)->as_number();
     this->d_factor = this->kernel->config->value(temperature_control_checksum, this->name_checksum, d_factor_checksum)->by_default(200)->as_number();
-    this->i_max    = this->kernel->config->value(temperature_control_checksum, this->name_checksum, i_max_checksum   )->by_default(50 )->as_number();
+    this->i_max    = this->kernel->config->value(temperature_control_checksum, this->name_checksum, i_max_checksum   )->by_default(255)->as_number();
     this->i = 0.0;
     this->last_reading = 0.0;
 }
 
-void TemperatureControl::on_gcode_received(void* argument)
-{
+void TemperatureControl::on_gcode_received(void* argument){
     Gcode* gcode = static_cast<Gcode*>(argument);
     if (gcode->has_m)
     {
@@ -119,6 +128,7 @@ void TemperatureControl::on_gcode_received(void* argument)
         }
         if (gcode->m == 301)
         {
+            gcode->mark_as_taken();
             if (gcode->has_letter('S') && (gcode->get_value('S') == this->pool_index))
             {
                 if (gcode->has_letter('P'))
@@ -134,6 +144,7 @@ void TemperatureControl::on_gcode_received(void* argument)
         }
         if (gcode->m == 303)
         {
+            gcode->mark_as_taken();
             if (gcode->has_letter('S') && (gcode->get_value('S') == this->pool_index))
             {
                 double target = 150.0;
@@ -146,49 +157,59 @@ void TemperatureControl::on_gcode_received(void* argument)
                 this->pool->PIDtuner->begin(this, target, gcode->stream);
             }
         }
+
+        // Attach gcodes to the last block for on_gcode_execute
+        if( ( gcode->m == this->set_m_code || gcode->m == this->set_and_wait_m_code ) && gcode->has_letter('S') ){
+            if( this->kernel->conveyor->queue.size() == 0 ){
+                this->kernel->call_event(ON_GCODE_EXECUTE, gcode );
+            }else{
+                Block* block = this->kernel->conveyor->queue.get_ref( this->kernel->conveyor->queue.size() - 1 );
+                block->append_gcode(gcode);
+            }
+
+        }
     }
 }
 
 void TemperatureControl::on_gcode_execute(void* argument){
     Gcode* gcode = static_cast<Gcode*>(argument);
     if( gcode->has_m){
-        // Set temperature without waiting
-        if( gcode->m == this->set_m_code && gcode->has_letter('S') )
-        {
-            if (gcode->get_value('S') == 0)
-            {
-                this->target_temperature = UNDEFINED;
-                this->heater_pin->set(0);
-            }
-            else
-            {
-                this->set_desired_temperature(gcode->get_value('S'));
-            }
-        }
-        // Set temperature and wait
-        if( gcode->m == this->set_and_wait_m_code && gcode->has_letter('S') )
+        if (((gcode->m == this->set_m_code) || (gcode->m == this->set_and_wait_m_code))
+            && gcode->has_letter('S'))
         {
-            if (gcode->get_value('S') == 0)
+            double v = gcode->get_value('S');
+
+            if (v == 0.0)
             {
                 this->target_temperature = UNDEFINED;
-                this->heater_pin->set(0);
+                this->heater_pin.set(0);
             }
             else
             {
-                this->set_desired_temperature(gcode->get_value('S'));
-                // Pause
-                this->kernel->pauser->take();
-                this->waiting = true;
+                this->set_desired_temperature(v);
+
+                if( gcode->m == this->set_and_wait_m_code)
+                {
+                    gcode->mark_as_taken();
+                    this->kernel->pauser->take();
+                    this->waiting = true;
+                }
             }
         }
     }
 }
 
 
-void TemperatureControl::set_desired_temperature(double desired_temperature){
+void TemperatureControl::set_desired_temperature(double desired_temperature)
+{
+    if (desired_temperature == 1.0)
+        desired_temperature = preset1;
+    else if (desired_temperature == 2.0)
+        desired_temperature = preset2;
+
     target_temperature = desired_temperature;
     if (desired_temperature == 0.0)
-        heater_pin->set((o = 0));
+        heater_pin.set((o = 0));
 }
 
 double TemperatureControl::get_temperature(){
@@ -214,9 +235,9 @@ uint32_t TemperatureControl::thermistor_read_tick(uint32_t dummy){
     {
         if ((r <= 1) || (r >= 4094))
         {
-            kernel->streams->printf("MINTEMP triggered on P%d.%d! check your thermistors!\n", this->thermistor_pin->port_number, this->thermistor_pin->pin);
+            this->min_temp_violated = true;
             target_temperature = UNDEFINED;
-            heater_pin->set(0);
+            heater_pin.set(0);
         }
         else
         {
@@ -230,7 +251,7 @@ uint32_t TemperatureControl::thermistor_read_tick(uint32_t dummy){
     }
     else
     {
-        heater_pin->set(0);
+        heater_pin.set((o = 0));
     }
     last_reading = temperature;
     return 0;
@@ -251,35 +272,35 @@ void TemperatureControl::pid_process(double temperature)
     if (i < -this->i_max)
         i = -this->i_max;
 
-    this->o = (p + i + d) * heater_pin->max_pwm() / 256;
+    this->o = (p + i + d) * heater_pin.max_pwm() / 256;
 
-    if (this->o >= heater_pin->max_pwm())
-    {
-        i -= (this->o - (heater_pin->max_pwm() - 1)) * 256 / heater_pin->max_pwm();
-        this->o = heater_pin->max_pwm() - 1;
-    }
-    if (this->o < 0)
-    {
-        if (this->o < -(heater_pin->max_pwm()))
-            i += (-(heater_pin->max_pwm()) - this->o) * 256 / heater_pin->max_pwm();
+    if (this->o >= heater_pin.max_pwm())
+        this->o = heater_pin.max_pwm();
+    else if (this->o < 0)
         this->o = 0;
-    }
 
-    this->heater_pin->pwm(o);
+    this->heater_pin.pwm(this->o);
 }
 
 int TemperatureControl::new_thermistor_reading()
 {
-    int last_raw = this->kernel->adc->read(this->thermistor_pin);
+    int last_raw = this->kernel->adc->read(&thermistor_pin);
     if (queue.size() >= queue.capacity())
     {
         uint16_t l;
         queue.pop_front(l);
-        running_total -= l;
         d = l;
     }
     uint16_t r = last_raw;
     queue.push_back(r);
-    running_total += last_raw;
-    return running_total / queue.size();
+    for (int i=0; i<queue.size(); i++)
+      median_buffer[i] = *queue.get_ref(i);
+    uint16_t m = median_buffer[quick_median(median_buffer, queue.size())];
+    return m;
+}
+
+void TemperatureControl::on_second_tick(void* argument)
+{
+    if (waiting)
+        kernel->streams->printf("%s:%3.1f /%3.1f @%d\n", designator.c_str(), get_temperature(), ((target_temperature == UNDEFINED)?0.0:target_temperature), o);
 }