@Dave1829 I haven’t been printing to serial, but I am printing to the terminal widget and the print out is working.
Its a heating elements, so in the water when its on it bubbles etc, and when off nothing happens so I can tell it is definitely still on.
@Lichtsignaal The code is below, its pretty long, but if you go to case 3 in the “Autobrewing” section of the code, which is the Mash start that is where the heaters should turn off and the pump on.
//////////////////////BLYNK CODE
//#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
SimpleTimer timer;
const char* ssid = "";
const char* password = "";
char auth[] = "";
WidgetTerminal terminal(V0);
WidgetTerminal terminalHops(V14);
////////Setting up variables to be declared by Blynk app
int MASHTEMP; // Desired Mash Temp(deg F)
int MASHTIME; //Desired Mash Time(milli sec.)
int BOILTIME; //Desired Boil Time(milli sec.)
int CHILLTIME; //Desired time to pump all wort through the wort chiller (milli sec.)
int hopCounter; //Number of hop adds that I input, based upon my terminal input
int HopAddtime;
int HOPTIME[20]; // Hop times
String HOPINFO[20]; // HOPINFO;
////////////Assign counters for independent and pause control buttons
int noButtonCounter;
int pacounter;
int pucounter;
int h1counter;
int h2counter;
////////////////////////Assign variables
float tanktemp; //Declaring temperature variables
unsigned long btstart;
unsigned long btstart1;
unsigned long btstart2;
unsigned long pausestart; //Time when pause button was pushed
unsigned long elapsedpausetime;
unsigned long elapsedpumptime;
unsigned long elapsedh1time;
unsigned long elapsedh2time;
unsigned long totalpausem;
unsigned long totalpauseb;
unsigned long totalpausec;
unsigned long startingtime; //overall starting time
unsigned long ElapsedPreMashTime;
unsigned long MashStartTime; //used for MASH TIME
unsigned long ElapsedMashTime;
unsigned long BoilStartTime; //used for BOIL TIME
unsigned long ElapsedBoilTime;
unsigned long ChillStartTime; //used for BOIL TIME
unsigned long ElapsedChillTime;
//Setup all states
int switchState;
boolean autostart = true;
boolean premash;
boolean mashPID;
boolean reheatpremash;
boolean mashrun;
boolean mashreheat;
boolean mashend;
boolean boilrun;
boolean reboil;
boolean boilend;
boolean chillrun;
boolean rechill;
boolean chillend;
//Pin Inputs/Outputs to Arduino:
const int BUZZER = D0;
const int HEATER1 = D5;
const int HEATER2 = D6;
const int PUMP = D7;
//Status variables for buttons
int val_start;
int val_pause;
int val_pump;
int val_heater1;
int val_heater2;
void brewingstuff(){
//No button pressed nothing is on (Also works so that when Auto button is on and then turned off, everything shuts down
if (val_start == LOW && val_pause == LOW && val_pump == LOW && val_heater1 == LOW && val_heater2 == LOW){
switch (noButtonCounter){
case 0:
digitalWrite(HEATER1, LOW);
digitalWrite(HEATER2, LOW);
digitalWrite(PUMP, LOW);
terminal.println("No Button Pressed, to pause must press pause button!");
terminal.flush();
noButtonCounter = 1;
pausestart = (millis()/60000);
break;
case 1:
elapsedpausetime = ((millis()/60000) - pausestart);
terminal.print("No button pressed for: ");
terminal.println(elapsedpausetime);
terminal.flush();
break;}
}
//If anything is pressed right after no button was pressed, reset no button counter, set re heat states if needed, and increase "pause" time
if ((val_start == HIGH || val_pause == HIGH || val_pump == HIGH || val_heater1 == HIGH || val_heater2 == HIGH) && noButtonCounter == 1){
noButtonCounter = 0;
if (premash == true){
reheatpremash = true;
}
else if (mashrun == true){
totalpausem = totalpausem + elapsedpausetime;
terminal.print("Time Added to Mash: ");
terminal.println(elapsedpausetime);
}
else if (boilrun == true){
reboil = true;
totalpauseb = totalpauseb + elapsedpausetime;
terminal.print("Time Added to Boil: ");
terminal.println(elapsedpausetime);
}
else if (chillrun == true){
rechill = true;
totalpausec = totalpausec + elapsedpausetime;
terminal.print("Time Added to Chill: ");
terminal.println(elapsedpausetime);
}
elapsedpausetime=0;
}
//pause stops everything
if (val_pause == HIGH){
switch (pacounter){
case 0:
Blynk.virtualWrite(V4,LOW);
Blynk.virtualWrite(V6,LOW);
Blynk.virtualWrite(V7,LOW);
Blynk.virtualWrite(V8,LOW);
val_start=LOW;
val_pump=LOW;
val_heater1=LOW;
val_heater2=LOW;
pucounter=0;
h1counter=0;
h2counter=0;
pausestart=(millis()/60000);
pacounter=1;
digitalWrite(HEATER1, LOW);
digitalWrite(HEATER2, LOW);
digitalWrite(PUMP, LOW);
terminal.println("PAUSE WORKING");
break;
case 1:
elapsedpausetime = ((millis()/60000) - pausestart);
terminal.print("Manual Pause for: ");
terminal.println(elapsedpausetime);
terminal.flush();
break;}
}
///Pause button on and then turned off it resets counter, re heats if needed, and increased pause time
if (pacounter == 1 && val_pause == LOW){
pacounter = 0;
if (premash == true){
reheatpremash = true;
}
else if (mashrun == true){
totalpausem = totalpausem + elapsedpausetime;
terminal.print("Time Added to Mash: ");
terminal.println(elapsedpausetime);
}
else if (boilrun == true){
reboil = true;
totalpauseb = totalpauseb + elapsedpausetime;
terminal.print("Time Added to Boil: ");
terminal.println(elapsedpausetime);
}
else if (chillrun == true){
rechill = true;
totalpausec = totalpausec + elapsedpausetime;
terminal.print("Time Added to Chill: ");
terminal.println(elapsedpausetime);
}
elapsedpausetime=0;
}
//Button pressed on pump starts
if (val_start == LOW && val_pause == LOW && val_pump == HIGH){
switch (pucounter){
case 0:
terminal.println("Pump starting, need to open ball valve!!");
terminal.flush();
tone(BUZZER,500,5000);
digitalWrite(PUMP, HIGH);
btstart=(millis()/60000);
pucounter=1;
break;
case 1:
elapsedpumptime = ((millis()/60000) - btstart);
terminal.print("Manual Pump On for: ");
terminal.println(elapsedpumptime);
terminal.flush();
break;
}
}
///Pump button on and then turned off it stops pump
if (pucounter == 1 && val_pump == LOW){
pucounter = 0;
digitalWrite(PUMP, LOW);
if (premash == true){
reheatpremash = true;
}
else if (mashrun == true){
totalpausem = totalpausem + elapsedpumptime;
terminal.print("Time Added to Mash: ");
terminal.println(elapsedpausetime);
}
else if (boilrun == true){
reboil = true;
totalpauseb = totalpauseb + elapsedpumptime;
terminal.print("Time Added to Boil: ");
terminal.println(elapsedpausetime);
}
else if (chillrun == true){
rechill = true;
totalpausec = totalpausec + elapsedpumptime;
terminal.print("Time Added to Chill: ");
terminal.println(elapsedpausetime);
}
elapsedpumptime = 0;
}
//Heater 1 button pressed on heater starts
if (val_start == LOW && val_pause == LOW && val_heater1 == HIGH){
switch (h1counter) {
case 0:
btstart1=(millis()/60000);
tone(BUZZER,500,5000);
terminal.println("Heat 1 starting, need cover w water!!");
terminal.flush();
digitalWrite(HEATER1, HIGH);
h1counter=1;
break;
case 1:
elapsedh1time = ((millis()/60000) - btstart1);
terminal.print("Manual Heater 1 On for: ");
terminal.println(elapsedh1time);
terminal.flush();
break; }
}
///When Heater1 button on and then turned off it stops one heater
if (h1counter == 1 && val_heater1 == LOW){
h1counter = 0;
digitalWrite(HEATER1, LOW);
if (premash == true){
reheatpremash = true;
}
else if (mashrun == true){
totalpausem = totalpausem + elapsedh1time;
terminal.print("Time Added to Mash: ");
terminal.println(elapsedpausetime);
}
else if (boilrun == true){
reboil = true;
totalpauseb = totalpauseb + elapsedh1time;
terminal.print("Time Added to Boil: ");
terminal.println(elapsedpausetime);
}
else if (chillrun == true){
rechill = true;
totalpausec = totalpausec + elapsedh1time;
terminal.print("Time Added to Chill: ");
terminal.println(elapsedpausetime);
}
elapsedh1time=0;
}
if (val_start == LOW && val_pause == LOW && val_heater2 == HIGH){
switch (h2counter){
case 0:
btstart2=(millis()/60000);
tone(BUZZER,500,5000);
terminal.println("Heat 2 starting, need cover w water!!");
terminal.flush();
digitalWrite(HEATER2, HIGH);
h2counter=1;
break;
case 1:
elapsedh2time = ((millis()/60000) - btstart2);
terminal.print("Manual Heater 2 On for: ");
terminal.println(elapsedh2time);
terminal.flush();
break;}
}
///When Heater2 button on and then turned off it stops two heater
if (h2counter == 1 && val_heater2 == LOW){
h2counter = 0;
digitalWrite(HEATER2, LOW);
if (premash == true){
reheatpremash = true;
}
else if (mashrun == true){
totalpausem = totalpausem + elapsedh2time;
terminal.print("Time Added to Mash: ");
terminal.println(elapsedpausetime);
}
else if (boilrun == true){
reboil = true;
totalpauseb = totalpauseb + elapsedh2time;
terminal.print("Time Added to Boil: ");
terminal.println(elapsedpausetime);
}
else if (chillrun == true){
rechill = true;
totalpausec = totalpausec + elapsedh2time;
terminal.print("Time Added to Chill: ");
terminal.println(elapsedpausetime);
}
elapsedh2time=0;
}
//Auto Brewing State decision upfront
ElapsedPreMashTime = (millis()/60000) - startingtime;
ElapsedMashTime = (millis()/60000) - MashStartTime - totalpausem;
ElapsedBoilTime = (millis()/60000) - BoilStartTime - totalpauseb;
ElapsedChillTime = (millis()/60000) - ChillStartTime - totalpausec;
if (tanktemp < MASHTEMP && autostart == true && switchState ==0) {
switchState=1;
}
else if (tanktemp >= MASHTEMP - 5.0 && tanktemp < MASHTEMP - 2.0 && premash == true && mashPID == false && switchState ==0) {
switchState=2;
}
else if (tanktemp >= MASHTEMP - 2.0 && tanktemp <= MASHTEMP + 2.0 && premash == true && switchState ==0) {
switchState=3;
}
else if (tanktemp <= MASHTEMP - 8.0 && mashrun == true && mashreheat == false && switchState ==0){
switchState=4;
}
else if (tanktemp >= MASHTEMP && mashreheat == true && switchState ==0){
switchState=5;
}
else if (ElapsedMashTime >= MASHTIME && mashrun == true && switchState ==0) {
switchState=6;
}
else if (tanktemp >= 200 && mashend == true && switchState ==0) {
switchState=7;
}
else if (reboil == true && switchState ==0){
switchState=8;
}
else if (ElapsedBoilTime < BOILTIME + 1 && boilrun == true && switchState ==0) {
switchState=9;
if (ElapsedBoilTime >= BOILTIME - 8 && ElapsedBoilTime <= BOILTIME - 7){
terminal.println("Boil Almost Done: Add Immersion Chiller & begin yeast starter");
terminal.flush();
}
}
else if (ElapsedBoilTime >= BOILTIME && boilrun == true && switchState ==0) {
switchState=10;
}
else if (tanktemp <= 190 && boilend == true && switchState ==0) {
switchState=11;
}
else if (rechill == true && switchState ==0){
switchState=12;
}
else if (ElapsedChillTime >= CHILLTIME && chillrun == true && switchState ==0) {
switchState=13;
}
else if (reheatpremash == true && switchState ==0) {
switchState=14;
}
//When Auto Brewing Start button pressed
if (val_start == HIGH && val_pause == LOW && val_pump == LOW && val_heater1 == LOW && val_heater2 == LOW){
switch (switchState){
//premash = Heater 1 & 2 on, pump off
case 1:
switchState = 0;
startingtime = (millis()/60000);
terminal.println(startingtime);
premash=true;
autostart = false;
tone(BUZZER,500,5000);
terminal.println("Heat starting, need to cover with water!!");
terminal.flush();
digitalWrite(HEATER1, HIGH);
digitalWrite(HEATER2, HIGH);
terminal.println("Heaters On");
terminal.flush();
break;
//reheatpremash: turn heaters back on after a pause during premash stage
case 14:
switchState = 0;
reheatpremash = false;
digitalWrite(HEATER1, HIGH);
digitalWrite(HEATER2, HIGH);
terminal.println("Back from pause, premash heaters back on");
terminal.flush();
break;
//close to mash temp = only one heater stay on (MY VERSION OF A PID)
case 2:
Blynk.notify("Close to MashTemp, ready to insert grain");
switchState = 0;
mashPID = true;
digitalWrite(HEATER2, HIGH);
tone(BUZZER,500,2000);
terminal.println("Temp close to Mash, one heater on");
terminal.flush();
break;
//mashrun = heaters off, pump on
case 3:
switchState = 0;
mashrun = true;
premash=false;
MashStartTime = (millis()/60000);
digitalWrite(HEATER1, LOW);
digitalWrite(HEATER2, LOW);
tone(BUZZER,500,2000);
terminal.println("Mash temp hit, mash begin");
terminal.flush();
digitalWrite(PUMP, HIGH);
break;
//Mash Reheat Adds function so that if paused or a lot of heat loss the heater keeps us at mash temp
case 4:
switchState = 0;
mashreheat = true;
digitalWrite(HEATER1, HIGH);
digitalWrite(HEATER2, HIGH);
terminal.println("Heat loss, heaters back on");
terminal.flush();
break;
//Mash Reheat Complete
case 5:
switchState = 0;
mashreheat = false;
digitalWrite(HEATER1, LOW);
digitalWrite(HEATER2, LOW);
terminal.println("Mash back up to temp, heaters back off");
terminal.flush();
break;
//mashend = heaters both on, pump off
case 6:
switchState = 0;
mashend = true;
mashrun = false;
digitalWrite(HEATER1, HIGH);
digitalWrite(HEATER2, HIGH);
digitalWrite(PUMP, LOW);
tone(BUZZER,500,2000);
terminal.println("Mash Complete, heat on, pump off, pre boil stage");
Blynk.notify("REMOVE GRAIN BAG: Mash Complete, heat on, pump off, pre boil stage");
terminal.flush();
break;
//boilrun
case 7:
switchState = 0;
boilrun = true;
mashend= false;
BoilStartTime = (millis()/60000);
tone(BUZZER,500,2000);
terminal.println("Boiling start, heaters on, pump off, look for hop adds");
terminal.flush();
break;
//reboil: turn heaters back on after a pause during boilrun stage
case 8:
switchState = 0;
reboil = false;
digitalWrite(HEATER1, HIGH);
digitalWrite(HEATER2, HIGH);
terminal.println("Back from pause, boil started again");
terminal.flush();
break;
//Hop Additions Code
case 9:
switchState =0;
for (int h=0 ; h=hopCounter; h++) {
HopAddtime = HOPTIME[h];
if (ElapsedBoilTime >= (HopAddtime - 1.0) && ElapsedBoilTime <= (HopAddtime + 1.0)) { //BE SURE THAT THE +/- of the elapsedboil time doesnt result in overlay of two hop additions or else it could be confusing
tone(BUZZER,500,2000);
terminal.print("Add: ");
terminal.println(HOPINFO[h]);
terminal.flush();
Blynk.notify(HOPINFO[h]);
tone(BUZZER,500,2000);
}
}
break;
//boilend = heat off , pump off
case 10:
switchState = 0;
boilend = true;
boilrun = false;
digitalWrite(HEATER1, LOW);
digitalWrite(HEATER2, LOW);
digitalWrite(PUMP, LOW);
terminal.println("Boil Complete");
Blynk.notify("INSERT IMMERSION CHILLER IMMEDIATELY, CONNECT ALL CHILL TUBING, MAKE SURE FERMENTER IS READY:Boil Complete");
terminal.flush();
break;
//chill run: Turns pump on once temp is low enough that going through plate chiller will work: Maybe bump up this temperature
case 11:
switchState = 0;
chillrun = true;
boilend = false;
ChillStartTime = (millis()/60000);
terminal.println("Pump starting, need to open ball valve!!");
terminal.flush();
tone(BUZZER,500,5000);
digitalWrite(PUMP, HIGH);
break;
//rechill: turn pump back on after a pause during chillrun stage
case 12:
switchState = 0;
rechill = false;
digitalWrite(PUMP, HIGH);
terminal.println("Back from pause, chill pumping started again");
terminal.flush();
break;
//chillend == turn pump off once estimated chill time is over
case 13:
switchState = 0;
chillend = true;
chillrun = false;
tone(BUZZER,500,5000);
digitalWrite(PUMP, LOW);
terminal.println("Auto Brewing Complete");
Blynk.notify("Auto Brewing Complete");
terminal.flush();
break;
}
}
}
/////////BLYNK CODE: DISPLAYS AND INPUTS
///////BLYNK DASHBOARD DISPLAYS
//Send tanktemp continuously
BLYNK_READ (V9)
{
Blynk.virtualWrite(V9,tanktemp);
}
//Send Elapsed Time to BLYNK Dashboard Display
BLYNK_READ(V11)
{
if (premash == true)
Blynk.virtualWrite(V11, ElapsedPreMashTime);
else if (mashrun == true)
Blynk.virtualWrite(V11, ElapsedMashTime);
else if (boilrun == true)
Blynk.virtualWrite(V11, ElapsedBoilTime);
else if (chillrun == true)
Blynk.virtualWrite(V11, ElapsedChillTime);
else
Blynk.virtualWrite(V11, 0);
}
//Display Phase which corresponds with the elapsed time above
BLYNK_READ(V10)
{
if (premash == true){
Blynk.virtualWrite(V10, "preM");}
else if (mashrun == true){
Blynk.virtualWrite(V10, "MASH");}
else if (mashend == true){
Blynk.virtualWrite(V10, "preB");}
else if (boilrun == true) {
Blynk.virtualWrite(V10, "BOIL");}
else if (chillrun == true){
Blynk.virtualWrite(V10, "CHILL");}
else {
Blynk.virtualWrite(V10, "N/A");}
}
//////////////////////USER INPUTS: Mash Time, Mash Temp, Boil Time, Chill Time, Hop Times, Hop Info, Manual State Change
BLYNK_WRITE(V15)
{
switch (param.asInt()){
case 1 :
terminal.println("Variables Reset");
terminal.flush();
autostart = false;
premash = false;
mashPID = false;
reheatpremash = false;
mashrun = false;
mashreheat = false;
mashend = false;
boilrun = false;
reboil = false;
boilend = false;
chillrun = false;
rechill = false;
chillend = false;
terminal.println("Reverted Back to Pre-Mash Stage");
terminal.flush();
switchState = 1;
break;
case 2 :
terminal.println("Variables Reset");
terminal.flush();
autostart = false;
premash = false;
mashPID = false;
reheatpremash = false;
mashrun = false;
mashreheat = false;
mashend = false;
boilrun = false;
reboil = false;
boilend = false;
chillrun = false;
rechill = false;
chillend = false;
terminal.println("Reverted Back to Mash Stage");
terminal.flush();
switchState = 3;
break;
case 3 :
terminal.println("Variables Reset");
terminal.flush();
autostart = false;
premash = false;
mashPID = false;
reheatpremash = false;
mashrun = false;
mashreheat = false;
mashend = false;
boilrun = false;
reboil = false;
boilend = false;
chillrun = false;
rechill = false;
chillend = false;
terminal.println("Reverted back to Boil Stage");
terminal.flush();
switchState = 6;
break;
}
}
BLYNK_WRITE(V1)
{
MASHTEMP= param.asInt();
terminalHops.print("MASHTEMP SET AS: ");
terminalHops.println(MASHTEMP);
terminalHops.flush();
}
BLYNK_WRITE(V2)
{
MASHTIME= param.asInt();
terminalHops.print("MASHTIME SET AS: ");
terminalHops.println(MASHTIME);
terminalHops.flush();
}
BLYNK_WRITE(V3)
{
BOILTIME= param.asInt();
terminalHops.print("BOILTIME SET AS: ");
terminalHops.println(BOILTIME);
terminalHops.flush();
}
BLYNK_WRITE(V13)
{
CHILLTIME= param.asInt();
terminalHops.print("CHILLTIME SET AS: ");
terminalHops.println(CHILLTIME);
terminalHops.flush();
}
BLYNK_WRITE(V14) // Terminal for HOPTIME and HOPINFO input
{
String fromTerminal = param.asStr();
if (fromTerminal.endsWith("?")) {
terminalHops.println("Comma delimited, and first letter followed by '!' resets previous inputs: HOPTIMES:start w/ 'T,'//HOPINFO: starts w/ 'I,'");
terminalHops.flush();
}
if (fromTerminal.startsWith("T") ) { //Hoptimes input
int lastIndex;
if (fromTerminal.endsWith("!")){ //In case I need to reset everything and re input hop additions
hopCounter = 0;
lastIndex = 0;
}
fromTerminal.remove(0,1);
for (int i = 0; i < fromTerminal.length(); i++) {
if (fromTerminal.substring(i, i+1) == ",") {
HOPTIME[hopCounter] = (fromTerminal.substring(lastIndex, i)).toInt();
lastIndex = i + 1;
hopCounter++;
}
if (i == fromTerminal.length() - 1) { // If we're at the end of the string (no more commas to stop us)
HOPTIME[hopCounter] = (fromTerminal.substring(lastIndex, i)).toInt();
}
}
terminalHops.print(HOPTIME[1]);
terminalHops.print(" from ArrayHOPTIME ");
terminalHops.print(hopCounter);
terminalHops.println(" total inputs");
terminalHops.flush();
}
if (fromTerminal.startsWith("I")){ //Hopinfo input
int counter;
int lastIndex;
if (fromTerminal.endsWith("!")){ //In case I need to reset everything and re input hop additions
counter = 0;
lastIndex = 0;
}
fromTerminal.remove(0,1);
for (int i = 0; i < fromTerminal.length(); i++) {
if (fromTerminal.substring(i, i+1) == ",") {
HOPINFO[counter] = fromTerminal.substring(lastIndex, i);
lastIndex = i + 1;
counter++;
}
if (i == fromTerminal.length() - 1) { // If we're at the end of the string (no more commas to stop us)
HOPINFO[counter] = fromTerminal.substring(lastIndex, i);
}
}
terminalHops.print(HOPINFO[1]);
terminalHops.print(" from CharArrayHOPINFO ");
terminalHops.print(counter);
terminalHops.println(" total inputs");
terminalHops.flush();
}
}
////Manual Controls
BLYNK_WRITE(V4) //Start Button
{
val_start= param.asInt();
}
BLYNK_WRITE(V5) //Pause Button
{
val_pause= param.asInt();
}
BLYNK_WRITE(V6) //Pump Button
{
val_pump= param.asInt();
}
BLYNK_WRITE(V7) //Heater 1 Button
{
val_heater1= param.asInt();
}
BLYNK_WRITE(V8) //Heater 2 Button
{
val_heater2= param.asInt();
}
void setup()
{
Serial.begin(115200);
Blynk.begin(auth,ssid,password);
timer.setInterval(1000, brewingstuff); //Check my brewing code every 1s
sensor.begin();
sensor.setResolution(9); //Resolution of 9 means 0.5degC increments.
pinMode(PUMP, OUTPUT); //initialize pin locations as output or input
pinMode(HEATER1, OUTPUT);
pinMode(HEATER2, OUTPUT);
pinMode(BUZZER, OUTPUT);
terminal.println("Setup done, Phil's beer is on the way, Ready?");
terminal.flush();
}
void loop()
{
Blynk.run();
timer.run();
sensor.requestTemperatures(); //Get TEMP reading continuously
tanktemp = sensor.getTempFByIndex(0);
}