Proportional, Integrative, Differential control.  There is a function in Arduino that implements this and I started thinking about how I would do this and if it would be appropriate.  The function, really an algorithm is all based on error and time.  In this case the error is the difference between the set point and the actual tank temperature.

All three functions Proportional, Integrative and Differential have a factor, Kp, Ki and Kd.  For example let’s calculate each portion of the formula starting with the proportional contribution Kp, if the current temperature of the tank is 100°F and the set point is 140°F the error is 40.  The integrative portion of the formula adds the contribution of the error over time.  This would be the Ki factor multiplied by 40 and added to the previous Ki*error for every time period.  The differential portion is the Kd multiplied by the difference in the tank temperatures or in other words the tank temperature at the beginning of the time period  minus the tank temperature at the end of the time period.  Let’s take some of the data collected by the OpenLog microSD card and take a stab at this in Excel. We’ll assume Kp=6, Ki=.6 and Kd =.2. The time period is one minute.

Raw data imported into Excel with PID data calculated

Now in practical terms how is the the fire being controlled now?  The auger time is being controlled.  Of course practically the fire must not go out so there is a minimum time the auger must run, since in this program the auger is on a fixed time of 5 secs this really means that all of the control comes from varying the time the auger is not running.  But again the fire can’t go out so I figure the max amount of time between the fixed auger feeds of five seconds is forty seconds.  So that is the slowest the fire can go.  How fast can it go?  Well theoretically the feed could run continuously but again we are dealing with a chemical process that cannot simply absorb 100% fuel feed.  In this case the auger motor added a practical aspect by limiting the feed to a duty cycle of 50%, so the maximum time that the feed can be on is half the time.

Since the PID control is based on time periods and the data collection time period is one minute,lets choose a time of 1 minute for argument.  In one minute at max run the feed will be on 30 seconds and off 30 seconds.  In one minute at min run the feed will be on for 5 secs, off for 40 secs, on for 5 secs and then off for the remaining 10 seconds of the minute.  So again we don’t control the on time only the off time and the difference between the max on time (min off time) and min on time (max off time) is 30 secs on, 30 secs off for the max and 10 secs on and 50 secs off for the min.   So the only control between full bore and idle is the difference between 50secs and 30 secs or 20 secs per minute.

This explains some of the challenge,  the other challenge is the inertial effect of the combustion reaction especially if unburned fuel has built up.  So now that the PID output has been calculated I’m having a hard time wrapping my mind around how this would translate to control of the time, I know I could set up a simple proportion between the PID output and the 0-20 scale of  auger off time dwell.  However in this example the PID output  increases as the error decreases.  I guess that’s the beauty of a spreadsheet I will play around with Kp, Ki and Kd to see if I can get this to work a little better.

# 12/14/12 data, more testing, draft improvements

I  added  gasket rope which I bought at a local hardware store, which is made to replace the gasket material which comes in a wood stove door between the burn plate and the boiler.  This gasket changed the Magnehelic vacuum reading from .1″H2O to .4″H2O.  That I thought would make the flame a bit more vigorous.  I also made the holes in the bottom of the burner larger to allow the ash to fall through.  Lastly I made minor changes by tacking some material across some holes and making more air holes in the ramp plate which the pellets fall down.

Temperature vs. Minutes 12/14/12 data

The main differences in this graph and the previous day’s graphs are at approximately minute 273  pellets were added and the sawdust which had been running finally ran out.   As you can see it had enough energy density to overcome the demands of the circulator circuit.  The biggest problem after that came at about 341 when the program allowed the temperature to go past the set point of 140°F  The only explanation I could come up with is the division by different types of declared variables was not allowed and yielded a result of zero.  I was dividing an unsigned long which is an integer by .8 to increase the Auger Off time by 20%.  Since you will not get an integer when you do this the program may not have liked this result.  The Arduino language is a slight variant of C++ .  I have since made all the variables doubles we’ll see if that works.  Today’s burn will be a better test of the burner floors ability to let ash fall through.  Sawdust is very difficult to burn.  It’s also difficult to get the ash to fall through the burner floor.   I think this is because the air cannot get around the sawdust sufficiently to burn it completely and hence it smolders in clumps instead of falling through the grate.    The burner when I pulled it out to inspect it was definitely not clean of ash but did appear better than yesterday.

# First Burn as a boiler

Prototype burn mode

Limited success, the temperature in the tank did rise quickly and peaked at approx. 90°F before I shut the boiler feed off.  The water in the boiler started at 56°F.  The boiler smoked excessively and I think the top exhaust fan needs to be more robust.  At present the bottom draft feed fans are approx. 1/3 more cfm than the top fan.  To induce some negative pressure and reduce the smoking issues the top fan needs to increase.  The other issue is the auger feed.  The motor had a few issues with binding, The motor may have to be more powerful as well.  I will take apart the feed tomorrow and hopefully determine where it was binding up.  With luck there was a misaligned bearing or some other explanation.  Otherwise I am a little at a loss.  Over the weekend the piping got run with help.  I mounted the 3/4″ copper on Unistrut this  connected to the oil fired hot water boiler.   A nice neat job if I say so myself.  The 4″ .125 wall tube I used for an exhaust pipe seemed to work fine and stay cool in the 1/2 hour I ran the boiler.  I still had some issues with the LCD screen however I am now convinced that this problem will fix it self with a separate power supply for the relays.

I wrote a very simple program this morning for the boiler control.  No frills at all, and there were minor LCD issues.  I think the LCD is very susceptible to voltage fluctuations.  I will test this theory tomorrow as well.