Reflow Soldering Arduino Code

The SparkFun IR component speaks a slightly different dialect of I2C that apparently requires the I2CMaster library. The reference link is here but I'm also going to post the version I used here in case the other link becomes orphaned.

The other link was a helpful "how-to" post at: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1214872633 by a fellow named "Sensor Junkie." Again this could vaporize so here is what he wrote:


====> snip

This looked a little intimidating at first but turned out to be really easy.....

I did the following steps:

1) Hardware:
Connect the MLX90614 (refer to the datasheet) as follows:
Pin 1 on MLX (SCC) connect to ANALOG pin 5 on Arduino
Pin 2 on MLX (SDA) connect to ANALOG pin 4 on Arduino
Pin 3 on MLX (VDD) connect to 3.3V on Arduino
Pin 4 on MLX (VSS) connect to GROUND on Arduino

Now use "pull ups" on the SCC and SDA lines by connecting a 4.7K ohm resistor from the Pin 3 VDD line to the SCC line and a 4.7K ohm resistor from the Pin 3 VDD line to the SDA line.

2) Software:
a) Download the I2c libraries as follows:

Go to:


and download the i2cmaster.zip

Make a folder in /{arduino root}/hardware/libraries and extract the

Make sure you restart Wiring if you load a new library into it so it can be found when it is called.....

3) Now you need to modify twimaster.c
Open it in a simple text editor and change the following if you are using an Arduino Duemilanove

Edit the twimaster.c to reflect the 16MHz clock, and change the bus frequency to 50Khz by changing the code at the beginning to:

#ifndef F_CPU
#define F_CPU 16000000UL

/* I2C clock in Hz */
#define SCL_CLOCK 50000L

4) Now copy Dave Eaton's EXCELLENT code into Wiring. You may have issues with seeing the new libraries or with missing brackets when you verify the code.
Dave's fix for the high precision (2 decimal place) thermal read also works well (this sensor is incredibly sensitive).

This is Dave's code as I used it:

#include <i2cmaster.h>

void setup()
i2c_init(); //Initialise the i2c bus
Serial.println("Return from i2c_init");
PORTC = (1 << PORTC4) | (1 << PORTC5);//enable pullups
void loop()
int dev = 0x5A<<1;
int data_low = 0;
int data_high = 0;
int pec = 0;

data_low = i2c_readAck(); //Read 1 byte and then send ack
data_high = i2c_readAck(); //Read 1 byte and then send ack
pec = i2c_readNak();

//This converts high and low bytes together and processes temperature, MSB is a error bit and is ignored for temps
double tempFactor = 0.02; // 0.02 degrees per LSB
double tempData = 0x0000;
int frac;

// This masks off the error bit of the high byte, then moves it left 8 bits and adds the low byte.
tempData = (double)(((data_high & 0x007F) << 8) + data_low);
tempData = (tempData * tempFactor)-0.01;
tempData = tempData - 273.15;
Serial.print((int)tempData); //Print temp in degrees C to serial

Upload the code in the Arduino making sure you are on the correct COM port (obviously). Open the serial port viewer (COM port correct?) and make sure the baud rate corresponds with the the baud rate in the code and you should be able to see the temperatures streaming live from the serial port.

BTW....Hooking up an Xbee is easy using the standard breakout board and Xbee to USB converter for the PC end of things. Just make sure all of the baud rates are the same (in the code and in the Xbee based on the setup in the XCTU program from Digi).

Thanks to Dave Eaton for making a fun afternoon successful, CalculusAE for a great trail of technical breadcrumbs and Peter Fleury for posting the libraries.

<==== end snip.


My Sketch

The sketch I currently use is here. Just unzip it and open it with your Arduino SDK. I also zipped the IC2Master library folder in my Arduino Library folder and it is here. You may have to recompile it per the instructions on the left but the source is all there.

Open the PDE (sketch file) from the link above so you can follow along and I'll outline the code. Basically the main part I borrowed from the example code in the how-to posts on the left is the part that reads the temperature. I haven't dug into all of the bit shifting therein to see exactly why it works. It just did and I lifted that part out as is, where is, to build my reflow controller. My design models the reflow "curve" in basically five phases. The "heart" of my code is the state variable "state" which progresses from the initial state of "0" through state "5". The main loop just consists of reading the temperature reported by the IR thermometer and a series of "if" statements that progress the state engine. The main loop also acts as a simple thermostat which turns the hotplate on until it reaches the current temperature setpoint and off when it is reached.

The first state is the ramp up of the temperature from ambient to the pre-heat temperature. The preheat temperature value is stored in the (double) variable preheatTemp. Currently this is 150 (deg C - all temps are centigrade.) So the logic just turns on the hotplate (hotplate pin=11 in my code) and loops until we hit the preheat temperature. I call this phase "ramp1" as it is the first ramp up of temperature. Upon reaching the preheat temperature we enter the preheat phase (state=2.) In this phase we start counting seconds (soakCount) until we achieve the desired preheat "soak" time (soakLimit=120). Then we enter the second "ramp" phase(3) by increasing the temperature setpoint to the solder temperature in the (double) solderTemp variable. In this example that is 215 deg C. Upon reaching the solder temperature we enter phase 4, soldering and start incrementing the solderCount for the desired number of seconds to remain at the solder temperature (solderLimit=60.) When the solderLimit time is reached the hotplate thermostat is disabled (running=false) and the hotplate is turned off and will remain off.

The program outputs the current count in seconds and the temperature setpoint and measurement as well as phase and AC power switch state as a tab delimited line each second. The idea is that you can cut and paste the serial monitor output into a spreadsheet and plot your reflow curve as it happened if you wish.

I originally just watched the serial monitor output but I later decided I wanted some visual indicators that I could watch more casually while doing other things in my shop so I added some code and state variables for a yellow and a red LED and connected them to pins 13 and 12 respectively. The idea here is simple. The yellow "preheat" LED comes on and toggles on and then off each second when I'm ramping up to the preheat temperature. Once it reaches that temperature and is in the "soak" phase it stays on. Then when the soak phase is over and the ramp up to solder temperatur begins, the yellow LED is turned off and the red "solder" LED starts to blink while the temperature is increasing. Then when the solder temperature is reached the red LED stays on steady state until the cool down and then turns off so that both LED's are now off. It turns out this is a very handy way to supervise the progress of the process without having to stand there reading the screen. It also allows operation without having to use the serial output monitor at all if so desired. Now that I've had several successful reflow sessions, I have the confidence that the program works reliably.

A word of warning here. No matter how reliable this may be, you never want to leave the hotplate unattended or un-monitored. If the program should freeze or fail for any reason, the hotplate could be left in the full on state and a fire could result. The first rule of cooking in my kitchen is that you never leave the stove unattended while it is in operation. The same rule applies here.

I suspect the code could be improved and condensed but I chose to write it with more verbosity for the sake of clarity rather than optimization. I find my biggest issues aren't with performance as much as returning to the code after a while and having to figure out what I was trying to do. So I went for maintainability vs performance, not that a simple thermostat requires much of the latter. Most of the time the code is processing the "delay(1000)" function.

One more thing, the "fudge" (double) factor is just that. When I hooked up the IR thermometer I compared the temperature readings it was giving by shooting the same spot on the hotplate and a scrap piece of PCB material with a commercial IR thermometer I have. I used a scrap piece of etched PCB to simulate a real target. Just shooting the blank hot plate will give different results due the the difference in "emissivity" of the material. I found the dark Teflon non-stick coating of the hotplate reasonably good but there is a slight difference with PCB material in the field of view. Also, don't use a non-etched scrap as the total copper surface is very reflective (low emissivity?) and will cause the temperature to read low.

To calculate the "fudge" factor I simply applied a ratio to the readings I got from the IR sensor to bring the temperature readout into substantial agreement with the commercial IR thermometer. I'm not sure why there was such a large difference in the raw numbers other than it may have something to do with the much wider field of view of the IR sensor vs the IR Thermometer (about 10x) but the important thing is that once "fudged" it tracks quite well over the temperature range.

Now if you don't have access to an IR thermometer I'd just start wth my fudge factor and put a bit of solder paste at several spots on a scrap piece of etched PCB. Your paste should have a specified melting point. I'm using ChipQuick (tm) SMD 291AX10 "no-clean" paste which is 63% tin and 37% lead. According to the manufacturer it melts at 183 deg C. With my setup I notice the first "silvering" of the melted solder paste when the temperature readout is between 185-190 degrees C so I'm close enough for government work. In my case I'm going up to 215 degrees anyway so I get a good melt.

There is a bit of thermal "lag" or "overshoot" in the temperature which is worse at lower temperatures. This is because I don't shut off the hotplate until the setpoint is reached and because the hotplate is actually "leading" the surface temperature of the PCB in the target zone and the temperature continues to rise a bit beyond the setpoint. It is quite common in my setup for the "soak" temperature to overshoot the 150 degree setting by 10-13 degrees. That doesn't appear to be critical and it is still below the melt point so I haven't moved it downward. You could anticipate the overshoot and split the difference by turning the hotplate off at say, 145 degrees instead but I didn't bother. Besides, if you examine the reflow curve the "soak" phase isn't flat but actually increases gradually so the overshoot actually tracks this more closely. I love it when a plan comes together. ;-)

Fortunately, on the high end where a gross overshoot might damage components, the thermal lag is much less. I typically get only 3-4 degrees of overshoot at the solder temperature. This is probably because the hotter temperature results in faster cooling because of the greater differential between the setpoint and the ambient temperature so when the power is removed at the setpoint of 215 degrees, the hotplate cools much more rapidly so the overshoot is smaller. Since this works to our benefit I don't bother trying to split the difference. Most of the components I work with are rated to 240 degrees or higher so I'm still being conservative. The key, as with all soldering, is to get enough heat to have a good joint and not much more. These numbers work well for me with the small PCB's I'm doing (typically about six square inches in area.) Larger boards may require a bit more heat. Smaller boards less.

Also, you want to do your SMT work before you solder on any of the components that are through hole mounted with conventional soldering. This is because the leads from those will elevate the PCB above the hotplate and provide a measure of insulation from the heat. Since the IR sensor is rather wide it will see some of the surface of the hotplate for small boards and be "fooled" into thinking the board is "hotter" than it really is. I found this out when trying to use the same program to "salvage" some SMT components by melting the solder and picking them off the board. When the board was supposedly at the solder temperature the solder hadn't actually started to melt. Even though there was only about a sixteenth of an inch air gap under the board, that provided enough "insulation" to prevent the hotplate from being able to melt the solder. Even when I bypassed the temperature control to go higher I found that the internal bi-metallic control would turn the hotplate off before it got hot enough for the SMT components to be removed. FWIW, I happened to have a hot air gun normally used for paint stripping and I was able to get the board hot enough by hitting it from the back side with the hot air gun to melt the solder and shake the components loose with a flick of the wrist.

Liquid solder has a surprising amount of surface tension and the components really want to "stick" in place. This actually works to your advantage when soldering. It is fun to watch SMT components that may be slightly crooked in the paste almost magically align themselves with the solder pads when the solder paste melts.

I created another version of the program with a longer solder time that I use to salvage components but the trick is to remove the through hole components using your favorite techniques (solder sucker, solder wick, etc.) so that the board sits flat on the griddle/hotplate. Then when the solder melts you can just pick off the SMT components with tweezers. Resistors are so cheap it's almost not worth the effort but LED's and the IC's that cost a bit more are worth salvaging from prototypes that didn't pass muster.