Smoking Meat with the Internet of Things
In the height of summer, I was getting into using my old Weber Kettle Grill as a smoker to do some low and slow cooking. I already had a remote grill thermometer and was using that to monitor the internal food temperature while I did other things around the house. After a few failed cooking attempts, I came to realize how important monitoring the internal grill temperature was. My thermometer didn’t do that, and I was about to order one from Amazon, when I asked myself, how hard could this be to build? Even better, could I build something that could tell me it was done? Or when it needed attention?
I’ve wanted to do an Arduino project ever since I heard about its capabilities, and now was the chance. I quickly validated that this was something that could actually be done, and as a software person, once I could get the data out of the temperature probes and into the Internet, I had a ton of options of what to do with it.
At a high level, my plan was to use two temperature probes - reusing one I had, and another from Amazon - connected to an Arduino. The Arduino would calculate the temperature readings and then send them up to Parse.com where it would store and monitor the data. When the temperature hits a certain threshold, it would send a push notification to my devices. I’d also have an iOS app on the phone where I could check the current temperatures whenever I wanted.
I’ve made all of the resources for this project available on Github and I’ll walk through how I’ve put all the pieces together in the following sections.
Here is a list of all the parts I used to put together the circuit.
- Misc jumper wires
- Arduino Uno
- Sparkfun Wifi Shield
- Maverick ET732 Smoker Probe
- Generic Remote BBQ Food Probe
- I’m using one from this, but you could use any one you might have
- 10K Potentiometer
- 16x2 LCD Module with pin headers
- 220K Ohm Resistor
- 1M Ohm Resistor
- 2x 2.5mm audio jack inputs
The central component to this device is the Arduino UNO. The UNO is a programmable microprocessor that can take in a number of digital and analog inputs. Using the Arduino IDE, we can write C code to control those inputs to read in signals or send out digital signals. For our example, the probes we’re going to use are analog inputs and will be plugged into the analog input pins 0 and 1.
The first thing that I needed to figure out was how to connect a BBQ temperature probe into the Arduino. It turns out that most BBQ thermometers are ‘thermistors’. A thermistor is a component whose resistance will vary depending on the temperature. Assuming you have the specifications on the thermistor, you can convert that resistance into a temperature reading. In my case, these specifics were unknowns and I’ll talk through how I figured out how to get around that. Physically, all we need to connect the probe is a 2.5mm audio jack input. Attach some wire, either soldered, or alligator style clip wires to the jack input and wire that into the Arduino.
Just wiring them into the Arduino is not going to be sufficient. In order to get proper values into the Arduino, we’ll need to setup a ‘Voltage Divider’. You can read more about voltage dividers here, but to set one up you need to choose a resistor to wire in the circuit that pairs with the resistance you want to measure. Because we don’t know the specific resistances required by the probes, we’ll have to get creative. For my setup, all that I did was use a multimeter to measure the resistance reported by the probe at room temperature and found a resistor that was closest to that value. In my case, it was 220K ohm for the food probe, and 1M ohm for the chamber probe. Place that resistor in between the Arduino and the Thermistor and we’ll be able to read some resistances that we can convert to temperatures.
Now that we can read in the resistances from the probes, we’ll need to figure out how to convert those values into temperatures. It turns out that there is a formula called the ‘Steinhart Hart Equation’ that will do that for you, granted you know all of the specifics. I won’t go into the detail of that equation nor do I really understand that portion, but you can go read about it here. I found some sample code on adafruit that did exactly what I wanted, and I just used pieces of that in the Arduino code. The one tricky piece to that equation is that it requires something called a beta-coefficient of the thermistor, which was unknown for my probes. One way to calculate that coefficient is to measure the resistance of the thermistor at a handful of different temperatures in its supported range and then plug them into an online calculator. I did that for my probes, and then tweaked that number a bit to get its converted temperature close to what I was using to compare it with. Not a perfect science, but was close enough for me.
Even though I wanted the temperatures to be sent into the cloud, I still wanted to be able to walk up to the device and see the current temperatures. For this, I plugged in a 2-line LCD screen and wired in a potentiometer to adjust the contrast. The LCD plugs into a number of the Arduino’s digital input pins to be able to set the text on the display.
Here is a wiring diagram of what we’ve put together so far. It’ll read two temps and output the values on the LCD display. The next step is to get those readings posting to the internet so we can read those values from anywhere.
There are a number of options for getting an Arduino talking to the internet. Even Arduino has a network enabled board called the YUN that has wifi/ethernet built into it. The YUN sounds awesome, but it’s also much more expense than the UNO. I wanted to keep this as low-cost as possible, so I searched for some other options. I read a bunch about the ESP8266 chip as a potential option. The ESP8266 is a programmable microcontroller with a wifi antenna built in. It even has it’s own GPIO pins and can be programmed via the Arduino IDE. But what makes this chip special is that it comes with a Serial->Wifi command set. Meaning I can send it commands from the Arduino using a serial interface to tell it to do things on the internet. You can read more about the AT commands here. The downside to using an ESP8266 is that it requires a bit of a more complicated setup as it requires 3.3v, whereas the Arduino usually powers 5v. Rather than mess around with voltage regulators, I found an option from SparkFun, where they took an ESP8266 and placed it onto a stackable Arduino board with built in voltage regulation, all for 15 bucks. Perfect.
You can go on Github and download a library that handles the ESP8266 communication layer specific to the wifi shield, but I wanted to dig in a bit further on how this device actually worked. It turns out that you can use the Arduino as a serial passthrough device to the ESP8266 chip. This means that you can place the shield onto the Arduino, and run some code ( named a sketch ) that passes through input from the Arduino IDE serial monitor into the ESP8266, and it’ll output the results from the ESP8266 to the serial monitor. From here, I can send my own AT commands to the device. For this project, the only thing I wanted to do was default the chip to connect to my home wifi when it started up. So all I had to do was enter ‘AT+CWJAP_DEF=”MY_SSID”,”MY_PASSWORD”’ into monitor, and the chip connected to my wifi and stored it into it’s memory so the next time it started up, it’ll automatically connect. You can see the complete passthrough sketch code here.
With the wifi shield connecting to my home network, the next step was to get the Arduino code sending the temperature data to the internet. It turns out that to send data to the internet with the ESP8266, it’s just a sequence of AT commands: 1. open the session, 2. tell it how much data you are sending, 3. pass it the data you want to send. To handle sending the data, I’m going to construct an HTTP POST of the data and POST that to a server. I won’t go through the code in detail, but that’s the basic sequence of events.
Let’s see what that circuit looks like now.
Even though the wifi shield is a stackable Arduino shield, I actually had trouble with it being set in the stacked position. If you push it too far in, it ends up shorting something that causes intermittent wifi drops. I actually had better luck just wiring up the shield with only the wires it needed to operate. In this case it’s just power, ground, and the two pins 8/9 for the software serial transmission.
You can view the final Arduino code here.
Our circuit is now setup to send our temperature data somewhere. I’ve chosen to use Parse.com as it’s super simple to setup and free for our purposes. Parse provides cloud storage of the data with the ability to do push notifications and has API’s available to access the data from pretty much anywhere. Parse will store the data we’re sending, and we’ll configure it to send a push notification when our food is ready. In order to get our device talking to Parse, we’ll specifically use their REST API to POST the data to.
The problem with using Parse is that it requires you to send the data over HTTPS and the ESP8266 does not support HTTPS. Not a problem, we’ll just create a Proxy server between the Arduino and Parse that will accept our HTTP data and forward it to Parse using HTTPS. For a more permanent solution, you could find an online service to do this, but we’ll just build our own using NodeJS and Express.
Express is a web application framework that will allow us to create a simple endpoint that will receive our POST request from the device, prepare the data for Parse, and then send it to Parse via https. When the request comes in, we’ll first convert our POST data into a JSON object. Next we’ll create a set of HTTP options to tell Node how to handle our request. Most importantly, we’ll need to add in the Application ID and Rest API key for Parse, so it knows where to process our data. We’ll construct a request to ‘/1/classes/TempData’ which means it’ll save the data into the TempData collection. Once we have our options setup, we can now use the https module from Node to send the data to Parse securely.
You can view the full proxy server code here.
I’ve done a bunch of iOS development, but for this example I’m going to keep it simple and just download the QuickStart iOS app from Parse. The quick start application will setup the Xcode environment to handle their libraries for connecting to their services. The most important thing to do is update the section that wants to use your Parse id’s. You’ll want to plug in your Application ID and Client Key in your AppDelegate file here.
My application will show the two temperatures in the UI, with a date that shows the last updated time. I won’t go into all the detail of iOS development, but I’ve added my UI components to my storyboard, set up the appropriate outlets, and I’m ready to connect to Parse and update those outlets.
In iOS, when the app loads, it’ll call
viewDidLoad. There we’ll setup a timer to run every 10 seconds that will query Parse and find the most recent entry recorded and update our UI with that information.
You can view the complete iOS code here.
We now have everything connected where we can see the last record temperature from the Arduino on an iPhone.
To finish this off, I wanted to be able to get a push notification when my food hit a certain temperature. Parse makes it pretty simple for you to enable push notifications for your application. You can just follow their tutorial to get things set up, but the general gist is that you have to use iTunes Connect to set up your application there and generate a certificate that will let Parse utilize the Apple push notification system.
Once you’ve set up Parse to do push notifications, you need to make sure in your iOS application that you add some code to enable receiving those notifications (registerForRemoteNotifications), and that when you run the app, you accept the dialog that asks if you’d like to receive notifications for this application. Once your device registers for notifications, Parse will know where to send the notification information.
There are a few places in code that we could determine when a temperature hits a certain threshold, but the easiest place to put this logic is in a
beforeSave trigger using the Parse cloud code. A trigger is a piece of code that runs at a specific points, in this case it’ll run before a record is saved.
We’ll define a threshold temperature in this trigger that we’ll use to check to see if our new temperature has crossed. It’ll be hard coded in the trigger for now, but you could easily move this into a value that gets configured elsewhere. Since we don’t want a notification every time the temperature is above the threshold, we’ll only send a message the first time it crosses that threshold. To do that we’ll query the last record saved, look at it’s temperature and check if that number is less than the threshold, and the new temperature we’re about to save is above that threshold. Once that happens, we’ll use the Cloud Push library to send a message to the global push channel.
If we’ve set everything up correctly, we should now be able to see temperatures being logged from the Arduino to Parse in the native iOS application. Once the food probe hits 165, it should send a push notification to the phone letting us know that it’s ready to eat.
You can see the code for this here.
The beauty of making something like this is that you can swap out different components and change things for improvement. This is by no means the best way to do everything. It’s just a digest of what I did to build it. With the basics in place, you could eventually build this system to be more robust by doing things like: adding additional notifications for temperature changes alerts, adding charts of temperatures over time, or being able to look at previous times you’ve cooked.
Getting the Arduino hooked into the internet was a little tricky, but devices in this space are rapidly evolving and are becoming easier and easier to use. With new low cost powerful boards with built in wifi, like the Sparkfun Photon, this process could become even easier. Pair that with some of the new IoT services coming out with AWS, and you could try a different approach at handling the data/networking aspect.
Some may say that all this takes some of the fun out of barbecuing, but for me it was the perfect marriage of two hobbies I really enjoy, technology and barbecue. With the technology put in place, I took on more and more challenging recipes over the summer. The best thing I ended up making was hickory smoked pork spare ribs that I cooked following the 3-2-1 method. I coated the ribs with my favorite dry rub and smoked them with hickory chunks for three hours, then wrapped them in foil with some apple juice for two hours, and then finished them on some higher heat with some sauce. With colder weather coming, I’ll likely not be using the grill as much, but when I do, at least I can check the temperature from inside the house.