2013 in review

The WordPress.com stats helper monkeys prepared a 2013 annual report for this blog.

Here’s an excerpt:

A New York City subway train holds 1,200 people. This blog was viewed about 7,200 times in 2013. If it were a NYC subway train, it would take about 6 trips to carry that many people.

Click here to see the complete report.


Minor Software changes can make life much more convienient

DSC00698This time of year in New Hampshire it is warm days and cool nights.  Pleasant for the most part but it is still fall.  There can be some rainy raw days that need a touch of heat and to heat the hot water or maybe the day is warm enough but just cloudy so you want to heat the hot water for showers.  So in other words the boiler can often run for 3-4 hours per night, maybe one or two evenings per week.

Shutting the unit down before the upgrade consisted of unplugging the unit which includes all the controls except the draft fan.  This of course shuts off the feed and everything else but the fire still burns the remaining fuel.  I keep the draft fan on to minimize any smoking that might occur otherwise.  I live on the second floor of the building and the boiler is on the first floor so typically I would walk down unplug the unit, take a shower and then go back down and unplug the draft fan.  More than once I have had to go down later after forgetting to unplug the draft fan.  So I added a physical button, the Attn button, to the front of the control panel, and rewired the control box to relay control the draft fan.  Now with a minor software change made I can go down hit the button and the unit shuts the auger feed immediately and then after twenty minutes turns off the relay for the draft fan.  It’s so cool my girlfriend wants to go push the button.  Can life get any better?


Fuel savings built into the software

I added a function to check for the time of year and hour of day to shut the boiler down automatically, I mentioned this in the last post. But as the days get warmer I wanted to make additional changes. I probably ought to be calculating the HDD and comparing to the present outside temperature to calculate a dynamic time needed for adequate heat, however that seemed too complicated so I wrote a simple function to check for date and time. At this time of year it shuts the boiler off at midnight. In March it ran until 3 am.

void FuelSavingsDateCheck() {//start function
DateTime now = RTC.now();  //get the data from the RTC
Month =now.month(),DEC;    //get the month from the RTC
Day =now.day(),DEC;        //get the day from the RTC
hour = now.hour(),DEC;     //get the hour from the RTC
if (Month ==12 && Day <15)  //month of December before the 15th
{//start if section
if (hour >3 && hour <9)  //shut off time of 3 am
FuelTest =0;
else
FuelTest =1;
}// end if section
if (Month == 3 && Day >15)  //after March 15th
{//start if section
if (hour >3 && hour < 9)  //at 3am shutoff burner
FuelTest =0;
else
FuelTest=1;
}// end if section
if (Month == 4)              //month of April
{//start if section
if (hour ==0 && hour < 9)  //midnight shutoff
FuelTest =0;
else
FuelTest=1;
}// end if section
}//end function


The view from April, Daylight savings time adjustment for your RTC

The boiler has worked flawless all winter, I am happy with the software and hardware but with all things mechanical there is room for improvement. I have just started my 7th ton of pellets. And I really don’t want to get into my 8th and don’t think I will have to, especially if I institute some energy conservation in the software. This is the time of year that I would normally burn what my grandmother called a “trash fire”. In her case it was some cardboard boxes from the trash and maybe an odd shaped piece of wood or two. Just enough for 3-4 hours in the evening, letting it burn out overnight since the days get up to 40°F or 50°F there’s no need for more fire than that. Later in the month most of the nights will be above freezing. But I still want to light the boiler in the evening mostly for the hot water and then turn it off at 2-3 am, so I wrote that into the software and it has gotten the consumption down to 1-2 bags per day. I also added a function in the software to change the real time clock for Daylight savings time and back automatically. It’s not fully tested but I think it will work OK.

void DaylightSavingsSchedule(){//start function
if (Year ==2013 && Month ==11 && Day ==2 && hour ==2&&DaylightTest ==0)//fall back an hour
FallBack();
if (Year ==2013 && Month ==11 && Day ==4 && hour ==2&&DaylightTest ==1)//reset flag
DaylightTest =0;
if (Year ==2014 && Month ==3 && Day ==9 && hour ==2&&DaylightTest ==0)//spring forward an hour
SpringForward();
if (Year ==2014 && Month ==3 && Day ==10 && hour ==2&&DaylightTest ==1)//reset flag
DaylightTest =0;
if (Year ==2014 && Month ==11 && Day ==2 && hour ==2&&DaylightTest ==0)//fall back an hour
FallBack();
if (Year ==2014 && Month ==11 && Day ==3 &&DaylightTest ==1)//reset flag
DaylightTest =0;
if (Year ==2015 && Month ==3 && Day ==8 && hour ==2&&DaylightTest ==0)//spring forward an hour
SpringForward();
if (Year ==2015 && Month ==3 && Day ==9 && hour ==2&&DaylightTest ==1)//reset flag
DaylightTest =0;
if (Year ==2015 && Month ==11 && Day ==1 && hour ==2&&DaylightTest ==0)//fall back an hour
FallBack();
if (Year ==2015 && Month ==11 && Day ==2 &&DaylightTest ==1)//reset flag
DaylightTest =0;
if (Year ==2016 && Month ==3 && Day ==13 && hour ==2&&DaylightTest ==0)//spring forward an hour
SpringForward();
if (Year ==2016 && Month ==3 && Day ==14 && hour ==2&&DaylightTest ==1)//reset flag
DaylightTest =0;
if (Year ==2016 && Month ==11 && Day ==6 && hour ==2&&DaylightTest ==0)//fall back an hour
FallBack();
if (Year ==2016 && Month ==11 && Day ==7 &&DaylightTest ==1)//reset flag
DaylightTest =0;
}//end function

void SpringForward(){//start function
DateTime now = RTC.now(); //get the data from the RTC
now =now.unixtime()+3600; //subtracts an hour from the time
RTC.adjust(DateTime(now.unixtime())); //resets the time to an hour earlier
DaylightTest =1; //flag variable so it won’t go back in time continously
}//end function

void FallBack(){//start function
DateTime now = RTC.now(); //get the data from the RTC
now =now.unixtime()-3600; //subtracts an hour from the time
RTC.adjust(DateTime(now.unixtime())); //resets the time to an hour earlier
DaylightTest =1; //flag variable so it won’t go back in time continously
}//end function


Deja Vu (it got really cold again), Test Plan

After writing a similar post on 1/15/2012 I find myself saying basically the same thing, after a -10F night the boiler has kept up. Additionally except for a 12 hour period when I made some boiler modifications the boiler has run continuously for 14 days. There are several differences however. The software is 100% better and controlling the temperature to within a few degrees. The burner is now a waterfall type burner that is much safer and runs more consistently. The hopper and auger setup is much more consistent and dependable as a worm and worm gear than the chain and sprocket setup from last year. Most significantly the burner has proved it can run on chips as well as pellets. During these colder nights it is more difficult for the burner to keep up with chips because of the density differences. The chips are much less dense and because of this the auger must feed significantly more of them. The auger motor may need to be changed to accommodate this burning however during weather that does not require so much energy the chips will burn just fine. I could have easily burned chips for most of December with no issues if they had been dry enough. Which brings me to my second topic.

A test plan. I have taken the Holidays off but it is now the new year and time to make some constant progress. To facilitate the test plan I want to make some incremental improvements in the software. The first change in the software is to gather more data to make better decisions.  To do this I am going to first add the date and outside temperature readings to both the LCD display and the data collected.  By knowing these I can correlate the feed times to temperature and see how close a relationship between them exists. Next I would like to total the run time of the auger per minute and correlate that to both outside temperature and fuel usage. Armed with this additional data I can then make various burner modifications and see the differences if any graphically. The data is good now but could be better. As you can see from the data below the software is not working properly now. The derivative portion of the formula is not contributing at all. This needs to be fixed in the software.

Data collected on SD card

Data collected on SD card


PID works!

122012PID

After tweaking the Kp and making the Ki work in the software the graph speaks for itself. The software is controlling the temperature to the set point of 140°F within a fraction of a degree for the most part. This was the last difficult piece of puzzle. I did not use the PID function in the Arduino language, instead I wrote my own with a large part of the understanding of the code coming from the excellent description by Brett Bueargard who wrote the PID library, as well as assistance from a friend who helped me understand the problem better in a spreadsheet. I now have a burner that works dependably and is modular so that I can make changes and see if I can further improve the efficiency. I now have software which will hold the temperature without worry. I plan to add a proof of fire sensor next for the mechanical part of the project, and add the ability to set the Real Time clock in the software. Onward, ever onward, but for today I think I will have a beer!


Thinking about PID control

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

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.