ESP32 NTP Temperature Probe Cooking Thermometer With Steinhart-Hart Correction and Temperature Alarm.




Introduction: ESP32 NTP Temperature Probe Cooking Thermometer With Steinhart-Hart Correction and Temperature Alarm.

About: Our grandkids keep me busy!

Still on the journey to complete an "upcoming project", "ESP32 NTP Temperature Probe Cooking Thermometer With Steinhart-Hart Correction and Temperature Alarm" is an Instructable showing how I add an NTP temperature probe, piezo buzzer and software to my capacitive touch Instructable "ESP32 Capacitive Touch Input Using "Metallic Hole Plugs" for Buttons" to create a simple but accurate cooking thermometer with a programmable temperature alarm.

The three capacitive touch buttons allow the temperature alarm level to be set. Pressing the center button displays the "Set Alarm Temperature" display, enabling the left and right buttons to reduce or increase the alarm temperature respectively. Pressing and releasing the left button will reduce the alarm temperature one degree, while pressing and holding the left button will continuously reduce the alarm temperature until released. Similarly, pressing and releasing the right button will increase the alarm temperature one degree, while pressing and holding the right button will continuously increase the alarm temperature until released. When finished adjusting the alarm temperature, simply touch the center button again to return to the temperature display. At any time the temperature is equal to or higher than the alarm temperature, the piezo buzzer will sound.

And as mentioned, an NTP temperature probe is used in the design along with the Steinhart-Hart equations and coefficients necessary for accurate temperature readings. I've included an overly-verbose description of the Steinhart-Hart equation, the Steinhart-Hart coefficients, voltage dividers and algebra in Step 1 (as a bonus, it puts me to sleep every time I read it, so you may wish to skip Step 1 and head straight to Step 2: Assembling the Electronics, unless of course you need a nap).

If you decide to build this cooking thermometer, for customization and 3D printing I've included the following files:

  • Arduino file "AnalogInput.ino" containing the software for the design.
  • Autodesk Fusion 360 cad files for the case showing how the case was designed.
  • Cura 3.4.0 STL files "Case, Top.stl" and "Case, Bottom.stl" ready for 3D printing.

You will also need familiarity with the Arduino environment as well as soldering skills and equipment, and in addition may need access to accurate digital ohmmeters, thermometers and temperature sources for calibration.

And as usual, I probably forgot a file or two or who knows what else, so if you have any questions, please do not hesitate to ask as I do make plenty of mistakes.

The electronics were designed using pencil, paper and a Radio Shack EC-2006a (Cat. No. 65-962a) solar powered calculator.

The software was designed using Arduino 1.8.5.

The case was designed using Autodesk Fusion 360, sliced using Cura 3.4.0, and printed in PLA on an Ultimaker 2+ Extended and an Ultimaker 3 Extended.

And one final note, I receive no compensation in any form, including but not limited to free samples, for any of the components used in this design

Step 1: Math, Math and More Math: Steinhart–Hart, Coefficients, and Resistor Dividers.

My earlier designs incorporating an NTC temperature probe used a table lookup technique for converting the incoming voltage from a resistor divider to temperature. Since the ESP32 is capable of twelve bit analog input, and since I was designing for increased accuracy, I decided to implement the "Steinhart-Hart" equation in the code for voltage to temperature conversion.

First published in 1968 by John S. Steinhart and Stanley R. Hart, the Steinhart-Hart equation defines the resistance to temperature relationship of an NTC temperature probe as follows:

1 / T = A + (B * (log(Thermistor))) + (C * log(Thermistor) * log(Thermistor) * log(Thermistor))


  • T is degrees Kelvin.
  • A, B, C are the Steinhart-Hart coefficients (more on that in a moment).
  • And Thermistor is the temperature probe thermistor resistance value at the current temperature.

So why is this seemingly complicated Steinhart-Hart equation necessary for a simple NTC temperature probe based digital thermometer? An "ideal" NTC temperature probe would provide a linear resistance representation of the actual temperature, thus a simple linear equation involving voltage input and scaling would result in an accurate temperature presentation. However, NTC temperature probes are not linear and, when combined with the non-linear analog input of virtually all low cost single board processors such as the WiFi Kit 32, produce non-linear analog inputs and thus inaccurate temperature readings. By using an equation such as Steinhart-Hart along with careful calibration, highly accurate temperature readings using NTC temperature probes with a low cost single board processor can be attained by generating a very close approximation of the actual temperature.

So back to the Steinhart-Hart equation. The equation utilizes the three coefficients A, B and C to determine temperature as a function of the thermistor resistance. Where do these three coefficients come from? Some manufacturers provide these coefficients with their NTC temperature probes, and others do not. Furthermore, the manufacturer provided coefficients may or may not be for the exact temperature probe you may purchase, and are most likely coefficients representative of a large sample of all temperature probes they manufacture over a period of time. And finally, I simply could not locate the coefficients for the probe used in this design.

Without the needed coefficients, I created Steinhart-Hart Spreadsheet , a spreadsheet based calculator that assists in generating the needed coefficients for an NTC temperature probe (I lost the link to a similar web based calculator I used many years ago, so I created this one). To determine the coefficients for a temperature probe, I start by measuring the value of the 33k resistor used in the voltage divider with a digital ohmmeter, and enter the value into the yellow area of the spreadsheet labeled "Resistor". Next, I place the temperature probe in three environments; first room temperature, second ice water and third boiling water, along with a known accurate digital thermometer, and allow time for the temperature on the thermometer and the thermistor input count appearing on the WiFi Kit 32 display (more on this later) to stabilize. With both the temperature and thermistor input count stabilized, I enter the temperature indicated by the known accurate thermometer and the thermistor count appearing on the display of the WiFi Kit 32 into the yellow area of the spreadsheet labeled "Degrees F from Thermometer" and "AD Count from WiFi Kit 32" respectively, for each of the three environments. Once all measurements are entered, the green area of the spreadsheet provides the A, B and C coefficients required by the Steinhart-Hart equation that are then simply copied and pasted into the source code.

As previously mentioned the output of the Steinhart-Hart equation is in degrees Kelvin, and this design displays degrees Fahrenheit. Conversion from degrees Kelvin to degrees Fahrenheit is as follows:

First, convert degrees Kelvin to degrees Celsius by subtracting 273.15 (degrees Kelvin) from the Steinhart-Hart equation:

Degrees C = (A + (B * (log(Thermistor))) + (C * log(Thermistor) * log(Thermistor) * log(Thermistor))) - 273.15

And second, convert degrees Celsius to degrees Fahrenheit as follows:

Degrees F = ((Degrees C * 9) / 5) + 32.

With the Steinhart-Hart equation and coefficients complete, a second equation is required to read the resistor divider output. A model of the resistor divider used in this design is:



  • vRef in this design is 3.3vdc.
  • Thermistor is the NTC temperature probe used in the resistor divider.
  • vOut is the voltage output of the resistor divider.
  • Resistor is the 33k resistor used in the resistor divider.
  • And ground is, well, ground.

vOut of the resistor divider in this design is attached to the WiFi Kit 32 analog input A0 (pin 36), and the voltage output of the resistor divider is calculated as follows:

vOut = vRef * Resistor / (Resistor + Thermistor)

However, as noted in the Steinhart-Hart equation, the thermistor resistance value is required in order to obtain temperature, not the voltage output of the resistor divider. So rearranging the equation to output the thermistor value requires the use of a little algebra as follows:

Multiply both sides by "(Resistor + Thermistor)" resulting in:

vOut * (Resistor + Thermistor) = vRef * Resistor

Divide both sides by "vOut" resulting in:

Resistor + Thermistor = (vRef * Resistor) / vOut

Subtract "Resistor" from both sides resulting in:

Thermistor = (vRef * Resistor / vOut) - Resistor

And finally, using the distributive property, simplify:

Thermistor = Resistor * ((vRef / vOut) - 1)

Substituting the WiFi Kit 32 A0 analog input count of 0 through 4095 for vOut, and substituting the value of 4096 for vRef, the resistor divider equation providing the thermistor resistance value required by the Steinhart-Hart equation becomes:

Thermistor = Resistor * ((4096 / Analog Input Count) - 1)

So with the math behind us, let's assemble some electronics.

Step 2: Assembling the Electronics.

For the electronics, I had previously assembled the ESP32 Capacitive Touch demonstrator With that assembly, the following additional components are required:

To assemble the additional components, I performed the following steps:

    • Stripped and tinned the ends of each 4" wire length as shown.
    • Soldered one end of the yellow wire and one end of the 33k ohm resistor to the "Tip" pin of the phone connector.
    • Soldered one end of the black wire to the free end of the 33k ohm resistor and trimmed off the excess resistor wire.
    • Applied heat shrink tubing over the wires and resistor.
    • Soldered one end of the red wire to the "Sleeve" pin on the phone connector.
    • Soldered the free end of the yellow wire to pin 36 on the WiFi Kit 32.
    • Soldered the free end of the black wire to the GND pin on the WiFi Kit 32.
    • Soldered the free end of the red wire to the 3V3 pin on the WiFi Kit 32.
    • Soldered one green wire to one lead of the piezo buzzer.
    • Soldered the remaining green wire to the remaining lead of the piezo buzzer
    • Soldered the free end of one of the green piezo wires to pin 32 on the WiFi Kit 32.
    • Soldered the free end of the remaining green piezo wires to the GND pin on the WiFi Kit 32.
    • Plugged the temperature probe into the phone connector.

    With all wiring complete, I double checked my work.

    Step 3: Installing the Software.

    The file "AnalogInput.ino" is an Arduino environment file containing the software for the design. In addition to this file, you will need the "U8g2lib" graphics library for the WiFi Kit32 OLED display (see for further information on this library).

    With the U8g2lib graphics library installed in your Arduino directory, and "AnalogInput.ino" loaded into the Arduino environment, compile and download the software into the WiFi Kit 32. Once downloaded and running, the top line of the OLED display on the WiFi Kit 32 should read "Temperature" with the current temperature displayed in large text in the center of the display.

    Touch the center button (T5) to display the "Set Alarm Temperature" display. Adjust the alarm temperature by pressing either the left button (T4) or right button (T6) as described in the introduction. To test the alarm, adjust the alarm temperature to be equal to or lower than the current temperature and the alarm should sound. When finished setting the alarm temperature, touch the center button to return to the temperature display.

    The values dProbeA, dProbeB, dProbeC and dResistor in the software are the values I determined during calibration of the probe I used in this design and should generate temperature readings accurate to within a few degrees. If not, or if higher accuracy is desired, then calibration is next.

    Step 4: Calibrating the NTP Temperature Probe.

    The following items are required to calibrate the temperature probe:

    • One digital ohmmeter.
    • One known accurate digital thermometer capable of 0 through 250 degrees F.
    • One glass of ice water.
    • One pot of boiling water (be very, very careful!).

    Start by obtaining the actual 33k resistor value:

    • Remove power from the WiFi Kit 32 board.
    • Remove the temperature probe from the phone connector (it may also be necessary to de-solder the black wire from the WiFi Kit 32, depending on your digital ohmmeter).
    • Open the Steinhart-Hart Spreadsheet.
    • Measure the value of the 33k ohm resistor using the digital ohmmeter and enter it into the yellow "Resistor" box in the spreadsheet and into the variable "dResistor" in the software. While this may seem excessive, a 33k ohm 1% resister can indeed effect the accuracy of the temperature display.
    • Plug the temperature probe into the phone connector.

    Next obtain the Steinhart-Hart coefficients:

    • Turn on the known accurate digital thermometer.
    • Plug a USB power source into the WiFi Kit 32.
    • Simultaneously press and hold the left (T4) and right (T6) buttons until the "Thermistor Counts" display appears.
    • Allow both the digital thermometer and thermistor counts displays to stabilize.
    • Enter the temperature and thermistor counts into the yellow "Degrees F from Thermometer" and "AD Counts from ESP32" columns on the "Room" row.
    • Insert both the digital thermometer and thermistor probes into ice water and allow both displays to stabilize.
    • Enter the temperature and thermistor counts into the yellow "Degrees F from Thermometer" and "AD Counts from ESP32" columns on the "Cold Water" row.
    • Insert both the digital thermometer and thermistor probes into boiling water and allow both displays to stabilize.
    • Enter the temperature and thermistor counts into the yellow "Degrees F from Thermometer" and "AD Counts from ESP32" columns on the "Boiling Water" row.
    • Copy the green "A:" coefficient into the variable "dProbeA" in the source code.
    • Copy the green "B:" coefficient into the variable "dProbeB" in the source code.
    • Copy the green "C:" coefficient into the variable "dProbeC" in the source code.

    Compile and download the software into the WiFi Kit 32.

    Step 5: 3D Printing the Case and Final Assembly.

    I printed both "Case, Top.stl" and "Case, Bottom.stl" at .1mm layer height, 50% infill, with no supports.

    With the case printed, I assembled the electronics and the case as follows:

    • I desoldered the wires from the three hole plugs, pressed the hole plugs into position in "Case, Top.stl", then re-soldered the wires to the hole plugs, carefully noting the left (T4), center (T5) and right (T6) wires and the respective buttons.
    • Secured the phone connector to the round hole in "Case, Bottom.stl" using the included nut.
    • Positioned the piezo buzzer in the case bottom assembly next to the phone connector, and secured in place with double sided tape.
    • Slid the WiFi Kit 32 into position into the case bottom assembly, making sure the USB port on the WiFi Kit 32 aligned with the oval hole in the case bottom (do NOT press on the OLED display to position the WiFi Kit 32 in the case bottom assembly, trust me on this one, just don't do it!).
    • Pressed the case top assembly onto the case bottom assembly and secured in place using small dots of thick cyanoacrylate glue on the corners.

    Step 6: About the Software.

    The file "AnalogInput.ino" is a modification of the file "Buttons.ino" from my previous Instructable "". I've modified the original three code sections "setup()", "loop()" and "InterruptService()" to include software for the probe and alarm, and I've added an additional three code sections "Analog()", "Buttons()" and "Display()" to clean up "loop()" and to add the necessary software for the probe and alarm.

    "Analog()" contains the code necessary to read the thermistor count into an array, average the array of counts, use the voltage divider to generate the thermistor value and finally use the Steinhart-Hart equations and temperature conversion equations to generate degrees Fahrenheit.

    "Buttons()" contains the code necessary to process button presses and edit the alarm temperature.

    "Display()" contains the code necessary to present the information on the OLED display.

    If you have any questions or comments about the code, or any other aspect of this Instructable, feel free to ask and I will do my best to answer them.

    I hope you enjoyed it (and are still awake)!

    Step 7: The "Upcoming Project".

    The upcoming project, "Intelligrill® Pro", is a dual temperature probe smoker monitor featuring:

    • Steinhart-Hart temperature probe calculations (as opposed to "look-up" tables) for increased accuracy as incorporated in this Instructable.
    • Predictive time to completion on probe 1 incorporating the increased accuracy derived from the Steinhart-Hart calculations.
    • A second probe, probe 2, for monitoring smoker temperature (limited to 32 through 399 degrees).
    • Capacitive touch input controls (as in the previous Instructable).
    • WIFI based remote monitoring (with a fixed IP address, enables monitoring of the smoker progress from anywhere an internet connection is available).
    • Extended temperature range (32 through 399 degrees).
    • Audible completion alarms both within the Intelligrill® transmitter and on most WiFi capable monitoring devices.
    • Temperature display in either degrees F or degrees C.
    • Time format in either HH:MM:SS or HH:MM. Battery display in either volts or % charged.
    • And PID output for auger based smokers.

    "Intelligrill® Pro" is still testing to become the most accurate, feature packed and reliable HTML based Intelligrill® I have designed. It's still under test, but with the meals it's assisting to prepare during testing, I've gained more than a few pounds.

    Again, I hope you enjoy it!

    Arduino Contest 2019

    Participated in the
    Arduino Contest 2019

    Be the First to Share


      • Remote Control Contest

        Remote Control Contest
      • Stone Concrete Cement Contest

        Stone Concrete Cement Contest
      • Pets Challenge

        Pets Challenge



      Question 8 months ago on Step 7

      Hello, I'm trying to make a pellet grill pellet level sensor and stumbled upon your Intelligrill project. I am using it as the starting point because of the way it allows the user to go into a setup webpage and enter the local wifi network, and then uses the wifi network rather than having to be connected directly to it with your phone. I was port it over to the Heltec ESP32 (an easy port) when I stumbled upon this project. I am wondering if you have done anymore with this. I am having issues with the ESP32 being extremely slow to respond, even to ping requests, sometimes over a second. I have heard that it is because the ESP32 puts the wifi module into a low power state, have you encounterd anything like this with your work on the esp32?
      My hope is to use Google Firebase as a backend database for the pellet level readings, and also dual temperature probe readings to allow a phone app to access it from anywhere and also do some graphing data. I've always wanted to see a graph of the "stall" when smoking a pork shoulder to see what it really looks like.
      Thank you so much for your projects, they have given me a ton of help in getting my project started.


      Answer 8 months ago

      Hi thanatos65,

      I've had others use this Instructable to create a pellet grill / smoker controller and they've expressed great success! Unfortunately, I have not tried that. I did create what I called "Intelligrill Pro" and use it almost daily. It has two temperature inputs, one for the meat and a second for the smoker temperature, which could be adapted for pellet grill / smoker use, but I never published it.

      I have not experienced the slow response you've encountered with the ESP32. I've used both Adafruit and Heltec boards and have not encountered slow responses.

      And finally, I'm not very happy with the temperature probes I've used as they have very poor repeatability between probes.

      Hope this helps!



      Reply 8 months ago

      Hi Greg,
      Thank you for your reply. I think the slow response and other connection issues were caused by my router. I changed the code to store your local SSID and Password in the ESP32's EEPROM so that it saves all the data through a reset or power cycle and it now works well. Not sure why that changed the behavior.

      My plan is to make a mashup of your Intelligrill's wireless connectivity with your Intelligrill Pro's dual temperature inputs and touch buttons, and then add in a pellet level sensor using a VL6180X Time of Flight sensor to measure the distance to the pellets. All of this data will be accessible through your phone. At least that's the plan.

      Thank you so much for publishing these projects, they have been a huge help in me getting started on this.


      9 months ago

      Thank you for this excellent instructable! I started making my own now. However, I can’t get the C coefficient from your spreadsheet, it seems that the formula has been replaced by a hard coded “2”
      I’m far from smart enough to setup up the formula myself :)

      I’m a hobbyist that have been making small programs for my self from time to time, your code gave me a whole new perspective of how a code should look like, your structure and comments are really helpful! I’m trying to work like that from now on



      Reply 9 months ago

      Thank you NessK86, I'm glad you enjoyed it!

      I'll check on the spreadsheet and see why it does that.

      Sorry for the trouble!



      Reply 8 months ago

      You have nothing to say sorry for! I really appreciate this excellent instructable!

      Thank you!


      1 year ago

      Can this be used with Hassio? I am trying to somehow use your config with my electrical smoker that I am controlling like this:


      Reply 1 year ago

      Hi RonL,

      I do not see why it couldn't since it uses WIFI to communicate with either a router or other WIFI device.



      Question 3 years ago

      I'm confused: first you start talking about NTP, and this is applied to labels throughout. Then you start talking about NTC. But you never say why you stop talking about NTP and start talking about NTC. What's the difference between these two devices? And I never found where you referenced the actual NTP or NTC device you were using so I could buy one, yet you give the specifics on the solar powered calculator.


      Answer 3 years ago

      Hi javaben,

      I've used these probes in a variety of applications for over ten years. Some suppliers listed them as "NTP" and some listed them as "NTC", so when searching for the probe, I've used both although the NTP designation isn't as prevalent as it once was.

      The Steinhart-Hart equations use the term NTC, so I used it there.

      The probe is quite common, and as shown in "Step 2: Assembling the Electronics", I provide both a searchable term and link to the manufacturer:
      Unless a part is highly unique and/or difficult to search for, I try to avoid making vendor recommendations as website rules are changing in regard to promotional vs. educational postings. Thus regarding the specific reference to the "Radio Shack EC-2006a (Cat. No. 65-962a) solar powered calculator", it indeed qualifies as a highly unique and/or difficult to search for item since Radio Shack is no longer in existence. However, most any calculator available today, even those on a "smartphone", would have sufficed.


      3 years ago

      Wow! I never thought about reverse engineering a temp probe lie this!


      Reply 3 years ago

      Hi auderyobscura,

      Yes, in order to obtain accurate temperatures with NTP temperature probes, this is one of a few ways, and my favorite. It is quite a mathematical discussion of where the numbers come from, , but in the end it's just a few measurements in a spreadsheet, a copy and paste into the source code, and that's it!