brauduino semi automated single vessel rims

31
/* 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/>.*/ //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

Upload: pferato

Post on 22-Nov-2015

87 views

Category:

Documents


1 download

TRANSCRIPT

/*

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 .*/

//libraries

#include

#include

#include

#include

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_temp = 35;

float Temp_c, stageTemp,pumptempError,Temp_PID;

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,

};

//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[i] = ds.read();

}

unsigned int raw = (data[1] 5){

digitalWrite(Heat,HIGH);

if ((Setpoint - Input)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){

pumpRest = false;

if (Temp_c= 95)tempReached = true;

}

else{

pumptempError = stageTemp-Temp_c;

if (pumptempError = 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 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);

display_lcd(9,1,"/");

lcd.print(Temp_c);

lcd.write((uint8_t)0);

}

change_temp(stageTemp,H_temp,L_temp);

pump_rest(stage);

if (pumpRest==false)PID_HEAT();

if (stage==9){

if(stageTime 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=0) && (i=4) && (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;

int stgtmpSetword;

int stgtimSet;

nmbrStgs = EEPROM.read(38);

for (int i=0; i