iBrew - First Photos
Moderator: Post Moderators
- backyard brewer
- Posts: 3774
- Joined: Fri Feb 18, 2005 5:38 pm
- Location: Orange County, CA
- Contact:
iBrew - First Photos
I took a few pictures of my Arduino based brew controller.
This shows the front of the controller hardware with a few components detailed out.
Here is the copper side of the board with all the traces. The two headers are what allow it to plug into the Arduino. This makes it what they call a "Shield"
Here's a stack of 4 temperature sensors built on the LM34 chip. I'm having some problems now though as the reading floats all over. I think I need a decoupling capacitor, but i don't know yet. On the breadboard these worked great. Everything else on the board, relays, rotary encoder etc seem to be working fine individually.
Here's a temp sensor with the sleeve removed, showing the LM34.
And here's a shot of the iBrew Shield coupled to the Arduino board.
This shows the front of the controller hardware with a few components detailed out.
Here is the copper side of the board with all the traces. The two headers are what allow it to plug into the Arduino. This makes it what they call a "Shield"
Here's a stack of 4 temperature sensors built on the LM34 chip. I'm having some problems now though as the reading floats all over. I think I need a decoupling capacitor, but i don't know yet. On the breadboard these worked great. Everything else on the board, relays, rotary encoder etc seem to be working fine individually.
Here's a temp sensor with the sleeve removed, showing the LM34.
And here's a shot of the iBrew Shield coupled to the Arduino board.
Last edited by backyard brewer on Mon Nov 17, 2008 9:52 am, edited 1 time in total.
- maltbarley
- Posts: 2408
- Joined: Thu Dec 08, 2005 9:31 am
- Location: Orange, CA
- backyard brewer
- Posts: 3774
- Joined: Fri Feb 18, 2005 5:38 pm
- Location: Orange County, CA
- Contact:
I need to make a youtube video of this, otherwise it'll be too many pictures. I still need to put it in a case, but for the brewery control part of things it's done and working. Still to do is place it in a case, finish the other temperature probes , decide how I want to log data and write the second sketch to control fermentation. Actually, I'll just add to this one and have an option to select the brewery control program or the fermentation program.
When you start it, there is a splash screen for 5 seconds, then it goes to displaying the HLT temp. There is a rotary encoder (like a potentiometer but with no ends) that has a push button selector like a car stereo or iPod. You can cycle through each of the 6 temperature displays.
If you are on the HLT or Mash Temp displays, you can press the encoder to enter the setpoint routine and set a setpoint for either of those. It'll tell you "Setpoint Accepted" and then jump back to the temp display routine. If a setpoint has been entered, the HLT or Mash displays will display the setpoint as well as the current temp and tell you in the burner is on. There is a built-in 30 second delay on the burner ignition, so the burner cannot re-ignite within 30 seconds of having just been on. If the 30 second lock-out is active, the display has a count-down timer on it, otherwise it will display "ON" or "OFF" on the corner of the display when you are viewing HLT or MLT temps.
Here's the code so far:
When you start it, there is a splash screen for 5 seconds, then it goes to displaying the HLT temp. There is a rotary encoder (like a potentiometer but with no ends) that has a push button selector like a car stereo or iPod. You can cycle through each of the 6 temperature displays.
If you are on the HLT or Mash Temp displays, you can press the encoder to enter the setpoint routine and set a setpoint for either of those. It'll tell you "Setpoint Accepted" and then jump back to the temp display routine. If a setpoint has been entered, the HLT or Mash displays will display the setpoint as well as the current temp and tell you in the burner is on. There is a built-in 30 second delay on the burner ignition, so the burner cannot re-ignite within 30 seconds of having just been on. If the 30 second lock-out is active, the display has a count-down timer on it, otherwise it will display "ON" or "OFF" on the corner of the display when you are viewing HLT or MLT temps.
Here's the code so far:
Code: Select all
// **************************************************************
// ** Backyard Brewing Co. **
// ** iBrew **
// ** Brewery Logging and Control System v 2.0 **
// ** ***********************************************************
#include <LCD4Bit.h> //create object to control an LCD.
LCD4Bit lcd = LCD4Bit(2); //number of lines in display=2
#define LM34 0.48828125 // defines LM34 as .48828125 which is 500/1024 for the LM34 which produces .5mV per 1/2*F.
#define encoderPinA 2
#define encoderPinB 3
#define encoderSelector 0
// Variable Declarations
int i = 0; // Used for For loop control
int selectorCount = 0; // holds count for encoder selector button presses
unsigned long time = 0; // used to take a snapshot of current runtime and hold it.
char lcdString[12]; // temp variable for int to char conversion for LCD
volatile int encoderPos = 0; // Stores rotary encoder position
volatile int selectorLimit = 0; // Holds maximum value before encoder stops counting
// Array definitions
int relayPin [4] = {10, 11, 12, 13 }; // sets relay pins on 10, 11, 12, 13
int relayStatus [4] = {0, 0, 0, 0 };
int setPoint [2] = {0, 0 };
unsigned long offTime [2] = {0, 0 };
boolean relayDelayOn [4];
/*
Relay pin array position Relay:
0 = HLT Relay
1 = MLT Relay
*/
// Sensor Read definitions
int sensorPin [6] = {0, 1, 2, 3, 4, 5 }; // defines analog pins temp sensors are on
float tempReading [6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; // array to store temp readings, sets all to 0
/*
TempReadings array positions:
0 = HLT Temp
1 = MLT Main body Temp
2 = MLT Sparge/recirc return temp
3 = Boil Kettle Temp
4 = Chiller H20 inlet temp
5 = Chiller H20 Outlet temp
*/
void setup() {
lcd.init();
//Serial.begin (9600);
pinMode(encoderPinA, INPUT);
digitalWrite(encoderPinA, HIGH); // turn on pullup resistor
pinMode(encoderPinB, INPUT);
digitalWrite(encoderPinB, HIGH); // turn on pullup resistor
pinMode(encoderSelector, INPUT);
digitalWrite(encoderSelector, HIGH); // turn on pullup resistor
attachInterrupt(0, doEncoder, CHANGE); // encoder pin on interrupt 0 - pin 2
lcd.clear(); // clears LCD screen
lcd.printIn("Backyard Brewing Co.");
lcd.cursorTo(2, 0);
lcd.printIn("iBrew v2.0");
for ( i = 0; i < 4; i ++) { // Set Digital Pin modes and turn all relays off
pinMode(relayPin [i], OUTPUT);
digitalWrite(relayPin [i], LOW);
}
delay (5000); // Hold splash screen for 5 seconds
} // end setup
void loop(){ // Begin Program loop
for ( i = 0; i < 6; i++) { // Read all sensors
tempReading [i] = (analogRead(sensorPin [i]) * LM34); // Reads each analog pin, converts the reading to *F and stores it in the TempReading array
}
selectorLimit = 5; // Sets top limit on encoder to 5
switch (encoderPos) { // selects display based on encoder position
case 0 :
if (digitalRead (encoderSelector) == LOW ) { // In the selector is pressed, accept new setpoint
selectorLimit = 212; // Set encoder top limit to 212
encoderPos = setPoint[0]; // starts encoder position at current setpoint
delay (300); // debounce selector
while (digitalRead (encoderSelector) == HIGH) { // while the selector is NOT pressed, accept new setpoint from encoder
lcd.cursorTo(1, 0); // Places LCD cursor to line 1 pos 0
lcd.printIn("Enter HLT Setpoint : ");
lcd.printIn(itoa(encoderPos, lcdString, 10)); // converts integer to char for LCD print
lcd.printIn(" "); // print empty space to blank LCD without refreshing it
lcd.cursorTo(2, 0);
lcd.printIn("Current Setpoint = ");
lcd.printIn(itoa(setPoint[0], lcdString, 10));
lcd.printIn(" ");
}
setPoint[0] = encoderPos; // Sets new setpoint to encoder position
lcd.clear(); // clear LCD
lcd.printIn("New Setpoint Accepted");
encoderPos = 0; // clear encoder position
delay (1000); // wait 1 second to read message
break; // return to program
}
else {
lcd.cursorTo(1, 0); // if selector has not been pressed, display as normal
lcd.printIn("HLT Temp = ");
lcd.printIn(itoa(tempReading[0], lcdString, 10));
lcd.printIn(" ");
if (relayStatus[0] == 1) { // Check if relay is on or off
if (relayDelayOn [0]) { // Check delay status
lcd.cursorTo(1,21);
lcd.printIn(itoa(30-(time - offTime [0]), lcdString, 10)); // If delay is on, display count down timer
lcd.printIn(" ");
}
else { // delay is not on, display "ON"
lcd.cursorTo(1, 21);
lcd.printIn("ON ");
}
}
if (relayStatus[0] == 0) { // relay is flagged as off
lcd.cursorTo(1, 21);
lcd.printIn("OFF"); // display "OFF"
}
lcd.cursorTo(2, 0);
lcd.printIn("HLT Setpoint = ");
lcd.printIn(itoa(setPoint[0], lcdString, 10));
lcd.printIn(" ");
break;
}
case 1 : // All other cases are based on case 0
if (digitalRead (encoderSelector) == LOW ) {
selectorLimit = 212;
encoderPos = setPoint[1];
delay (300);
while (digitalRead (encoderSelector) == HIGH) {
lcd.cursorTo(1, 0);
lcd.printIn("Enter Mash Setpoint: ");
lcd.printIn(itoa(encoderPos, lcdString, 10));
lcd.printIn(" ");
lcd.cursorTo(2, 0);
lcd.printIn("Current Setpoint = ");
lcd.printIn(itoa(setPoint[1], lcdString, 10));
lcd.printIn(" ");
}
setPoint[1] = encoderPos;
lcd.clear();
lcd.printIn("New Setpoint Accepted");
encoderPos = 1;
delay (1000);
break;
}
else {
lcd.cursorTo(1, 0);
lcd.printIn("Mash Temp = ");
lcd.printIn(itoa(tempReading[1], lcdString, 10));
lcd.printIn(" ");
if (relayStatus[1] == 1) {
if (relayDelayOn [1]) {
lcd.cursorTo(1,21);
lcd.printIn(itoa(30-(time - offTime [1]), lcdString, 10));
lcd.printIn(" ");
}
else {
lcd.cursorTo(1, 21);
lcd.printIn("ON ");
}
}
if (relayStatus[1] == 0) {
lcd.cursorTo(1, 21);
lcd.printIn("OFF");
}
lcd.cursorTo(2, 0);
lcd.printIn("Mash Setpoint = ");
lcd.printIn(itoa(setPoint[1], lcdString, 10));
lcd.printIn(" ");
break;
}
case 2 :
lcd.cursorTo(1, 0);
lcd.printIn("Vorlauf Return Temp= ");
lcd.printIn(itoa(tempReading[2], lcdString, 10));
lcd.printIn(" ");
lcd.cursorTo(2, 0);
lcd.printIn(" ");
break;
case 3 :
lcd.cursorTo(1, 0);
lcd.printIn("Boil Kettle Temp = ");
lcd.printIn(itoa(tempReading[3], lcdString, 10));
lcd.printIn(" ");
lcd.cursorTo(2, 0);
lcd.printIn(" ");
break;
case 4 :
lcd.cursorTo(1, 0);
lcd.printIn("Chiller H20 In Temp= ");
lcd.printIn(itoa(tempReading[4], lcdString, 10));
lcd.printIn(" ");
lcd.cursorTo(2, 0);
lcd.printIn(" ");
break;
case 5 :
lcd.cursorTo(1, 0);
lcd.printIn("Chillr H20 Out Temp= ");
lcd.printIn(itoa(tempReading[5], lcdString, 10));
lcd.printIn(" ");
lcd.cursorTo(2, 0);
lcd.printIn(" ");
break;
}
// Compare sensor reads to setpoints and set relays accordingly
// HLT Control
time = millis() / 1000; // Sets time to the current total program runtime in seconds.
if (tempReading [0] < setPoint [0] ) { // Compare HLT temp: Temperature is below setpoint
if ( time - offTime [0] > 30) { // Check to confirm burner has been off at least 30 seconds
digitalWrite( relayPin [0], HIGH); // Turn HLT Burner On.
relayStatus [0] = 1; // Set HLT Burner Status as on
relayDelayOn [0] = false; // Set burner delay flag as off
}
else { // 30 second delay is not over
relayStatus [0] = 1; // Flag the relay as on (even though it isn't)
relayDelayOn [0] = true; // Flag the relay delay as true
}
}
else { // Temperature is above setpoint
if (relayStatus[0] == 1) { // Confirm relay is currently on
digitalWrite( relayPin [0], LOW); // Turn HLT Burner Off.
relayStatus [0] = 0; // Set HLT Burner Status to off
offTime [0] = time; // Time stamps the off time for Burner.
}
}
// End HLT Control
// MLT Control
time = millis() / 1000; // Sets Time to the current total program runtime in seconds.
if (tempReading [1] < setPoint [1] ) { // Compare MLT: Temperature below setpoint
if ( time - offTime [1] > 30) { // Check to confirm burner has been off at least 30 seconds
digitalWrite( relayPin [1], HIGH); // Turn MLT Burner On.
digitalWrite( relayPin [2], HIGH); // Turn Pump On to ensure wort is not scortched
relayStatus [1] = 1; // Set MLT Burner Status as on
relayStatus [2] = 1; // Set MLT Pump Status as on
relayDelayOn [1] = false; // Set relay 2 delay as false
relayDelayOn [2] = false; // Set relay 3 delay as false
}
else { // 30 second delay is not over
relayStatus [1] = 1; // Flag MLT burner as on
relayStatus [2] = 1; // Flag pump as on
relayDelayOn [1] = true; // Flag MLT burner delay as true
relayDelayOn [2] = true; // Flag pump delay as true
}
}
else { // Temperature is above setpoint
if (relayStatus[1] == 1) { // Confirm relay is on
digitalWrite( relayPin [1], LOW); // Turn HLT Burner Off.
digitalWrite( relayPin [2], LOW); // Turn pump off.
relayStatus [1] = 0; // Set HLT Burner Status
relayStatus [2] = 0; // Set relay 3 pump status
offTime [1] = time; // Time stamps the off time for Burner.
}
}
// End MLT control
} // End Program loop
void doEncoder(){ // encoder routine. modified from Arduino.cc Playground.
if (digitalRead(encoderPinA) == HIGH) { // found a low-to-high on channel A
if (digitalRead(encoderPinB) == LOW) { // check channel B to see which way encoder is turning
encoderPos ++ ; // CW
}
else {
encoderPos -- ; // CCW
}
}
else { // found a high-to-low on channel A
if (digitalRead(encoderPinB) == LOW) { // check channel B to see which way encoder is turning
encoderPos --; // CCW
}
else {
encoderPos ++; // CW
}
}
if ( encoderPos <=0 ) { // set lower limit of encoder to 0
encoderPos = 0;
}
if ( encoderPos >= selectorLimit ) { // set upper limit of encoder to set limit
encoderPos = selectorLimit;
}
//Serial.println (encoderPos, DEC); // debug - remember to comment out
}
That's really cool Derrin, I can't wait to see it in action. Next up ... hooking it to your universal remote control!
http://blog.makezine.com/archive/2008/1 ... 6B48984890
(Yea, this would be the other way around, but it got me thinking...)
http://blog.makezine.com/archive/2008/1 ... 6B48984890
(Yea, this would be the other way around, but it got me thinking...)
- backyard brewer
- Posts: 3774
- Joined: Fri Feb 18, 2005 5:38 pm
- Location: Orange County, CA
- Contact:
I know, i saw several of those when i was looking for a way to use an iPod as a control source. Plenty of info on controlling an iPod with the Arduino though.brahn wrote:That's really cool Derrin, I can't wait to see it in action. Next up ... hooking it to your universal remote control!
http://blog.makezine.com/archive/2008/1 ... 6B48984890
(Yea, this would be the other way around, but it got me thinking...)
I'll be late tonight but I'll bring it by.
- backyard brewer
- Posts: 3774
- Joined: Fri Feb 18, 2005 5:38 pm
- Location: Orange County, CA
- Contact:
Re: iBrew - First Photos
Here are some photos of the latest generation of my iBrew. I hope to have it operational (meaning actually attached )by the Jan 3rd brew day. I made some changes to the circuit board. I added an inverter to the board to power the EL backlight on the LCD and I moved the temp sensor jacks onto the board instead of connecting via headers; there were just too many wires going from the board to elsewhere in the enclosure. That allowed me to move the RC signal cleaning circuits to the board too. This enclosure is temporary, I don't like it and the switches are just too big. I wanted a heavy duty looking switch but I've since changed my mind and will go with something that A) doesn't require a square f-ing hole and B) Doesn't take up so much room.
iBrew inside shot:
Here's a closeup of the new board, installed in the case:
This is the new Splash Screen:
Here's the HLT screen. The setpoint has been set to 80* and the screen and LED are indicating the burner would be ON:
This is what the screen looks like when entering a new setpoint:
And the MLT screen, also indicating the MLT burner and pump are both on. If the iBrew turns on the MLT burner is turns on the pump at the same time to prevent scortching.
The rest of the photos are just cycling through the remaining temperature reading screens. There were only 3 sensors hooked up when I took the pictures so the remaining screens show random values. The inputs float if there is not a sensor attached.
iBrew inside shot:
Here's a closeup of the new board, installed in the case:
This is the new Splash Screen:
Here's the HLT screen. The setpoint has been set to 80* and the screen and LED are indicating the burner would be ON:
This is what the screen looks like when entering a new setpoint:
And the MLT screen, also indicating the MLT burner and pump are both on. If the iBrew turns on the MLT burner is turns on the pump at the same time to prevent scortching.
The rest of the photos are just cycling through the remaining temperature reading screens. There were only 3 sensors hooked up when I took the pictures so the remaining screens show random values. The inputs float if there is not a sensor attached.
Re: iBrew - First Photos
Very cool Derrin.
Dan
Dan
Re: iBrew - First Photos
I agree, very cool Derrin. Now I really wish I could make the Jan 3rd Brew Day.
- backyard brewer
- Posts: 3774
- Joined: Fri Feb 18, 2005 5:38 pm
- Location: Orange County, CA
- Contact:
Re: iBrew - First Photos
Current Code as of 12-23. Posted for thread on HBT Forum:
Code: Select all
// **************************************************************
// ** Backyard Brewing Co. **
// ** iBrew **
// ** Brewery Logging and Control System v 2.0 **
// ** LM34's must have 82ohm resistor in series with 1uF cap **
// ** from signal to ground in addition to .1uF cap across **
// ** Vs to ground at jack. **
// **************************************************************
#include <LCD4Bit.h> //create object to control an LCD.
LCD4Bit lcd = LCD4Bit(2); //number of lines in display=2
#define LM34 0.48828125 // defines LM34 as .48828125 which is 500/1024 for the LM34 which produces .5mV per 1/2*F.
#define encoderPinA 2
#define encoderPinB 3
#define encoderSelector 0
// Variable Declarations
int i = 0; // Used for For loop control
int selectorCount = 0; // holds count for encoder selector button presses
unsigned long time = 0; // used to take a snapshot of current runtime and hold it.
char lcdString[12]; // temp variable for int to char conversion for LCD
volatile int encoderPos = 0; // Stores rotary encoder position
volatile int selectorLimit = 0; // Holds maximum value before encoder stops counting
// Array definitions
int relayPin [4] = {10, 11, 12, 13 }; // sets relay pins on 10, 11, 12, 13
int relayStatus [4] = {0, 0, 0, 0 };
int setPoint [2] = {0, 0 };
unsigned long offTime [2] = {0, 0 };
boolean relayDelayOn [4];
/*
Relay pin array position Relay:
0 = HLT Relay
1 = MLT Relay
*/
// Sensor Read definitions
int sensorPin [6] = {0, 1, 2, 3, 4, 5 }; // defines analog pins temp sensors are on
float tempReading [6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; // array to store temp readings, sets all to 0
/*
TempReadings array positions:
0 = HLT Temp
1 = MLT Main body Temp
2 = MLT Sparge/recirc return temp
3 = Boil Kettle Temp
4 = Chiller H20 inlet temp
5 = Chiller H20 Outlet temp
*/
void setup() {
lcd.init();
//Serial.begin (9600);
pinMode(encoderPinA, INPUT);
digitalWrite(encoderPinA, HIGH); // turn on pullup resistor
pinMode(encoderPinB, INPUT);
digitalWrite(encoderPinB, HIGH); // turn on pullup resistor
pinMode(encoderSelector, INPUT);
digitalWrite(encoderSelector, HIGH); // turn on pullup resistor
attachInterrupt(0, doEncoder, CHANGE); // encoder pin on interrupt 0 - pin 2
lcd.clear(); // clears LCD screen
lcd.printIn("Backyard Brewing Co.");
lcd.cursorTo(2, 0);
lcd.printIn("iBrew v2.0");
for ( i = 0; i < 4; i ++) { // Set Digital Pin modes and turn all relays off
pinMode(relayPin [i], OUTPUT);
digitalWrite(relayPin [i], LOW);
}
delay (5000); // Hold splash screen for 5 seconds
} // end setup
void loop(){ // Begin Program loop
for ( i = 0; i < 6; i++) { // Read all sensors
tempReading [i] = (analogRead(sensorPin [i]) * LM34); // Reads each analog pin, converts the reading to *F and stores it in the TempReading array
}
selectorLimit = 5; // Sets top limit on encoder to 5
switch (encoderPos) { // selects display based on encoder position
case 0 :
if (digitalRead (encoderSelector) == LOW ) { // In the selector is pressed, accept new setpoint
selectorLimit = 212; // Set encoder top limit to 212
encoderPos = setPoint[0]; // starts encoder position at current setpoint
delay (300); // debounce selector
while (digitalRead (encoderSelector) == HIGH) { // while the selector is NOT pressed, accept new setpoint from encoder
lcd.cursorTo(1, 0); // Places LCD cursor to line 1 pos 0
lcd.printIn("Enter HLT Setpoint : ");
lcd.printIn(itoa(encoderPos, lcdString, 10)); // converts integer to char for LCD print
lcd.printIn(" "); // print empty space to blank LCD without refreshing it
lcd.cursorTo(2, 0);
lcd.printIn("Current Setpoint = ");
lcd.printIn(itoa(setPoint[0], lcdString, 10));
lcd.printIn(" ");
}
setPoint[0] = encoderPos; // Sets new setpoint to encoder position
lcd.clear(); // clear LCD
lcd.printIn("New Setpoint Accepted");
encoderPos = 0; // clear encoder position
delay (1000); // wait 1 second to read message
break; // return to program
}
else {
lcd.cursorTo(1, 0); // if selector has not been pressed, display as normal
lcd.printIn("HLT Temp = ");
lcd.printIn(itoa(tempReading[0], lcdString, 10));
lcd.printIn(" ");
if (relayStatus[0] == 1) { // Check if relay is on or off
if (relayDelayOn [0]) { // Check delay status
lcd.cursorTo(1,21);
lcd.printIn(itoa(30-(time - offTime [0]), lcdString, 10)); // If delay is on, display count down timer
lcd.printIn(" ");
}
else { // delay is not on, display "ON"
lcd.cursorTo(1, 21);
lcd.printIn("ON ");
}
}
if (relayStatus[0] == 0) { // relay is flagged as off
lcd.cursorTo(1, 21);
lcd.printIn("OFF"); // display "OFF"
}
lcd.cursorTo(2, 0);
lcd.printIn("HLT Setpoint = ");
lcd.printIn(itoa(setPoint[0], lcdString, 10));
lcd.printIn(" ");
break;
}
case 1 : // All other cases are based on case 0
if (digitalRead (encoderSelector) == LOW ) {
selectorLimit = 212;
encoderPos = setPoint[1];
delay (300);
while (digitalRead (encoderSelector) == HIGH) {
lcd.cursorTo(1, 0);
lcd.printIn("Enter Mash Setpoint: ");
lcd.printIn(itoa(encoderPos, lcdString, 10));
lcd.printIn(" ");
lcd.cursorTo(2, 0);
lcd.printIn("Current Setpoint = ");
lcd.printIn(itoa(setPoint[1], lcdString, 10));
lcd.printIn(" ");
}
setPoint[1] = encoderPos;
lcd.clear();
lcd.printIn("New Setpoint Accepted");
encoderPos = 1;
delay (1000);
break;
}
else {
lcd.cursorTo(1, 0);
lcd.printIn("Mash Temp = ");
lcd.printIn(itoa(tempReading[1], lcdString, 10));
lcd.printIn(" ");
if (relayStatus[1] == 1) {
if (relayDelayOn [1]) {
lcd.cursorTo(1,21);
lcd.printIn(itoa(30-(time - offTime [1]), lcdString, 10));
lcd.printIn(" ");
}
else {
lcd.cursorTo(1, 21);
lcd.printIn("ON ");
}
}
if (relayStatus[1] == 0) {
lcd.cursorTo(1, 21);
lcd.printIn("OFF");
}
lcd.cursorTo(2, 0);
lcd.printIn("Mash Setpoint = ");
lcd.printIn(itoa(setPoint[1], lcdString, 10));
lcd.printIn(" ");
break;
}
case 2 :
lcd.cursorTo(1, 0);
lcd.printIn("Vorlauf Return Temp= ");
lcd.printIn(itoa(tempReading[2], lcdString, 10));
lcd.printIn(" ");
lcd.cursorTo(2, 0);
lcd.printIn(" ");
break;
case 3 :
lcd.cursorTo(1, 0);
lcd.printIn("Boil Kettle Temp = ");
lcd.printIn(itoa(tempReading[3], lcdString, 10));
lcd.printIn(" ");
lcd.cursorTo(2, 0);
lcd.printIn(" ");
break;
case 4 :
lcd.cursorTo(1, 0);
lcd.printIn("Chiller H20 In Temp= ");
lcd.printIn(itoa(tempReading[4], lcdString, 10));
lcd.printIn(" ");
lcd.cursorTo(2, 0);
lcd.printIn(" ");
break;
case 5 :
lcd.cursorTo(1, 0);
lcd.printIn("Chillr H20 Out Temp= ");
lcd.printIn(itoa(tempReading[5], lcdString, 10));
lcd.printIn(" ");
lcd.cursorTo(2, 0);
lcd.printIn(" ");
break;
}
// Compare sensor reads to setpoints and set relays accordingly
// HLT Control
time = millis() / 1000; // Sets time to the current total program runtime in seconds.
if (tempReading [0] < setPoint [0] ) { // Compare HLT temp: Temperature is below setpoint
if ( time - offTime [0] > 30) { // Check to confirm burner has been off at least 30 seconds
digitalWrite( relayPin [0], HIGH); // Turn HLT Burner On.
relayStatus [0] = 1; // Set HLT Burner Status as on
relayDelayOn [0] = false; // Set burner delay flag as off
}
else { // 30 second delay is not over
relayStatus [0] = 1; // Flag the relay as on (even though it isn't)
relayDelayOn [0] = true; // Flag the relay delay as true
}
}
else { // Temperature is above setpoint
if (relayStatus[0] == 1) { // Confirm relay is currently on
digitalWrite( relayPin [0], LOW); // Turn HLT Burner Off.
relayStatus [0] = 0; // Set HLT Burner Status to off
offTime [0] = time; // Time stamps the off time for Burner.
}
}
// End HLT Control
// MLT Control
time = millis() / 1000; // Sets Time to the current total program runtime in seconds.
if (tempReading [1] < setPoint [1] ) { // Compare MLT: Temperature below setpoint
if ( time - offTime [1] > 30) { // Check to confirm burner has been off at least 30 seconds
digitalWrite( relayPin [1], HIGH); // Turn MLT Burner On.
digitalWrite( relayPin [2], HIGH); // Turn Pump On to ensure wort is not scortched
relayStatus [1] = 1; // Set MLT Burner Status as on
relayStatus [2] = 1; // Set MLT Pump Status as on
relayDelayOn [1] = false; // Set relay 2 delay as false
relayDelayOn [2] = false; // Set relay 3 delay as false
}
else { // 30 second delay is not over
relayStatus [1] = 1; // Flag MLT burner as on
relayStatus [2] = 1; // Flag pump as on
relayDelayOn [1] = true; // Flag MLT burner delay as true
relayDelayOn [2] = true; // Flag pump delay as true
}
}
else { // Temperature is above setpoint
if (relayStatus[1] == 1) { // Confirm relay is on
digitalWrite( relayPin [1], LOW); // Turn HLT Burner Off.
digitalWrite( relayPin [2], LOW); // Turn pump off.
relayStatus [1] = 0; // Set HLT Burner Status
relayStatus [2] = 0; // Set relay 3 pump status
offTime [1] = time; // Time stamps the off time for Burner.
}
}
// End MLT control
} // End Program loop
void doEncoder(){ // encoder routine. modified from Arduino.cc Playground.
if (digitalRead(encoderPinA) == HIGH) { // found a low-to-high on channel A
if (digitalRead(encoderPinB) == LOW) { // check channel B to see which way encoder is turning
encoderPos ++ ; // CW
}
else {
encoderPos -- ; // CCW
}
}
else { // found a high-to-low on channel A
if (digitalRead(encoderPinB) == LOW) { // check channel B to see which way encoder is turning
encoderPos --; // CCW
}
else {
encoderPos ++; // CW
}
}
if ( encoderPos <=0 ) { // set lower limit of encoder to 0
encoderPos = 0;
}
if ( encoderPos >= selectorLimit ) { // set upper limit of encoder to set limit
encoderPos = selectorLimit;
}
//Serial.println (encoderPos, DEC); // debug - remember to comment out
}
- backyard brewer
- Posts: 3774
- Joined: Fri Feb 18, 2005 5:38 pm
- Location: Orange County, CA
- Contact:
mwahahahahaha!!! - More Power!!!
Someone on the Homebrew talk forum just pointed me to the Sanguino. It's an Arduino based on the ATMega 644P chip vs the ATMega168. What's that mean?
64K of flash memory instead of 16K
4K of ram instead of 1K
2K of EEPROM instead of 512
32 total general I/O pins of which 8 are analong vs 20 of which 6 are analog.
Smaller overall footprint
Anyone want to buy a first generation iBrew based on an Arduino?
64K of flash memory instead of 16K
4K of ram instead of 1K
2K of EEPROM instead of 512
32 total general I/O pins of which 8 are analong vs 20 of which 6 are analog.
Smaller overall footprint
Anyone want to buy a first generation iBrew based on an Arduino?
- backyard brewer
- Posts: 3774
- Joined: Fri Feb 18, 2005 5:38 pm
- Location: Orange County, CA
- Contact:
Re: iBrew - First Photos
Welp....
Looks like some more engineering is in order.... When the Direct Spark Ignition module sparks, it scrambles the Arduino. I haven't grounded the frame which might help, but I think I might have to go with a pilot light system instead of the DSI modules.... The Arduino has to be about 6' from the DSI module. I disconnected the DSI and directly controlled the valve and there was no problem.
Hopefully the pump doesn't do the same thing. It's isolated with a relay but so is the DSI.
Looks like some more engineering is in order.... When the Direct Spark Ignition module sparks, it scrambles the Arduino. I haven't grounded the frame which might help, but I think I might have to go with a pilot light system instead of the DSI modules.... The Arduino has to be about 6' from the DSI module. I disconnected the DSI and directly controlled the valve and there was no problem.
Hopefully the pump doesn't do the same thing. It's isolated with a relay but so is the DSI.
- maltbarley
- Posts: 2408
- Joined: Thu Dec 08, 2005 9:31 am
- Location: Orange, CA
Re: iBrew - First Photos
Perhaps you can protect the controller with an appropriately placed diode.