Work out the software bugs to test burn, Step 8 of a DIY Record

Over the summer and fall I have written and tested a number of programs to have the building blocks of a working program.  I knew the key this year would be the ability to log data.  Of course to log data and have it mean something you have to have good data.  So I spent several days working the bugs out of OpenLog, which works but I would not recommend.  I also spent some time figuring out a combination of moving averages which resultx in stable data.

Of course the integration process was a train wreck.  The arrays used for moving average data smoothing were declared wrong so that bug had to be found and fixed.  The Serial LCD needed to be replaced, and my soldering iron wouldn’t work.    A few of the functions are timed and there were some issues with those functions.  The code for Open Log was not robust enough, once I worked out all those issues, which took most of the weekend, it is finally ready to test.

I had a plow in the shop for repair and soaked up the spilled hydraulic fluid off the floor with some sawdust, actually pellets that got wet.  So the hydraulic oil soaked sawdust is in the hopper to be burned.  It’s burning now, so tomorrow I should have some excel data which will help me make decisions to improve the software.  At this point I am not sure it will be valid however, it is really taking a long time to come up to temperature with the sawdust.   Another data point.

Boiler hooked up and burning for the first time

Boiler hooked up and burning for the first time


Feed improvments fix the LCD garbling!

The sprockets have been replaced and improved with key ways cut into the jack shaft and auger.  This allows positive feeding without slippage.  The jack shaft placement was constrained so adjustment of the chains is limited to what linkages can be removed or replaced with half links and adding a slack tension device on the slack side of the roller chain.  With this complete the LCD problems appear to be fixed.  Without proper tension the chain did not ride on the sprockets smoothly and the tension could take up suddenly adding a jerk to the system.  Without this mechanical jerk in the system the motor can work more smoothly allowing the LCD to not get the power fluctuations that garble the display.  The feed problems appear to be fixed but in the last test the unit ran for four days without fail and at this point although there is a marked improvement that time has not been surpassed.  Next on the list is the hopper extension to allow feeding of two bags of pellets.  This will allow 16 hours of run time without any software improvements.

Top view of roller chain drive of auger feed


Remaining Issues

Last night I went over the remaining issues with my girlfriend.  So here is the list and the possible fixes and approaches to each item.

1) Smoke.  There is still some remaining minor smoking issues. Possible fixes, better caulking, stronger fans, a wind baffle, burner redesign?  Pipe cleaning?  I think I will start with a wind baffle and some better caulking, next furnace will have a better gasket design.  I also have ordered a Magnehelic to help determine the normal static pressure so that a baseline can be established and tested against.  The boiler is working so ordering fans without more facts would be a expensive trial and error process.

2) Feed issues.  There continues to be an occasional feed issue.  So much so that today I am  going to take the burner off the boiler and see if I can determine the binding issue.  Possible solutions?  Increase in torque, already ordered more sprockets.

3) LCD issues.  The problem has been traced to the relay and I think needs some old fashioned power regulation, no doubt involving a capacitor to remove the spike when the relay is released.  Possible fixes, ordered an LCD backpack to free up some IO and also allow only one power and ground to go to the LCD.

4) Hopper Extension.  3 bags per day means a bag every 8 hours, no all that conducive to being able to leave for a day long event.

5) Data logging.  Tuning the machine is always the fun part and so dependable data logging needs to happen.  I ordered a SD card writer.  This should allow the internal Arduino software to work with the card independently of Windows XP which seems to have problems with continual or repeated Arduino upload.  I also plan to test the upload and communication with a Linux operating system.

Back to work!  Today I built the wind baffle and so after the auger is clear back to the experiment.


Changed feed sprocket

The New Year practically demands resolutions and change for the better.  So with that constant improvement theme in mind I am publicly stating my goal to lose 15#’s and so  I am starting from  195.7.  My second resolution is the constant improvement of the boiler.  So here we go……

Auger feeding failure  due to the motor stalling demanded the  sprocket change  on the auger motor feed assembly.   The sprocket I chose  doubles the torque available for feeding pellets.  Since the shaded pole motor is constant speed the program had to change to double the auger run time.  So taking the data I had gathered I changed the program in two ways.

New sprocket added

I changed the times to accommodate the speed change  demanded by the sprocket change and I changed the paradigm to have constant run time and vary  the dwell or off time.  The increased torque is a vast improvement and since the change it has had no problem feeding even  adding an entire bag of pellets at one time.

A second advantage of the change is the improvement of the LCD display.  I think that this problem is now fixed since the LCD has been running without garbling the characters for several hours, long past the time when the LCD would normally have failed.  By increasing the torque the auger feed motor is running at less amp draw and so it feeds back less to the relays.  I also grounded the relay in a more positive way.

LCD display


Real world vs. Bench Top

I’m a big proponent of having some skin in the game.  If you don’t you are fooling yourself.  I learned that in the financial markets.  If you can trade on paper you have a better chance of succeeding in the real world trading but when you have real money involved sometimes you can’t make the decisions needed.

That seems to be the case with the LCD display.  After having worked out some basic electrical issues the display worked fine for 3-4 days with the relays tripping but no motors hooked up.  Now that the motors are hooked up again it seems to be garbling the LCD.  So, the only assumption I can make is there is some kind of electro-magnetic field  or a bad ground that is interfering with the LCD.    The motor is a shaded pole motor which has a large electromagnetic core which no doubt radiates interference for the controller.  Below is a picture of a similar motor.As a fix I think I will twist the LCD wires so they are less of an antenna and see if using some tin foil to shield inside the project box as well as above the feed motor and see if I can improve the ground.


Burner Improvments

A friend and excellent engineer visited over the weekend and between us we decided to improve the burner a little.  The first change we decided to make was to add some insulation.    I measured the temperature around the outside of the boiler with a non contact thermometer at approx. 350°F in the area of the firebox.  The mounting plate that holds the burner was approaching that temperature as well.  The air box was lower but still this is an excessive temperature.  The Auger pipe was solid from the hopper to the burner unit and since I have both 4″ pipe and 4″ tube we decided to make a thermal break in the auger feed for additional safety.  The 4″ pipe even though it is surrounded by the air box eventually gets warm and since the feed auger has a fair amount of room between the auger and the pipe there is a certain amount of fuel that remains in the pipe and at shut down this can smolder.  So to remove this problem and make the unit more safe a redesign was initiated. Adding  insulation between the air chamber and the burner with the addition of a thermal break prompted us to take the unit apart, check it over and see how everything was faring as well as make improvements.  But of course after the burner and hopper were cut apart and on the bench more improvements were noted. Most of the improvements now fall into minor design for manufacturing type areas, maybe a little less welding and a little more tabbed nut and bolt assembly so minor changes can be made more quickly.  Of course being able to pull the auger feed away from the burner assembly without unbolting anything will be a big change and improvement.  I am going to make the air box bolt on as well.  Should be reassembled for another test on Wednesday.

Of course it wouldn’t be a weekend if we didn’t play with the software.  We added a For loop to the thermistor function to improve the accuracy.  I added an array to smooth the results using a moving average.  But most importantly we found the lingering problem with the LCD characters being garbled.  It was a wiring issue.  Now fixed it has run 24hours without a problem and I am confident it will stay fixed now.  The next step will be to add a capacitor if the problem resumes.  I am quite confident it will not be a problem however since it looks more solid even.  There is less flickering and more solid character display.  So all in all a fun and productive weekend.


3rd Burn Test

Boiler control box with manual feed control

Success!  At least compared to the last burn.  Virtually no smoke, although some paint burned off.  There is still some lingering smell from duct tape and caulking but overall much better, with no smoke.  The burn start/ ash clean out door needs to be rebuilt with hinges, so that is still a problem area, but overall great.  The program ran reasonably well, however, I added some hysteresis to the circulator loop to keep the relay chattering to a minimum.  At this point I have the oil fired burner locked out, but I think I will reduce the temperature set point of the boiler and it just won’t come on unless needed.  There are a list of small items that are required to run a 24 hour test, but I can probably do most of these things tomorrow and be able to be successful with this tomorrow afternoon.   One thing that still needs to be done is shop cleanup.  But for now, YEAH!  Thanks

to friends!

Boiler installation

Boiler installation for testing


2nd Burn Test

New exhaust fan configuration

I changed the configuration of the exhaust fan to pull the intake air from the top of the furnace to the exhaust pipe, which continues down the pipe to help create a vacuum to pull more air from the furnace.  I also used hi temp caulking to close up more leaking area making the boiler much tighter.  The positive draft, not quite a vacuum and the caulking allowed the furnace to heat to the set point of 160°F and turn on the circulator pump without filling the shop with smoke.   The shop did eventually get quite smoky so I shut the boiler down to allow addressing the smoke issue.

The boiler water circulated through the oil fired boiler loop.  I turned up the thermostat in the shop to include the shop to be heated and use some of the hot water.  The circulator turned on and off several times in response to the returning cooler water, but eventually managed to maintain the water temp for the most part.  I probably only ran the boiler for 2 hours total and only 1/2 hour to 45 minutes with the circulator pump on.  Great test run though.

The software is still in the prototype stage as well.  I wired a potentiometer into an Analog pin of the Arduino to set the on time of the Auger.  The dwell time (off time) of the Auger is a fixed 50 seconds.  I made the program so that the on time is some percentage of the off time.   So the potentiometer can turn the Auger up to a 50 second on time or down to a 1 or 2 second on time.  After the first burn it was apparent that changing the parameters on the computer, compiling and uploading was a pain so I wired in a hardware solution.  The next iteration of the software needs to have some error checking and data smoothing added into the program to allow the program to make more informed decisions and stop the relay chatter on the circulator pump.    So considering I am babysitting today, actually I was told it was parenting, I think I will stick to software upgrades and maybe go to Aubochon’s to see if they have braided fire insulation to seal the burner unit and lighting doors.  I think I may order some over center latches for the lighting door to allow easy access but tight sealing and of course more caulking.

The LCD stayed perfect all day yesterday, the other change I made was to put the relays on a separate power supply.   I also added back in the clock which does not seem to be a problem to the LCD.  The other thing I can productively do today is order another clock and Uno so that I can build another enclosed box to run the thermostat.  I miss having the outside temp on my desk and last night since the Arduino was tied up on the boiler I had to be the thermostat for the solar tank.  WTF?


Electronics mounted

Arduino mounted in project box

Finally the electronics have been mounted in a project box which makes them much more portable and easy to use.  The LCD has been disconnected electrically from the relay for nearly 24 hours.  The relay may have taken enough power to cause enough voltage fluctuation to garble the LCD display which seems very sensitive to voltage fluctuations.  Of course this configuration will be much easier to work with, easier to move without worrying about wires and easier to keep clean and safe.  The Arduino is mounted so that the USB cable can be plugged in without removing the cover.  All seems to be working well, another milestone.  I think I will build a second one which I can use either as the thermostat or the boiler controller.  The project box part number 270-1809 was obtained at Radio Shack and the PC board inside was also obtained at Radio Shack.  The PC board is very easy to use with board that consists of many mini bus bars to make hook up and soldering easy, the part number is 276-168.Today’s goal is to deal with the smoking issues of the boiler.More update later.


Added hopper and auger feed motor, LCD problems still

| Author: | Filed under: Homemade Boiler, LCD display | Tags: , , | Leave a comment

Yesterday I added a hopper to the auger feed and mounted the auger motor.  By depending on my memory I found that I did not have any of  the #35 chain I thought I had and so I had to order some from McMaster-Carr.  Their website is the best I have found and their service is great, so I should have the chain on Tuesday or Wednesday and a test burn is planned for then.  I need to finish up a few minor issues on the boiler, and then it is time for a water test for leaks on the KBS coatings job.    The LCD is now working better I no longer have the garbled characters, however I am finding that the thermister readings go to zero on the display, but again not in the Arduino loop.

At this point I need to finish the boiler ash clean out door, weld up a hole where the tank strap wore through the tank when it was mounted on the truck, line the inside with fire brick, and hook up a removable chimney flange, make the sensor wells and hook up the plumbing, sounds like a lot, but in reality is probably only two days work.  The weather looks mild for this next week but it is really time to finish up and make the boiler work.  I have one other major project in the shop which I need to finish but when that’s complete the decks should be cleared for design of experiments on this boiler, starting work on the next iteration and PLOWING!

If anyone understands the issues with the LCD better than me, please let me know, since it is frustrating to experiment until it works instead of understanding the issue thoroughly.  Here’s the code.

/*
Circulator pump controller

This code turns a circulator pump on by closing a relay, simulating a thermostat.
A thermistor in the solar storage tank measures the temperature and if it is below a certain value
then the relay closes, the temperature of the tank is displayed to a LCD as well as the outside temperature
on the third line of the display the state of the circulator pump is listed. The program smooths the data from the
solar tank to avoid relay chatter, and include a RTC to decide what time of day the heat should be on for the hot
water heating. The time that is given to the RTC comes from the computer so as soon as possible after compiling upload
to the Arduino to make the time as accurate as possible.  The time should be within a minute which seems close enough for
my purposes.

The two thermistors are attached to analog pins 0 and 1, the relay pin is digital pin 8 and the LCD pins are listed below
The Real time clock SDA pin is attached to analog 4, the RTC SCL pin is attached to analog pin 5

The circuit:
Inputs
* Thermister Solar Store, Analog in 0
* Thermister Outside Temp, Analog in 1
* RTC SDA, Analog pin 4
* RTC SCL, Analog pin 5
Outputs
* Relay, Digital pin 8
* LCD Pins Date 2,3,4,5
* LCD Pins RW/E Pins 11,12

Created 11/14/11
Michael Clark

http://www.frugaltinker.wordpress.com

*/
#include <math.h> // include the library code for thermsiter functions
#include <Wire.h>
#include <LiquidCrystal.h>  // include the library code for LCD:
#include “RTClib.h”

//define function to calculate the temperature in fahrenheit for Analog pin 0
double ThermisterTank(int RawADC) {//beginning of function
double Temp;
Temp = log(((10240000/RawADC) – 10000));
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
Temp = Temp – 273.15;            // Convert Kelvin to Celcius
Temp = (Temp * 9.0)/ 5.0 + 32.0; // Convert Celcius to Fahrenheit
return Temp;
}//end of function
//define function to calculate the temp in fahrenheit for analog pin 1
double ThermisterOut(int RawADC1) {//beginning of function
double Temp;
Temp = log(((10240000/RawADC1) – 10000));
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
Temp = Temp – 273.15;            // Convert Kelvin to Celcius
Temp = (Temp * 9.0)/ 5.0 + 32.0; // Convert Celcius to Fahrenheit
return Temp;
}//end of function

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);  // initialize the lcd with the numbers of the interface pins
//char buffer[5];//gobetwino example

//int count;   // declaring an integer for count
int Solar_Relay = 1;     // init relay toggle to off.
#define Solar_Relay  8   // Arduino Digital I/O pin number 8
// Define the number of samples to keep track of.  The higher the number,
// the more the readings will be smoothed, but the slower the output will
// respond to the input.  Using a constant rather than a normal variable lets
// use this value to determine the size of the readings array.

//smoothing variables for Thermal storage
const int TSTnum=10; //Thermal Storage readings array
int TSTtemptotal=0; // Thermal Storage tank temperature
int TSTtempaverage=0;// Thermal Storage tank average
int TSTarray[TSTnum]; //Thermal Storage reading array
int index=0;  //index for Thermal storage array
int count=0; //initial count for average
//smoothing variables for Outside temp
const int Outnum=10; //Outside temperature reading array
int OutTotal=0; //declare variable and set to 0 for outside temp total
int OutAverage=0; //declare integer variable and set to 0
int Outarray[Outnum]; //decleare array for outside temps
int index1=0; //index for outside temp array
int count1=0; //initial count for average
//section for time keeping
int hour;
int minute;
int pmhour;
int lcdcount =0;

int Outsidetemp;
int test;

RTC_DS1307 RTC;

void setup()
{//Begin Setup section
Serial.begin(9600); // initiate serial communication
lcd.begin(20, 4);// set up the LCD’s number of rows and columns:
lcd.clear();
delay(75);
lcd.setCursor(0, 0);// set the cursor to column 0, line 0
delay(75);
lcd.print(“Solar   Outside”);// Print a message to the LCD.
delay(75);
digitalWrite(Solar_Relay,1); //turn circulator pin off
pinMode(Solar_Relay, OUTPUT); //Arduino digital pin 8 output
Wire.begin();
RTC.begin();
RTC.adjust(DateTime(__DATE__, __TIME__));
// initialize all the readings to 0:
for (int thisReading = 0; thisReading < TSTnum; thisReading++)
TSTarray[thisReading] = 0;
for (int thisReading = 0; thisReading < Outnum; thisReading++)
Outarray[thisReading] = 0;
} //End setup section

void loop()
{//Begin Loop section
//Thermal storage tank temperature smoothing section
TSTtemptotal=TSTtemptotal-TSTarray[index];  // remove reading from array
TSTarray[index]=int(ThermisterTank(analogRead(0)));
TSTtemptotal=TSTtemptotal+TSTarray[index];
index=index+1;
count=count+1;
if (index>=TSTnum)
{//start if section
index=0;
}//end if section
if (count<=TSTnum)
{//start if section
TSTtempaverage=TSTtemptotal/count;
} //end if section
else
{//start else section
TSTtempaverage=TSTtemptotal/TSTnum;
}//end else section
//end Thermal storage tank smoothing section
//outside temperature smoothing section
OutTotal=OutTotal-Outarray[index1]; //remove reading from array
Outarray[index1]=int(ThermisterOut(analogRead(1)));  //get the Outside temperature reading
OutTotal=OutTotal+Outarray[index1];
index1=index1+1;
count1=count1+1;
if (index1>=Outnum)
{//start if section
index1=0;
} //end if section

if (count1<=Outnum)
{//start if section
OutAverage=OutTotal/count1;
}//end if section
else
{//start else section
OutAverage=OutTotal/Outnum;
}//end else section
//end outside temp smoothing section

/*
Start relay on/off section, want circulator pump to turn on if the following conditions are true, tank temperature is
below 120°F and the time is between 4pm and 9pm.  All other times the tank temperature can float.  Note: Three conditions can happen here
1) not in the time frame, circulator off, this is the else section to the initial time check 2) you are within the time constraints and are below
or above the setpoints, turn circulator on, and 3) you are within the time settings and in between the temp settings, leave circulator off.
*/
if ((hour>=16) and (hour<21)) //condition 1
{//start if section
//this section turns on the relay to control the thermostat wire to run the circulator pump to heat water
//if the temperature of the thermal storage tank is below 100°F
if (TSTtempaverage < 120) //change this temp if you want to change the lower limit
{   //code within brackets applies if above condition is true
digitalWrite(Solar_Relay, 0);    // turns Relay On
} //end of the if true section
if (TSTtempaverage >125) // change this temp if you want to change the upper limit
{  //code within brackets applies if above conditions are true
digitalWrite(Solar_Relay, 1); //Turns relay off
} //end of the if true section
}//end if section
else //not between the hours above
{//begin else section
digitalWrite(Solar_Relay, 1); //Turns relay off
}//end else section

if (lcdcount>=10)
{// start if section

//This section prints the thermistor readings to the LCD
lcdcount=0;
//Serial.print(lcdcount);
lcd.clear();
delay(75);
lcd.noAutoscroll();
delay(75);
lcd.setCursor(0, 0);// set the cursor to column 0, line 0
delay(75);
lcd.print(”                    “); //clear line
delay(75);
lcd.setCursor(0,0); //reset cursor
delay(75);
lcd.print(”                    “);
delay(75);
lcd.setCursor(0,0);
delay(75);
lcd.print(“Solar   Outside”);// Print a message to the LCD.
//Serial.print (TSTtempaverage);
//Serial.print (OutAverage);
lcd.setCursor(0,1);
delay(75);
lcd.print(”                    “);
delay(75);
lcd.setCursor(0, 1);// set the cursor to column 1, line 1, line 1 is the 2nd row
delay(75);
lcd.print(TSTtempaverage); //print to the lcd should be the Solar Store temp if thermistor is hooked up properly
delay(75);
lcd.setCursor(8, 1);// set the cursor to column 1, line 1, line 1 is the 2nd row
delay(75);
lcd.print(OutAverage); //print to the lcd should be the Solar Store temp if thermistor is hooked up properly
delay(75);
//end lcd printing section
//Time section, gets and displays the time
DateTime now = RTC.now();
hour=now.hour(),DEC;     //get the hour from the RTC chip
Serial.println(hour);
minute=now.minute(),DEC; //get the minute from the RTC chip
Serial.println(minute);
//changes from 24 hour time to AM, PM
lcd.setCursor(0,2);
delay(75);
lcd.print(”                    “);
delay(75);
if (hour>=13) //PM Section
{//start if section
pmhour=hour-12;
lcd.setCursor(0,2);      //set cursor to the 1st column, 4th row where the time will be displayed
delay(75);
lcd.print (pmhour);
delay(75);
lcd.print(‘:’); // print :
delay(75);
if (minute<10)//adds a “0” if the time is single digit
{//start if section
lcd.print(“0″);
delay(75);
}//end if section
lcd.print(minute);
delay(75);
lcd.print(” PM”);
delay(75);
}//end if section
if (hour<13) //AM Section
{//start if section
lcd.setCursor(0,2);      //set cursor to the 1st column, 4th row where the time will be displayed
delay(75);
lcd.print (hour);
delay(75);
lcd.print (“:”);
delay(75);
if (minute<10)//adds a “0” if the time is single digit
{//start if section
lcd.print(“0″);
delay(75);
}//end if section
lcd.print(minute);
delay(75);
if (hour>=12)
{ //start if section
lcd.print (” PM”);
delay(75);
}// end if section
if (hour<12)
{// start if section
lcd.print(” AM”);
delay(75);
} //end if section
}//end if section
//End time section

//checks condition and writes accordingly
lcd.setCursor(0,3);
delay(75);
lcd.print(”                    “);
delay(75);
test=digitalRead(Solar_Relay);// prints the state of the circulator if in the middle ground of temp
if (test==1)
{// start if section
lcd.setCursor(0,3);              //sets cursor to column 1, line 3
delay(75);
lcd.print(“Circulator Off”); //prints “Circulator Off to lcd line 3
delay(75);
}//end if section
if (test==0)
{//start if section
lcd.setCursor(0,3);              //sets cursor to column 1, line 3
delay(75);
lcd.print(“Circulator On “);      //prints circulator on to lcd line 3
}// end if section
//End Relay on/off section
}//end if section
lcdcount=lcdcount+1;
delay(1500);
//Start Gobetweeno Data collection section
// lcd.setCursor(6, 3);// set the cursor to column 8, line 4, line 3 is the 4th row
// lcd.print(millis()/10000);// print the number of seconds since reset:
// if (count == 30)
//{  //does everything within the brackets section if the statement is true goes on otherwise
//  Serial.print(“#S|LOGTEST|[“);//if gobetwino is running this will log the data
//Serial.print(itoa((int(ThermisterTank(analogRead(0)))),buffer, 10));//sends data to file for inside temp
// Serial.print(“,”);// comma to delimit the data between inside and outside temps
// Serial.print(itoa((int(ThermisterOut(analogRead(1)))),buffer, 10));//collects outside temp in file
// Serial.println(“]#”);//gobetino command ending
//   count = 0;
//} //end of the if true section
//   count = (count + 1);
// Serial.println (count); //display count on the com monitor window

//End Gobetweeno data collection section

}//End loop section