Matho's controller

Australia & New Zealand Homebrewing Forum

Help Support Australia & New Zealand Homebrewing Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.
Hi everyone,
Now that I have used this controller a few times, and every thing has worked like a charm, thanks Steve and lael
I wanted to know what mash schedules others where using as the stock one, seems to take quite a while, just wondering if all the steps are worth it?

Cheers
 
I mainly run with a two step schedule on mine. 60 minute mash (temp is dependant on recipe) with a 10 minute mash out @ 78 degrees.

Works well for me
 
For anyone making one of these controllers in Melbourne, I have the Jaycar ABS case for it that I don't need. (I am putting mine in a bigger enclosure).

I have already drilled the holes for the buttons and made the cutout for the LCD.

PM me if interested. (price is a bottle of your finest homebrew)
 
Hey all...

I'm in the build process, and have searched with no success... Is there a quick-n-easy way to convert the code/system to Fahrenheit? (I know... Stubborn Americans won't switch)

Even if it isn't quick or easy, I'm not opposed to digging if anyone can point me in the right direction. TIA!

-Chris
 
Hello to all.

In Italy we have created a project derived from Brauduino and we used both degrees Celsius and degrees Faherenheit.

The project is the same as illustrated by Savio with the transformation of the single-sided PCB.
At the original Matho's software I made ​​the following changes:


Modified by Massimo Nevi (2014)
- Added Buzzer Modulation (NumBeep, Period)
- Added Stage CountDown in Automatic Mode
- Added Stage Watch in Manual Mode
- Modified Max Number of Hops (10)
- Modified stage Wait in Active Pause (PID Controlo On)
- Modified H e P indicator for ON-OFF and Active-Disactive Modulation
- Added Some Control Parameter in Configuration Menu
- Added Temp Pump Stop in Manual Mode
- Dual Scale Temp (°C-°F)
- Reorganized EEPROM
- Reorganized Configuration

- Added Second Menu Configuration
- Set Scale Temp (°C-°F)
- Set Temp of Boil
- Set Set Time Pump Cycle and Time Rest
- Set Location of Temp Sensor
- Set Pump ON-OFF at Boil
- Set Temp Pump Stop
- Set Calibration Temp

- Reorganized Automation
- Removed Number of Stages Setting
- Fixed Name of Stages (7)
- Correct Mash In Stage
- Auto Mash Design
- Correct Time Reset of Pump
- Added Iodine Test (Active Pause)

- Stage Managing
- Load Stage Set
- Save Stage Set
- Delete Stage Set
- Initialize EEPROM

- LCD 16x2 wiew
- LCD 20x4 wiew
- Italian Language
- English Language

compiled on Arduino V1.0.5
 
Hi,

Captnausium, I just cobbled together a version that displays degrees F but I will need to test it tomorrow. I'll post it if it works ok (compiles ok)

MaxN68, sounds nice. Where can we find this version?

Regards, Dave
 
We are finishing the test operation of the software with the latest changes made ​​regarding the Italian version.

The English translation is still in Beta version, in a short time I'll put the link with the complete package so I helped to test the operation in English and with Fahereheit


Sorry for my broken English, I am translating with Google
 
Thanks for the quick replies guys! MaxN68, that sounds awesome! If you need a "lab rat" just let me know, I would love to try out your version.

Grazie per le risposte veloci ragazzi! MaxN68, che suona impressionante! Se avete bisogno di un "topo da laboratorio" fammelo sapere, mi piacerebbe provare la versione.
 
Here is a version that displays degrees fahrenheit. Sorry about the formating, if anyone knows how to attach a file or at least keep the indenting etc then please let me know.
Regards, Dave

/*
brauduino semi automated single vessel RIMS
created by s.mathison
Copyright (C) 2012 Stephen Mathison

compiled on Arduino V1.0

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.



27 Feb 2014 Modified by D. Blunn to display fahrenheit for our US cousins.
*/
 
 
//libraries
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <OneWire.h>
#include <PID_v1.h>
OneWire ds(11);
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
 
// push buttons
const char Button_up = A3;
const char Button_dn = A2;
const char Button_prev = A1;
const char Button_nxt = A0;
 
// outputs
const int Heat = 9;
const int Pump = 8;
const int Buzz = 10;
 
// global variables
unsigned int WindowSize;
unsigned long windowStartTime;
unsigned long start;
double Setpoint, Input, Output,eepromKp, eepromKi, eepromKd;
//boolean autoLoop = false;
boolean manualLoop = false;
boolean waterAdd = false;
boolean Conv_start = false;
boolean mpump = false;
boolean mheat = false;
boolean wtBtn = false;
boolean autoEnter = false;
boolean tempReached = false;
boolean pumpRest = false;
//boolean boilLoop = false;
boolean resume = false;
float mset_tempF, mset_temp = 35;
float Temp_c, stageTemp,pumptempError,Temp_PID, Temp_f, stageTempF;
int x;
int stageTime,hopTime;
byte mainMenu = 0;
byte pumpTime;
byte data[2];
byte second;
//byte minute;
//byte i;
byte Busy = 0;
byte nmbrStgs;
byte nmbrHops;
byte tempHAddr;
byte tempLAddr;
byte timeAddr;
byte blhpAddr;
byte hopAdd;
char* stgName[] ={
"MashIn","Stage1","Stage2","Stage3","Stage4","Stage5","Stage6","Stage7","Stage8","Boil "};
//// degree c sybmol
//byte degc[8] =
//{
// B01000,
// B10100,
// B01000,
// B00011,
// B00100,
// B00100,
// B00011,
// B00000,
//};
// degree f symbol
byte degf[8] =
{
B01000,
B10100,
B01000,
B00011,
B00100,
B01110,
B00100,
B00000,
};
//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,100,20,5, DIRECT);
 
//****** start of the funtions**************
 
void Buzzer(int number)
{
for (int i=0; i < number; i++)
{
digitalWrite (Buzz,HIGH);
delay (500);
digitalWrite(Buzz,LOW);
delay(100);
}
}
 
void pause_stage(void){
boolean stage_pause = false;
if (Button_1sec_press(Button_prev)){
Buzzer(1);
stage_pause = true;
digitalWrite(Heat,LOW);
digitalWrite(Pump,LOW);
display_lcd(0,0," Paused " );
while (stage_pause)
{
if (Button_1sec_press(Button_prev))stage_pause=false;
}
}
}
 
void display_lcd (int pos , int line ,const char* lable){
lcd.setCursor(pos,line);
lcd.print(lable);
 
}
 
 
 
 
// 1 second button press
int Button_1sec_press (int Button_press){
if (digitalRead(Button_press)==0){
delay (1000);
if (digitalRead(Button_press)==0){
lcd.clear();
while(digitalRead(Button_press)==0){
}
return 1;
}
}
return 0;
}
 
 
 
 
// repeat button press
int Button_repeat (int Button_press){
if (digitalRead(Button_press)==0){
delay(200);
return 1;
}
return 0;
}
 
 
 
// holds whilst button pressed
int Button_hold_press (int Button_press){
if (digitalRead (Button_press)==0){
delay(50);
while (digitalRead (Button_press)==0){
}
return 1;
}
return 0;
}
 
 
 
// reads the DS18B20 temerature probe
void Temperature(void){
ds.reset();
ds.skip();
// start conversion and return
if (!(Conv_start)){
ds.write(0x44,0);
Conv_start = true;
return;
}
// check for conversion if it isn't complete return if it is then convert to decimal
if (Conv_start){
Busy = ds.read_bit();
if (Busy == 0){
return;
}
ds.reset();
ds.skip();
ds.write(0xBE);
for ( int i = 0; i < 2; i++) { // we need 2 bytes
data = ds.read();
}
unsigned int raw = (data[1] << 8) + data[0];
Temp_PID = (raw&0xFFFF)*0.0625;
Temp_c = (raw & 0xFFFC) * 0.0625;
Temp_f = (Temp_c * 1.8) + 32;
Conv_start = false;
return;
}
}
 
 
 
void PID_HEAT (void){
if(autoEnter){
Setpoint = stageTemp;
}
else{
Setpoint = mset_temp;
}
Input = Temp_PID;
if((Setpoint - Input)>5){
digitalWrite(Heat,HIGH);
if ((Setpoint - Input)<6)
{
myPID.Compute();
}
}
else{
myPID.Compute();
unsigned long now = millis();
if(now - windowStartTime>WindowSize)
{ //time to shift the Relay Window
windowStartTime += WindowSize;
}
if((Output*(WindowSize/100)) > now - windowStartTime) digitalWrite(Heat,HIGH);
else digitalWrite(Heat,LOW);
}
}
 
 
 
void load_pid_settings (void)
{
eepromKp = word(EEPROM.read(0),EEPROM.read(1));// read the PID settings from the EEPROM
eepromKi = word(EEPROM.read(2),EEPROM.read(3));
eepromKd = word(EEPROM.read(4),EEPROM.read(5));
eepromKi = eepromKi/100;
myPID.SetTunings(eepromKp,eepromKi,eepromKd); // send the PID settings to the PID
WindowSize = word(EEPROM.read(33),EEPROM.read(34));
myPID.SetOutputLimits(0, 100);
myPID.SetSampleTime(5000);
}
 
 
 
 
boolean wait_for_confirm (boolean& test)
{
wtBtn = true;
while (wtBtn){ // wait for comfirmation
if (Button_hold_press(Button_prev)){
test = true;
wtBtn = false;
lcd.clear();
}
if (Button_hold_press(Button_nxt)){
test = false;
wtBtn = false;
lcd.clear();
}
}
}
 
 
 
 
float change_temp(float& temp_change,int upper_limit,int lower_limit)
{
// Increase set temp
if (Button_repeat(Button_up)){
if (temp_change>=100){
temp_change++;
}
else{
temp_change+=0.25;
}
if (temp_change > upper_limit)temp_change = upper_limit;
}
// decrease temp
if (Button_repeat(Button_dn))
{
if(temp_change>=100){
temp_change--;
}
else{
temp_change-=0.25;
}
if ( temp_change < lower_limit) temp_change = lower_limit;
}
}
 
 
 
void quit_mode (boolean& processLoop)
{
if ((digitalRead(Button_dn)==0) && (digitalRead(Button_up)==0)){
digitalWrite(Heat,LOW);
digitalWrite(Pump,LOW);
processLoop = false;
lcd.clear();
}
}
 
 
 
 
void heat_control(void)
{
//turns heat on or off
if (Button_hold_press(Button_prev)){
if (mheat==false){
mheat = true;
windowStartTime = millis();
}
else{
mheat = false;
digitalWrite(Heat,LOW);
}
}
}
 
 
 
 
void pump_control(void)
{
//turns the pump on or off
if (Button_hold_press(Button_nxt)){
if (mpump == false){
mpump = true;
digitalWrite(Pump,HIGH);
}
else{
mpump = false;
digitalWrite(Pump,LOW);
}
}
}
 
 
 
void prompt_for_water (void){
display_lcd(0,0," Water added? ");
Buzzer(3);
display_lcd(0,1," Ok Quit");
}
 
 
void pump_prime(void)
{
lcd.clear();
lcd.print(" Pump Prime "); // priming the pump
digitalWrite(Pump,HIGH);
delay (1000);
digitalWrite(Pump,LOW);
delay(200);
digitalWrite(Pump,HIGH);
delay (1000);
digitalWrite(Pump,LOW);
delay(200);
digitalWrite(Pump,HIGH);
delay (1000);
digitalWrite(Pump,LOW);
lcd.clear();
}
 
void pump_rest (int stage)
{
if (stage==9){
if (Temp_c<94.0) digitalWrite(Pump,HIGH);
else digitalWrite(Pump,LOW);
if (Temp_c >= 95)tempReached = true;
}
else{
pumptempError = stageTemp-Temp_c;
if (pumptempError <= 0)tempReached = true;
if ((pumpTime < 10)){ // starts pumps and heat
digitalWrite(Pump,HIGH);
pumpRest =false;
}
if ((pumpTime >= 10)){ // pump rest
digitalWrite(Pump,LOW);
digitalWrite(Heat,LOW);
pumpRest = true;
if(pumpTime>=12 || (pumptempError > 1.0))pumpTime = 0;
}
}
}
void check_for_resume(void){
if(EEPROM.read(35)){ // read the auto started byte to see if it has been set and if so ask to resume
display_lcd (0,0," Resume Process?");
display_lcd (0,1," Yes No");
wait_for_confirm(resume);
if(resume==true){
tempHAddr = (EEPROM.read(36)*3)+6;
tempLAddr = tempHAddr+1;
timeAddr = tempHAddr+2;
x = EEPROM.read(36);
autoEnter = true;
lcd.clear();
}
}
}
 
 
void load_stage_settings (void){
tempHAddr = 6; // setup intitial stage addresses
tempLAddr = 7;
timeAddr = 8;
nmbrStgs = EEPROM.read(38);// read the number of steps
nmbrHops = EEPROM.read(39);//read the number of hop additions
}
 
 
void start_time (void)
{
start = millis();
// windowStartTime = millis();
second = 0;
// minute = 0;
}
 
 
 
void stage_timing (int stage)
{
if ((millis()-start)>1000){ // timing routine
start = millis();
second++;
if(!(tempReached))second=0;// starts counting down when temp reached
if (second>59){
display_lcd(10,0," ");
second = 0;
pumpTime++;
if(stage == 0)pumpTime = 0;
stageTime--;
EEPROM.write(37,lowByte(stageTime));// saves stage time incase of interuption
}
}
}
 
 
 
void hop_add (void)
{
if(hopAdd <= nmbrHops){
if (stageTime == hopTime){
Buzzer(3);
lcd.clear();
lcd.print(" Add Hops");
delay(2000);
Buzzer(3);
hopAdd++;
EEPROM.write(49,hopAdd);
blhpAddr++;
hopTime = EEPROM.read(blhpAddr);
lcd.clear();
}
}
}
 
 
void stage_loop (int stage, float H_temp=80, float L_temp=30){
int lastminute;
while ((stageTime>0)&&(autoEnter)){
lastminute=stageTime;
stage_timing(stage);
Temperature();// get temp
pause_stage();
if (pumpRest){
display_lcd(0,0," Pump Rest ");
display_lcd(0,1," ");
}
else{
display_lcd(0,0,stgName[stage]);
display_lcd(6,0," ");
display_lcd(11,0,"T=");
lcd.print(stageTime);
display_lcd(0,1,"S/A=");
// lcd.print(stageTemp);
lcd.print(stageTempF,1);
display_lcd(9,1,"/");
// lcd.print(Temp_c);
lcd.print(Temp_f,1);
lcd.write((uint8_t)0);
lcd.write(' ');
}
change_temp(stageTemp,H_temp,L_temp);
pump_rest(stage);
if (pumpRest==false)PID_HEAT();
if (stage==9){
if(stageTime<lastminute){
hop_add();
}
}
quit_mode (autoEnter);
}
 
}
 
 
 
void get_stage_settings (void)
{
stageTemp = word(EEPROM.read(tempHAddr),EEPROM.read(tempLAddr));
stageTemp = stageTemp/16.0;
stageTempF = (stageTemp * 1.8) + 32;
if (resume){ // on the start of resume gets saved time
stageTime=EEPROM.read(37);
resume = false; // clears resume for next loop
}
else{
stageTime = EEPROM.read(timeAddr); // gets stage time
EEPROM.write(37,lowByte(stageTime));// saves the intial stage time
}
}
 
 
 
void add_malt (void)
{
boolean malt;
lcd.clear();
digitalWrite(Pump,LOW);
digitalWrite(Heat,LOW);
display_lcd(0,0," Add Malt ");
Buzzer(3);
display_lcd(0,1," Ok Quit");
wait_for_confirm(malt);
if (malt==false){
digitalWrite(Heat,LOW);
digitalWrite(Pump,LOW);
lcd.clear();
delay(50);
mainMenu=0;
autoEnter = false;
}
}
 
void remove_malt (void)
{
boolean malt;
lcd.clear();
x = 9; // used add to stage count on the final stage for the resume
EEPROM.write(36,lowByte(x)); // stores the stage number for the resume
digitalWrite(Pump,LOW);
digitalWrite(Heat,LOW);
display_lcd(0,0," Remove Malt ");
Buzzer(3);
display_lcd(0,1," Ok Quit");
wait_for_confirm(malt);
if (malt==false){
stageTime = EEPROM.read(40);
EEPROM.write(37,lowByte(stageTime));
digitalWrite(Heat,LOW);
digitalWrite(Pump,LOW);
lcd.clear();
delay(50);
mainMenu=0;
autoEnter = false;
}
}
 
 
 
 
 
void get_boil_settings (void)
{
nmbrHops = EEPROM.read(39);
if (resume){
if(x!=9){
stageTime = EEPROM.read(40);
}
else{
stageTime= EEPROM.read(37);
}
}
else{
stageTime = EEPROM.read(40);
EEPROM.write(37,lowByte(stageTime));
}
hopAdd = EEPROM.read(49);
blhpAddr = hopAdd+41;
lcd.clear();
hopTime = EEPROM.read(blhpAddr);
}
 
 
void manual_mode (void)
{
load_pid_settings();
prompt_for_water();
wait_for_confirm(manualLoop);
while (manualLoop){ // manual loop
Temperature();
mset_tempF = (mset_temp * 1.8) + 32;
display_lcd(0,0," Manual Mode ");
display_lcd(0,1,"S/A=");
// lcd.print(mset_temp);
lcd.print(mset_tempF,1);
display_lcd(9,1,"/");
// lcd.print(Temp_c);
lcd.print(Temp_f,1);
lcd.write((uint8_t)0);
lcd.write(' ');
change_temp(mset_temp,120,20);
quit_mode(manualLoop);
heat_control();
pump_control();
if (mheat){
PID_HEAT();
}
}
}
 
void auto_mode (void)
{
load_stage_settings();
load_pid_settings();
check_for_resume();
if(!(resume)){ // if starting a new process prompt for water
prompt_for_water();
wait_for_confirm(autoEnter);
if(!(autoEnter))return;
pump_prime();
x = 0;
}
if (autoEnter){ // mash steps
EEPROM.write(35,1);// auto mode started
for (int i = x;i < nmbrStgs;i++){
EEPROM.write(36,lowByte(x)); // stores the stage number for the resume
x++; // used to count the stages for the resume
tempReached = false;
get_stage_settings();
start_time();
stage_loop(i);
if (!(autoEnter)) break;
if( i==0 && autoEnter){ // at the end of the mashIn step pauses to add grain
add_malt();
if (!(autoEnter))break;
}
if(i==(nmbrStgs-1)&& autoEnter){ // at the end of the last step pauses to remove the malt pipe before the boil
remove_malt();
if (!(autoEnter))break;
}
Buzzer(1);
tempHAddr +=3; // increase stage addresses
tempLAddr +=3;
timeAddr +=3;
lcd.clear();
}
}
// start of the boil
if(autoEnter){
start_time();
stageTemp= 98.0; // set the intital boil temp to 98 deg c
tempReached = false;
get_boil_settings();
stage_loop(9,120,94);
if(autoEnter){ // finishes the brewing process
display_lcd(0,0," Brewing ");
display_lcd(0,1," Finished ");
Buzzer(3);
delay(2000);
EEPROM.write(35,0); // sets auto start byte to 0 for resume
EEPROM.write(49,0); // sets hop count to 0
mainMenu=0;
autoEnter =false;
resume =false;
}
 
}
}
 
 
void save_settings (int addr,int data)
{
EEPROM.write(addr,highByte(data));
EEPROM.write((addr+1),lowByte(data));
}
 
 
void save_settings (int addr,byte data){
EEPROM.write(addr,data);
}
 
 
 
int change_set(int& set_change,int upper_limit,int lower_limit,int step_size)
{
// Increase set temp
if (Button_repeat(Button_up)){
set_change+=step_size;
display_lcd(0,1," ");
}
if (set_change > upper_limit)set_change = upper_limit;
// decrease temp
if (Button_repeat(Button_dn))
{
set_change-=step_size;
display_lcd(0,1," ");
}
if ( set_change < lower_limit) set_change = lower_limit;
}
 
int change_set(byte& set_change,int upper_limit,int lower_limit,int step_size)
{
// Increase set temp
if (Button_repeat(Button_up)){
set_change+=step_size;
display_lcd(0,1," ");
}
if (set_change > upper_limit)set_change = upper_limit;
// decrease temp
if (Button_repeat(Button_dn))
{
set_change-=step_size;
display_lcd(0,1," ");
}
if ( set_change < lower_limit) set_change = lower_limit;
}
 
 
 
void unit_set (void)
{
int param[] ={
100,-100,1,100,-100,1,100,-100,1,5000,500,500,9,1,1,8,0,1 };
int a = 0;
boolean pidLoop = false;
int pidSet,setaddr;
int windowSizeSet;
char* setName[] ={
"Kp = ","Ki = ","Kd = ","Windowsize= ","Num of Stages=","Num of Hops=" };
setaddr = 0;
for(int i=0;i<6;i++){
if((i>=0) && (i<=3)){
if (i==3) setaddr = 33;
pidSet=word(EEPROM.read(setaddr),EEPROM.read((setaddr+1)));
}
if (i==4)setaddr = 38;
if((i>=4) && (i<6)){
pidSet= EEPROM.read(setaddr);
}
pidLoop= true;
display_lcd(0,1," ");
while (pidLoop){
display_lcd(0,1,setName);
lcd.print(pidSet);
change_set(pidSet,param[a],param[a+1],param[a+2]);
quit_mode(pidLoop);
if (!(pidLoop))i=6;
if(Button_hold_press(Button_nxt)){
if (i >= 4){
save_settings(setaddr,lowByte(pidSet));
pidLoop = false;
}
else{
save_settings(setaddr,pidSet);
pidLoop = false;
}
}
}
if (i>=4){
setaddr+=1;
}
else{
setaddr+=2;
}
a+=3;
}
}
 
void set_stages (void)
{
boolean autotempLoop = false;
boolean autotimeLoop = false;
tempHAddr = 6;
tempLAddr = 7;
timeAddr = 8;
float stgtmpSet, stgtmpSetF;
int stgtmpSetword;
int stgtimSet;
nmbrStgs = EEPROM.read(38);
for (int i=0; i<nmbrStgs;i++){ // loops for the number of stages
stgtmpSet = word(EEPROM.read(tempHAddr),EEPROM.read(tempLAddr));
stgtmpSet = stgtmpSet/16.0;
autotempLoop = true;
while (autotempLoop){ // loops for temp adjust
display_lcd(0,1,stgName);
lcd.print("Temp=");
// lcd.print(stgtmpSet);
stgtmpSetF = (stgtmpSet * 1.8) + 32;
lcd.print(stgtmpSetF,1);
quit_mode(autotempLoop);
if (autotempLoop == false){
return;
}
change_temp(stgtmpSet,85,20);
if (Button_hold_press(Button_nxt)){
stgtmpSet = stgtmpSet*16;
stgtmpSetword =word(stgtmpSet);
save_settings(tempHAddr,stgtmpSetword);
display_lcd(0,1," ");
autotempLoop = false;
}
}
autotimeLoop = true;
stgtimSet = EEPROM.read(timeAddr);
while (autotimeLoop){ // loops to adjust time setting
display_lcd(0,1,stgName);
lcd.print(" time=");
lcd.print(stgtimSet);
quit_mode(autotimeLoop);
if (autotimeLoop == false){
return;
}
change_set(stgtimSet,120,0,1);
if (Button_hold_press(Button_nxt)){
save_settings(timeAddr,lowByte(stgtimSet));
display_lcd(0,1," ");
autotimeLoop = false;
}
}
tempHAddr+= 3;
tempLAddr+= 3;
timeAddr+= 3;
}
}
void set_hops (void)
{
boolean hopLoop = false;
blhpAddr = 40;
byte hopSet;
nmbrHops = EEPROM.read(39);
nmbrHops+=1;
for(int i =0;i<nmbrHops;i++){
hopLoop = true;
hopSet = EEPROM.read(blhpAddr);
while (hopLoop){
if (i==0){
display_lcd(0,1,"Boil time = ");
lcd.print(int (hopSet));
}
else{
display_lcd(0,1,"Hop ");
lcd.print(i);
lcd.print(" time = ");
lcd.print(int(hopSet));
}
quit_mode(hopLoop);
if( hopLoop == false){
return;
}
change_set(hopSet,180,0,1);
if (Button_hold_press(Button_nxt)){
save_settings(blhpAddr,hopSet);
lcd.setCursor(0,1);
lcd.print(" ");
hopLoop = false;
}
}
blhpAddr+= 1;
}
}
 
 
void auto_set(void)
{
set_stages();
set_hops();
}
 
 
void setup_mode (void)
{
byte setupMenu = 0;
boolean setupLoop = true;
while (setupLoop){
switch (setupMenu){ // to select between PID and Auto menu
case(0):
display_lcd(0,0,"Unit Parameters ");
display_lcd(0,1," ");
quit_mode(setupLoop);
if (Button_hold_press(Button_up))setupMenu = 1;
if (Button_hold_press(Button_nxt))unit_set();
break;
case(1):
display_lcd(0,0," Auto Parameters");
display_lcd(0,1," ");
quit_mode(setupLoop);
if (Button_hold_press(Button_dn))setupMenu = 0;
if (Button_hold_press(Button_nxt))auto_set();
break;
}
}
}
 
 
 
 
 
void setup()
{
// Start up the library
lcd.begin(16,2);
pinMode (Button_up,INPUT);
pinMode (Button_dn,INPUT);
pinMode (Button_prev,INPUT);
pinMode (Button_nxt,INPUT);
pinMode (Heat,OUTPUT);
pinMode (Pump,OUTPUT);
pinMode (Buzz,OUTPUT);
windowStartTime = millis();
//tell the PID to range between 0 and the full window size
myPID.SetMode(AUTOMATIC);
// write custom symbol to LCD
// lcd.createChar(0,degc);
lcd.createChar(0,degf);
}
 
 
 
void loop()
{
switch(mainMenu){
case (1):
display_lcd(0,0," Manual Mode ");
display_lcd(0,1," ");
delay (1000);
lcd.clear();
manual_mode();
mainMenu = 0;
break;
case (2):
display_lcd(0,0," Auto Mode ");
display_lcd(0,1," ");
delay (1000);
lcd.clear();
auto_mode();
mainMenu = 0;
break;
case (3):
display_lcd(0,0," Setup Mode ");
display_lcd(0,1," ");
delay (1000);
lcd.clear();
setup_mode();
mainMenu = 0;
break;
default:
digitalWrite(Heat,LOW);
digitalWrite(Pump,LOW);
Temperature();
display_lcd(0,0," The Brauduino ");
display_lcd(0,1," Temp=");
// lcd.print(Temp_c);
lcd.print(Temp_f);
lcd.write((uint8_t)0);
lcd.write(' ');
 
if (Button_1sec_press(Button_dn))mainMenu = 1;
if (Button_1sec_press(Button_prev))mainMenu = 2;
if (Button_1sec_press(Button_nxt))mainMenu = 3;
break;
}
 
}
 
hello to all
here are the links to download our software version Matho with the changes described previously.
We tested for a long time and corrected many bugs, we hope there are not more.
We will be happy if someone could help us to improve the English side, which is still in Beta version.
I also put the link to the manual (still is in Italian only).
Let me know what you think

Manual (only Italian): http://goo.gl/x9rnmJ
Software:http://goo.gl/3c2u40
 
Would be great if the code for this was hosted somewhere like github.
 
lukencode said:
Would be great if the code for this was hosted somewhere like github.
Matho's code is on github
 
Also the amazing and powerful Italian branch of the controller from maxN68 is on github

https://github.com/MaxN68it/Open-ArdBir

I'm working to nanual translation in English so you can really understand the great improvement performed

Stay tuned
Davide
 
arzaman said:
Also the amazing and powerful Italian branch of the controller from maxN68 is on github

https://github.com/MaxN68it/Open-ArdBir

I'm working to nanual translation in English so you can really understand the great improvement performed

Stay tuned
Davide

I look forward to the English translation of the manual arzaman, thank you for your effort.

The changes made above have made quite a few worth while improvements and I thank all those involved for their efforts. It is high appreciated.

Cheers :)
 
At this time we are testing some small additions.

1) Audible alarm on reaching the Set Point in MODE MANUAL

2) Ask to save the setting automation after the end of data entry

3) Jump Step (except Mash In) after a long press of the ENTER key, with audible alarm and confirmation in AUTO MODE


They are also fixed minor errors display (flashing character)
 
MaxN68 said:
At this time we are testing some small additions.

1) Audible alarm on reaching the Set Point in MODE MANUAL

2) Ask to save the setting automation after the end of data entry

3) Jump Step (except Mash In) after a long press of the ENTER key, with audible alarm and confirmation in AUTO MODE


They are also fixed minor errors display (flashing character)
These sound like good additions. for #2 - if the settings are not automatically saved - what happens if the system gets switched off? does it still auto-recover as it does with matho's code?
 
In ArdBir the current setting is saved in the EEPROM just like in Brauduino, as well as the ability to resume a stopped job.
The novelty is to manage (load, save, delete) up to 10 different settings (recipes).
At the end of the insertion of automation parameters are asked if you want to save this setting to be able to be reused at other times through the upload function in the "Recipe" menu.

We are workinkg for the english manual.
 
Oh, that's cool! Can't wait to see the English manual for it!
 
Just playing with the new Italian code - NICE.... very nice. Can we have two alpha amalyse steps please? I'll frequently step at both 66(or thereabouts) and 72 before heading to mash out at 78.

Any chance its possible to name the saved settings? (not just 1 / 2 / 3 etc?)

As for the English manual - everything seems pretty straight forward - Is is possible to set a delay prior to brewing - eg: get everything ready and mash in the night before. Brauduino starts mashing @ 6am and is ready for me to lift malt pipe and boil when I wake up.

It seems like it might have a time for counting down/ up on manual? How do you set it?

Nice work!! Makes the controller an even nicer bit of kit!
 
Back
Top