# TheÂ GrillÂ

After lusting after a Traeger for some time, the Traeger sales men at Costco had my number. Â The primary resistance happened to be tagging along, and saw the look on my face that I was going to be walking out the door with a Traeger Junior. Â Somehow she convinced me to think it over while we shopped. Â I do have to admit when she is right, and we walked away with the Traeger Century, twice as large as the Junior.

The Traeger is a smoker that burns wood pellets. Â It is simple to use, almost inspired by the Ronco slogan. A couple of hours at low-and-slow can result in some delicious BBQ.

The cooking station is a steel cylinder. Â The meat sits on grill grates, which are suspended above the firebox. Â Small pellets (think rabbit food) are fed into the firebox by an auger from the pellet storage. Â During startup, an electric ignition hotrod ignites the pellets. Â Since this is an exothermic reaction,the firebox fire is self sustaining after ignition. Â A small fan run continuously to provide oxygen to the firebox, and force the smoke to flow from the bottom of the cylinder out the chimney. Â Therefore, there are only 3 electronic components, the fan, auger, and igniter. Â All 3 components run at 120V AC.

The name of the game is low, steady, heat. Â The temperature of the grill is regulated by augeringÂ more pellets in to the firebox. Â The original Traeger controller had a few settings, that corresponded to particular auger duty cycleÂ (the auger is either on or off). Â However, there are many factors in play such as outside temperature, wind, and pellet type. Â Therefore, open-loop control is not very effective. Â Traeger introduced the "elite" line, which offered digital controllers. Â By adding a RTD temperature probe to measure the grill temperature, the controller is able to vary the auger duty cycle with the goal of maintaining a set temperature. Â However, the interface remains simple, with a knob that changes the set temperature. Â Furthermore, the Traeger digital controller implements simplicit control algorithms, has can easily swing +- 50F.

# The Goal

Much like Everest, my new Traeger immediately needed a new controller, because it was there. Â I was certainly not the first to add an aftermarket controller to Traegers, often with impressive results. Â Although there were off the shelf solutions, what fun is that? Â My goals:

• Tighter temperature control (+- 10F)
• Internet control
• Grill and meat temperature plotting

## Platform Selection

The controller has to be capable of toggling 3 relays, reading two RTDs, and performing simple calculations. Â Additionally, I want it to have WiFi capability for backhauling this information. Â

When you start talking about DIY controllers, a microcontroller such as theÂ Arduino always pops to mind. Â However, perhaps only similar in size and relative cost, the a minicomputer such as the Raspberry Pi is also capable of achieving similar results.

# The Hardware

With the RPi selected, all that was required was to fill in the gap between the Traeger and the RPi, which wasn't too difficult.

## Traeger Control (Output)

As mentioned earlier, the Traeger has 3 components, the fan, auger, and igniter that run at 120V AC. Â These components connect to the controller (any controller) with a total of 4, 2-Pin molex connectors (AC + 3 Components). Â However, the RPi is not capable of switching 120V. Â Therefore relays would be required. Â At another level of annoyance, most relays run at 5V to reliably energize the relay coil while the RPi General Purpose Input Output (GPIO) pins operate at 3.3V.

However, a little relay board, similar to one by SainSmart comes through to save the day. Â It is capable of switching large loads at 120V, can take a 5V power supply and the input pins are simply connected to ground to energize the relay. Â Fortunately, the RPi has a 5v output (from the power supply) and can be used to trigger the relay. Â Since each board can switch a pair of relays, two boards were needed.

### Part List

Item Part Quantity Price Subtotal
Relays SainSmart 4-Channel Relay 1 $8.99$8.99
Plug Molex Plug 4 $0.27$1.08
SSOP Breakout SSOP20 to Breadboard Breakout 2 $5.42$10.84
Pins Molex Pins 8 $0.13$1.04

## Power

The RPi requires a (quality) 5V input. Â Typically this is provided over a micro-usb header. Â Conveniently, the relay boards can be powered from the RPi 5V GPIO pins. Â However, the Traeger provides us with 120V AC via a molex connector. Â Rather than add an ugly USB power supply externally, I added a AC/DC 5V 20W power supply to the circuit.

## AssemblyÂ

I began prototyping on the standard breadboards with 0.1" hole spacing. Â However, lose wires are a receipt for disaster. Â I certainly didn't want to debug a lose connection years down the road. Â A PCB would have been a great solution, but the effort and cost were not justified. Â Therefore, I used a solderable breadboard which has the advantage of permanence and transition from the prototype breadboard.

An Adafruit Cobler was used to provide an interface for the RPi. Â This provides access to all of the GPIO pins via a 40-Pin IDE cable.

### Part List

Item Part Quantity Price Subtotal
Breadboard Solderable Breadboard 1 $6.5$6.5
Cobbler Adafruit Pi Cobbler Plus 1 $6.95$6.95
Jumpers DC Connections
Wire 18 GA for AC Connections
Misc
Total \$13.45

## LCD Display

You may wish to add an LCD for direct control from the smoker. Â I find that I rarely actually use the LCD/button on the device, and primarily use my phone. Â The Adafruit LCD Kit is a great use, and the PiSmoker software is written to take advantage of it. Â The LCD connects using the IC2 bus, and requires 5V power. I leave it up to you to implement the waterproof casing and external buttons.

## Wiring Diagram

Where's the beef? Â Well, you aren't getting it. Â A good wiring diagram would do wonders for repeating this project. Â However, it would also discourage understanding the logic. Â Plus, since good wiring diagrams are hard to make, I am going to skip that step. Â However, the connections that need to be made.

• Traeger AC -> AC/DC Power supply
• Traeger Fan -> Relay Board
• Traeger Auger -> Relay Board
• Traeger Igniter -> Relay Board
• 5V DC Power -> RPi, Relay Boards
• 3.3V DC Power -> MAX 31865s
• SPI: MISO, MOSI, CLK, CS1 & CS 2 -> MAX 31865s
• Resistors and Caps for MAX 31865 (See datasheet)
• RTD -> MAX 31865
• GPIO for Fan, Auger and Igniter -> Relay Boards [Double check with PiSmoker.py]

I suggest you understand the flow of information, study the MAX 31865 datasheet, and make the connections. I realize this is probably unsatisfying, and I'd be happy to post a good wiring diagram if someone else makes it.

# Software

## Implementation

A Raspbian based linux distrubution was used on the Raspberry Pi. Â DietPi was select since it is relatively lightweight, however, I am a bit concerned about the long term maintenance. Â Therefore, if I were to do it again, I would likely us Raspbian lite. Â However, the goal was to keep the installation as light-weight as possible, avoding booting a GUI and other unnecessary services. Â Python was used for the PiSmoker implementation. Â The required code, and modules is available on GitHub. Â The script runs as root, primarily due to access control to access the underlying pins.
The local service reports states (temperatures, on/off toggles, etc) to a great webservice, Firebase. Â Conversely, the client pushes parameters (hold temperature, mode, etc) to Firebase, which PiSmoker implements. The web clients use a static HTML/JS page that interfaces with the Firebase database. Â Therefore, PiSmoker does not need to be internet addressable, and the load of serving content is handled by Firebase. Â I have been extremely impressed by Firebase, and think this is a perfect use.

## Modules

The smoker application, known as PiSmoker consists of a few modules that run on the RPi:

• PiSmoker.py - Main loop that handles communication with the Traeger, RTDs, and Firebase.
• Traeger.py - In the spirit of future extension, the toggle of states (fan/auger/igniter) is handled by this library. Â In this implementation, it toggles relays.
• MAX31865.py - Subprocess that initializes each MAX31865 RTD, and reports the current temperature.
• PID.py - This module provides a fairly straightforward PID implementation. Â It is initialized with PID parameters, is updated with the current reading, and responds with a new command.
• LCDDisplay.py - Subprocess that displays pertinent information of interest to the operator. Â Also updates PiSmoker parameters on button push

In my opinion, most of these modules are fairly self-documented. Â Therefore, I suggest that you read through them and understand what is going on.

## PID Controller

I spent more time thinking about this than I would care to admit. Â PID controllers are commonly used in industry, and calculate control based on the Error in a Proportional, Integral, and Differential sense. Â While PID basics are easy to understand, very few implementation examples are provided. Â What I finally settled on is cobbled together from Wikipedia, Control Texbooks, and the experiences of the fine folks at Pellet Heads.

W have a Process Variable (PV) that we want to control [Grill Temp] to the Set Point (SP) [Target Temp]. Â We can calculate the Error (E) as the difference of the two:

error = GrillTemp - TargetTemp

IF the GrillTemp is at the TargetTemp, no need to make any changes. Â The controller gains, $K_p, K_i, K_id$ are defined by the operator. For a timestep $dT$, the proportional component of the new command can be computed:

The integralÂ component sums up the error over time:

The derivative component attempts to predict the future position based on the change in error:

The new command, $u$, can be calculated as the sum of each of the PID components:

A couple of quick thoughts on what this all means in our context. Â What is the command, $u$? Â How can we control the grill temperature? Â Well, the only thing we can do is turn the auger on and off. Â Therefore, $u$ is defined as the augerÂ duty-cycle. Â Therefore, it is the proportion of the time the auger is on. Â A command of $1.0$ would be constantly running the auger, so maximum temperature. Â A command of $0.0$ would turn the smoker off.

It appears to be more common to use different definitions for the gains, rather than $K_p, K_i, K_d$ directly.

• Proportional Band ($PB$): This is the temperature band centered around the set point, that the controller is active. Â If the error is greater than $PB/2$, the command is $0$. Â If the error is less than $PB/2$, the command is $1.0$
• Integral Time ($T_i$): Time (in seconds) to eliminate the integral error.
• Derivative Time ($T_d$): Time (in seconds) to predict the future value.

These three parameters can be used to calculate the appropriateÂ  $K_p, K_i, K_d$ values.

So, what is that $0.5$ doing hanging out in the P term? Â This centers the control at 0.5 if there is no errors. Â While this is likely not the case, it provides a starting point. Â The integral term will produce a constant offset to determine the steady-state control signal.

While PID control is (relatively) easy to understand, tuning is not. Â Therefore, I leverage what other values had been used for Traegers. Â I stand on the shoulders of giants, and used the recommendations from BMerril onÂ Pellet Heads.

## Firebase Authentication

Firebase defaults to allowing all users read and write access. Â To limit write access to those authorized, add the following to the rules:

{
"rules": {
".write": "auth !== null"
}
}

The PiSmoker and webclient use Firebase tokens for authentication. Â Firebase provides documentation for generating each token.

## Web Client

The webclient is a static HTML page with several custom JS scripts to provide realtime updating. Â The client pushes and pulls from Firebase. Â The webclient is available in the GitHub repository, and can be served from anywhere. Â In fact, the FireBase static hosting would make the most sense.

The web client displays the current grill and meat temperature, and their history. Â It shows the current status of each of the Traeger states (fan/auger/igniter). Â It allows the operator to set the current mode (temperature hold, smoke, etc) and the appropriate parameters. Â If desired the operator can queue up commands in a program, with specific targets, such as time or meat temperatures, to advanced to the next mode. Â In general, it is simplistic, but suites my needs well. Â It works well on my phone as well.

If the user accesses the URL without an authentication string, they are only able to view your progress. Â If a "?" and then a firebase authentication token is provided (and verified), they will be able to change the smoker settings. Â Be careful with this!

## What needs changed

For the most part, PiSmoker was written to be as generic as possible. Â However, every implementation is different. Â You should be able to get away with changing the following:

• PiSmoker.py - The top 20 lines allow you to set static parameters. Â This will let you change the RPi pins associated with each relay, etc.
• f = open('/home/pi/PiSmoker/AuthToken.txt','r') will read the Firebase authentication token (required)
• firebase = firebase.FirebaseApplication('https://pismoker.firebaseio.com/') This should be changed to target your Firebase instance
• www/js - These files should be updated to target your firebase instance.

# Conclusions

It is a bit of a cobbled together set of tools, but they work together well. Â The end result is a controller that meets all of my goals. Â I can control the smoker remotely, and hold the temperature generally +-3F. Â Furthermore, I enjoy monitoring the process remotely. Â I love giving my guests the URL, and letting them know to come over when the meat is 165F.

I would certainly love your input. Â The code is free to use, and I'd love to incorporate any improvements you may think of. Â I also realize everybody has their unique style, and I am no different. Â However, if I little community popped up with PiSmokers, I would be more than happy to participate.

## 15 thoughts on “PiSmoker”

1. This is facinating! Beyond my abilities, but totally amazing. I'd be interested in purchasing one of these units.

2. Hi, I have some question on your PiSmoker project. On the FireBase setup do you have a list of the variables that I have to define in the FireBase DB or does the service just write them out as a JSON object. First time using FireBase and I'm trying to understand it a little better.

On another note... I've just about ordered all my pieces to create my PiSmoker! I have my Raspberry Pi and I'm off and running. I'm giving my project a name PelletPirate! I plan to add a 2nd meat thermometer so i can monitor a brisket and pork shoulder in the same cook.

If all goes well, I may contribute a wiring diagram to the project and some other tweaks!

I really want to thank you for posting all this great information. It's a huge jump-start!

3. Hi Brian,

I am glad to hear PiSmoker helped motivate PelletePirate! Adding another meat thermometer is a good idea. I have the parts, and intentions of doing that myself. Are you planning on using RTDs? I went with an RTD since that is what is in the Traeger. Just a heads up, the MAX 31865 uses SPI. The RPi only has 2 Chip Selects for SPI. However, I believe there may be some options to use other pins for CS.

Firebase will let you just write to variables without defining them. However, I believe the parent variable must be defined before you write to a child. For example, you can just write "Bob", but not "Steve"/"Bob" without defining "Steve" first. Firebase is great, and the web interface helps you visualize what is going on. For my implementation, I believe I can clobber the entire tree and everything still works.

Please keep me posted on your progress. I would be happy to get you an account here for you to document your progress.

4. This is super cool and I'm building one! Thanks for putting this together and sharing this info. I was thinking exactly similar project and was very happy to see this. I have made some progress, most of the electronics are done and working with your code and the back-end Firebase. Now I just need to box this thing up and hook up with the smoker. By the way, I decided to go with Pi 3, which has wifi already already included and I'm using Raspbian Lite. I also realized that you need to make sure you order reference resistor correctly and also those capacitors according to RTD probes you have. 1KOhm resistors did not really work for me, I had to get close to 400 and 4000Ohms for my PT100 and PT1000 probes. I did not have a heat gun, so I drag soldered the MAX chip, also first time for me, but it was surprisingly easy (well, I might have busted one, but I luckily had ordered an extra one)

• Tomi,

Thank you for the feedback. I am always glad to hear there is another PiSmoker out in the world. Please share pictures! (As I say that, I realize I don't have any final pictures in this thread).

I also went with 400 and 4k Ohm resistors for the reference. Sorry for the confusion, I should have included that. The MAX31865 recommends 4x the RTD resistance.

Best of luck. Please let me know how it works out.

Dan

5. Hi Dan,

It is up and working. You have done amazing job with coming up with the design and the software for this. Really fun project to do. Here is link to some pictures:

https://goo.gl/photos/D5hhu8swLLbDuYhUA

I do have few improvement ideas for the future (and I'm happy to work on these):

1. Change the code to use "Service Account" to log on to Firebase (or automate the token generation from the secret)
2. Change the web app code to support Google authentication
3. Change the code to report 0 as meat temperature if the meat probe is disconnected (now it jumps up to 1500). My meat probe can be disconnected.
4. Configurable temperature for meat ready and notification to mobile when is temp is reached
5. Notification to mobile if there is too big deviation from the set grill temperature

By the way the Power Supply that I have in the pictures did not work properly, I changed to something similar to what you are using. The enclosure that I got from Adafruit is a bit tight for all the components, also it gets quite warm in the sun. I will keep my eye on the CPU temp to see if I need to do something about it.

Cheers,

Tomi

• Hi Tomi,

Excellent work! It eerily similar to mine!

I am glad to hear that everything went together smoothly.

I agree that the Firebase authentication could be smoothed out. I went with the simplest option (outside of wide open), and never got around to anything better.

The mobile notifications is a good idea. I had a short with my button setup (which I rarely used, so I simply commented out the code that read them), which resulted in ruining a large July 4th brisket. Ooops. I'll have to give some thought to an easy way to send notifications. Text or email would work great, but require 3rd party services.

Best of luck. Please keep me posted as you toss some meat on the smoker.

Dan

6. Wow this looks amazing, I need to build this!

I'm familiar with Linux, databases and a bit of Python programming, but not so much with the hands-on stuff. Could you help me out with how to figure out which resistors and capacitors to get for this project?

Based on the comments below this post, it looks like I need to find a 400 and 4000 Ohm resistor. Your original 100 Ohm resistor has a power rating of 1/8 W and a tolerance of 0.1% Does that hold for the 400 and 4k as well? If so, these Mouser part number should do the trick:

400: 71-RN55E4000B
4k: 71-RN55E-B-4K or 71-PTF564K0000BYEB (that last one is different 'series' with lower coefficient, no idea how crucial that is)

For the capacitors I'm not sure at all what to get. The spec sheet lists 10nF and 100nF for the 2 RTD's..

Hope you can help!

• Hi Erik,

I hope you decide to dig in. Consider this poor documentation part of the fun ðŸ™‚

For resistors, you likely can't go wrong. However, I did go with higher tolerance for the reference resistors. However, I don't think that is necessary for the rest of the resistors, so you probably can save a bit of money there. .

For the capacitors, it looks like I have 0.1uF and 10 nF listed. That is the same as 100 nF and 10nF.

Best of luck!

Dan

7. Hi dborello,
this is a very nice project. IÂ´m from Germany an i have also a traeger smoker.
where kann i download the img for the pi with all software?
MAX 31865s - i donÂ´t understand the connektion of the two 31865! i buy from https://www.adafruit.com/product/269 two breakout boardÂ´s. Do you have a sample Picture vor the connektion?
thank you

• Martin,

I do not have an image ready to go.

The link you provided are for MAX31855, Not the MAX 31865.

Honestly, it is a pretty cobbled together project. This post should get you started, but there will be some learning along the way.

Best of luck.

8. I have been wanting to do something like this for a while. I was never happy with the Traeger controller.

Here's an idea for your next iteration, if possible. Use of any number of sensors to detect when the hopper is getting low on pellets. Could be something along the lines of an ultrasonic sensor on the lid to give a real-time sense of how full the hopper is, or just a light sensor somewhere below the half full mark to alert when the hopper is low.