That’s a Black & Decker CTO4400B convection toaster oven. It’s not well liked amongst those that actually use their kitchen appliances for cooking. It does, however hit all the major points I was looking for in a reflow soldering device – it has top and bottom heating elements (with a combined output of 1500W), and it has a convection fan.

Reflow Toaster Oven

I’ve modified it to have 3 individual power cords – one for the convection fan, one for the top heating elements, and one for the bottom heating elements. All of the extra oveny electronics (thermostat, timer, etc.) have been disconnected. The neon power lights (it has 2!) were retained for indicating when each of the heating elements is on (one light for the top, and one for the bottom). As far as I can tell, it doesn’t have a single safety device – not even a fuse (thermal or otherwise) – so there’s little risk of any protection devices unexpectedly tripping during a reflow cycle.

Control hardware

Reflow Oven Controller

It doesn’t take much to build a closed-loop controller for a reflow oven – really, only about 3 things: something to modulate the oven’s power, something to sense the oven’s temperature, and something to orchestrate the whole operation. And an oven is a slow enough device that none of those components needs to be especially exotic.

Since I was in the market for a tool and not yet-another-project, I chose my components based on ease-of-use and performance, rather than absolute cost.

For power switching, solid-state relays were the device of choice – they’re easier to use than a relay, but give you the performance of a triac. I had a couple of RA2450-D06 SSRs left over from my days of building Tesla Coils – they’re capable of switching 240V at 50A using just an isolated logic-level input. That’s a bit overkill (I only need around 120V at 10A) – but at least I know that the SSRs will likely survive even the most catastrophic of oven failures (the 15A in-line fuse that I added helps with that, as well). There are two separate SSRs; one for the top, and one for the bottom. The convection fan is always powered.

Temperature sensing is handled by two Type-K thermocouples from McMaster-Carr (model 9251T93). Only one sensor is really required (the control algorithm I’m using only relies on one); the other is primarily provided for diagnostics (e.g. evaluating temperature uniformity in the oven). The thermcouples’ wiring is quite stiff (20awg wire), which both helps and hinders the positioning of them (depending on where you’re trying to put them in the oven). Lower-gauge thermocouples may be preferable (if only to improve responsiveness by reducing thermal mass).

To interface the thermocouples to a microcontroller, I’m using two of Maxim’s MAX6675 chip. They’re cold-junction-compensated thermocouple ADCs with an SPI bus interface. They’re expensive ($12 each!), but make thermocouple interfacing into a trivial task. I haven’t actually designed a custom PCB for my reflow controller yet, so I had to use some SOIC adapter boards to mount the ADCs to my breadboard.

Reflow Oven Controller - closeup

Control is provided by one of Paul Stoffregen’s fantastic Teensy++ 2.0 boards. It’s a breakout board for one of Atmel’s USB-enabled AVR microcontrollers (an AT90USB1286). They come pre-programmed with a USB bootloader, so no other development tools are required. A reflow controller is hardly a demanding application, compute-wise, so any microcontroller could really be used here. AVRs are my default microcontroller choice.

Firmware

The firmware I’ve written for the AVR implements a complete self-contained closed-loop PID controller.

SSR control

The most timing-critical portion of the code is the logic that drives the solid-state relays. Since they’re triac-based (they won’t shut off until a zero-crossing), the fastest they can usefully be driven is about 120 Hz. Furthermore, these particular SSRs are designed so that they will only turn on at zero-crossings, as well – so finer-grained phase control isn’t an option. One of the AVR’s timers is, thus, setup to produce a ~120 Hz interrupt.

In order to offer smoother control over the oven’s power output, a crude form of PWM is implemented (actually, it’s more of a crude form of pulse-density modulation). Each 0.25s interval is divided into 30 AC half-cycles (the smallest unit of time that the SSRs can switch). Then, depending on the desired power level, each SSR is enabled for some evenly-spaced integer number of those half-cycles (0 cycles when off, 30 cycles for full-power, 15 cycles for half-power, etc.).

The code has a provision for synchronizing the AVR’s internal timer with that of the actual mains AC waveform. The timer can be run at a slightly lower frequency (e.g. 119 Hz), and an external interrupt can be used to reset the timer. The external interrupt would be driven by something that samples the AC waveform, looking for zero-crossing events. If one were using a low-voltage transformer to power the controller, the transformer’s unfiltered outputs could be used for this exact purpose (with a little signal conditioning to limit the voltages applied to the AVR).

My controller is currently powered solely from USB, so it has no concept of where the zero-crossings are. This can create some strange beat-frequencies as the ~120 Hz timer’s phase slowly varies relative to the AC phase – but, in practice, it doesn’t have a significant impact on the controller’s operation (it’s a lot more obvious when driving a more.. visible.. load, like an incandescent bulb).

MAX6675 interfacing

The choice of quarter-second intervals isn’t entirely arbitrary. The MAX6675 devices have a relatively simplistic interface, which doesn’t provide any indication of when a conversion is complete – and if you try to read from them before they’re done converting, you’ll wind up with an incomplete conversion (corrupted or just less accurate? I haven’t tested this). The chip’s worst-case conversion time is specced for 0.22s, and 0.25s (4 Hz) was the nearest interval that mapped cleanly to an integer multiple of AC half-cycles (for both 60 Hz and 50 Hz utilities).

Both MAX6675 devices are attached to the AVR’s integrated SPI controller. They’re read in sequence at the beginning of each 4 Hz update. Reading each chip also triggers a new conversion (to be read on the next iteration). The system performance requirements are low, so the code just busy-waits until each SPI transactions is done. If these chips were being used in a system that had more compute requirements, you’d want to switch to an interrupt-driven methodology (or, at the very least, execute some other useful processing code before entering the busy-wait loop).

PID control loop

Since updated sensor readings are only available at 4 Hz, that’s also the rate that the main PID control loop runs. The control loop is based loosely on information presented in Tim Wescott’s excellent PID without a PhD article. On the AVR, I’ve implemented it using purely integer math. All of the control-loop constants are rounded to power-of-2 values, so that bit-shift operations can be used instead of costly divide (and less-costly multiply) operations. At 4 Hz, you might even be able to get away with using software-emulated floating-point operations, if you’re so inclined.

I actually had the control-loop designed and most of the firmware written before I had even received all of the needed hardware (like the thermocouples). I was anxious to see some sort of results – so, in order to test and tune the control loop, I built a rudimentary simulated toaster-oven in Python. By having it modeled in software, I was able to do a lot of automated tuning by having the program rapidly evaluate a whole slew of different control-loop parameters. For each set of parameters, the simulation recorded a variety of metrics (max overshoot, max undershoot, average error, stability, etc.). Those metrics were then used to select an “optimal” set of parameters.

Reflow oven profile

Above is a plot obtained when reflowing a real circuit board using Kester EP256 lead solder paste (probably my FMC-LPC to SATA adapter board). “Optimal” isn’t exactly the first word that comes to mind – maybe “sufficient” is better (it does reliably reflow boards, so it’s hard to complain). The model that I used for tuning isn’t perfect, of course (it started out as pure intuitive guess-work, after all). It certainly doesn’t help that thermal systems like this are extremely slow to respond. Time-permitting, I’ll be investigating more robust control methods in the future.

The biggest concern on that plot is the oscillation in the slow preheat zone (it isn’t much of a functional issue, but it sure looks bad). During the quick ramp up to the peak temperature in the reflow zone, the oven isn’t able to keep up; a less-aggressive profile may be needed. The overshoot after reaching peak temperature is reasonably well-controlled (overshoot was an especially important metric when I was optimizing the parameters).

As a consequence of that conversative tuning, however, the oven is consistently under the target temperature during most of its ramps. Beyond the reflow zone, during cool-down, the control algorithm is essentially irrelevant (the hardware can only add energy to the system, and has no way of rapidly removing it). The rapid drop-off in temperature is due to my opening the oven’s door.

Profile generation

The actual reflow soldering profile is hard-coded into the AVR. The profile is planned out in a spreadsheet, then converted into an array of constant values for the AVR. Each linear segment of the reflow profile is represented by two values: the duration of the segment (in quarter-second control-loop-time-units), and the rate of change in temperature-units (1/1024 degrees each) per time-unit.

For example, a ramp from 25 C to 125 C over a 200 second interval would be encoded as { 800, 128 }:

That conversion is normally handled by software (e.g. equations in the profile planning spreadsheet).

The profile data is (clearly) designed to simplify the profile code on the AVR. Each 4 Hz update-cycle, the profile is also advanced. The current target temperature is adjusted by the rate-of-temperature-change parameter for the current profile segment, and the time remaining for the current profile segment is also updated. When the segment runs out of time, the code moves on to the next segment. Once all segments are executed, the entire profile is done and the oven is turned off.

Communications

While the AVR could operate completely stand-alone (with the minor addition of a button to trigger the reflow profile), I wanted to have more real-time monitoring capability

The command/control channel has minimal bandwidth/latency requirements – so a lowest-common-denominator, nearly-universal interface was chosen: serial. Not RS-232, though – rather, the AVR’s USB interface presents a virtual serial port to the host computer. From the computer’s perspective, it’s just a dumb RS-232 serial port. From the AVR, it’s a bit more complicated.

Fortunately, USB-enabled AVR microcontrollers have very good (and free) libraries available for implementing various USB peripherals. LUFA is, by far, the most feature-packed AVR USB library. I didn’t really need feature-packed, however – I just needed a serial port. Paul has written a light-weight and easy-to-use USB serial library for his Teensy boards, which I’m using in my firmware.

The communications protocol is, likewise, quite simple – pure human-readable ASCII. The AVR accepts a few commands for starting/pausing/resetting the reflow controller. It has additional commands that allow for manual control of the oven (e.g. manually specifying the target temperature, or even specifying the raw commands to the SSRs). There are even a few hooks for using a virtual toaster-oven (as provided by aforementioned Python toaster oven simulator), instead of external hardware (this feature was used for testing the AVR implementation of the control loop, before testing it with real hardware).

The only feedback provided by the AVR are periodic (once every 4 Hz update-cycle) status messages. The messages include most of the controller’s state (anything that might be relevant to the host), including: operational state (idle/running/done), elapsed time, target temperature, current temperatures, and current SSR commands.

The communications logic is coded so-as to prevent any interference with the reflow control logic. The reflow logic is always triggered by a timer interrupt, while the communications code runs exclusively in the main loop. All communication between the two contexts is non-blocking. When a host isn’t connected to the virtual serial port, the main loop will block – but the reflow code will continue executing. Thus, a failure of the host shouldn’t cause a reflow operation to fail.

Porting

Most of this code should be easy to port between different AVR microcontrollers. Pin mappings would probably need to be changed, but the peripherals used are readily available (a 16-bit timer and an SPI controller).

The communications code would be the hardest to port. If moving to a non-USB AVR, you could modify it to just use one of the hardware UARTs. Or, you could remove the communications code entirely (at the expense of having no ability to connect to a host for monitoring/control).

Software

Reflow oven controller GUI

The host-side monitoring and control program is a simple Python application. It uses Nokia’s Qt GUI toolkit (via PyQt). The plots are generated by Qwt plot widgets. PySerial is used for serial communications with the AVR.

Being the 2nd Python program I’ve ever written (the 1st was the aforementioned toaster oven simulator), this program doesn’t have a lot of features or flair – but it works well enough. It provides temperature plots (including the current target temperature, and the actual sensed temperatures), and SSR power plots (both the command output of the PID controller, and the individual top/bottom SSR commands). It has numeric readouts for the current temperatures. It has sliders for manually specifying temperature targets, or manually specifying SSR levels. And, it has buttons for changing the controller’s state (the most important being the “Go” button, which starts a reflow operation).

It also automatically logs all operations to time-stamped CSV files (one-such CSV file is the source of the reflow profile plot you saw above).

A separate QThread is used to handle serial communications. The thread uses QT Signals to send events to other program elements upon receipt of a new status message from the AVR. Signals are also used for event handling between other GUI elements.

The program works fine in operation, but has a few issues on exit that I haven’t been able to debug yet. They all appear to be due to threading-induced race conditions (e.g. the application exiting before the communications thread has completely finished). This doesn’t hurt anything in practice, but it’s not up to my usual exacting standards.

Don’t mind the misaligned SOT-223 regulator; I’m reasonably certain that the oven played no role in that.

Downloads

All of the C code for the AVR microcontroller and the host-side Python code is available under a BSD license from my reflow_controller Mercurial repository (you can also directly download a ZIP snapshot of it).

In addition to the code, the OpenOffice spreadsheet used for generating the reflow profile is also included. An example CSV oven log file (the one used to generate the reflow profile plot above) is there as well.

I’m not quite yet ready to release the toaster-oven simulator program yet, as it’s in dire need of refactoring.

Update: 2011-06-16: Someone over on fclab.ru has extended my reflow oven control firmware to support stand-alone operation with an LCD and buttons. He designed a custom PCB with an on-board triac for it and put together a nice enclosure for the whole thing. It’s topnotch work! Source-code and a schematic are available for download there. The writeup is in Russian, but Google’s translation is actually half-decent.

Whenever I get around to converting the controller to a proper PCB (rather than this breadboarded thing), I’ll create and post the EAGLE design (including schematic).

In the meantime, someone else has leveraged and extended my firmware to create a standalone controller (complete with LCD and the like). He’s posted complete schematics and firmware. The writeup is in Russian, but Google has an okay translation.

Just curious – I see that you’ve got a cord for control of the convection fan, but no SSR to control it. Do you plug it into a regular outlet and let it run continuously, or is that a provision for future tweaks…?

Dan, thanks so much for taking the time to document your project. I am doing a similar one now but of course a little bit different.

There is a really good idea posted in buildlog.net in which member lasersafe1 increased the power of the elements by simply trimming the coil of wire inside the elements down until 2kW power was reached. I have done this to my $40 B&D oven and brought it up to 1900Watts.

You just need to have some butt-splice connectors with the insulation removed. I found that checking the resistance of the elements was not reliable using a DMM. I used a current source to put 1A through and then measured voltages to find the spot to trim the elements to.