Tuesday, July 20, 2010

Code complete Version 1.00

After 7 alpha and 23 beta revisions, here's version 1.0 of the code. It's amazingly simple.

/*
Kegerator Thermostat Version 1.0

The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD pin 1 to ground
* LCD pin 2 to +5v
* LCD pin 3 to 4.7K ohm res to ground

* LM-34 Vout pin to Analog 0

* Button up to digital pin 7
* Button down to digital pin 8

* Relay on digital pin 13

*/

// include the library code:
#include

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// set pin numbers:
const int relay = 13; // the number of the relay pin
const int buttonUpPin = 8; // the number of the Temp Up pin
const int buttonDnPin = 7; // the number of the Temp Down pin
const int tempPin = 0; // analog temp sensor pin
// set wait values
const int maxOffWait = 50000; // How many ms to wait to turn off
const int maxOnWait = 50000; // How many ms to wait to turn on


// variables:
int setTemp = 50; // variable storing the Set temp
int currTemp = 0; // variable storing the actual, current temp
int tempTemp = 0; // temporary temp
int buttonUpState = 0; // variable for reading the pushbutton status
int buttonDnState = 0; // variable for reading the pushbutton status
int tempIn = 0; // get temperature variable
int flagOff = 0; // flag for off delay loop
int flagOn = 0; // flag for on delay loop


void setup() {
// set up the LCD's number of rows and columns:
lcd.begin(16, 2);
// initialize the pushbutton pins as input:
pinMode(relay, OUTPUT);
digitalWrite(relay, HIGH);
pinMode(buttonUpPin, INPUT);
pinMode(buttonDnPin, INPUT);
lcd.setCursor(0, 0);
lcd.print(" Key Largo");
lcd.setCursor(0, 1);
lcd.print(" Brewery");
delay(500);
lcd.setCursor(0, 1);
lcd.print(" ");
}

void loop() {
// Print header line of output
lcd.setCursor(0, 0);
lcd.print(" Current | Set ");

// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(3, 1);
lcd.print(currTemp);
lcd.print("F ");
lcd.setCursor(9, 1);
lcd.print("|");
lcd.setCursor(11, 1);

// Check buttons for set temp
buttonUpState = digitalRead(buttonUpPin);
if (buttonUpState == HIGH) {
// add 1 to setTemp
setTemp++;
delay(250);
}
buttonDnState = digitalRead(buttonDnPin);
if (buttonDnState == HIGH) {
// subtr 1 from setTemp
setTemp--;
delay(250);
}
lcd.print(setTemp);
lcd.print("F ");

//Get the temp
tempIn = analogRead(tempPin)/8.0;
currTemp = (tempIn * 9)/ 5 + 32; // converts to fahrenheit
tempTemp = setTemp-1;

//Relay switch off logic (Anti-thrashing)
if ((tempTemp > currTemp)&&(flagOff == 0)) {
flagOff = 1;
}
if ((flagOff != 0)&&(flagOff <= maxOffWait)){
++flagOff;
}
if (flagOff >= maxOffWait){
// turn on relay
lcd.setCursor(15, 1);
lcd.print("-");
digitalWrite(relay, LOW);
flagOff = 0;
}

//Relay switch on logic (Anti-thrashing)
if ((setTemp < flagon ="="">
flagOn = 1;
}
if ((flagOn != 0)&&(flagOn <= maxOnWait)){
++flagOn;
}
if (flagOn >= maxOnWait){
// turn off relay
lcd.setCursor(15, 1);
lcd.print("+");
digitalWrite(relay, HIGH);
flagOn = 0;
}
}

All night test - Complete!

I finally got the thermostat working. I added a delay to the relay loop that makes it wait ~ 3 minutes before shutting off the relay and ~ 3 minutes before turning on the relay.

This keeps the relay/freezer from thrashing (turning on and off rapidly) when the temperature is on the cusp. I ran it all night with the set temp at 50° when I got up this morning the current temp was 48° FTW!

I’m going to lengthen the delay a little bit and add 1° to the upward set temp so it stays off longer on the temperature rise and gives a bigger compressor rest zone between runs.

Pictures and source code to follow.

Tuesday, July 6, 2010

IT'S DONE! -- Sort of...

The boarduino came Saturday. It took me about 10 minutes to assemble with these instructions: http://www.ladyada.net/make/boarduino/solder.html

I uncharacteristically did not take pictures. The above instructions illustrate the process better than I could.

I soldered all the connections to the peripherals and added connections to the high voltage box. I put it all together, updated the programming and plugged it it. It was a complete success... until... it cooled down to the set temp and began thrashing. The temp flickered back and forth between 51 degrees and 49 degrees about twice a second. The relay was clicking back and forth like a buzzer.

I pulled it out of service and I am working on a way to delay the cycling. My goal is to make it stay on for an extra 10 minutes to allow the temperature to "latch" and stay off on the way up for the same reason.


Wednesday, June 23, 2010

Waiting on parts

I ordered a "brain" for my controller. I'm getting a boarduino http://www.hvwtech.com/products_view.asp?ProductID=661 from solarobotics.
This will let me permanently solder the *duino in place. Once it arrives, I'll be minutes from being done.

Sunday, June 20, 2010

High Voltage; Done & Tested

I finished wiring and mounting all the little bits in the enclosure. Testing everything was nerve-wracking.
First the Power supply. No smoke. No fire.
Then the relay board (Which I finally got working when I realized the transistor in my opto-isolator wasn't powerful enough to trip the relay. Upgrade that and Viola!). No smoke. No fire.
Then came the "All the Marbles" test. The power outlet. Plugged in a light. Tripped the relay. No smoke! No fire! Light's on!

Very exciting!

Construction complete!

Getting ready to commit to the project!


Drilling begins!



4" hole!



Tap tower installed.



First pint pulled. FTW!



Electronics to follow... Hopefully tonight.

Saturday, June 19, 2010

Almost there!

Tomorrow is father's day. My gift to me will be to get the tower installed and get, at least temporarily, some temperature control going. When I get the boarduino from Solarobotics, I can solder everything together permanently. I can't wait to pull the first pint of Piratical Nerve from the tap.

HIGH VOLTAGE enclosure nearly complete.

The enclosure and the relay assembly, which still needs to be installed.


5Volt power supply


Power in



And power out. This is the business end of the high voltage enclosure. The outlet is switched by the system to keep the chest freezer at a constant temperature!


Thursday, June 17, 2010

Finished temp probe

Heat shrink and a stereo plug make for a finished temp probe.




Tuesday, June 15, 2010

Tap Handle

Last night I made a simple tap handle for the one faucet on the tower. I will make some "Tap boards" for the faucets once all 3 are installed.

Sunday, June 13, 2010

Kegerator tower starts to take shape


Nothing beats a Forstner bit for making perfectly smooth holes.

I used a 1" bit to drill the first hole in the 4" diameter tower.

I plan to use sheets of foam to insulate the inside of the tower and eventually add a temperature probe at the top that will switch on a fan to blow cool air from the main chamber up into the tower to help cool the lines.

Then I put the faucet and shank that I've had for over 10 years in the hole and snugged it up. As I get more faucets and shanks I will drill and mount them. I think this tower can hold 3 faucets which is convenient since the chest freezer can only hold 3 Corny kegs.












Saturday, June 12, 2010

Making the temperature probe

I'm making the temperature probe to go in the main body of the freezer out of
  • 4 feet of cat 5 cable
  • 1 LM-34 temp sensor
  • 1 3 inch length of 3/8 inch copper tube
  • Electrical tape
  • JB Weld
I started by unjacketing the cat 5 and untwisting one pair (orange). I then retwisted the solid orange onto the blue - blue/white pair.

Next I soldered the wires to the legs of the LM-34 and TESTED it. I've built stuff like this in the past and not tested it before I commited to making it a permanent installation. Bad idea.


Then I wrapped the legs in electrical tape and dry fitted it in the tube


Next I mixed up some JB weld and slathered it over the sensor and pulled it back into the tube. I then scooped more JB weld into the end of the tube, taped both ends and hung it up to set overnight. I'll fill the tube completely in the morning with thinned JB weld and then let it rest 24 hours before I'll deem it "ready."

The kegerator code so far

This is a work in progress:

/*
Kegerator Controller by Chuck McKenna
is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD pin 1 to ground
* LCD pin 2 to +5v
* LCD pin 3 to 4.7K ohm res to ground

* LM-34 Vout pin to Analog 0
* Button up to digital pin 7
* Button down to digital pin 8

*/

// include the library code:
#include

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// set pin numbers:
const int buttonUpPin = 7; // the number of the Temp Up pin
const int buttonDnPin = 8; // the number of the Temp Down pin
const int tempPin = 0; // analog temp sensor pin

// variables:
int setTemp = 50; // variable storing the Set temp
int currTemp = 0; // variable storing the actual, current temp
int tempTemp = 0; // temporary temp
int buttonUpState = 0; // variable for reading the pushbutton status
int buttonDnState = 0; // variable for reading the pushbutton status
int tempIn = 0; // get temperature variable


void setup() {
// set up the LCD's number of rows and columns:
lcd.begin(16, 2);
// initialize the pushbutton pins as input:
pinMode(buttonUpPin, INPUT);
pinMode(buttonDnPin, INPUT);
lcd.setCursor(0, 0);
lcd.print(" Key Largo");
lcd.setCursor(0, 1);
lcd.print(" Brewery");
delay(2500);
lcd.setCursor(0, 1);
lcd.print(" ");
}

void loop() {
// Print header line of output
lcd.setCursor(0, 0);
lcd.print(" Current | Set ");
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(3, 1);
lcd.print(currTemp);
lcd.print("F ");
lcd.setCursor(9, 1);
lcd.print("|");
lcd.setCursor(11, 1);
// Check buttons for set temp
buttonUpState = digitalRead(buttonUpPin);
if (buttonUpState == HIGH) {
// add 1 to setTemp
setTemp++;
delay(250);
}
buttonDnState = digitalRead(buttonDnPin);
if (buttonDnState == HIGH) {
// subtr 1 from setTemp
setTemp--;
delay(250);
}
lcd.print(setTemp);
lcd.print("F ");

//Get the temp
tempIn = analogRead(tempPin)/8.0;
currTemp = (tempIn * 9)/ 5 + 32; // converts to fahrenheit

tempTemp = setTemp-1;
//Psuedo Relay
if (tempTemp > currTemp) {
// turn off relays
lcd.setCursor(15, 1);
lcd.print("-");
}
if (setTemp <>
// turn on relays
lcd.setCursor(15, 1);
lcd.print("+");
}
}

Some photos