rename the temperature switch config entrythat specifies the switch to use, this...
[clinton/Smoothieware.git] / src / modules / tools / temperatureswitch / TemperatureSwitch.cpp
CommitLineData
abe97b79 1/*
2 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
3 Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
4 Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
6*/
7
8/*
9TemperatureSwitch is an optional module that will automatically turn on or off a switch
10based on a setpoint temperature. It is commonly used to turn on/off a cooling fan or water pump
11to cool the hot end's cold zone. Specifically, it turns one of the small MOSFETs on or off.
12
13Author: Michael Hackney, mhackney@eclecticangler.com
14*/
15
16#include "TemperatureSwitch.h"
17#include "libs/Module.h"
18#include "libs/Kernel.h"
19#include "modules/tools/temperaturecontrol/TemperatureControlPublicAccess.h"
20#include "SwitchPublicAccess.h"
21
22#include "utils.h"
23#include "Gcode.h"
24#include "Config.h"
25#include "ConfigValue.h"
26#include "checksumm.h"
27#include "PublicData.h"
28#include "StreamOutputPool.h"
29
1dc339ee 30#define temperatureswitch_checksum CHECKSUM("temperatureswitch")
5cbf2253 31#define enable_checksum CHECKSUM("enable")
1dc339ee 32#define temperatureswitch_hotend_checksum CHECKSUM("hotend")
33#define temperatureswitch_threshold_temp_checksum CHECKSUM("threshold_temp")
34#define temperatureswitch_type_checksum CHECKSUM("type")
fe3323e7 35#define temperatureswitch_switch_checksum CHECKSUM("switch")
1dc339ee 36#define temperatureswitch_heatup_poll_checksum CHECKSUM("heatup_poll")
37#define temperatureswitch_cooldown_poll_checksum CHECKSUM("cooldown_poll")
5cbf2253 38#define designator_checksum CHECKSUM("designator")
1dc339ee 39
abe97b79 40TemperatureSwitch::TemperatureSwitch()
41{
5cbf2253
JM
42 this->temperatureswitch_state = false;
43 this->second_counter = 0;
abe97b79 44}
45
46// Load module
47void TemperatureSwitch::on_module_loaded()
48{
5cbf2253
JM
49 vector<uint16_t> modulist;
50 // allow for multiple temperature switches
51 THEKERNEL->config->get_module_list(&modulist, temperatureswitch_checksum);
52 for (auto m : modulist) {
53 load_config(m);
54 }
e6b0fc38 55
5cbf2253
JM
56 // no longer need this instance as it is just used to load the other instances
57 delete this;
58}
59
60
61bool TemperatureSwitch::load_config(uint16_t modcs)
62{
63 // see if enabled
64 if (!THEKERNEL->config->value(temperatureswitch_checksum, modcs, enable_checksum)->by_default(false)->as_bool()) {
65 return false;
abe97b79 66 }
67
5cbf2253
JM
68 // create a temperature control and load settings
69
70 char designator= 0;
71 string s= THEKERNEL->config->value(temperatureswitch_checksum, modcs, designator_checksum)->by_default("")->as_string();
72 if(s.empty()){
73 // for backward compatibility temperatureswitch.hotend will need designator 'T' by default
74 if(modcs == temperatureswitch_hotend_checksum) designator= 'T';
75
76 }else{
77 designator= s[0];
78 }
abe97b79 79
5cbf2253 80 if(designator == 0) return false; // no designator then not valid
57235957 81
5cbf2253
JM
82 // create a new temperature switch module
83 TemperatureSwitch *ts= new TemperatureSwitch();
84
85 // get the list of temperature controllers and remove any that don't have designator == specified designator
86 vector<uint16_t> tempcontrollers;
87 THEKERNEL->config->get_module_list(&tempcontrollers, temperature_control_checksum);
88
89 // see what its designator is and add to list of it the one we specified
f53fe49d 90 void *returned_temp;
5cbf2253 91 for (auto controller : tempcontrollers) {
f53fe49d 92 bool temp_ok = PublicData::get_value(temperature_control_checksum, controller, current_temperature_checksum, &returned_temp);
93 if (temp_ok) {
94 struct pad_temperature temp = *static_cast<struct pad_temperature *>(returned_temp);
5cbf2253
JM
95 if (temp.designator[0] == designator) {
96 ts->temp_controllers.push_back(controller);
f53fe49d 97 }
98 }
99 }
57235957 100
5cbf2253
JM
101 // if we don't have any matching controllers, then not valid
102 if (ts->temp_controllers.empty()) {
103 delete ts;
104 return false;
57235957
JM
105 }
106
abe97b79 107 // load settings from config file
fe3323e7 108 s = THEKERNEL->config->value(temperatureswitch_checksum, modcs, temperatureswitch_switch_checksum)->by_default("")->as_string();
5cbf2253 109 if(s.empty()) {
fe3323e7
JM
110 // handle old configs where this was called type @DEPRECATED
111 s = THEKERNEL->config->value(temperatureswitch_checksum, modcs, temperatureswitch_type_checksum)->by_default("")->as_string();
112 if(s.empty()) {
113 // no switch specified so invalid entry
114 delete this;
115 return false;
116 }
5cbf2253 117 }
fe3323e7 118 ts->temperatureswitch_switch_cs= get_checksum(s); // checksum of the switch to use
abe97b79 119
5cbf2253 120 ts->temperatureswitch_threshold_temp = THEKERNEL->config->value(temperatureswitch_checksum, modcs, temperatureswitch_threshold_temp_checksum)->by_default(50.0f)->as_number();
abe97b79 121
5cbf2253
JM
122 // these are to tune the heatup and cooldown polling frequencies
123 ts->temperatureswitch_heatup_poll = THEKERNEL->config->value(temperatureswitch_checksum, modcs, temperatureswitch_heatup_poll_checksum)->by_default(15)->as_number();
124 ts->temperatureswitch_cooldown_poll = THEKERNEL->config->value(temperatureswitch_checksum, modcs, temperatureswitch_cooldown_poll_checksum)->by_default(60)->as_number();
125 ts->current_delay = ts->temperatureswitch_heatup_poll;
f53fe49d 126
127 // Register for events
5cbf2253
JM
128 ts->register_for_event(ON_SECOND_TICK);
129
130 return true;
abe97b79 131}
132
133// Called once a second but we only need to service on the cooldown and heatup poll intervals
134void TemperatureSwitch::on_second_tick(void *argument)
135{
136 second_counter++;
137 if (second_counter < current_delay) {
138 return;
139 } else {
140 second_counter = 0;
141 float current_temp = this->get_highest_temperature();
57235957 142
abe97b79 143 if (current_temp >= this->temperatureswitch_threshold_temp) {
144 // temp >= threshold temp, turn the cooler switch on if it isn't already
145 if (!temperatureswitch_state) {
146 set_switch(true);
57235957 147 current_delay = temperatureswitch_cooldown_poll;
abe97b79 148 }
149 } else {
150 // temp < threshold temp, turn the cooler switch off if it isn't already
151 if (temperatureswitch_state) {
152 set_switch(false);
153 current_delay = temperatureswitch_heatup_poll;
154 }
57235957 155 }
abe97b79 156 }
157}
158
159// Get the highest temperature from the set of temperature controllers
160float TemperatureSwitch::get_highest_temperature()
161{
162 void *returned_temp;
163 float high_temp = 0.0;
164
165 for (auto controller : temp_controllers) {
166 bool temp_ok = PublicData::get_value(temperature_control_checksum, controller, current_temperature_checksum, &returned_temp);
167 if (temp_ok) {
168 struct pad_temperature temp = *static_cast<struct pad_temperature *>(returned_temp);
169 // check if this controller's temp is the highest and save it if so
57235957 170 if (temp.current_temperature > high_temp) {
abe97b79 171 high_temp = temp.current_temperature;
abe97b79 172 }
173 }
174 }
175 return high_temp;
176}
177
178// Turn the switch on (true) or off (false)
179void TemperatureSwitch::set_switch(bool switch_state)
180{
181 this->temperatureswitch_state = switch_state;
fe3323e7 182 bool ok = PublicData::set_value(switch_checksum, this->temperatureswitch_switch_cs, state_checksum, &this->temperatureswitch_state);
abe97b79 183 if (!ok) {
184 THEKERNEL->streams->printf("Failed changing switch state.\r\n");
185 }
186}