SMT Table Top Reflow Oven (part 3): Final Build
by Andrew on 28 Nov 2011
Two previous articles described the my attempts to create a Reflow Oven.I finally thought it time to document the final construction.
ThermocoupleReading a K-Type Thermcouple from a microcontroller with a MAX6675 chip was described here. I ruined several thermocouple wires when they got snagged/bent and the wire broke. To reduce the time to replace a wire I wrapped two together with kapton tape, so the backup can be plugged in if the first breaks. The two wires also makes the cable less likely to bend and break, particularly when further wrapped in some heatshrink tubing.The thermocouple was inserted through a hole in the oven and position just above the centre of the tray.
The MAX6675 code was wrapped in a simple C++ class with a read() method to return the temperature multiplied by 4 (as it comes back from the MAX6675) as an integer.See MAX6675.h and MAX6675.cpp
Rotary EncoderBy removing the existing front panel switches it was possible to mount a rotary encoder using the existing holes and fixtures.
Rotary Encoder Fit into the space from the ovens timer and 'on/off bar control' knobs.
Decoding was done as described here, except that the Arduino interrupt mechanism was used:
attachInterrupt(0, knob_turned, CHANGE);attachInterrupt(1, knob_turned, CHANGE); | This will result in the knobturned() method being called when pins 2 and 3 (connected to the rotary encoder) change level.void knob_turned(){ _delay_ms(1); int pin0 = digitalRead(ENCODER_LEFT); int pin1 = digitalRead(ENCODER_RIGHT); if (pin0 != pinValues[0]) { rotary_encoder_change(0, pin0); } else if (pin1 != pinValues[1]) { rotary_encoder_change(1, pin1); }}void rotary_encoder_change(uint8_t changedPin, uint8_t value){ pinValues[changedPin] = value; // only increment for each 'click' of the dial - when both pins have gone back to 0 if (value == 0 && pinValues[0] == pinValues[1]) { unsigned long this_change = millis(); // if the change is within 50ms of the last then move 10 positions rather than 1 short multiplier = (last_changed != 0 && (this_change - last_changed) < 50) ? 10 : 1; target_temp += ((changedPin) ? 1 : -1) * multiplier; last_changed = this_change;} | The delay_ms(1) is used to debounce the encoder (the Arduino delay() method can't be used from within an interrupt).Currently the target maximum temperature is set by the rotary encoder - to speed selection, the time when the last change happened is recorded and if the next change occurs within 50ms the temperature is incremented/decremented by 10 rather than 1.
The default Arduino interrupt library only supports 2 external interrupts - rather than resorting to AVR lib interrupt routine to capture when the push button is pressed - I simply polled it in the loop() method (which runs every 200ms). Pushing the button is used to turn the device on and off.
LEDThe original oven had some kind of bulb that's powered by mains when the elements are on, this was replaced with a red LED controlled from the Arduino. Rather than using a current limiting resistor I just connected to one of the PWM pins (9) and used analogWrite to power for a fraction of the time:
analogWrite(9, 70);
LCDI wanted the oven to be self contained so the screen needs to be big enough to display what's going on and to and display options etc. A 2x8 LCD was a little small, 2x16 just about big enough for all the information. There was no way to really house it neatly in the existing front panel so it was positioned vertically and some brushed aluminium sheet used to create a new panel.
New front panel showing LCD, Dial, and on/off LED button.
The standard LiquidCrystal Arduino library was used with the LCD connected to the analogue pins:
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);
The display was updated every 200 milliseconds. The current test sketch display is shown below, the display code is in the update_display() method in the sketch.
Close up of the Aluminium panel, with LCD showing actual Temperature, rate of change (°C/Second), whether the heating elements are on, the time since heating session started, and the target temperature.
ControlAfter completing the front panel construction I fitted the Arduino into an ABS box on the back of the oven - its cooler there and is easier to get to.
Arduino housed in ABS Box on back of oven.
I had originally intended to use a predefined reflow profile and a PID algorithm, but testing showed that with both the heater elements full on the oven reached peak (240°C) in approximately 300 seconds. The preheat is a little short and the soak and reflow stages a little long:
Temp/Time chart (for empty oven).
Using a PID algorithm won't make the reflow stage any quicker. To test I've used a small Arduino script that lets the user select the maximum temperature, the heating elements are then turned on until the max is reached. Usually open the door to increase the cooling rate.
The source can be found here, a few tests have shown acceptable results.
First Reflow solder test: SOIC 16, perhaps to little solder.
I'd bridged a few of the pads with smear of paste but the reflow process has successfully 'sucked' the solder onto the pad apart from a few beads.
Closeup of solder joint.
ConclusionsI've been using the oven for awhile now on simple boards with some success - the boards have been fairly simple and haven't had to fix any issues. I'm still deciding whether to spend the time implementing (and more importantly tuning) a PID controller for the oven. My feeling is that the ovens elements can't be made to increase/decrease the ovens temperature quick enough to make it worthwhile.
Others say that applying solder paste by hand and using an oven is as time consuming as using a soldering iron, but I find the process quicker, cleaner (even with a solder fume extractor), and less of an eyestrain - I find it easier to hold a syringe of paste under a microscope than a soldering iron.
|