Tempiture: A Raspberry Pi-Powered Wireless Grilling Thermometer System

A Raspberry Pi-Powered Wireless Grilling Thermometer System

If I’m not at work or watching princess movies with the family, I’m probably cooking. If I have it my way, the method is the grill or smoker, my medium Big Green Egg to be exact. For my longer smokes, I needed a way to monitor the chamber temp and the temp of the meat. I fired up Amazon and looked for dual-probe wireless thermometers, and while there are plenty out there, I couldn’t find exactly what I wanted (e.g. check the temp from anywhere via phone), so I decided to build one myself.


I had just set up my first Raspberry Pi 3 as an FTP server, so I wondered if I could build a system powered by a Pi and tailor it exactly to my needs. I’m a software developer by trade, so that part shouldn’t be too difficult, but hardware and electrical engineering are definitely not my forte. (I had one EE class in college and stumbled my way through making an LCD counter — my solution was definitely achieved via brute force).

My first iteration used a Raspberry Pi Model 3 and an Arduino UNO, and while it worked, I realized using both the Pi and UNO were overkill, so I eliminated the UNO and got an analog to digital converter chip to use with the Pi instead.

I decided since I was getting a lesson in hardware design, it would be worth learning some new software tools, too. The software components are all new to me. I’m using node.js for the SPI interface to the temperature probes and Docker for hosting two containers: Graphite and Grafana. If you’re an expert in either node.js or Docker, I welcome your constructive criticism.

Graphite is a monitoring tool, typically used to monitor things like servers, websites, applications, etc. Essentially anything that has time-based metrics is suited for Graphite. Reading and storing temperatures every couple of seconds is perfect for Graphite. It will essentially be our database.

Grafana is a front-end for Graphite and other time-based databases. And it’s pretty. Just look at some of the dashboards created with Grafana. It also has built-in alerting (albeit with some limitations) and responsive designs so your dashboard looks great on both mobile and desktop.

Getting everything together was a journey, for sure. Did you know that the power/ground rails on large breadboards are typically separated in the middle so each half of the rail is isolated? If you’re an electrical engineer or day-to-day hacker, of course you did. I did not (this stumped me for quite a while). Did you know that asynchronous design is awesome for speedy apps, but can be a real pain to troubleshoot? I do, now.

Below is a complete guide to getting a wireless thermometer system build, dubbed Tempiture. This guide assumes you already have a Pi 3 up and running and connected to your network. If you need help with that part, the official Raspberry Pi documentation has a good guide here that uses NOOBS (best to use this if it’s your first time using a Pi). I’m using Raspian Stretch Lite because I wanted a minimal installation, but using NOOBS should be fine.

Table of Contents

  1. Parts
  2. Assembly
  3. Calibration
  4. Software
  5. Grilling/Smoking


Here’s a complete parts list with links via Amazon, where I bought everything.


It’s time to wire up the circuit board. Get your breadboard, cobbler, resistors, ADC chip and jumper wires ready. Our goal is a circuit that looks like this:


You can download this Fritzing file by visiting my Fritzing project page.

The black circles on the top right are thermistors, which are taking the place of our probes for the diagram’s sake. The probes themselves are actually thermistors, albeit much larger ones than on the diagram.

Start by mounting your cobbler at one end of the breadboard across the divider channel. Do the same with the MCP3008, being careful not to bend the legs. Knowing how the MCP3008 is mounted is essential. There’s one end that has a small half-circle divot. That’s the so-called “top”. In my circuit, I have the MCP3008 upside down to make it easier to run wires from the cobbler to the chip.

The MCP3008 Analog-to-Digital converter is necessary because the Pi does not have built-in analog inputs, just digital. The ADC allows us to read from analog input sources (e.g. thermistors) and return a digital signal to the Pi.

The MCP3008 is an SPI-enabled chip. SPI stands for Serial Peripheral Interface which is a synchronous serial communication interface that’s very common in digital communication. To wire it up to the Pi, we need to connect it as follows.

  • MCP3008 VDD to Raspberry Pi 3.3V
  • MCP3008 VREF to Raspberry Pi 3.3V
  • MCP3008 AGND to Raspberry Pi GND
  • MCP3008 DGND to Raspberry Pi GND
  • MCP3008 CLK to Raspberry Pi SCLK
  • MCP3008 DOUT to Raspberry Pi MISO
  • MCP3008 DIN to Raspberry Pi MOSI
  • MCP3008 CS/SHDN to Raspberry Pi CE0

Here’s the pinout of the chip (a full datasheet and more info can be found on Adafruit’s website here. If you follow Adafruit’s guide, make sure you use the Hardware SPI instructions):


Here’s the fritzing diagram with the pinout names overlayed (excuse my awesome graphic design skills).


The cobbler has the SCLK, MISO, MOSI and CE0 connections marked (as well as the 3.3V and GND connections), which makes it easy hook up the MCP3008. You don’t have to use the same 3.3V and GND connections I did, just make sure not to use 5V or your software calculations will be off.

The following instructions for connecting the probes is adapted from Adafruit’s write up on using a thermistor with an Arduino. I suggest reading their article to get some more technical information on how the pieces fit together.

Next, we need to create a voltage drop circuit to measure the voltage of the thermistors (aka temperature probes). I won’t go into how a voltage drop circuit works, because I’m sure I wouldn’t explain it correctly. Just know that we connect it in this way so that the MCP3008 can determine the voltage of the thermistor and return an ADC value — more on that later.

To connect the probes, use the alligator clips and connect them to the ends of your 2.5 mm jacks. The ones I linked to above have three legs. You’ll want to use the leg that’s closest to the jack (on the “side” of the jack) and the leg furthest away from that one. If you’re using a different jack, plug the food probe into the jack and then use a multimeter to measure the resistance across the legs. When you get a non-infinite resistance, you’ve found the two legs to use.

See below:


Place a resistor on your breadboard (start with 100 k ohm). You’ll want one end of the resistor connected to 3.3V and the other end on a breadboard terminal strip that will also be a connection point for a wire to the MCP3008 and an end from your probe.

Plug the ends of the alligator clips into the breadboard with one end to GND and the other end in line with the resistor (but make sure the resistor is between 3.3V and the end from the alligator clip).

See in the image below how the two ends of the alligator clips (square black connectors) have one end in in the ground rail and the other just to the left of the resistor leg with the channel wire to the MCP3008 to the right of the resistor leg (left and right are relative here — if you assembled your breadboard differently, adjust the terminology to fit your setup).


Here are some more pictures of the breadboard. Keen readers will notice a 1MΩ resistor in these pictures. I took the pics before I replaced it with a 100KΩ which gives a better temperature resolution for the temperature range needed for a chamber probe. If you’ll be reading very high temperatures 400 °F+, use a MΩ resistor.

After getting your breadboard setup, connect the cobbler to the Raspberry Pi’s GPIO pins using the ribbon cable. At this point I suggest testing your setup. Adafruit has a good guide here that will work with our setup. Follow the Hardware SPI guide and run the simpletest.py app to verify you’re receiving communication from your probes.


Next, it’s time to calibrate your probes. As a quick aside, our food probes are technically NTS (negative temperature coefficient) thermistors. What this means is they are very similar to resistors in the fact that they have a resistance value, but the resistance changes with respect to temperature. As the temperature increases, the resistance decreases. There are also PCT (positive temperature coefficient) themistors, which have resistances that increase with temperature increases. It’s possible to use PCTs with the Pi, but this post will not cover that.

To calibrate your probes, you’ll need to take resistance measurements over a series of temperatures (in Kelvin). The simplest way to do this is to get the resistance value of the probes in ice water, at room temperature and in boiling water. That gives you a rough estimate of resistance values for 273.15 °K (32 °F), 295.37 °K (72 °F) and 373.15 °K (212 °F). If you have an existing thermometer that you know is accurate, measure the temperature at each of the stages above to get more accurate readings. For example, when measuring the resistance of the ice water, it’s probably closer to 33 °F by the time you can perform your measurement.

Here’s my calibration process suggestion:

Using two pairs of alligator clips connected together, connect one pair of ends to the legs of a 2.5mm jack and the other ends to your multimeter’s probes. Plug the probe in to the 2.5 mm jack and then you can use your multimeter to measure the resistance of the probe.

Get a pot of water boiling. While it’s boiling, away from your heat source, log the resistance of the probe at room temperature. Then, get a glass of ice and top it off with just enough water to get about 2 inches of the probe submerged. Put the probe in the ice bath, wait about 10 seconds, and then log the resistance. Finally, place the probe in the boiling water and measure the resistance.

Repeat the process for each probe you’ll be using.

Here’s the values I recorded for the probes listed above.

Chamber Probe (straight probe):

Stage Resistance () Temp (°K)
Ice Water 1709000 288.15
Room Temp 1152000 295.35
Boiling Water 15416 407.039

Food Probe (probe with curved end):

Stage Resistance () Temp (°K)
Ice Water 230000 276.15
Room Temp 110000 295.35
Boiling Water 8100 372.35

Once you have the calibration values, it’s time to get the software set up. Keep your calibration values handy.


SSH in to your Raspberry Pi

ssh pi@tempiture.local

Note: The hostname of my pi is tempiture. If tempiture.local doesn’t resolve to your Raspberry pi, use the IP address of the Pi instead.

Change to the directory where you want to install tempiture (I suggest the home directory) and clone the tempiture GitHub repository by executing the following:

git clone https://github.com/kyleflan/tempiture

Enable Hardware SPI on your Pi if you haven’t already, then reboot.

# enable SPI on the pi
sed -i -e 's/#dtparam=spi=on/dtparam=spi=on/' /boot/config.txt
sudo reboot

Using a text editor (I prefer Vim), open the probes.json file.

vim probes.json # or nano probes.json

This JSON file is an array of JSON objects. You should create a JSON object for each probe you’ll be using. The default file contains two probes, Chamber Probe and Food Probe. Give each probe a unique name. Update the “channel” variable so that it corresponds to the channel on the MCP3008 to which the respective probe is connected (0-8).

Additionally, each probe object should have an array of calibration temperatures (calibration_temps) in order of coldest to warmest and a respective array of calibration resistances (calibration_resistances). Use the calibration resistances and temps you recorded for each probe for these arrays. Finally, the object should have an “R” variable specifying the resistance of the reference thermistor you used in your breadboard. If you used an 100k resistor, this value would be 1.0e5.

If you’d like temperature readings in a value other than Fahrenheit, change the temp_unit to either ‘K’ or ‘C’ for Kelvin and Celsius, respectively.

See the example below for a two-probe setup. I’ve placed the corresponding probe calibration values into each probe object.

    "name":"Chamber Probe",
    // Three different temperatures (in Kelvin), measured over a wide range
    "calibration_temps":[288.15, 295.35, 407.039],
    // Resistances in ohms
    "calibration_resistances":[1709000, 1152000, 15416],
    // R is the resistance of the resistor you couple with the
    // thermistor in the voltage drop circuit
    // Array to hold adc values so we can do an average
    // Define which channel this probe is connected to
    // temp holds the latest temp of the probe
    // temp_unit should be one of F, K, C (Fahrenheit, Kevlin, Celcius)
    "name":"Food Probe",
    // Three different temperatures, measured over a wide range
    "calibration_temps":[276.15, 295.35, 372.35],
    // Resistances in ohms
    "calibration_resistances":[230000, 110000, 8100],
    // R is the resistance of the resistor you couple with the
    // thermistor in the voltage drop circuit
    // Define which channel this probe is connected to

Note: comments can be used as they will be stripped out of the file before being parsed as JSON.

Modify and save the probes.json file when you’re done with your changes. Now we can run the setup script to get the tempiture environment configured and running.

From your tempiture directory, execute the following:

chmod +x ./setup.sh
sudo ./setup.sh

Note: The setup script assumes the default pi user. Update the $PI_USER variable in the setup script if your user is different.

The setup script performs the following:

  • Enables Hardware SPI if not enabled (you’ll need to reboot after running setup if you haven’t enabled hardware SPI yet)
  • Installs Node.js and npm
  • Installs dependencies for tempiture.js
  • Installs docker-hypriot (ARM-compatible Docker version)
  • Installs docker-compose, which we use to deploy our Graphite and Grafana servers.
  • Builds and deploys Grahpite (easypi/graphite) and Grafana (easypi/grafana) servers (many thanks to the folks at easypi for ARM-compatible Docker images of these!)
  • Creates the Grafana datasource for connecting to Graphite
  • Publishes the tempiture Grafana dashboard
  • Installs pm2, a process monitoring tool for Node.js applications.
  • Sets up docker images and tempiture.js to persist across restarts.
  • Starts tempiture.js

Now navigate to http://tempiture.local:3000 in your web browser (try it on your phone, too).

Note: You should change your Grafana admin password if your network is available outside of your LAN. Go to Menu -> Admin -> Org Users -> admin -> edit.

Tempiture should be your main dashboard, but if it isn’t, navigate to the Dashboard Menu and open the Tempiture dashboard. By default, it is configured for two probes: Chamber_Probe and Food_Probe (we replace spaces with underscores when sending the probe data to Graphite).

Here’s some pics of Tempiture in action.


To make tempiture portable, I use this external battery, by EC Technology usually used for charging phones/tablets. Our system needs minimal power, since we’re not using any of the external USB ports. I use the 2.1A port and I haven’t had any issues. I’ve done a 12+ hour brisket and it didn’t even drop the battery by 25%. (It’s also a great battery pack in general)

The best place to mount your temperature probe in your grill/smoker will depend on your setup. If your grill or smoker has an existing thermometer, try to mount the chamber probe close to it.

For my Big Green Egg, I put the probe right next to the BGE’s analog thermometer, so I can get a temperature reading similar to the baseline I’m used to. The temperature varies inside the BGE depending on where you place the probe. The temperature is higher closer to the grate (obviously) and near the exhaust, so placing it in the “middle” of the dome by the existing thermometer will give you a good reading of the air temperature inside the BGE.

There’s no permanent mount here, I simply route the probe through the exhaust and sit the probe on the metal bracket of the existing thermometer probe. Then I gently bend the probe wire on top of the exhaust and place the cast iron topper on the Egg. See the pics below.

By the way, now is a good time to calibrate the existing analog thermometer if you have one. For the BGE, gently pull on the existing thermometer, wiggling it a little bit and it should come out. There’s a metal bracket that holds the thermometer in place on the underside of the dome, so be sure to catch that as you pull out the thermometer.

Get a pot of boiling water like we used during calibration and carefully place the probe in the water. The temperature pointer should be right at 100 °C. If it’s not, gently adjust the nut at the base of the thermometer with a set of pliers until the thermometer reads 100 °C when placed in boiling water.


If you added additional probes, or want to make changes, read the next article on configuring a Grafana dashboard and an overview of the node.js app code.

If you have any issues with the setup script or the components of the tempiture software, please log an issue on github.


Author: kyleflan

Kyle is a software developer by day and a husband and father by night. He enjoys cooking, a good craft beer, and tinkering on various software/hardware projects. Current interests are data science, containerization, Raspberry Pi projects and Node.js.

24 thoughts on “Tempiture: A Raspberry Pi-Powered Wireless Grilling Thermometer System”

  1. I am only getting N/A on the temperatures. The probes are testing ok but it will not display in grafana.

  2. Kyle, I’m also a software eng, with a deep background on electronics; RPI, Beaglebone, ESP32, etc. Would be interested in conversing with you, as well as being a resource on electronics when needed. Drop me a note on my email with your email. Thanks! Ben

  3. Running setup.sh causes a ton of errors for me and ends up unable to resolve tempiture.local:3000 . I changed my hostname to tempiture.

  4. Good evening!
    When I run the setup.sh it is throw multiple errors. Would it be possible to get a disk image from a running project? Thank you in advance!

  5. I keep getting this error:
    curl: (7) Failed to connect to tempiture.local port 3000: Connection refused
    curl: (7) Failed to connect to tempiture.local port 3000: Connection refused

    When the grafana set-up files run. PM2 status then says watching is “disabled”

    1. Of course. But that takes all the fun out of it 🙂

      Jokes aside, I actually use this wireless thermometer these days: https://amzn.to/3oCjyez

      It’s less bulky and works without having to have an external power pack or long extension cord. If you’re just looking for something to remotely monitor the temperature of your grill/oven/etc., buy something pre-made. If you like to build, tinker and learn, then it’s a fun (albeit sometimes frustrating) project.

      1. I’m trying to make a bluetooth thermometer communicate with the Raspberry Pi, then the Raspberry Pi compares internal food temperature to preset setpoints, depending on rare, medium rare, well done, etc.. and if the setpoint is reached, it sends a signal to a solenoid operated valve to close. Then your food is done, and propane grill is off.

      2. I’m trying to make a bluetooth thermometer communicate with the Raspberry Pi, then the Raspberry Pi compares internal food temperature to preset setpoints, depending on rare, medium rare, well done, etc.. and if the setpoint is reached, it sends a signal to a solenoid operated valve to close, and cuts off propane gas to the burners. Then your food is done, and propane grill is off. I’m doing this for an engineering school project.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s