Brewing thermostat

Looks fine. The only change I'd make would be to replace this:

 else if(tempc == right)

with this:

 else if(tempc < too_hot)

It's highly unlikely in a brewing scenario, given one temperature sample a second that you would miss the 22 degree setting, but if you did, the heater would stay on until you reached too_hot, which wouldn't do your beer any favours.

With a gun to my head and asked to find other things to complain about, I could find these:
The constants such as too_hot should either be declared const or done with #define
When it is too cold, you turn on the heat and the audible twice - no need
Setting temp_c=0 at the end of loop is unnecessary

finally, with nitpick mode set to the max, you only use raw_temp once, so this:

raw_temp = analogRead(pin);          // get reading from LM35
tempc = ((100* raw_temp)/1024.0);    // convert to whole decimal degrees

could be this:

tempc = ((100* analogRead(pin))/1024.0);

Saving you a whole 2 bytes! :wink:

tempc = ((100* analogRead(pin))/1024.0);

What happens if the analogRead() returns a value greater than 327? 328 * 100 = 32800, which won't fit in an int. The output from analogRead needs to be cast to a long, and multiplied by a long, to avoid overflow.

tempc = ((100L * (long)analogRead(pin))/1024.0);

Paul, you've just answered a question that I had. When the thermostat reached 32 degrees, it would flip over to -31 degrees. That would be the overflow of which you speak. With that change to a long, I'm happily reading 69 degrees. The sensor has a range up to 100,and can read up to 99, which is a range of 100.

Wildbill, thanks for the suggestions, I've put them in place. I'm still pretty new to programming, so they were quite valuable tips. The suggestion about tempc == right vs. tempc < too_hot was particularly good, I hadn't even thought of that.

The thermostat is now running on my vat in the shed, keeping a nice dark ale at 22 degrees. I've got a working prototype of a new model with easily adjustable temperature setting and a display that reads the set temperature, the actual temperature, and the status of the heater. Here is the code:

/*
 
  The circuit:
 * LCD RS pin to digital pin 8
 * LCD Enable pin to digital pin 9
 * LCD D4 pin to digital pin 10
 * LCD D5 pin to digital pin 11
 * LCD D6 pin to digital pin 12
 * LCD D7 pin to digital pin 13
 * 10K resistor:
   * ends to +5V and ground
   * wiper to LCD VO pin (pin 3)
 
 *relay connected to D0 to control heating element
 *LED connected to D4 as quick visual indicator
 *LM35 temperature sensor to A0
 *1K Linear pot to A5 for adjustment
 
 */

// include the library code:
#include <LiquidCrystal.h>

int des = 0;   //set temperature variable
int pin = 1;   //LM35 input
int tempc = 0; //temperature variable
int pot = 5;   //temperature adjust input

int heat = 0;
int indicate = 4;

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

void setup() {
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  lcd.print("SET: ACT: HEAT?");  // Print headings the LCD.
  analogReference(INTERNAL);     
  pinMode(heat, OUTPUT);
  pinMode(indicate, OUTPUT);
  }

void loop(){
  analogRead(pin);
  delay(5);
  tempc = (100* (long)analogRead(pin)/1024.0);  //save temperature reading as 'tempc'
  delay(5);
  analogRead(pot);
  delay(5);
  des =  analogRead(pot)/34.14;     //saves pot reading as 'des'
                                    //gives a range of about 30
  
      
  lcd.setCursor(1, 1);
  lcd.print("  ");     //clear field
  lcd.setCursor(1, 1);
  lcd.print(des);     //print set temperature
   
  lcd.setCursor(6,1);
  lcd.print("  ");    //clear field
  lcd.setCursor(6,1);
  lcd.print(tempc );  //print actual temperature
   
  
  if(tempc <= des){                 //if actual temperature is less than
    digitalWrite(heat, HIGH);       //or equal to the set temperature, turn the heater on
    digitalWrite(indicate, HIGH);
    lcd.setCursor(11,1);
    lcd.print("ON ");
}
  else  if(tempc > des){             //otherwise leave the heater off
    digitalWrite(heat, LOW);
    digitalWrite(indicate, LOW);
    lcd.setCursor(11,1);
    lcd.print("OFF");
}
delay(100);
}

I would like to have a button that enters into a 'temperature set' mode so that the potentiometer won't affect the settings unless intended to, but I can't get that working. I'll play with it a bit more and post a bit later.

Here is my most recent code, using up/down buttons instead of a pot for temperature control. I still can't get the 'if buttonpress == true, enter set mode' function to happen though, but this is close enough for the moment:

/*
 
  The circuit:
 * LCD RS pin to digital pin 8
 * LCD Enable pin to digital pin 9
 * LCD D4 pin to digital pin 10
 * LCD D5 pin to digital pin 11
 * LCD D6 pin to digital pin 12
 * LCD D7 pin to digital pin 13
 * 10K resistor:
   * ends to +5V and ground
   * wiper to LCD VO pin (pin 3)
 
 *relay connected to D0 to control heating element
 *LED connected to D4 as quick visual indicator
 *LM35 temperature sensor to A0
 *up and down buttons to D1 and D2
 
 */



#include <LiquidCrystal.h>

int des = 20;           //set temperature variable
int lastdes = 0;
int tempc = 0;          //temperature variable
int Counter1 = 0;       // counter for the number of button presses
int Counter2 = 0;       // counter for the number of button presses
int State1 = 0;         // current state of the button
int State2 = 0;         // current state of the button
int lastState1 = 0;     // previous state of the button
int lastState2 = 0;
int val = 0;





int pin = 1;            //LM35 input
const int set1 = 1;     //temp up and temp down buttons
const int set2 = 2;
int heat = 0;           //output to heater control
int indicate = 4;       //visual indicator output


LiquidCrystal lcd(8, 9, 10, 11, 12, 13);   // initialize the library with the numbers of the interface pins

void setup() {
  lcd.begin(16, 2);
  lcd.print("SET: ACT: HEAT?");  // Print headings to the LCD.
  analogReference(INTERNAL);     
  pinMode(heat, OUTPUT);
  pinMode(indicate, OUTPUT);
  pinMode(set1, INPUT);
  pinMode(set2, INPUT);

}

void loop() {
 State1 = digitalRead(set1);
  State2 = digitalRead(set2);  
  if (State1 != lastState1) {
        if (State1 == HIGH && des!= 100) {      //if up button is pressed, add 1 to des
        des++;
     } 
    
  }
  
  if (State2 != lastState2) {  //if down button is pressed, subtract 1 from des
       if (State2 == HIGH && des != 0) {
       des--; 
    }
  }
  analogRead(pin);
  delay(10);
  tempc = (100* (long)analogRead(pin)/1024.0);  //save temperature reading as 'tempc'
  delay(1);                                     //gives a range of about 30
  
  lcd.setCursor(1, 1);
  lcd.print("    ");     //clear field
  lcd.setCursor(1, 1);
  lcd.print(des);     //print set temperature
  
   delay(50);
  lcd.setCursor(6,1);
  lcd.print("  ");    //clear field
  lcd.setCursor(6,1);
  lcd.print(tempc );  //print actual temperature
  
delay(50);
  if(tempc <= des){                 //if actual temperature is less than
    digitalWrite(heat, HIGH);       //or equal to the set temperature, turn the heater on
    digitalWrite(indicate, HIGH);
    lcd.setCursor(11,1);
    lcd.print("ON ");
    delay(50);
}
  else  if(tempc > des){             //otherwise leave the heater off
    digitalWrite(heat, LOW);
    digitalWrite(indicate, LOW);
    lcd.setCursor(11,1);
    lcd.print("OFF");
  
  }
}

If you're still looking for coding input, this doesn't look quite right:

  if (State1 != lastState1) {
        if (State1 == HIGH && des!= 100) {      //if up button is pressed, add 1 to des
        des++;
     }

You never do anything with lastState1, it's always 0. It looks like part of a debounce routine, but isn't debouncing at the moment - I assume the delays later in loop are actually taking care of the bounce issue, whether intended or not.

Thanks, that was indeed leftover code from debouncing that proved redundant.

Looks cool..:slight_smile:

I'm a homebrewer too, and plan on a project like this soon. Rather than arduino-ify the fermentation portion of the process, I am leaning more towards the mash. American science surplus has these cool little heaters from coffee pots right now and they are dirt cheap (2 for $1.25) I got 4 or them and plan on pump the mash liquor around them (in copper tubing of course) to give me a fully programmable and consistent step up and possibly even programmable decotion mashing. How about an update? How's it working for you?

The heaters I was talking about http://www.sciplus.com/recommend.cfm/recommendid/4157

My plan is to use this relay Solid State Relay - 8A - COM-10636 - SparkFun Electronics with a pot to adjust pwm in to the relay. I'll be using one of these Thermistor 10K - SEN-00250 - SparkFun Electronics to monitor temperature and would very much like to add my http://www.sparkfun.com/products/10168 to the project for visual feedback since it's doing little more than occupying space in my parts box right now. But, as of now this project is beyond my capability.

It does seem easy enough, I just have to learn , ie get these guys to help me, to do it.

What a great site, I love this place! Who needs school when you got all these brilliantly deviant minds in one spot on teh interwebz?

One day when I'm a genius I'll get up to all-grain brews, at which point I 'll experiment with a similar project, but for now the brewing stage is a good start. The main motivation for it was that I don't have much space, so I wanted to put my vat in the shed, which gets awfully cold. I'm in the process of trying to box it all up into an enclosure at the moment, but I've done something wrong in the transition and I can't for the life of me figure out what. The feedback-free prototype has been working very effectively for the past week-and-a-bit though, and I'll be bottling on Saturday. I love the look of those heaters, but alas, American Science & Surplus don't ship to Australia, otherwise I would jump on that.

You're right, it is quite easy, this is my first project that incorporates programming of any description, and with the help of these fellows and some books, it has been a rewarding challenge, though eminently possible.

First of all, you have no need for genius to brew with all grain. It's the oldest form of brewing there is and quite simple. I made a video of me brewing an all grain batch that many people really enjoyed, but google just removed it along with all the other videos they hosted. As soon as I find another host I will upload it and post the link here (It's too big for youtube, apparently) so you can see just how easy it is. With your shed being so cold you should brew a lager. Being here in the states we have to build things or buy gadgets for freezers to brew lagers. Brew a couple lagers and forget about them. Go about your ale making and in a few months you'll have homebrewed perfection waiting on. I can't be much help with electronics as I am here to learn from the very beginning almost, but as far as brewing I'll help you any way I can. Also, if you really want one of those heaters I'll ship you a couple. Is it crazy expensive to ship or something? I'm not even worried about you paying me for them. I think I can spare $1.25 :D, it's the shipping that might scare me.

You were talking about boxing your whole thing up, google "son of a fermentation chamber". Instead of cooling, just change the chillings bits to heating bits. Super cheap and easy to build.

Edit:Holy crap! It appears the video is still up for the moment! Enjoy!
http://video.google.com/videoplay?docid=-8400604593450308344#

Thanks for that, if I have any questions I'll be sure to come to you! That would actually be great if you could ship me some of those, I'll PM you. I'm not sure why they don't ship to Australia, but I tried to get some things from them a while ago and they refused to send to me.

With boxing it up, I was referring to the electronics rather than the whole system, but when I have room I intend to hack an old fridge as an insulated brew-box.

I've been doing the hardware side of things since I was 12, so I can offer you some help there if you like, though it is just a hobby of mine, my main pursuit being Classical History.

You can't get more classical history than brewing your own beer. Much like killing an antelope with a stick you sharpened on a rock and eating it raw...... well maybe not that dramatic, but you get the point :stuck_out_tongue:

compuslave:
American science surplus has these cool little heaters from coffee pots right now and they are dirt cheap (2 for $1.25) I got 4 or them

The heaters I was talking about http://www.sciplus.com/recommend.cfm/recommendid/4157

Howdy, have you tried these little babies yet? I was planning on a gas RIMS system - couldn't be bothered with a stainless steel electric system) so was wondering how you got on with these.

I'm heading over to the states soon, so might order a few to have waiting for me when I get there.

Still trying to get this damned thing to work, the whole thing works perfectly on the breadboard, but as soon as I try to migrate it to vero board or a PCB, it fails. I'm up to my second PCB design, I gave up on vero board after 3 failures, I have absolutely no clue what is going wrong. Does anyone have any ideas? I've checked and double-checked my connections, there are no short circuits that I've found. The one error I have found I have corrected. Any ideas would be greatly appreciated.

One of the electronics wizards can probably help you, but they'll need a bit more detail. Some pictures might help.

Hmm, good point.

The farthest into double checking that I've been ale to get is the display half of the circuit. I've checked so many times that the RS, EN, and D4-7 pins are connected to the right pins, and they are. For some reason though, when I power the circuit up, I get the first row filled with the black rectangles that make up the characters' spots, and the second row is empty. At the moment, getting the display working is the first priority, because the rest relies on it, and the rest is much easier to test/fix.

I'll see if I can come up with some good photos, but does that problem scream out to anyone as being caused by a particular thing?

Problem solved, it turns out the 7805 I had was interfering with the LCD in some way, I'm not entirely sure how, but I've gotten rid of it and it works fine. Does anyone have any ideas why this may have been a problem?

I've no idea specifically why it didn't work, but generally I can say that my experience is that if all connections are fine (triple checked and measured), you should have a look at the power supply. It is one of the things that also changes when moving off from the breadboard and into "reality". Powering from an USB, or desktop power supply with nice smooth voltage and steady current is something completely different than a dodgy old car battery, solar cell or whatever you end up connecting you thing to in the end.

I was using a switchmode regulated 12v power supply, feeding directly into the 7805, I'm now using the supply's equivalent in 5v with no regulator, works fine.