Steinhart Hart equation
The Steinhart-Hart equation provides a more accurate temperature-resistance relationship over a wide temperature range. \[ \frac{1}{T} = A + B \ln R + C (\ln R)^3 \]
Where:
- T is the temperature in Kelvins. (Formula to calculate kelvin from degree Celsius, K = °C + 273.15)
- R is the resistance at temperature T in Ohms.
- A, B, and C are constants specific to the thermistor's material, often provided by the manufacturer. For better accuracy, you may need to calibrate and determine these values yourself. Some datasheets provide resistance values at various temperatures, which can also be used to calculate this.
Calibration
To determine the accurate values for A, B, and C, place the thermistor in three temperature conditions: room temperature, ice water, and boiling water. For each condition, measure the thermistor's resistance using the ADC value and use a reliable thermometer to record the actual temperature. Using the resistance values and corresponding temperatures, calculate the coefficients:
- Assign A to the ice water temperature,
- B to the room temperature, and
- C to the boiling water temperature.
Calculating Steinhart-Hart Coefficients
With three resistance and temperature data points, we can find the A, B and C.
$$ \begin{bmatrix} 1 & \ln R_1 & \ln^3 R_1 \\ 1 & \ln R_2 & \ln^3 R_2 \\ 1 & \ln R_3 & \ln^3 R_3 \end{bmatrix}\begin{bmatrix} A \\ B \\ C \end{bmatrix} = \begin{bmatrix} \frac{1}{T_1} \\ \frac{1}{T_2} \\ \frac{1}{T_3} \end{bmatrix} $$
Where:
- \( R_1, R_2, R_3 \) are the resistance values at temperatures \( T_1, T_2, T_3 \).
Let's calculate the coefficients
Compute the natural logarithms of resistances: $$ L_1 = \ln R_1, \quad L_2 = \ln R_2, \quad L_3 = \ln R_3 $$
Intermediate calculations: $$ Y_1 = \frac{1}{T_1}, \quad Y_2 = \frac{1}{T_2}, \quad Y_3 = \frac{1}{T_3} $$
$$ \gamma_2 = \frac{Y_2 - Y_1}{L_2 - L_1}, \quad \gamma_3 = \frac{Y_3 - Y_1}{L_3 - L_1} $$
So, finally: $$ C = \left( \frac{ \gamma_3 - \gamma_2 }{ L_3 - L_2} \right) \left(L_1 + L_2 + L_3\right)^{-1} \ $$ $$ B = \gamma_2 - C \left(L_1^2 + L_1 L_2 + L_2^2\right) \ $$ $$ A = Y_1 - \left(B + L_1^2 C\right) L_1 $$
Good news, Everyone! You don't need to calculate the coefficients manually. Simply provide the resistance and temperature values for cold, room, and hot environments, and use the form below to determine A, B and C
ADC value and Resistance Calculation
Note: if you already have the temperature and corresponding resistance, you can directly use the second table to input those values.
If you have the ADC value and want to calculate the resistance, use this table to find the corresponding resistance at different temperatures. As you enter the ADC value for each temperature, the calculated resistance will be automatically updated in the second table.
To perform this calculation, you'll need the base resistance of the thermistor, which is essential for determining the resistance at a given temperature based on the ADC value.
Please note that the ADC bits may need to be adjusted if you're using a different microcontroller. In our case, for the the Raspberry Pi Pico, the ADC resolution is 12 bits.
Coefficients Finder
Adjust the temperature by entering a value in either Fahrenheit or Celsius; the form will automatically convert it to the other format. Provide the resistance corresponding to each temperature, and then click the "Calculate Coefficients" button.
Calculate Temperature from Resistance
Now, with these coefficients, you can calculate the temperature for any given resistance:
Rust function
fn steinhart_temp_calc( resistance: f64, // Resistance in Ohms a: f64, // Coefficient A b: f64, // Coefficient B c: f64, // Coefficient C ) -> Result<(f64, f64), String> { if resistance <= 0.0 { return Err("Resistance must be a positive number.".to_string()); } // Calculate temperature in Kelvin using Steinhart-Hart equation: // 1/T = A + B*ln(R) + C*(ln(R))^3 let ln_r = resistance.ln(); let inverse_temperature = a + b * ln_r + c * ln_r.powi(3); if inverse_temperature == 0.0 { return Err("Invalid coefficients or resistance leading to division by zero.".to_string()); } let temperature_kelvin = 1.0 / inverse_temperature; let temperature_celsius = temperature_kelvin - 273.15; let temperature_fahrenheit = (temperature_celsius * 9.0 / 5.0) + 32.0; Ok((temperature_celsius, temperature_fahrenheit)) } fn main() { // Example inputs let a = 2.10850817e-3; let b = 7.97920473e-5; let c = 6.53507631e-7; let resistance = 10000.0; match steinhart_temp_calc(resistance, a, b, c) { Ok((celsius, fahrenheit)) => { println!("Temperature in Celsius: {:.2}", celsius); println!("Temperature in Fahrenheit: {:.2}", fahrenheit); } Err(e) => println!("Error: {}", e), } }