Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/Heating/Sensors/Thermistor.cpp')
-rw-r--r--src/Heating/Sensors/Thermistor.cpp139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/Heating/Sensors/Thermistor.cpp b/src/Heating/Sensors/Thermistor.cpp
new file mode 100644
index 00000000..83e967df
--- /dev/null
+++ b/src/Heating/Sensors/Thermistor.cpp
@@ -0,0 +1,139 @@
+/*
+ * Thermistor.cpp
+ *
+ * Created on: 10 Nov 2016
+ * Author: David
+ */
+
+#include "Thermistor.h"
+#include "Platform.h"
+#include "RepRap.h"
+#include "GCodes/GCodeBuffer.h"
+
+// The Steinhart-Hart equation for thermistor resistance is:
+// 1/T = A + B ln(R) + C [ln(R)]^3
+//
+// The simplified (beta) equation assumes C=0 and is:
+// 1/T = A + (1/Beta) ln(R)
+//
+// The parameters that can be configured in RRF are R25 (the resistance at 25C), Beta, and optionally C.
+
+// Create an instance with default values
+Thermistor::Thermistor(unsigned int channel)
+ : TemperatureSensor(channel - FirstThermistorChannel, "Thermistor"), adcLowOffset(0), adcHighOffset(0)
+{
+ r25 = (channel == FirstThermistorChannel) ? BED_R25 : EXT_R25;
+ beta = (channel == FirstThermistorChannel) ? BED_BETA : EXT_BETA;
+ shC = (channel == FirstThermistorChannel) ? BED_SHC : EXT_SHC;
+ seriesR = THERMISTOR_SERIES_RS;
+ CalcDerivedParameters();
+}
+
+void Thermistor::Init()
+{
+ reprap.GetPlatform().GetThermistorFilter(GetSensorChannel() - FirstThermistorChannel).Init((1 << AdcBits) - 1);
+}
+
+// Configure the temperature sensor
+bool Thermistor::Configure(unsigned int mCode, unsigned int heater, GCodeBuffer& gb, StringRef& reply, bool& error)
+{
+ bool seen = false;
+ if (mCode == 305)
+ {
+ // We must set the 25C resistance and beta together in order to calculate Rinf. Check for these first.
+
+ gb.TryGetFValue('T', r25, seen);
+ gb.TryGetFValue('B', beta, seen);
+ gb.TryGetFValue('C', shC, seen);
+ gb.TryGetFValue('R', seriesR, seen);
+ if (seen)
+ {
+ CalcDerivedParameters();
+ }
+
+ if (gb.Seen('L'))
+ {
+ adcLowOffset = (int8_t)constrain<int>(gb.GetIValue(), -100, 100);
+ seen = true;
+ }
+ if (gb.Seen('H'))
+ {
+ adcHighOffset = (int8_t)constrain<int>(gb.GetIValue(), -100, 100);
+ seen = true;
+ }
+
+ TryConfigureHeaterName(gb, seen);
+
+ if (!seen && !gb.Seen('X'))
+ {
+ CopyBasicHeaterDetails(heater, reply);
+ reply.catf(", T:%.1f B:%.1f C:%.2e R:%.1f L:%d H:%d",
+ r25, beta, shC, seriesR, adcLowOffset, adcHighOffset);
+ }
+ }
+
+ return seen;
+}
+
+// Get the temperature
+TemperatureError Thermistor::GetTemperature(float& t)
+{
+ const volatile ThermistorAveragingFilter& filter = reprap.GetPlatform().GetThermistorFilter(GetSensorChannel() - FirstThermistorChannel);
+ if (filter.IsValid())
+ {
+ const int32_t averagedReading = filter.GetSum()/(ThermistorAverageReadings >> Thermistor::AdcOversampleBits);
+ const float temp = CalcTemperature(averagedReading);
+
+ if (temp < MinimumConnectedTemperature)
+ {
+ // thermistor is disconnected
+ t = ABS_ZERO;
+ return TemperatureError::openCircuit;
+ }
+
+ t = temp;
+ return TemperatureError::success;
+ }
+
+ // Filter is not ready yet
+ t = BAD_ERROR_TEMPERATURE;
+ return TemperatureError::busBusy;
+}
+
+// Calculate temperature from an ADC reading in the range 0..1
+float Thermistor::CalcTemperature(int32_t adcReading) const
+{
+ const float denom = (float)(AdcRange + (int)adcHighOffset - adcReading) - 0.5;
+ if (denom <= 0.0)
+ {
+ return ABS_ZERO;
+ }
+ const float resistance = seriesR * ((float)(adcReading - (int)adcLowOffset) + 0.5)/denom;
+ const float logResistance = log(resistance);
+ const float recipT = shA + shB * logResistance + shC * logResistance * logResistance * logResistance;
+ return (recipT > 0.0) ? (1.0/recipT) + ABS_ZERO : BAD_ERROR_TEMPERATURE;
+}
+
+// Calculate expected ADC reading at a particular temperature, rounded down as the ADC does
+int32_t Thermistor::CalcAdcReading(float temperature) const
+{
+ const double bDFiv3c = shB/(3.0 * shC);
+ const double halfY = (shA - 1.0/(temperature - ABS_ZERO))/(2.0 * shC);
+ const double x = sqrt((bDFiv3c * bDFiv3c * bDFiv3c) + (halfY * halfY));
+ const double oneThird = 1.0/3.0;
+ const float resistance = exp(pow(x - halfY, oneThird) - pow(x + halfY, oneThird));
+ const float fraction = resistance/(resistance + seriesR);
+ const int32_t actualAdcRange = AdcRange + (int)adcHighOffset - (int)adcLowOffset;
+ const int32_t val = (int32_t)(fraction * (float)actualAdcRange) + (int)adcLowOffset;
+ return constrain<int>(val, 0, AdcRange - 1);
+}
+
+// Calculate shA and shB from the other parameters
+void Thermistor::CalcDerivedParameters()
+{
+ shB = 1.0/beta;
+ const double lnR25 = log(r25);
+ shA = 1.0/(25.0 - ABS_ZERO) - shB * lnR25 - shC * lnR25 * lnR25 * lnR25;
+}
+
+// End