Who doesn't love smoked meats? Yes, I'm ignoring vegetarians and vegans. Who doesn't love them more when you don't require any skill to maintain temperature for the 6+ hours of cooking?
I picked up a Brinkman Gourmet Electric Smoker on an impulse one day. It's a steel can with a 1500W heater, a water pan, and some racks for food. For under $100, it's a reasonable device for getting really fantastic food. However, it only has one setting: about 250F degrees, and that depends a lot on the outside temperature. You see, the heater gets HOT, and when that heat rises, it hits the water pan and the water eventually boils. That barely at temperature steam rises up and mingles with a bit of the 400F degree air and you wind up with about a 250F degree cooking temp. 250F is great for pork, beef, and most other smokeables... but not fish, and not if you want to get a really thick bark on your meat.
Enter the Smoke-O-Tron; a PID controller that can handle the 1500W heater to within about 3 degrees F.
Step 1: Hardware Selection
OK, so what do we need to do? We need to control temperature in a large air mass using a 1500W heating element.
What does this entail?
1] Measuring temperature in the space
2] Switching the heater on and off at a given speed
3] Having the temperature be easily adjustable: Digital.
Since I wanted a digital read out, I was going to need a Micro Processor on this one. I haven't used one since I was an EE, and even then I spent most of my time keeping large industrial robots from running me over, which really limited my exposure to the actual processors. I went with the PICAXE 18 line for this one. It seemed to be what I needed, but the development language it uses really limits what you can do with the micro (e.g., couldn't set interrupts). This was kind of an annoyance, but for the precision needed here, it wasn't a deal breaker.
The thermometer was selected to be a K-Type Thermocouple. They tend to be rugged and are good to well beyond the range of temperatures in the smoker. To interface, I went with a Max 6675 Thermocouple Interface IC. This interfaced with SPI to the micro. The PICAXE doesn't do hardware SPI, so I bit-banged it.
Next, the display. The usual 20x2 display seemed enough for this task. The chip almost lacked enough pins to talk parallel to the LCD, so I got a serial one from SparkFun, just to make sure. Again, probably something I'd do differently, but there ya go.
For a relay, I figured that I would leave this thing running for about 8 hours at a time with a switching time of 6 seconds. That's about 2880 on/off cycles for a relay, and with anything reasonable being rated at 20,000, I figured I should look at solid state relays. I picked up a 250V, 20A model from Digikey (about $40), but since then I pick them up on eBay for about $10 with heat sink.
Finally, I went with a rotary encoder for user interface. I was always a fan of "knob with a button" interfaces, and this one was a good way to go.
The power section is your basic AC supply. There's a MOV in there for surge suppression, but you can leave it out. I have no idea why I left it there.
Step 2: Software Annoyances
The software should be fairly easy: in a loop figure out if it's time to do a PID cycle, do it; check if the output PWM needs attention, then handle that; otherwise, check to see if the UI needs attention.
In practice we have a couple of issues on the PICAXE.
1] There are no timing functions, outside of the delay functions.
2] There are no real hardware interrupts you're allowed to play with
3] The "soft" interrupts are really slow and you can only have one defined.
4] Variables are registers. If you want to use RAM, peek and poke out of it
5] Serial output is bit-banged and hangs the code for the duration of the transfer.
6] We can only use 16 GoSub calls in the software, or lose some program space elsewhere.
The last one was easy enough to fix... I got rid of as many GoSubs as possible by in-lining some code.
So, to get around the timing aspects, I found a post on the forums on how to peek/poke the hardware registers to run the timer. We'd still have to poll for overflows, but it's better than nothing.
Next, Since we can't define real interrupts, we had to make the best of the one we had. I put it on the "A" side of the rotary encoder. Every time the knob moved, it should trigger an interrupt and seeing if the"B" side went high or low would tell us the direction. If you move it too fast, it will lose track, but that's what we got.
The button is polled. Nothing exciting there. We simple keep track of how many counter overflows it's been held down to see if it's been held down a little or a lot.
#4 is inexcusable in a high-level language. The compiler should be handling this unless I tell it otherwise. Because of this, you will see a bunch of loads in and out of memory throughout the code.
The serial delays are fairly serious. This means that if you write more than 2 characters to the display, you will lose a timer overflow. I didn't bother to work around it. The PID timing is not precise, and neither is the PWM timing... however, it's less than 1% deviation, so it's fine in this application.
Step 3: PID Logic
The PID is the heart of this code. The basic theory is that you consider three factors to figure out how much heat to apply to the system:
1] how far away are we from the target setting?
2] how fast are we getting there?
3] How much have we been consistently off?
OK, so first off, since this is an 8-bit micro that can handle a few 16 bit registers, we represent the temperatures as the temp multiplied by 64. This is called fixed point math, since we're just shifting the decimal point. A 64x multiplier lets me get a temp up to 1024 degrees with 5 bits of decimal points (1/64th per division). Since the temp sensor is giving us 2 bits of decimal, this is plenty of precision for what we're up to.
When we calculate how much to heat the space (The power demand), we begin with the proportional gain. To get this, we subtract the target temp from the current temp and multiply by the gain setting. As we get closer, we add less and less heat. Running this by itself will, however, leave us with an error. If the gain is too low, then the error will be nearly constant. Too high, and it will oscillate. It's important to make sure when you do this math that you be on the look out for overflows on the registers. If your gain is 1024 and your reading is 16C, the math works out to well over the 65,535 you're allowed to go. So be sure to limit all values to sane ones.
To prevent oscillation we add the Derivative portion. The derivative of the temperature is a measure of how much it's changing. So to do this we save the last reading and subtract it from the current one. Now, we multiply that by the derivative gain and get a measure of how much of the proportional gain we need to get rid of to prevent overshooting the target temp.
Finally, that little bit of error that will always be present when you use only P and D portions can be removed by adding a factor that comes from how far off you've been. While handy for holding the set point, it cannot be stressed enough that because it accumulates, the integral gain has the potential to cause problems faster than anything else. Think about it: You start the system and it's 82F, but you've set it for 225F. For the 45 minutes it takes to come up to temp it's piling on more gain.
We avoid most of this by two simple methods:
1] Limit the I portion to something small... no more than about 10% total available gain
2] Don't accumulate I gain if the temperature is moving in the correct direction.
The second bit there is not standard, but it seemed to work best in this application.
Once you have all the gain components added up, convert to an output value.
Step 4: Building for Testing
You can pick up the same case at any home improvement store. I took a Dremel to the front panel to make the cut outs. I'm ashamed to say that I was sober and yet the cuts came out that badly.
So, how do you test this? Having a massive smoker in your house may not be convenient. I used a small Tiffany lamp. Tape your thermocouple above the bulb and maybe throw a cloth over it. This will make debugging the PID loop that much easier.
Step 5: Building a Real Version
So next, why not get this made up for real? I decided to give BatchPCB a try. Sure enough, I got back a working board. While selecting parts, I decided that since I was going to put on at least one SMD part, I might as well get the rest as SMD as well. SMD parts tend to be cheaper than the through-hole counterparts, so it was a no-brainer. Baking the boards was decidedly easy. My instructable is located elsewhere on the site .
Step 6: Making the Case Better Looking.
How do you finish this up and make it all sexy looking? Answer: Have your friend with a CNC machine take care of it for you . He did a fantastic job.
Thanks for taking a look through this. I hope this helps people. Please feel free to comment and ask questions. I'll try to answer what I can.
Step 7: Conclusions and Final Thoughts
OK, there are definitely some things that I would have done differently, but over all , the system works well.
1] Go on eBay and buy industrial thermocouples. The bare ones are nice for testing because they're fast, but the kiln thermocouple was far more convenient in practice since you can effectively forget about them. In fact, if I had to do it over again, go on ebay and buy a ready-made PID temperature controller and SSR and then just wire those up. This doesn't need .1 degree accuracy and it'll cost less and be done in a day.
If you've ignored that bit of advice and feel like doing it for the experience...
2] It helps to get in and really dig into a microprocessor to figure out which one works well for your project. Yes, the PICAXE was easy to use, but it's designed for teaching kids robotics and doing some basic controllers. It's fantastic for that, but it's not the perfect fit for this project.
3] The AC supply was pretty basic and brute force. There's really no need for that much transformer, nor did I need anywhere near that much bypass cap reserve. Using something like a SuperTex SR087 swithing converter, I can get the same result for about half the cost of the transformer and it would take up less than a quarter the space.
4] Backlit LCDs suck on bright days.
5] The board was laid out like a noob. Dual ground planes save a lot of etching and the second layer was really not needed. I should have also just left space on it for the LCD so that it could be mounted better.
6] You can't solder to thermocouple probes, so again, buy the industrial ones that come with screw connectors and just have a terminal for them. The keyed connectors were terrible and got replaced pretty quickly.
7] The software works terribly on Fahrenheit mode. I'd probably just add another memory spot for the desired temp in the desired unit and convert to a target temp (in C) on the fly.
8] A built in timer and wireless paging system would be nice, but I'm against spending more on the networking that everything else.
Thanks for reading!