Also ignore occasional failed measurements from the thermocouple.
Formatting changes.
class TempSensor
{
public:
- // Load config parameters using provided "base" names.
- virtual void UpdateConfig(uint16_t module_checksum, uint16_t name_checksum) = 0;
+ // Load config parameters using provided "base" names.
+ virtual void UpdateConfig(uint16_t module_checksum, uint16_t name_checksum) {};
- // Return temperature in degrees Celsius.
- virtual float get_temperature() = 0;
+ // Return temperature in degrees Celsius.
+ virtual float get_temperature() { return -1.f; };
- // Make sure the interface provides a destructor.
- virtual ~TempSensor() {}
+ // Make sure the interface provides a destructor.
+ virtual ~TempSensor() {}
};
#endif
TemperatureControl::TemperatureControl(uint16_t name) :
- name_checksum(name), waiting(false), min_temp_violated(false) {}
+ sensor(nullptr), name_checksum(name), waiting(false), min_temp_violated(false)
+{
+}
+TemperatureControl::~TemperatureControl()
+{
+ delete sensor;
+}
+
void TemperatureControl::on_module_loaded(){
// We start not desiring any temp
// Settings
this->on_config_reload(this);
- this->acceleration_factor = 10;
-
// Register for events
register_for_event(ON_CONFIG_RELOAD);
this->register_for_event(ON_GCODE_EXECUTE);
this->designator = THEKERNEL->config->value(temperature_control_checksum, this->name_checksum, designator_checksum)->by_default(string("T"))->as_string();
- // For backward compatibility, default to a thermistor sensor.
- std::string sensor_type = THEKERNEL->config->value(temperature_control_checksum, this->name_checksum, sensor_checksum)->by_default("thermistor")->as_string();
-
- // Instantiate correct sensor (TBD: TempSensor factory?)
- if(sensor_type.compare("thermistor") == 0)
- {
- sensor.reset(new Thermistor());
- }
- else if(sensor_type.compare("max31855") == 0)
- {
- sensor.reset(new Max31855());
- }
-
- sensor->UpdateConfig(temperature_control_checksum, this->name_checksum);
-
+ // For backward compatibility, default to a thermistor sensor.
+ std::string sensor_type = THEKERNEL->config->value(temperature_control_checksum, this->name_checksum, sensor_checksum)->by_default("thermistor")->as_string();
+
+ // Instantiate correct sensor (TBD: TempSensor factory?)
+ delete sensor;
+ sensor = nullptr; // In case we fail to create a new sensor.
+ if(sensor_type.compare("thermistor") == 0)
+ {
+ sensor = new Thermistor();
+ }
+ else if(sensor_type.compare("max31855") == 0)
+ {
+ sensor = new Max31855();
+ }
+ else
+ {
+ sensor = new TempSensor(); // A dummy implementation
+ }
+ sensor->UpdateConfig(temperature_control_checksum, this->name_checksum);
+
this->preset1 = THEKERNEL->config->value(temperature_control_checksum, this->name_checksum, preset1_checksum)->by_default(0)->as_number();
this->preset2 = THEKERNEL->config->value(temperature_control_checksum, this->name_checksum, preset2_checksum)->by_default(0)->as_number();
#include "Module.h"
#include "Pwm.h"
#include "TempSensor.h"
-#include <memory> // for auto_ptr
class TemperatureControlPool;
public:
TemperatureControl(uint16_t name);
+ ~TemperatureControl();
void on_module_loaded();
void on_main_loop(void* argument);
TemperatureControlPool *pool;
friend class PID_Autotuner;
- float get_temperature();
+ float get_temperature();
private:
- uint32_t thermistor_read_tick(uint32_t dummy);
+ uint32_t thermistor_read_tick(uint32_t dummy);
void pid_process(float);
float target_temperature;
float preset1;
float preset2;
- std::auto_ptr<TempSensor> sensor;
-
+ TempSensor *sensor;
+
// PID runtime
float i_max;
float last_reading;
- float acceleration_factor;
float readings_per_second;
uint16_t name_checksum;
float Thermistor::get_temperature()
{
- return adc_value_to_temperature(new_thermistor_reading());
+ return adc_value_to_temperature(new_thermistor_reading());
}
float Thermistor::adc_value_to_temperature(int adc_value)
class Thermistor : public TempSensor
{
public:
- Thermistor();
- ~Thermistor();
-
- // TempSensor interface.
- void UpdateConfig(uint16_t module_checksum, uint16_t name_checksum);
+ Thermistor();
+ ~Thermistor();
+
+ // TempSensor interface.
+ void UpdateConfig(uint16_t module_checksum, uint16_t name_checksum);
float get_temperature();
-
+
private:
- int new_thermistor_reading();
+ int new_thermistor_reading();
float adc_value_to_temperature(int adc_value);
// Thermistor computation settings
RingBuffer<uint16_t,QUEUE_LEN> queue; // Queue of readings
uint16_t median_buffer[QUEUE_LEN];
-
+
};
#endif
#define chip_select_checksum CHECKSUM("chip_select_pin")
#define spi_channel_checksum CHECKSUM("spi_channel")
-Max31855::Max31855()
+Max31855::Max31855() :
+ spi(nullptr)
{
}
Max31855::~Max31855()
{
+ delete spi;
}
// Get configuration from the config file
void Max31855::UpdateConfig(uint16_t module_checksum, uint16_t name_checksum)
{
- // Chip select
+ // Chip select
this->spi_cs_pin.from_string(THEKERNEL->config->value(module_checksum, name_checksum, chip_select_checksum)->by_default("0.16")->as_string());
- this->spi_cs_pin.set(true);
- this->spi_cs_pin.as_output();
-
+ this->spi_cs_pin.set(true);
+ this->spi_cs_pin.as_output();
+
// select which SPI channel to use
int spi_channel = THEKERNEL->config->value(module_checksum, name_checksum, spi_channel_checksum)->by_default(0)->as_number();
PinName miso;
PinName mosi;
PinName sclk;
if(spi_channel == 0) {
- // Channel 0
+ // Channel 0
mosi=P0_18; miso=P0_17; sclk=P0_15;
} else {
- // Channel 1
+ // Channel 1
mosi=P0_9; miso=P0_8; sclk=P0_7;
}
- spi.reset(new SPI(mosi, miso, sclk));
+ delete spi;
+ spi = new mbed::SPI(mosi, miso, sclk);
- // Spi settings: 1MHz (default), 16 bits, mode 0 (default)
- spi->format(16);
+ // Spi settings: 1MHz (default), 16 bits, mode 0 (default)
+ spi->format(16);
}
float Max31855::get_temperature()
{
- this->spi_cs_pin.set(false);
- wait_us(1); // Must wait for first bit valid
+ // Return an average of the last readings
+ if (readings.size() >= readings.capacity()) {
+ readings.delete_tail();
+ }
+
+ float temp = read_temp();
+
+ // Discard occasional errors...
+ if(!isinf(temp))
+ {
+ readings.push_back(temp);
+ }
+
+ if(readings.size()==0) return infinityf();
- // Read 16 bits (writing something as well is required by the api)
- uint16_t data = spi->write(0);
-// Read next 16 bits (diagnostics)
+ float sum = 0;
+ for (int i=0; i<readings.size(); i++)
+ sum += *readings.get_ref(i);
+
+ return sum / readings.size();
+}
+
+float Max31855::read_temp()
+{
+ this->spi_cs_pin.set(false);
+ wait_us(1); // Must wait for first bit valid
+
+ // Read 16 bits (writing something as well is required by the api)
+ uint16_t data = spi->write(0);
+ // Read next 16 bits (diagnostics)
// uint16_t data2 = spi->write(0);
- this->spi_cs_pin.set(true);
-
- float temperature;
+ this->spi_cs_pin.set(true);
+
+ float temperature;
//Process temp
if (data & 0x0001)
- {
- // Error flag.
+ {
+ // Error flag.
temperature = infinityf();
- // Todo: Interpret data2 for more diagnostics.
- }
+ // Todo: Interpret data2 for more diagnostics.
+ }
else
{
data = data >> 2;
temperature = ((data & 0x1FFF) + 1) / -4.f;
}
}
- return temperature;
+ return temperature;
}
\ No newline at end of file
#include <string>
#include <libs/Pin.h>
#include <mbed.h>
-#include <memory>
+#include "RingBuffer.h"
class Max31855 : public TempSensor
{
public:
- Max31855();
- ~Max31855();
- void UpdateConfig(uint16_t module_checksum, uint16_t name_checksum);
- float get_temperature();
+ Max31855();
+ ~Max31855();
+ void UpdateConfig(uint16_t module_checksum, uint16_t name_checksum);
+ float get_temperature();
private:
- Pin spi_cs_pin;
- std::auto_ptr<mbed::SPI> spi;
+ float read_temp();
+ Pin spi_cs_pin;
+ mbed::SPI *spi;
+ RingBuffer<float,16> readings;
};
#endif