Reflow oven with PID control

grimmjaw

Member
Hi guys ,

i' currently building a reflow oven with PID control with PICAXE 28X1.I'm using a standard pizza oven and using a relay to control the main power switch.
Since i'm still a newbie in regard of PID control and PWM, i have intergrate the PID control from greencardigan project 'coffee maker' into the source code of my project.

The oven should operate with this parameters
1.heat to 150°C and maintain for 40s
2.heat to 190°C and maintain for 10s
3.heat to 245°C and maintain for 10s
4. Cool down to room tempereature

the code is as followed:



Code:
symbol Kp = 1000
symbol Ki = 20
symbol Kd = 10

symbol dt = 1
symbol set_temp =w0
symbol set_time =b0
symbol sensor = 1
symbol cur_temp = w1
symbol cur_time=b1
symbol oven = 7

symbol led_hot =5
symbol led_hold =4
symbol err = b2
symbol pre_temp =b3
symbol INT_MAX = 1000
symbol PRO_MAX = 15000
symbol DER_MAX = 5000
symbol PID_MAX = 52768
symbol PID_MIN = 12768
symbol PID = w2
symbol x=b4
symbol input_button1= pinc.1




'#########################################################################################

INIT:
set_temp =0
set_time =0
PID = 49000

'#########################################################################################


Main:


do
low oven
low led_hot
low led_hold

if input_button1 = 0 then	'Waits in this loop until button1 is pressed
  exit    
 endif  
		
gosub get_temp
gosub Phase_1
gosub get_temp

gosub Phase_2
gosub get_temp

gosub Phase_3
gosub get_temp

gosub Phase_4


low oven

loop

goto main



'#########################################################################################


get_temp:	'Reads thermocouple 

readadc10 sensor, cur_temp

return


'#########################################################################################

Phase_1:

set_temp =123 'set temperate at 150°C
set_time =40  'hold 150°C for 40s



if cur_temp < set_temp then
gosub get_temp
  high led_hot
  gosub PID_calc
  gosub PID_control
endif

low led_hot  
for  cur_time=1 to set_time 
gosub get_temp
  high led_hold
  gosub PID_calc
  gosub PID_control
  pause 1000
next cur_time 

low led_hold



return 

'#########################################################################################  
 
Phase_2:

set_temp =156 'set temperate at 190°C
set_time =10  'hold 190°C for 10s

if cur_temp < set_temp then
gosub get_temp
  high led_hot
  gosub PID_calc
  gosub PID_control
endif

low led_hot  
for  cur_time=1 to set_time 
gosub get_temp
  high led_hold
  gosub PID_calc
  gosub PID_control
  pause 1000
next cur_time 

low led_hold



return 



'#########################################################################################  
 
Phase_3:

set_temp =201 'set temperate at 245°C
set_time =10  'hold 245°C for 10s

if cur_temp < set_temp then
gosub get_temp
  high led_hot
  gosub PID_calc
  gosub PID_control
endif

low led_hot  
for  cur_time=1 to set_time 
gosub get_temp
  high led_hold
  gosub PID_calc
  gosub PID_control
  pause 1000
next cur_time 

low led_hold



return 


'#########################################################################################  
 
Phase_4:

set_temp =20 'set temperate at 25°C
set_time =10  'go to 25°C to cool down


if cur_temp => set_temp then
gosub get_temp
  high led_hot
  gosub PID_calc
  gosub PID_control
endif

low led_hot
return 

'#########################################################################################  

PID_calc:
 
gosub get_temp

if PID > 49000 then
	PID = 49000
else
	PID = PID
endif


if cur_temp <= set_temp then	'for negative errors
	
	err = set_temp - cur_temp	max 65 	'error
	
	w3 = Ki * err * dt max INT_MAX	'INTEGRAL..........................
	PID = PID + w3 max PID_MAX	
			
	w3 = Kp * err max PRO_MAX	'PROPORTIONAL......................
	PID = PID + w3 max PID_MAX	'Int + Pro
	
else 'for positive errors

	err = cur_temp - set_temp	max 65	'error
	
	w3 = Ki * err * dt max INT_MAX	'INTEGRAL.........................
	PID = PID - w3 min PID_MIN	
	
	w3 = Kp * err max PRO_MAX	'PROPORTIONAL....................
	PID = PID - w3 min PID_MIN	'Int + Pro
	
endif



'if cur_temp > err then 'temp increasing
	'w3 = cur_temp - err
	'w3 = w3 * Kd max DER_MAX	'DERIVATIVE ......................
	'PID = PID - w3 min PID_MIN	'int + pro + der
'elseif cur_temp < err then 'temp decreasing
	'w3 = err - cur_temp
	'w3 = w3 * Kd max DER_MAX	'DERIVATIVE ......................
	'PID = PID + w3 max PID_MAX	'int + pro + der
'else
	'w3 = 0 'no derivative part
'endif


'pre_temp= cur_temp


return

'#########################################################################################  


PID_control:

for x = 1 to 1000				'Manual PWM with 1 second period (adjust pause at end of main routine to get 1 sec period)
	if x > PID then
		low oven
	else
		high oven
	endif
	
	pause 6
next x



pause 54					'Adjust to get timing right on PID mode (1 sec PWM period)

return

'#########################################################################################

The PID controller seems to be not functioning. The oven will heat to 160°C and the picaxe will exit the program.
Can someone spot any mistake?

Thanks

grimmjaws
 

Armp

Senior Member
The PID controller seems to be not functioning. The oven will heat to 160°C and the picaxe will exit the program.
So you successfully complete phase 1, and then go to phase 2 before the error?
Is there a delay before it shuts down, or is it as soon as you enter phase 2?
Does it occur when the relay operates and injects noise into the ADC?
 

grimmjaw

Member
@armp
nope..as soon as it reach 150°C, the program shut down ..meaning that it doest hold the temperature for 40s

the picaxe is outside the box containing the relay and power supply..it should be no noise( i think...)
 

RexLan

Senior Member
Is the response time v. actual temperature of your Pizza Oven capable of instantaneous heat changes in seconds?
 

grimmjaw

Member
@Rexlan...yup..give or take a few seconds.but cooling take a few more..but the oven is capable to reach the set parameter.

i think the problem is in the code..but not sure where exactly

edit:maybe at PWM part of the program..
 

hippy

Ex-Staff (retired)
Add a #TERMINAL 4800 to the program then add SERTXD commands so you can see where execution of the code gets to.

With SERTXD at the entry and exit of "Phase" routines you will be able to see if it's entering those routines and how long it stays in them.
 

Goeytex

Senior Member
Several errors.

You have X assigned as a byte (b4) variable but are trying to count to 1000 in the PID_control sub routine. A byte max value is 255, so the program will get stuck in the for next loop as b4 overflows to zero.

Most of the variables are stepping on each other. B4 is part of W2. B0 is part of W0 etc. You need to reassign the variables so that they are not shared.

Here are the culprits

symbol set_temp = w0 ' W0 is the same as (b1:b0)
symbol set_time = b0 ' b0 already used in W0 !
symbol cur_temp = w1 ' w1 is the same as (b3:b2)
symbol cur_time = b1 'b1 already used in w0 !
symbol err = b2 'b2 already used in w1 !
symbol pre_temp = b3 'b3 already used in w1 ! This should probably be a word variable ??
symbol PID = w2 'w2 is the same as (b5:b4)
symbol x = b4 'b4 already used in W2! This needs to be a word variable anyway

A good practice is to assign the word variables first and then assign byte variables that are not in conflict with the assigned word variables. Or assign byte variables first and the assign word variables that are not in conflict. Make sure that variables that will exceed 255 are assigned as word variables and not byte variables
 
Last edited:

grimmjaw

Member
thanks Goeytex

i done some changes in the source, both in pwm part and the variable.it seem that the problem still persists, the program exit (both led off, relay are off) after reaching 150°C
symbol Kp = 1000
symbol Ki = 20
symbol Kd = 10

symbol dt = 1
symbol set_temp =w0
symbol set_time =b12
symbol sensor = 1
symbol cur_temp = w1
symbol cur_time=b13
symbol oven = 7

symbol led_hot =5
symbol led_hold =4
symbol err = w4
symbol pre_err =w2
symbol INT_MAX = 1000
symbol PRO_MAX = 15000
symbol DER_MAX = 5000
symbol PID_MAX = 52768
symbol PID_MIN = 12768
symbol PID = w3
symbol x=b15
symbol input_button1= pinc.1




'#########################################################################################

INIT:
set_temp =0
set_time =0
PID = 49000

'#########################################################################################


Main:


do
low oven
low led_hot
low led_hold

if input_button1 = 0 then 'Waits in this loop until button1 is pressed
exit
endif

gosub get_temp

gosub Phase_1
gosub get_temp

gosub Phase_2


gosub get_temp

gosub Phase_3


gosub get_temp

gosub Phase_4



low oven

loop

goto main



'#########################################################################################


get_temp: 'Reads thermocouple

readadc10 sensor, cur_temp

return


'#########################################################################################

Phase_1:

set_temp =123 'set temperate at 150°C
set_time =40 'hold 150°C for 40s


if cur_temp < set_temp then
gosub get_temp
high led_hot
gosub PID_calc
gosub PID_control
endif
low led_hot

for cur_time=1 to set_time
gosub get_temp
high led_hold
gosub PID_calc
gosub PID_control
pause 1000
next cur_time

low led_hold



return

'#########################################################################################

Phase_2:

set_temp =156 'set temperate at 190°C
set_time =10 'hold 190°C for 10s

if cur_temp < set_temp then
gosub get_temp
high led_hot
gosub PID_calc
gosub PID_control
endif

low led_hot
for cur_time=1 to set_time
gosub get_temp
high led_hold
gosub PID_calc
gosub PID_control
pause 1000
next cur_time

low led_hold



return



'#########################################################################################

Phase_3:

set_temp =201 'set temperate at 245°C
set_time =10 'hold 245°C for 10s

if cur_temp < set_temp then
gosub get_temp
high led_hot
gosub PID_calc
gosub PID_control
endif

low led_hot
for cur_time=1 to set_time
gosub get_temp
high led_hold
gosub PID_calc
gosub PID_control
pause 1000
next cur_time

low led_hold



return


'#########################################################################################

Phase_4:

set_temp =20 'set temperate at 25°C
set_time =10 'go to 25°C to cool down


if cur_temp => set_temp then
gosub get_temp
high led_hot
gosub PID_calc
gosub PID_control
endif

low led_hot
return

'#########################################################################################

PID_calc:

gosub get_temp

if PID > 49000 then
PID = 49000
else
PID = PID
endif


if cur_temp <= set_temp then 'for negative errors

err = set_temp - cur_temp max 65 'error

w5 = Ki * err * dt max INT_MAX 'INTEGRAL..........................
PID = PID + w5 max PID_MAX

w5 = Kp * err max PRO_MAX 'PROPORTIONAL......................
PID = PID + w5 max PID_MAX 'Int + Pro

else 'for positive errors

err = cur_temp - set_temp max 65 'error

w5 = Ki * err * dt max INT_MAX 'INTEGRAL.........................
PID = PID - w5 min PID_MIN

w5 = Kp * err max PRO_MAX 'PROPORTIONAL....................
PID = PID - w5 min PID_MIN 'Int + Pro

endif


if PID <= 32678 then
PID = 0
else
PID = PID - 32678 'convert to range 1-20000
PID = PID / 200 'convert to range 1-100
endif



'if cur_temp > err then 'temp increasing
'w3 = cur_temp - err
'w3 = w3 * Kd max DER_MAX 'DERIVATIVE ......................
'PID = PID - w3 min PID_MIN 'int + pro + der
'elseif cur_temp < err then 'temp decreasing
'w3 = err - cur_temp
'w3 = w3 * Kd max DER_MAX 'DERIVATIVE ......................
'PID = PID + w3 max PID_MAX 'int + pro + der
'else
'w3 = 0 'no derivative part
'endif


'pre_temp= cur_temp


return

'#########################################################################################


PID_control:


for x = 1 to 100 'Manual PWM with 1 second period (adjust pause at end of main routine to get 1 sec period)
if x > PID then
low oven
else
high oven
endif

pause 6
next x

high oven

pause 54 'Adjust to get timing right on PID mode (1 sec PWM period)

return

'#########################################################################################
 

g6ejd

Senior Member
A cursory look a the revised programme shows your not waiting for the oven to reach temperature, just checking the temperatgure and moving on, you should check the logic around phase-1 2 and 3, it looks wrong to me.
 

Goeytex

Senior Member
Assuming you have the variables corrected, then take Hippy's advise and add some sertxd lines at strategic places in the code so that you can see via the terminal where the code is going or not going.

What thermocouple are you using? Type K? What thermocouple buffer/ amplifier?
 

grimmjaw

Member
Hi again,

@g6ejd:i just noticed the mistakes ..thanks!
@Goeytex: i'm using type K but with a thermometer.so the analog input is always between 0V to 1V (0°C to 250°C)


with the alteration,the code seems to be working!!.just need to tweek the PID controller (Kp,Ki, etc)..has some overshoot problem..it seem that my relay is too slow for this project..perhaps SSR or TRIAC as replacement

Thanks for the help and patient.Will post any update.
 

g6ejd

Senior Member
Agreed, the thermal inertia is much slower than any relay. This is just a coding problem, but it's getting there.
 

Goeytex

Senior Member
What is the time period? Anything less than about 5 seconds will wear out a relay pretty fast, and you also have to deal with contact arcing. While a solid state relay will not solve your coding problem it would be a definite improvement.

The thermal inertia (and lag) are related to heater power, type, and location of the thermocouple in relation to the heating element. A heating element such as a mica strip heater with considerable mass will have more lag/inertia than a bare nichrome wire loop. The closer the thermocouple is to the heater element the more offset will be needed and the more responsive the PID loop will need to be.

With a time base of 5 seconds, the sample rate should be somewhere around 4 times per second. Some Cheap no name PID controllers found on Ebay have a sample time of 1 to 2 samples per second while the good ones, (Watlow, Honeywell, Omron, Cal Controls,et al) have a sample rate from 4 to 10 times per second.

A PID loop can be unstable because the heater is improperly sized for the application. Usually too large. A rule of thumb is that within the acceptable ambient temperature range, the system will reach and hold the max set point with a heater power of 20 to 80 percent of the heaters maximum output. For example. Manually apply 20 percent power and see what temperature is reached at stasis. If this considerably higher than the max set point then the heater is too large and the loop will likely be unstable regardless of coding modifications.
 
Last edited:

moninos

New Member
Have you seen Lady Ada's solution to the reflow oven. It is great and seems to work well. She simply controls the thermostat knob with a servo motor. She controls the ramp-up ,reflow and ramp down temperature profile. Any simpler?
 

moninos

New Member
Someone mentioned the final solution to avoid variable assignment mess:
1 - Always keep b0 for flags, even if you don't use any
2 - Start assigning Byte variables from b1 on
3 - Assign Word variable from the top down (stating with the last one available)
I think this recommandation should be included in the manual, it would save a lot of headhache
Also use a standard template for your new programs with e clean listing of all the variables. fill-up and uncomment as needed.
 

Armand

New Member
My experience with relays and microcontrollers are very very bad. Hook up a scope and have a look for spikes when they turn on and especially off. There is a good chance spikes mess up your uC. It needs careful design of the circuit, possibly with some optocouplers. Also, solid state realys are sold for as little as 4$ nowadays... http://www.ebay.com/itm/Solid-State-Relay-10A-120-240VAC-Load-3-32VDC-input-trigger-voltage-/150711237512?pt=LH_DefaultDomain_0&hash=item231716fb88

We are also building a (pizza)reflow oven. But our approach is no PID at all. Considered all the mass you have to heat up and cool down in a pizza oven a few PCB's will not make any significant difference. We are therefore going for the empirical trial-error solution before we throw PCB's in there and then hardcode the timing and power output. We are using three 16A triacs for the power steering of a total of three heating elements and that works like a charm. It's cheap too :). Our problem now is that the heating just takes too long for a optimum temerature curve. Our oven manages only 0,53 degrees celcius per second at full blast. (3000W) :-(
 

grimmjaw

Member
After a few tweeking(burn a few boards), my reflow oven seems to be working.The PWM part has to be set at 5s cycle rather than 1s since the relay and the oven cannot react that fast...But everything working great now, just solder finished soldering >500 resistors, and a typical soldering process takes about 7-8 minutes.

But the swicthing of the relay is be very annoying :)
 
Top