Yuri's Brew Yurt (Hut)

Homebrew Talk - Beer, Wine, Mead, & Cider Brewing Discussion Forum

Help Support Homebrew Talk - Beer, Wine, Mead, & Cider Brewing Discussion Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.
That is RAD!:rockin:

Even if the camera is not that useful it definatly has the cool factor going. I am really starting to think that Phase 2 of my build might have to be pc based operation. Seeing some of these threads lately is inspiring. Just need to get it complete and running first then plan for phase 2
Same problem I have. Must establish Phase 1 before I can move on to the even cooler phase 2 :)
 
And I thought I had a problem...

At least I know there is a ton of growing room from where I am now.
 
The temperature sensors are K-type thermocouples from Omega. I use MAX6675 converters and the Arduino SPI library to interface with them.

The pressure sensor is an MPX4250GP, which would also be well suited for monitoring kegerator serving pressures.

The volume sensors are ultrasonic "PING)))" modules from Parallax (measuring the distance from the top of the kettle to the surface of the liquid). I may switch to pressure sensors (digital "sight tubes") like kladue and others use, but the ultrasonic method works for now.
 
brewhutscreenshot.jpg

Yer mash temp is a bit low. :D
 
My server runs a 700MHz Pentium III on a crappy old Dell laptop, and it works fine. The webcam process spikes CPU usage to 4% during updates.

Oddly enough, CshreCat, the pressure and mash temp values are the only actual sensor data (accurately reporting the slight amount of pressure I applied to the boiler and the ambient temp in the brew hut). The rest are just meaningless constants that Arduino spits out since I don't have everything completely wired yet. I've tested all of the sensors individually, but I need to do some work on the control circuit before I can tie them all together at the same time (it will likely be a printed board from Sparkfun's BatchPCB service). The rig is functional, but it's definitely a work in progress.
 
LM34 and LM35 sensors are cheap and easy to use, but building them a waterproof casing that maintains a reasonable response time is a bit of a pain (epoxy is a great, simple solution if you're willing to wait a long time for the temp to stabilize). So, I went with grounded thermocouples. Omega will custom make a ton of different configurations for rather reasonable prices. All of mine are stainless probes brazed onto stainless NPT fittings.

I may still use LM-series sensors for other projects (like a kegerator or fermentation cabinet).
 
LM34 and LM35 sensors are cheap and easy to use, but building them a waterproof casing that maintains a reasonable response time is a bit of a pain (epoxy is a great, simple solution if you're willing to wait a long time for the temp to stabilize). So, I went with grounded thermocouples. Omega will custom make a ton of different configurations for rather reasonable prices. All of mine are stainless probes brazed onto stainless NPT fittings.

I may still use LM-series sensors for other projects (like a kegerator or fermentation cabinet).


I was planning on inserting them into stainless tubes and sealing the end with epoxy, as you suggest. I don't expect a long response time given the specs on the part. What sort of experience did you have?
 
I used an old dip tube from a Corny keg and JB weld to seal it up. The response time was very slow from room temp to mash temps (30 seconds or so). Once it was up to temp, I'm confident that it was good for trend data, but the readings were likely a few seconds off.
 
I think I can live with a response like that for now. I'll fine tune it all once it's together and working.

Any other tips you can give to a prospective Arduino brewery builder? Did you write a PID algorithm for your burners?
 
I haven't messed with PID yet, but I may. There's some open source code that looks very user friendly on the Arduino site. For the moment, I'm manually running any recirculation or steam injection. I may play with PWM control of the element that heats the boil kettle later this weekend.

As far as advice:
Test everything and test again. Dive into writing code and building seemingly complex circuits. Don't be afraid of mistakes. Have mechanical fail-safes that prevent software/hardware errors from becoming dangerous. Any plan is better than no plan, but plans alone won't brew your beer - get to work!

Oh yeah, and don't take advice from anyone.
 
Here is the Java code I have cobbled together for a PID loop that can compensate for small and large input ranges, integral limit to control windup, and has a calculation cycle time adjustment.

public class PIDLogic implements Runnable {

private double KProportional;
private double KIntegral;
private double KDifferential;
private double IntegralLimit;
private double ProportionalGain;
private double IntegralGain;
private double DifferentialGain;
private double CycleTime;
private double Setpoint;
private double Output;
private double ErrorSum;
private double ErrorGain;
private double Error;
private double PrevError;

public PIDLogic(double kP, double kI, double kD, double lI, double Ctime, double Egain, double SP) {
setProportionalConstant(kP);
setIntegralConstant(kI);
setDifferentialConstant(kD);
setIntegralLimit(lI);
setSetpoint(SP);
setErrorGain(Egain);
setCycleTime(Ctime);


Thread P = new Thread(this);
P.setDaemon(true);
P.setPriority(5);
P.start();
}

public int CalculateGain(double PV) {
try {
Thread.sleep((int)(CycleTime*1000));
} catch (InterruptedException ie) {
}
Error = (Setpoint - PV) * ErrorGain;
ErrorSum += Error;
if (ErrorSum > (IntegralLimit / KIntegral)) {
ErrorSum = (IntegralLimit / KIntegral);
}
ProportionalGain = KProportional * Error;


IntegralGain = KIntegral * ErrorSum;
if (IntegralGain > IntegralLimit) {
IntegralGain = IntegralLimit;
}
if (IntegralGain < -IntegralLimit) {
IntegralGain = -IntegralLimit;
}
DifferentialGain = KDifferential * (PrevError - Error);
PrevError = Error;
Output = ProportionalGain + IntegralGain + DifferentialGain;
return (int) Output;
}

public double getProportionalGain() {
return ProportionalGain;
}

public double getIntegralGain() {
return IntegralGain;
}

public double getDifferentialGain() {
return DifferentialGain;
}

public double getProportionalConstant() {
return KProportional;
}

public double getIntegralConstant() {
return KIntegral;
}

public double getDifferentialConstant() {
return KDifferential;
}

public double getIntegralLimit() {
return IntegralLimit;
}

public double getSetpoint() {
return Setpoint;
}

public void setProportionalConstant(double kP) {
KProportional = kP;
}

public void setIntegralConstant(double kI) {
KIntegral = kI;
}

public void setDifferentialConstant(double kD) {
KDifferential = kD;
}

public void setIntegralLimit(double lI) {
IntegralLimit = lI;
}
public void setSetpoint(double setpoint) {
Setpoint = setpoint;
}

public void setErrorSum(double sum) {
ErrorSum = sum;
}

public void setErrorGain(double EGain) {
ErrorGain = EGain;
}
public void setCycleTime(double Ctime){
CycleTime = Ctime;
}

public void run() {
} //Main driver for threaded version.
}
 
Here is the Java code I have cobbled together for a PID loop that can compensate for small and large input ranges, integral limit to control windup, and has a calculation cycle time adjustment.
<<snip>>

cool. I've been working on a perl version. This should help with the steep curve I'm approaching!

Thanx a bunch
 
I don't approve of your style of beginning variables with a capital letter...
Ok, so it's not perfect naming convention. But that's some fine code. It's well organized, easy to decipher, and likely works well.

On a different note, my brew day is going really well. I got 100% conversion efficiency and it's looking like over 90% lauter efficiency (60 minute mash, 90 minute fly sparge). Things are working very well.

I wrote a quick and dirty PWM control routine this morning. Now I can reduce my extremely violent boil to a nice, controlled, rolling one.
 
Sorry if I offend with the variable naming, but this is not my line of work just what I have taught myself over the last year as a means to control the PLC hardware for my brewing system. If I had the benefit of time to attend a course on writing Java applications the code would have followed the established methods. My field is industrial and commercial instrumentation and most of my time last 5 years has been away from home managing construction projects, not writing software for a living. This is what I do to fill in nights and weekends while on the road, turning control concepts into code to achieve safe automatic unattended brewing system operation. The current code is a combination of Java and MySQL tables with integrated recipe generation and brewing sequence control, and fermentation temperature control for up to 6 fermenters.
 
Another success! My apparent overall efficiency was "only" 80%, which is just fine with me. I think because I used PWM to throttle back the boil, my boil off rate was much reduced, and I got more volume than required into the fermenter. The wort tastes great, and I'm going to RDWHAHB!
 
Another success! I think because I used PWM to throttle back the boil, my boil off rate was much reduced,

Did you determine your pulse width experimentally or did you use a feedback loop with a variable setpoint? I'm wondering if setting the boil to 212, 213, or some other temp would be optimal for a good steady boil without overdriving the element.
 
Due to the awesomeness of the system I will have to let your naming conventions slide.... THIS TIME
 
As I have stated previously this has been a learn as I go process without the benefit of programming guidance, the goal of the latest software revision is to keep CPU time minimized and running memory consumption down. The executable Jar file is down to 3.88 MB and average CPU load is running 5-10% during execution, with 40 - 50MB memory used.
 
Did you determine your pulse width experimentally or did you use a feedback loop with a variable setpoint? I'm wondering if setting the boil to 212, 213, or some other temp would be optimal for a good steady boil without overdriving the element.
I used trial and error to determine a pulse width that would keep a rolling boil. Using temperature as a gauge really doesn't work well, since the temperature of a violent boil is nearly identical to the temperature of a simmer. I found that throttling back to about 50% kept the boil rolling really well.
 
Using temperature as a gauge really doesn't work well, since the temperature of a violent boil is nearly identical to the temperature of a simmer.

That's exactly what I was thinking. Perhaps a PID algorithm isn't really needed at all. Simply 100% duty cycle until 212 (adjusted for altitude) and then go to 50%. I wouldn't think it would need allowance for a small amount of overshoot.

By the way, awesome brew hut! I'll be building in the basement but I don't think I'll be hitting your standard. I haven't finished rebuilding the entire inside of my house yet. ;)
 
You know, I'm really regretting not putting a temp sensor in the boil kettle. In fact, I nearly wrote the code to do exactly what you suggested, Fingers, until I remembered that "tempKettle" didn't exist! I'll probably add another thermocouple soon.
 
That's exactly what I was thinking. Perhaps a PID algorithm isn't really needed at all. Simply 100% duty cycle until 212 (adjusted for altitude) and then go to 50%. I wouldn't think it would need allowance for a small amount of overshoot.

By the way, awesome brew hut! I'll be building in the basement but I don't think I'll be hitting your standard. I haven't finished rebuilding the entire inside of my house yet. ;)

I think 'sugar water' will boil a little higher, at least in the little I've done.
 
I am going to try the changing temperature approach, when the BK temp is the same for 3 cycles 30 seconds apart then boil is true. I was wondering if you have had the time to monitor BK temp to see if temperature rise stops at boil.
 
You know, I'm really regretting not putting a temp sensor in the boil kettle. In fact, I nearly wrote the code to do exactly what you suggested, Fingers, until I remembered that "tempKettle" didn't exist! I think I'll probably add another thermocouple soon.

I ordered a set of four LM35 sensors. One for the MLT, one for the HLT, one for the boil kettle, and one to give me outside temps so I know why I'm brewing in the basement.

I think 'sugar water' will boil a little higher, at least in the little I've done.

That's a good point, Hermit. I think Yuri's approach is best. Simply find the sweet spot and then program it in.
 
I am going to try the changing temperature approach, when the BK temp is the same for 3 cycles 30 seconds apart then boil is true. I was wondering if you have had the time to monitor BK temp to see if temperature rise stops at boil.
That sounds like a fine approach. I would use the following conditions: temp greater than 200° AND stable over a long enough period of time to assure that the temperature rise is complete. That way there's no chance that you'll throttle the element back at a low temp. I have not specifically measured and charted the rise time, but I think you can be reasonably assured that the temperature will stabilize +/- one degree once a boil is achieved.
 
Back
Top