# 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.