Ever wonder what temperature your Thanksgiving turkey is really at when that plastic pop-up timer pops? When your oven says it's pre-heated to 375°F do you actually believe it? This Thanksgiving I decided to question everything and monitor these temperatures myself. The goal of this project is to monitor, from the interwebs, the ambient temperature inside the oven as well as the meat temperature of my turkey.
So how do we get a temperature reading from inside the oven? We can't just stick a TMP36 or DS1820 in there because neither go up into the three and four hundred degree range. Besides, we wouldn't want to try to embed one inside the turkey anyway. For higher temperatures like the oven we need a special kind of temperature sensor known as a thermistor. A thermistor is simply a temperature dependent resistor. As the temperature changes so does its resistance. There are two main types of thermistors. With a PTC (positive temperature coefficient) thermistor as the temperature rises, so does the resistance (hence the "positive" part). When using an NTC (negative temperature coefficient) thermistor the resistance drops as the temperature rises.
Thermistors come in many shapes and sizes. So how do we find one for our project? Turns out there are lots of lame, non-IoT oven/meat temp tracking devices out there and many sell replacement probes. A quick search on Amazon and eBay yields lots of options. All you are looking for is a replacement probe that looks like it terminates with a headphone plug (read the Lessons Learned section below before ordering anything).
Now that we have this temperature dependent resistor how do we read it's resistance? We don't have a
function in any of the IoT platforms I've played with. What we do have in many scenarios is a GPIO pin capable of reading an analog voltage. All we have to do is connect our thermistor to a known resistor value in a voltage divider configuration and read the output. Once we know the fixed resistance as well as the output voltage from the divider some simple algebra allows us to solve for the resistance of the thermistor. Perfect... except we need a temperature, not a resistance.
Now that we know how to get the resistance of our thermistor we need to turn it into a temperature. Turns out some smart folks back in the 60s figured out that all thermistors have a fairly standard non-linear characteristic curve which describes the relationship between temperature and resistance. It's called the Steinhart-Hart equation and it's our best friend for turning our thermistor resistance into a temperature.
The problem with the Steinhart-Hart equation (and it's simplified form) is that we need some coefficient values to plug into the equation. Ideally you would buy a thermistor that has a datasheet spelling out what the coefficient values are but when you buy them online in the form of random replacement meat probes you are unlikely to get that information. The way around this is to use a simple online calculator. Plug in 3 resistances that you measure from 3 known temperatures and the SRS Thermistor Calculator will spit out your coefficients. With that information we can turn our thermistor value into a temperature.
At the heart of this project we need an IoT hardware platform to read the thermistors, calculate a temperature for each probe and send the data to the cloud. Everything is better in the cloud. At least that's what people tell me. For this project I decided to use the WiPy from Pycom. The WiPy is based on the ESP32 module and is programmed in Python. It has an onboard ADC which is exactly what we need to "talk" to our thermistors. Here's how I wired everything up.
I intentionally decided not to have a local display on this project. As part of my Maker IoT journey I'm trying to explore lots of different platforms and technologies. Lately I've been spending a lot of time in Losant and loving every minute of it. Losant is an online IoT platform that allows you to create workflows and dashboards around your connected device data. For example, this is the dashboard I used on Thanksgiving day to keep an eye on things.
The early drop in oven temp and rise in meat temp was during a basting when I had the oven door open. I was concerned because the meat temperature wasn't going up so I pulled the thermistor out and stuck it down by the heating element (hence the short spike) to test it. I learned that the meat mostly heats up to "done" temperature during the last 30-45 minutes of cooking.
In addition to the dashboard I created some Losant workflows to send me a text when the oven is pre-heated and when the internal temp of the turkey hits 170°F. Workflows are very easy to create in the visual workflow editor.
If you decide to recreate this project I've included the workflow files below that can be imported into your Losant account.
Until I get that 3D printer I've been begging my wife to let me buy (yes, it's actually a necessity) I needed some other way to keep the hardware protected while sitting on the counter next to the stove and oven. The last thing I need is a boiled over pot of mashed potatoes ruining my temperature monitoring goodness. I looked around my office to find a suitable project enclosure or even a part box that would work when I remembered that the WiPy came in a very slick, clear plastic box with a magnetic lid. It was perfect! I used a Dremel to cut out an opening in the back for the USB supply and a standard drill to create openings on the front for the thermistor jacks. With the small form factor breadboard everything fits perfectly snug.
ADCs Can Be Hard
I ran into a couple of obstacles during this project. The biggest, by far, was trouble getting a good reading from the ADC on the WiPy. After hours of research and pouring over the Espressif datasheet and forums I learned that the ESP32 onboard ADC is really quite terrible as far as onboard ADCs go. It's not very linear, doesn't work rail to rail and doesn't support a single shot mode of reading just one channel even if you just use a single ADC pin. After reading an incredibly helpful article about ADCs and thermistors I found that I needed a charge reservoir cap on the output of the voltage divider to compensate for the large input impedance presented to the ADC circuit. Ultimately I got the job done with the onboard ADC but readings could be much more accurate with a better ADC.
MicroPython != Python
The other obstacle I hit was one of software libraries. Losant has done an amazing job of providing libraries to the community to get up and running on their platform quickly in different programming languages. I found, however, that their Python library would not run in the MicroPython execution environment of the WiPy. This wasn't really a big deal as I just took their regular Python version and trimmed it down to only require modules that exist in MicroPython. The regular version uses paho-mqtt for the MQTT functionality. Since that library also won't run in MicroPython I modified the code to use the out-of-box Pycom MQTT module. After hours of debugging I found that the out-of-box version didn't work with the Losant MQTT broker. This seems to have something to do with how they send the CONNECT message. The ultimate solution was to swap out the Pycom MQTT module for the umqtt module from MicroPython.
Thermistor Datasheet is a Must Have
While it is possible to calculate the Steinhart-Hart or Beta coefficients for your thermistor through measurement this is not a very accurate approach and will lead to unreliable data. In my case even after using the online calculator my readings appear to be off by as much as 30 degrees F at times. With a proper datasheet that includes the coefficients you could get the readings locked in pretty tight.
This project was such a blast to work on and it came together nicely. I enjoyed the new experience of coding in Python on an IoT hardware platform and really enjoyed the deep dive learning I was forced to do on analog to digital converters. If you have any questions at all on the project please ask away. I'm happy to help.