Boiler controller

Janne

Senior Member
Hello all!

My first picaxe project is a wood fired boiler controller. The purpose of the controller is to control the air inlet to the boiler, based on the fumes temperature. The goal here is to keep the fumes around 250C, hotter than that and it's wasteful and lower that that it's not burning cleanly.

I measure the fumes with a PT-100 temperature sensor, and I use a geared down stepper motor to control the air inlet hatch. Also in the contoller are 3 buttons, to choose auto / manual mode and 2 buttons to drive the motor manually. 2 leds indicate motor is turning in either direction. So far the controller seems to work, but i seem to have some interference problems, as sometimes the controller behaves a little irregular. Also the required delay for the stepper motor between pulses seems high - there might be some problems with the board layout too, as i've used a veroboard for the design. The slow speed is not an issue, as the boiler response is also rather slow.

For driving the stepper motor I use L6219 IC chip.(actully a whole circuit board stolen from old scanner.. i just cut off the control pins and wired picaxe to those :) ) The picaxe outputs 0,1,4 and 5 are used to control the current, and outputs 2 and 3 are connected to the "phase" leads. I decided to wire all the current pins individually, in case i would have wanted to use the half and micro-step modes, but they seem to be unnecessary in this case.

Anyways, I've included the circuit schematic, and the picaxe code for axe-18x.. I know the code is rather wasteful, i didn't bother to tidy it up too much as the fits easily in 18x.

ps. I would have included the schematic in gif format, but for some reason the board only accepts very small gif-files.
 

Attachments

westaust55

Moderator
Uploading pictures

Try converting you pitcures to jpg format.

Use the JPG extension and not JPEG as the is a difference in the allowable file length there as well (976.6kB for JPG versus 19.5kB for GIF and JPEG).
 

Janne

Senior Member
Okay the controller has been in test for some time now, and it looks promising. Most of the time it does what it's supposed to do, keep the boiler burning efficiently. But still I though there was room for improvement :)

I've decided to make a neater version of the controller, and use 20M instead of 18x for the chip.. 18x felt overkill lol :).. Improvements on the schematic include also water temperature measuring, to prevent boiling. Currently i need to manually oversee the final phase of the heating to prevent boiling.

Other improvements in the program include a lot of fine tweaking, and also some memory to remember last measured value, to find out in what direction the temperature is going. And also a variable to log the hatch position, to prevent opening it too far wide open. It required some optimization on the code to make it fit, but it did :)

One problem I haven't been able to figure out is the long delay required between "step" pulses for the stepper motor to operate reliable... it's not too much of an issue, because a high speed is not required, but still it puzzles me why it's responding so slowly.

I'll upload the circuit schematic of the controller later in case someone's interested.
 

eclectic

Moderator
@Janne

If you send a program as a .bas file,
then we have to

Click on the file.
Save As
Then go to Programming Editor.
Then Load the code
Then look at the program.

It is much easier if you use the

[ code ]
and the [ /code ]
(without spaces).

Code:
'BOILER CONTROLLER SOFTWARE FOR PICAXE 20M

'define symbols

'inputs

SYMBOL FUMES	= 1   	'inpur pin 1 reads the voltage from the temperature sensor
SYMBOL MODE 	= PIN0	'input pin 0 for mode switch
SYMBOL OPEN		= PIN4	'input pin 4 for open button
SYMBOL CLOSE	= PIN5	'input pin 5 for close button
SYMBOL WATER	= 2		'input pin 2 is reserved for water temperature

'outputs

SYMBOL CURRENT	= 0		'use outpin 0 for controlling the current on the stepper controller I pins
SYMBOL PHASE_1	= 1		'use outpin 1 for controlling phase 1
SYMBOL PHASE_2	= 2		'use outpin 2 for controlling phase 2
SYMBOL PWRLED	= 5		'power led
SYMBOL LED1		= 6		'led "open"
SYMBOL LED2		= 7		'led "close"

'variables

SYMBOL TEMP		= W2	'variable for current temperature storage
SYMBOL LASTTEMP	= W3	'variable for last measured temperature 
SYMBOL WTR_TEMP	= W4	'variable for water temperature
SYMBOL SETPOINT	= W5	'target for temperature. 667 is ok for normal operation = no dannger of boiling
SYMBOL AUX		= W6	'aux variable for readadc
SYMBOL STEPS	= B3	'aux variable in stepper control 
SYMBOL POSITION	= B2	'variable for current hatch position
SYMBOL i		= B1 	'aux variable for loops
SYMBOL DIRECTION	= BIT0'variable for storing the direction data
SYMBOL BOILING 	= BIT1'if set to high mean boiling danger
SYMBOL dT		= BIT2'if set to high, temperature is going up, 0 means it's going down
SYMBOL KISSA	= BIT3'another helper variable

'constants

SYMBOL DELAY 	= 12
SYMBOL MAX_OPEN	= 254 'max value for the hatch opening

'Initialize controller. Set motor current to zero, and wait a while for the power to stabilize
INIT:

	HIGH CURRENT
	PAUSE 1000
	LET SETPOINT = 667
			
MAIN:

	'Read mode switch, and goto automatic or manual mode
		
	IF MODE	=1 THEN
	
		GOTO MANUAL
		
	ELSE
	
		GOTO AUTO
		
	ENDIF
	
	
	
AUTO:					'automatic controller operation

		
	LET TEMP = 0		'INIT TEMP VARIABLE
	
	FOR i = 1 TO 5	
		READADC10 FUMES,AUX 'Read the analogue voltage from input pin 0
		LET TEMP = TEMP+AUX 'Add the value just read to temp	
	NEXT i	
	LET TEMP = TEMP / 5	'get the average of 5 readdowns
	
	LET WTR_TEMP = 0		'init WTR_TEMP variable
		
	FOR i = 1 TO 5	
		READADC10 WATER,AUX	'read water temperature
		LET WTR_TEMP = WTR_TEMP + AUX 'add the value to wtr_temp	
	NEXT i
	LET WTR_TEMP = WTR_TEMP / 5 'get the average of 5 readdowns	
	
	
	'IF WTR_TEMP < 500 THEN			'lower the temperature setpoint if boiling is immenent
	'LET SETPOINT = 600
	'LET STEPS = POSITION-4
	'GOSUB TAAKSE
	'GOTO DELAYER
	'ENDIF	
	
	
	IF TEMP < LASTTEMP THEN 'determine which way the temperature is headed
	LOW dT
	ELSE 
	HIGH dT
	ENDIF
	
	LET LASTTEMP = TEMP	
	LET TEMP = TEMP - SETPOINT	'Substract SETPOINT from the temp value. value of 0 means temperatu is at desired position.
	
	
	IF TEMP > 20000 THEN		'Check if the temp variable has overflown. if it has 
	LET DIRECTION = 1			'set the direction flag to 1, and return a positive small value
	LET  TEMP = 65535 - TEMP
	ELSE 
	LET  DIRECTION = 0
	ENDIF
	
	LET STEPS = TEMP / 2		'set steps to half of the temperature
			
	LET KISSA = DIRECTION ANDNOT dT 	'if the temperature is too low, and it is going down, then increase the speed the hatch is opened
	IF  KISSA =1 THEN				'and vice versa if the temperature is going up	
	LET STEPS = STEPS * 2
	ENDIF	
	
	IF STEPS = 0 THEN			'if steps = skip the motor driving part
	GOTO DELAYER
	ENDIF
	
	IF DIRECTION =1 THEN	'Check the direction flag to deside which way to drive the motor
	GOSUB ETEEN
	ELSE
	GOSUB TAAKSE
	ENDIF 
	
	
DELAYER:
	
	FOR i = 1 to 70		'setup a delay loop for 35 secs. Check every half second, if the mode switch has been changed
		
		PAUSE 500
		IF MODE = 1 THEN
		GOTO MAIN
		ENDIF
		TOGGLE PWRLED   'toggle led on / off to give a signal that everyting is working ok
		
	NEXT i
	
	GOTO AUTO
		
		

MANUAL:

	LET STEPS 	=1 'SET steps to 1
		
	IF OPEN=1 THEN				
		GOSUB ETEEN	
	ENDIF
	
	IF CLOSE=1 THEN	
		GOSUB TAAKSE	
	ENDIF
		
	GOTO MAIN
	
ETEEN: 'The sub for driving the motor forward = opening the hatch
	
	LET OUTPINS = %10000000 'set output current to max and led 1 on
	
	FOR i= 1 to STEPS 	'setup a loop to drive motor STEPS amount of steps 
		
		IF POSITION >= MAX_OPEN THEN 'if hatch is already opened the permittible maxium, then exit the loop
		EXIT 
		ENDIF		
		
		PAUSE DELAY
		TOGGLE PHASE_1
		PAUSE DELAY
		TOGGLE PHASE_2
		PAUSE DELAY
		TOGGLE PHASE_1
		PAUSE DELAY
		TOGGLE PHASE_2
		INC POSITION
				
	NEXT i	
	
	PAUSE 20
	LET OUTPINS = %11000001 'disable output current and led 

RETURN



TAAKSE: 'The sub for driving the motor backward = closing the hatch

	
	LET PINS = %01000000 'set output current to max and led 2 on
	
	
	FOR i= 1 to STEPS 	'setup a loop to drive motor STEPS amount of steps
	
		IF POSITION = 0 THEN 'if the hatch is already completely shut, exit the loop
		EXIT
		ENDIF
		
		PAUSE DELAY
		TOGGLE PHASE_2
		PAUSE DELAY
		TOGGLE PHASE_1
		PAUSE DELAY
		TOGGLE PHASE_2
		PAUSE DELAY
		TOGGLE PHASE_1
		DEC POSITION
				
	NEXT i
	
	PAUSE 20
	LET PINS = %11000001 'disable output current and led 
	
RETURN
e
 

Janne

Senior Member
Thanks for the heads up eclectic. Haven't really thought of that before, even though I tend to check the new threads here almost daily.
 

Janne

Senior Member
Boiler controller revisited &amp; revamped

Recently I've been burning a bit different kind of firewood than before on my boiler, mostly some smaller stuff. The boiler controller that I had originally built would have needed re-programming to work well with this new kind of wood.. Instead I decided to do a complete revamp on the controller :) Since this thing was my first picaxe project ever, and the functionality required is not very complex I felt that the job could still be well sorted out with another picaxe.

Overall, the system is still pretty much the same. It controls the boiler draft, based on the measured temperature of fumes and the setpoint of the controller. The draft is controlled with a stepper motor pulling the air hatch open, with an attached line. Temperature of the fumes is measured with a resistive PT100 sensor, and now a new feature is that the setpoint can be varied with potentiometer input. The potentiometer is an important addition, as the ideal working temperature depends on how dirty the boiler is (has it been cleaned recently), and how hot the feedwater is.

The old hardware that was based around a 18X was kinda bad, as the stepper motor controller was a complete board gutted out an old scanner machine, that I had just cut off the control lines and hooked them up to the 18X. There was some form of current control going on in the board, as the controller would not give very good output current to the stepper motor, resulting in very slow maxium speed it could have without loosing steps. I had a few spare 14M's, so I built a new circuit with it and a similar stepper controller (UDN2916) on a stripboard. The UDN2916 (or L6202 from ST micro - both are practically the same) is one of my favourite ways of driving bipolar steppers, it has all the stuff needed + the possibility to control the output current easily is a big plus. Price is not too bad either for the allegro part - for some reason the ST micro parts cost a whole lot more.

schema.jpg

The stepper control needs nothing fancy, so the typical application was a good starting point. Sense resistor value is important, if you want to have precise current control, for most other parts near values work ok. The good thing about using a resistor divider like this to read the PT100 sensor is, that no precision voltage regulator is needed. Even if the supply voltage varies, the proportional measured voltage is still the same. The only component affecting precision here is the 120ohm resistor, and the temperature drift of that component.

circuit.JPG

Stripboarded circuits hardly ever look nice, but it works. I had salvaged the stepper IC earlier from another scanner board, by cutting the pins. I had to solder it to the underside, like an oversized SMD-part. Sorry, didn't remember to take pictures of that before hot-gluing in place.

(Continued on next post.)
 

Janne

Senior Member
part 2

box.jpg

The old interface looks a bit busted, but nothing wrong with it. So I just added the potentiometer but otherwise used the old box and the lid.

stepper.jpg

The stepper motor is also salvaged from an old scanner. The belt pulley now works as a line reel, the line is attached to the air hatch of the boiler.
 
Last edited:

Janne

Senior Member
part 3

sensor.jpg

Since the enviroment isn't really nasty (electrically-wise) a normal flat speaker cable works ok here. Only thing that could be better is the sensor response time. Because of the stainless steel sensor pocket, the response time of the sensor is quite slow, somewhere between 1-2 minutes. That makes is hard for the controller to react to sudden chages, that I've tried to overcome in software.

Code:
#REM 

Boiler controller software 15.10.2011 Janne Peltonen
V1.0: Initial release, compared to old software; faster manual mode, potentiometer adjusted setpoint and D term
V1.1: Added compensation to adjustment P for hatch position, trimmed some functions to make room for new features

#ENDREM

#picaxe 14m
#terminal 4800



'outputs
SYMBOL virta 	= 5		'Active low 0 = full power 1 = no power 
SYMBOL phase1 	= 4		
SYMBOL phase2 	= 3
SYMBOL pwr_LED	= 0
SYMBOL auki_LED	= 1
SYMBOL kiinni_LED	= 2

'inputs

'analogue
SYMBOL potikka 	= 4	'ADC4
SYMBOL pt100 	= 0	'ADC0

'digital
SYMBOL mode_vipu 		= PIN1
SYMBOL auki_nappi	 	= PIN2
SYMBOL kiinni_nappi	= PIN3

'constants
SYMBOL delay 	= 3
SYMBOL asetusarvo = 700
SYMBOL kiinni 	= 0
SYMBOL auki		= 1
SYMBOL auki_suunta = $0304
SYMBOL kiinni_suunta = $0403

'variables
'b0 for bit variables
SYMBOL first_loop = bit0
SYMBOL dt		= bit1


SYMBOL Wtemp 	= W6
SYMBOL suunta 	= W5
SYMBOL suunta_LB	= B10
SYMBOL suunta_HB	= B11
SYMBOL lampotila 	= W4
SYMBOL lampotila_vanha = W3
SYMBOL vetoluukku_position = W2

SYMBOL temp 	= B1
SYMBOL i		= B2





Init:

first_loop = 1
pins = $21 'ouput current set to 0,pwrled on
'SERTXD ("START",CR,LF)



'********************************************************************'
'Main program loop

Main:

	IF mode_vipu = 1 THEN	'check mode switch
		first_loop = 1
		'HIGH pwr_LED
		GOSUB Manual
	ELSE
		GOSUB Auto
	ENDIF

GOTO Main 'End of main program loop	

'********************************************************************'
'Sub program for manual mode, 
'input none
'output none
Manual:	

	temp  = 2 'set steps
	IF auki_nappi = 1 THEN
		LOW virta	'enable power to stepper motor
		suunta = auki_suunta
		'HIGH auki_LED	
		GOSUB Stepper
	
	ELSEIF kiinni_nappi = 1 THEN
		LOW virta	'enable power to stepper motor
		suunta = kiinni_suunta
		'HIGH kiinni_LED
		GOSUB Stepper
	ELSE  
		PAUSE 15
		pins = $20 'disable drive , set other pins low
	ENDIF

RETURN

'********************************************************************'
'Sub program for automatic mode, 
'input none
'output none
Auto:

	lampotila = 0
	READADC potikka, temp
	temp = temp / 4	'scale to max 63
	
	FOR i = 1 TO 10
		READADC10 pt100, Wtemp
		lampotila = lampotila + Wtemp
	NEXT i
	
	Wtemp = asetusarvo - temp	'adjust setpoint with potentiometer reading
	Wtemp = Wtemp * 10		'lampotila is read 10 times
	
	IF first_loop = 1 THEN		'if it's the first auto loop
		dt = 0
		lampotila_vanha = lampotila
		first_loop = 0
	ELSE
		IF lampotila > lampotila_vanha and lampotila > Wtemp THEN'if things are going from bad to worse
			dt = 1
		ELSEIF lampotila < lampotila_vanha and lampotila < Wtemp THEN
			dt = 1
		ELSE 
			dt = 0
		ENDIF
		lampotila_vanha = lampotila			
	ENDIF	
	
	lampotila = lampotila - Wtemp
	IF lampotila > $8000 THEN	'if lampotila overflowed
		suunta = auki_suunta	
		lampotila = 0 - lampotila
	ELSE
		suunta = kiinni_suunta	
	ENDIF	
	IF dt = 1 THEN			'check for need of fast adjustment
		temp = lampotila / 35	
	ELSE
		temp = lampotila / 140
	ENDIF

	IF temp <> 0 THEN			'if adjustment is needed..
		
		LOW virta	'enable power to stepper motor
		IF vetoluukku_position > 60 THEN	'compensate for hatch position
			temp = vetoluukku_position / 60 * temp MAX 254
		ENDIF
		temp = temp * 2
		
		#REMIF suunta = kiinni_suunta THEN
			HIGH kiinni_LED
		ELSE
			HIGH auki_LED
		ENDIF
		#ENDREM
		GOSUB Stepper
		PAUSE 10
		pins = $20 'disable drive , set other pins low
		
	ENDIF
	
	FOR i = 0 TO 33
		IF mode_vipu = 1 THEN 	'if automatic mode aborted
			RETURN
		ENDIF
		TOGGLE kiinni_LED
		PAUSE 500
	NEXT i
	
RETURN

'********************************************************************'
'Sub program for driving the stepper motor
'input 	temp = amount of steps to drive steps must be multiple of 2; 2 = 1 full step
'		suunta_LB & suunta_HB for directional control

'output none
Stepper:
	
	'LOW virta	'enable power to stepper motor
	
	FOR i = 1 TO temp
	
		IF suunta = auki_suunta THEN		'check for hatch position limits, and write new position
			HIGH auki_LED
			IF vetoluukku_position >= 500 THEN
				EXIT
			ENDIF
			vetoluukku_position = vetoluukku_position + 1
		ELSE
			HIGH kiinni_LED
			IF vetoluukku_position = 0 THEN
				EXIT
			ENDIF
			vetoluukku_position = vetoluukku_position -1
		ENDIF
		
		TOGGLE suunta_LB				'toggle output defined by number on low byte of suunta
		PAUSE delay
		TOGGLE suunta_HB				'toggle output defined by number on high byte of suunta
		PAUSE delay

	NEXT i
	'pins = $20 'disable drive , set other pins low
	
RETURN
Here is the latest version of the running code. It was actually quite a fun project to write the program, as I had to trim the functions of some fat a couple of times to make room for all the functions I wanted :) Now it just fits - change a pause 15 or pause 10 delay to pause 16 and it won't :)

The base of the program is still the same P-type controller as before, where the error is amplified and stepper motor is adjusted based on that. But I've also added some new features. Now it also takes into account the direction where the temperature is going. If, for example, the temperature is too high, and it's still going up the rate of adjustment is quadrupled. Also, the hatch position affects the gain. When the hatch is already opened a substantial amount. the adjustment is faster. It's because the proportional change would be much smaller with a fixed number of steps, compared to when the hatch is just barely open. Without this, the adjustment would work well only in a narrow hatch opening band.

It was interesting to go back to my first real program written - and to notice how bad / unreadable my code was back then :) I've adopted some standards to my BASIC programs, that others might find useful too. The syntax, for example (copied from BCJkiwi originally)
Write all basic commands in ALL CAPS.
variables in all lowercase
labels with Initial Character In Upper Case
use TAB indenting for blocks of code

On each function I write a short comment about what it does overall, and then what variables / memory it does use for it's input and output.

I also try to use symbolic names as much as possible - to make the code as readable as feasible without commenting on obvious things. Then write comments to comment what blocks of code are doing - or tell what an odd looking piece of code is doing like the line
"pins = $20 'disable drive , set other pins low", where pins = $20 wouldn't really be self explaining.
 
Last edited:

Janne

Senior Member
Last week the controller started acting weird. It would freeze ocassionally only to start working again after a power reset. Yesterday it refused to work at all. Today after a few more power cycles it seemingly started to work again, except it wasn't measuring anything!
Upon debugging with debug command (heh) I found that all the analog channels were dead. It's a bit curious how that might have happened, it would make sense if one of the inputs would have fried say from a static spark. Maybe a power spike fried the analog part of the chip, and it refused to power until enough power cycling "blew" the analogue part, and the chip worked again apart from the analogue section?

Anyways, a new chip in place and it works again. Good think I had the program stashed away here, as I had lost the original source code containing USB-stick :D
 
Top