Owen control for SMD reflow with Arduino

before you read this : many hobbyist simply dont use closed loop controled owen to process their reflow. They just carefully check how their owen heat with a multimeter and a thermocouple. And they control by hand the process.
It looks that with some practice they have very nice results.
you can look here :

  • http://ejenn.free.fr/index.php?title=Soudure_de_CMS
  • http://wiki.jelectronique.com/souder_des_cms
    If you want a more controled system you can read this text now.

    I use an arduino board + my arduino thermocouple shield to control a mini owen for reflow soldering of SMD.
    (see Arduino shield for two thermocouples)
    The power is controled by a triac, via an opto triac for galvanic isolation.
    Software regulate owen temperature with closed loop control to follow a correct reflow curve according JEDEC standard.

    Schematic

    The schematic comes directly from the data sheet of the MOC 3041
    owen control by triac
    The output D2 of the shield is to be plug on the diode of the opto triac.

    Board


    I use a small piece of experimentation board to mount the opto triac and his resistors. Resistors are made with two parallel mounted resistors for better power dissipation. I am not sure this is really necessary.
    I use an isolated version of triac to mount it directly on a small dissipator (from an old graphic card).

    Software

    Sensors reading

    Software use the interpolated readings of thermocouple and TNC .
    ATTENTION : calibration tables here are just for exemple and works with my thermocouples, my NTC and the gain of my amplifiers. Components Tolerances doesn't allow you to use those tables as is .

    State machine

    A finite state machine is used to control successive steps of heating and cooling.

    Typical reflow temperature curves from an altera document :


    According reflow curves the state machine has 5 steps (+ 0 = STOP state) : reflow is divided in REFLOW_HEATING and REFLOW_STABLE.
    Transtion beetwen two states is possible if desired temperature or nominal time is reached.

    Theorical temperature calculation

    Temperature is incremented/decremented at each steps : a increment depend of the state.
    During stable heating state there is no increment/decrement of theorical temp.

    Regulation

    Temperature is regulated by ON / OFF power control of the owen. The regulation function use differential correction to avoid overshoot during critical phase of reflow.
    The higher is the value passed to the regulation funtion the less the overshoot will be. But also the temperature rise will be slower.
    Differential gain are adjust by trial and miss process. You have to make those adjustements by yourself for your owen.

    
    #define TEMP 1
    #define CAN 0
    
    #define STOP  0
    #define PREHEAT 1
    #define ACTIVATION 2
    #define REFLOW_HEATING 3
    #define REFLOW_STABLE 4
    #define COOLING 5
    
    #define PREHEAT_SLOPE 0.15 			// 1.5 °C /sec (un pas toutes les 0,1 sec)
    #define ACTIVATION_TEMP 150 		// Flux activation temperature
    #define ACTIVATION_SLOPE 0.0275 	// for 33 °C in 120 sec
    #define MELTING_TEMP 183 			// Melting temp of solder (lead solder)
    #define REFLOW_SLOPE 0.1 			// 1 °C / sec --> 27 sec from 183 °C to 210 °C
    #define REFLOW_TEMP 210				// 10 °C under max package temperature
    #define Reflow_Time 6000 			// Adjust this to stay enough time in the reflow zone
    #define COOLING_SLOPE -0.4			// cooling : 4°C / sec
    
    #define DELTA 100 //  Time step of mesurements and regulation.
    
    #define MIN(A,B) ((A) > (B) ? (B) : (A) )
    #define MAX(A,B) ((A) > (B) ? (A) : (B) )
    
    #define N_CTN 4 // number of points in TNC calibration table 
    #define N_TC 12  // number of points in thermocouple calibration table 
    // Table calibration for THERMISTOR
    float calib_CTN [N_CTN][2] = { // put here calibration points : first the value read on arduino ADC, second the value read on your reference thermoemter.
    {340,15},{395,19},{405,20},{470,30} 
    };
    // Table calibration for THERMO COUPLE
    float calib_TC  [N_TC][2] = {
    {0,0}, // first point : at 0°C the TC give no voltage
    {25,10},{135,40},{305,86},{444, 125},{580,160},{616,170},{655,180},{709,195},{734,201},{841,231},{888,261}
    };
    
    int STATE = 0 , POWER = 0;
    unsigned long S_millis , Reflow_start;
    float Temp = 20 , Temp_theo= 20;
    
    void setup() {
      // initialize serial communication at 9600 bits per second:
      Serial.begin(9600);
      pinMode(2,OUTPUT); // Owen command
      pinMode(4,OUTPUT) ; // Buzzer
      pinMode(3,INPUT) ; digitalWrite(3, HIGH) ; // start button
    }
    
    // the loop routine runs over and over again forever:
    void loop() {
      // read the input on analog pin 0 and 1 :
          float Diff_correction ;
          static int BUZZ = HIGH ;
      static float Tfilt ;
      int Can_comp = analogRead(A0);
      int Can_TC = analogRead(A1);
      float T_ctn = converti(Can_comp , calib_CTN, N_CTN);
      float T_Thcp = converti(Can_TC, calib_TC, N_TC) ;
      float Temp = T_ctn + T_Thcp ;
      Tfilt = (1000*Tfilt + Temp)/1001 ;  // Crude moving average filter
      
      int BUTTON = digitalRead(3);
      
    	if (millis() >= S_millis + DELTA){
    		S_millis = millis();
                    Diff_correction = 0 ;
      // STATE machine
    		if (STATE == STOP && BUTTON == LOW) {
    			STATE = PREHEAT ;
    		}
    		if (STATE == PREHEAT && Temp >= ACTIVATION_TEMP) {
    			STATE = ACTIVATION ;
    		}
    		if (STATE == ACTIVATION && Temp >= MELTING_TEMP) {
    			STATE = REFLOW_HEATING ;
    		}
    		if (STATE == REFLOW_HEATING && Temp >= REFLOW_TEMP) {
    			STATE = REFLOW_STABLE ; Reflow_start = millis() ;
    		}
    		if (STATE == REFLOW_STABLE && millis() >= Reflow_start + Reflow_Time) {
    			STATE = COOLING ;
    		}
    		if (STATE == COOLING && Temp <= ACTIVATION_TEMP){
    			STATE = STOP ;
    		}
       // Theorical temp calculation
    		if (STATE == PREHEAT){
    			Temp_theo += PREHEAT_SLOPE ; Temp_theo = MIN(Temp_theo , ACTIVATION_TEMP );
    		}
    		if (STATE == ACTIVATION){
    			Temp_theo += ACTIVATION_SLOPE ; Temp_theo = MIN(Temp_theo , MELTING_TEMP );
                            Diff_correction = 20 ; // Adjust this coeff by try and miss to avoid overheating 
    		}
    		if (STATE == REFLOW_HEATING){
    			Temp_theo += REFLOW_SLOPE ; Temp_theo = MIN(Temp_theo , REFLOW_TEMP );
                            Diff_correction = 50 ; // Adjust this coeff by try and miss to avoid overheating 
    
    		}
    		if (STATE == REFLOW_STABLE){
    			Temp_theo = Temp_theo ;
                            Diff_correction = 50 ; // Adjust this coeff by try and miss to avoid overheating 
    		}
    		if (STATE == COOLING){
    			Temp_theo += COOLING_SLOPE ; 
                            Temp_theo = MAX(Temp_theo, 10) ;
                          if (BUZZ == HIGH ) {tone (4,1000);} else { noTone(4); }
                          if (BUTTON == LOW) BUZZ = LOW ;
    
    		}
      // Regulate owen temp 
    		POWER = Regulate (Temp_theo , Tfilt, Diff_correction) ;
     
      // print out the value you read:
    		Serial.print(S_millis/1000);
    		/* Serial.print("\tSTATE =\t"); */   Serial.print("\t");	Serial.print(STATE);
    		/* Serial.print("\tTemp =\t");  */  Serial.print("\t");	Serial.print(Temp);
    		/* Serial.print("\tT theo =\t"); */ Serial.print("\t");	Serial.print(Temp_theo);
    		/* Serial.print("\tT PWR =\t"); */  Serial.print("\t");	Serial.println(POWER);
    	}
    }
    
    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
    float Regulate(float Temp_theo , float Temp, int Diff_correction){
             static float Old_Residu ; float DT , Residu ;
            Residu = Temp - Temp_theo ;
            DT = (Residu - Old_Residu) * Diff_correction ; // Crude differential correction to avoid overshoot
            Old_Residu = Residu ;
    	if (Residu > - DT) {
    		digitalWrite(2, LOW); return LOW ;
    	} else {
    		digitalWrite(2, HIGH); return HIGH ;
    	}
    }
    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
    float Int_lin(float x, float X1, float Y1 , float X2, float Y2){
     float a , b ;  
      a = (Y1 - Y2) / (X1 - X2) ;
      b = Y1 - a*X1 ;
      return a*x + b ;
    }
    // =======================================================================================================//
    float converti(float X ,          // value read on ADC to convert in °C
                   float calib[][2],  // Calibration table to use --> not the same for TCN en thermo couple
                   int N
    			   ){
    	int i ;
    	if (X < calib [0][CAN]){ // Entry outside calibration table (lower) --> extrapolation
    	                         // with the two first points of table
    		return Int_lin(X, 	
    				calib [0][CAN], calib [0][TEMP] , 
    				calib [1][CAN], calib [1][TEMP]) ;
    	}
    	if (X > calib [N-1][CAN]){ // Entry outside calibration table (higher) --> extrapolation
    	                             // with the two last points of table
    
    		return Int_lin(X, 	
    				calib [N-1][CAN], calib [N-1][TEMP] , 
    				calib [N][CAN], calib [N][TEMP]) ;
    	}
    	for (i=0 ; i < N ; i++){
    		if (X < calib [i][CAN]){
    			return Int_lin(X, 	
    					calib [i-1][CAN], calib [i-1][TEMP] , 
    					calib [i][CAN], calib [i][TEMP]) ;
    		}
    	}
    }
    

    Use


    Man machine interface is more then basic : you need to edit the program if you want to change the parameters.
    You need to plug your Arduino board to a computer to read output on the serial port.

    You can monitor temperature by using the arduino serial monitor or any software listening the convenient serial port. I use "Datalogger" to record temperature curves and Gnuplot to trace them.

    Turn on the serial monitor to reset the arduino : you force the system to STOP state.

  • To trigger the reflow sequence you just have to push the button of the shield.
  • When the reflow time is reached the owen begin to cool along the cooling slope. The buzzer of the shield is activated to warn you.
    You can turn off the buzzer by pushing button on the shield

    With most of owen the natural cooling slope of the owen is too slow and you have to open the door to cool quickly. .
    With my owen I have the best cooling slope by half opening the door.
    You will need several test to find the best tuning of your process :

  • it's important to stay for enough time in the reflow zone (above 183 °C for leaded solder)
  • to overheat the packages can destroy them.
  • some package need slower pre heating. In some case packages have to be baked to dry before being processed.
    Check your component data sheets to control your reflow process.


    Exemple of recorded temperature with my owen.