Setting variable value in Blynk which then ESP8266 based WeMos D1 will pull

#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
//#include <Time.h>
// Data wire (containing the Temp Sensors) is plugged into pin 3 on the Arduino
#define ONE_WIRE_BUS 3
// Setup a oneWire instance to communicate with any OneWire device
OneWire oneWire(ONE_WIRE_BUS);
// Pass the oneWire reference to Dallas Temperature. 
DallasTemperature sensor(&oneWire);
// Assign the addresses of the 1-Wire DS18B20 Temp sensors.
DeviceAddress TEMPSENSOR = { 0x28, 0xC3, 0x14, 0xAC, 0x04, 0x00, 0x00, 0x9E };
//LCD Library
LiquidCrystal_I2C lcd(0x38);
const char degree = 223;  //Degree symbol

//////////////////////BLYNK CODE
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "da8b62f0ecec4fd283a1121c7821b6c4";

//////////////////////USER INPUTS from Blynk Terminal
BLYNK_WRITE(V0)  // Terminal
{
  String fromTerminal = param.asStr();
  if (fromTerminal.endsWith("MASHTEMP") ){
    float MASHTEMP = fromTerminal.toFloat(); 
  }
  else if (fromTerminal.endsWith("MASHTIME") ) {
    const int MASHTIME = fromTerminal.toFloat();
  }
  else if (fromTerminal.endsWith("BOILTIME") ) {
    const int BOILTIME = fromTerminal.toFloat();
  }
  else if (fromTerminal.endsWith("CHILLTIME") ) {
    const int CHILLTIME = fromTerminal.toFloat();
  }
  else if (fromTerminal.endsWith("HOPADDS") ) {
    const int HOPADDS = fromTerminal.toFloat();
  }
  
  else {
    string HAPADDSINFO = fromTerminal;
  }
}


////////Setting up variables to be declared by Blynk app
const int MASHTEMP; // Desired Mash Temp(deg F)
const int MASHTIME; //Desired Mash Time(milli sec.)
const int BOILTIME; //Desired Boil Time(milli sec.)
const int CHILLTIME; //Desired time to pump all wort through the wort chiller (milli sec.)
//HOP ADDITIONS, HOPADDS and HOPADDSINFO must be the same array length
int HOPADDS []; //Hop times
const char* HOPADDSINFO []//Hop adds contents
float HopAddtime; //Creating variable for for loop below
int h; //Declare the for loop variable

////////////////////////Assign variables
float mashtanktemp; //Declaring temperature variables
unsigned long minutes = (millis()/60000); //Code to switch elapsed time from milliseconds to minutes 
unsigned long MashStartTime; //used for MASH TIME
unsigned long ElapsedMashTime; //Time minutes-mashstarttime
unsigned long BoilStartTime; //used for BOIL TIME
unsigned long ElapsedBoilTime; // time minutes-boilstarttime
unsigned long ChillStartTime; //used for BOIL TIME
unsigned long ElapsedChillTime; // time minutes-boilstarttime

//Setup all states
boolean mashcycle = true;
boolean premash;
boolean mashstart;
boolean mashrun;
boolean mashend;
boolean boilcycle;
boolean preboil;
boolean boilstart;
boolean boilrun;
boolean boilend;
boolean chillstart;
boolean chillrun;
boolean chillend;


//Pin Inputs/Outputs to Arduino:
//BUZZER module = Pin 5, called by tone function so doesnt need to be initialized
const int PUMP = 9;
const int HEATER1 = 10;
const int HEATER2 = 11;
const int START = 0;
const int PAUSE = 1;
const int PUMPBUTTON = 2;
const int HEATER1BUTTON = 3;
const int HEATER2BUTTON = 4;

//Status variables for buttons
int val_start = 0; 
int val_pause = 0;
int val_pumpbutton = 0;
int val_heater1button = 0;
int val_heater2button = 0;




void setup() 
{
  // start serial port to report back values and status
  Serial.begin(9600);
  //Start Blynk
  Blynk.begin(auth,"ssid", "pass");
  // Start up the library
  sensor.begin();
  // set the resolution to 9 bit
  sensor.setResolution(TEMPSENSOR, 9); //Resolution of 9 means 0.5degC increments.
 
  
  //initialize pin locations as output or input
  pinMode(PUMP, OUTPUT);
  pinMode(HEATER1, OUTPUT);
  pinMode(HEATER2, OUTPUT);
  pinMode(START, INPUT);
  pinMode(PAUSE, INPUT);
  pinMode(PUMPBUTTON, INPUT);
  pinMode(HEATER1BUTTON, INPUT);
  pinMode(HEATER2BUTTON, INPUT);
  
  //Initialize LCD to 16 characters by 2 lines
  lcd.begin(16, 2);
  //lcd.setBacklightPin(3,POSITIVE); MIGHT NEED TO CONTROL BACKLIGHT ETC
  //lcd.setBacklight(HIGH);
  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print("Phil's beer is on the way, Ready?");
   
}




//The Control System script starts here:

void loop() 
{ 
  Blynk.run();
  timer.run();
  
  val_start = digitalRead(START); 
  val_pause = digitalRead(PAUSE);
  val_pumpbutton = digitalRead(PUMPBUTTON);
  val_heater1button = digitalRead(HEATER1BUTTON);
  val_heater2button = digitalRead(HEATER2BUTTON);
  
if (val_start == HIGH && val_pause == HIGH){

      analogWrite(HEATER1, 0);
      analogWrite(HEATER2, 0);
      analogWrite(PUMP, 0);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Start and Pause Pressed, Fix issue");
      delay(1000); 

  }

  
if (val_start == LOW && val_pause == HIGH){

      analogWrite(HEATER1, 0);
      analogWrite(HEATER2, 0);
      analogWrite(PUMP, 0);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Manual Pause");
      delay(1000); 

  }

if (val_start == LOW && val_pause == LOW && val_pumpbutton == HIGH){
      
      tone(5, 500, 5000);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Pump starting, need to open ball valve!!");
      delay(30000);
      analogWrite(PUMP, 255);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Manual Pump On");
      delay(1000);

  }

if (val_start == LOW && val_pause == LOW && val_heater1button == HIGH){

      tone(5, 500, 5000);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Heat 1 starting, need cover w water!!");
      delay(30000);
      analogWrite(HEATER1, 255);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Manual Heater 1 On");
      delay(1000);

  } 
  
if (val_start == LOW && val_pause == LOW && val_heater2button == HIGH){

      tone(5, 500, 5000);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Heat 2 starting, need cover w water!!");
      delay(30000);
      analogWrite(HEATER2, 255);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Manual Heater 2 On");
      delay(1000);

  } 
  
 
if (val_start == HIGH && val_pause == LOW && val_pumpbutton == LOW && val_heater1button == LOW && val_heater2button == LOW){

  delay(2000); //give a reading every 2.0 sec
  sensor.requestTemperatures();
  mashtanktemp = sensor.getTempF(TEMPSENSOR);
  ElapsedMashTime = minutes-MashStartTime; //If this global formulas dont work then have to put the raw formula into each line like it used to be
  ElapsedBoilTime = minutes-BoilStartTime;
  ElapsedChillTime = minutes-ChillStartTime;


//////////////////SETTING UP STATES CODE  
//premash
if (mashtanktemp < MASHTEMP && mashcycle == true) { 
    premash=true;
  }

//mashstart
if (mashtanktemp >= MASHTEMP - 2.0 && mashtanktemp <= MASHTEMP + 2.0 && premash == true) { 
    mashstart = true;
    premash=false;
  }

//mashrun
if (mashstart = true) { 
    MashStartTime = minutes;
    mashrun = true;
    mashstart = false;
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Mash Elapsed Time Test: Should be very low");
    lcd.print(ElapsedMashTime);
    delay(1000);
  }

//mashsend
if (ElapsedMashTime >= MASHTIME) { 
    mashend = true;
    mashrun = false;
    mashcycle = false;
  }

//preboil
if (mashend = true) { 
    boilcycle = true;
    preboil = true;
    mashend= false;
  }

//boilstart
if (preboil = true && mashtanktemp >= 212) { 
    boilstart = true;
    preboil = false;
  }

//boilrun
if (boilstart = true) { 
    BoilStartTime = minutes;
    boilrun = true;
    boilstart = false;
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Boil Elapsed Time Test: Should be very low");
    lcd.print(ElapsedBoilTime);
    delay(1000);
  }

//boilend
if (ElapsedBoilTime >= BOILTIME) { 
    boilend = true;
    boilrun = false;
    boilcycle = false;
  }

//chill start
if (boilend = true && mashtanktemp <= 100) { 
    chillstart = true;
    boilend = false;
  }

//chill run
if (chillstart = true) { 
    ChillStartTime = minutes;
    chillrun = true;
    chillstart = false;
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Chil Elapsed Time Test: Should be very low");
    lcd.print(ElapsedChillTime);
    delay(1000);
  }

//chill end
if (ElapsedChillTime >= CHILLTIME) { 
    chillend = true;
    chillrun = false;
  }



////////////////////ACTIONS CODES
//premash = Heater 1 & 2 on, pump on
if (premash = true) {
    tone(5, 500, 5000);
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print("Pump & Heat starting, need to open ball valve!!");
    delay(10000);
    analogWrite(HEATER1, 255);
    analogWrite(HEATER2, 255);
    analogWrite(PUMP, 255);
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("T:");
    lcd.print(mashtanktemp);
    lcd.print(degree);
    lcd.print("F");
    lcd.setCursor(0, 2);
    lcd.print(" Pump and Heaters On");
    delay(1000);
  }

//mashrun == mashstart is skipped because that is only used to initialize the time, mashrun heaters off, pump on  
if (mashrun = true) {
    analogWrite(HEATER1, 0);
    analogWrite(HEATER2, 0);
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Mash Temp hit");
    lcd.print(mashtanktemp);
    lcd.print(degree);
    lcd.print("F");
    delay(1000);
  }
  
//mashend = heaters both on, pump off
if(mashend = true){
    analogWrite(HEATER1, 255);
    analogWrite(HEATER2, 255);
    analogWrite(PUMP, 0);
    tone(5, 500, 2000);
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Mash Complete, heat on, pump off");
    lcd.print(mashtanktemp);
    lcd.print(degree);
    lcd.print("F");
    delay(1000);
  }  
  
//boilrun == skip preboil and boilstart as they are both just used to initialize the boil timer, boilrun hits heaters stay on (need to test to see if both heat needs to be on) pump off  
if (boilrun = true){
    analogWrite(HEATER1, 255);
    analogWrite(HEATER2, 255);
    analogWrite(PUMP, 0); 
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Boiling, heaters on, pump off");
    lcd.print(mashtanktemp);
    lcd.print(degree);
    lcd.print("F");
    delay(1000);   
  }

//Hop Additions Code
if (boilrun == true) {
  for (h=0 ; h=sizeof(HOPADDS); 1) {
  HopAddtime = HOPADDS[h];
    if (ElapsedBoilTime >= (HopAddtime - 1) && ElapsedBoilTime <= (HopAddtime + 1)) { //BE SURE THAT THE +/- of the elapsedboil time doesnt result in overlay of two hop additions or else it could be confusing
      tone(5, 500, 2000);
      lcd.setCursor(0,1);
      lcd.print(ElapsedBoilTime);    
      lcd.print("Add");
      lcd.print(HOPADDSINFO[h]);
      delay(15000);
      }
    }
  }
     
//boilend = heat off , pump off
if (boilend = true){
     chillrun = true;
     boilend = false;
     analogWrite(HEATER1, 0);
     analogWrite(HEATER2, 0);
     analogWrite(PUMP, 0);
     lcd.setCursor(0, 1);
     lcd.print("Boil Complete");
     lcd.print(mashtanktemp);
     lcd.print(degree);
     lcd.print("F");
     delay(1000);
   }

//chillrun = skip chillstart as that just initialized the chill timer, chill run turn pump on
if (chillrun = true){
    tone(5, 500, 2000);
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print("Pump starting, need to open ball valve!!");
    delay(10000);
    analogWrite(HEATER1, 0);
    analogWrite(HEATER2, 0);
    analogWrite(PUMP, 127);    
  }

//chillend == turn pump off once chill time is over THIS NEEDS TO BE TEST AND FIGURED OUT.
if (chillend = true){
    tone(5, 500, 5000);
    analogWrite(PUMP, 0); 
    analogWrite(HEATER1, 0);
    analogWrite(HEATER2, 0);
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print("Auto Brewing Complete");       
  }

 }
}

Hardware context:

2 heating elements, one water pump
one temperature sensor

5 buttons: Start Auto code, Pause to stop code, 3 buttons to independently control the heating elements and pumps as needed

Provide a link to the LCD library.

OK I have my new brewery set up at this end now :smiley:

Installed the LCD library but still have a problem with LiquidCrystal_I2C lcd(0x38); so commented out all LCD stuff at this side. If LiquidCrystal_I2C lcd(0x38); works at your end reinstate the LCD stuff with edit, find, replace all //lcd. with lcd. but I noticed you had commentted out a few lcd entries already. Therefore in my sketch find these before the replace all and change them from //lcd… to //*lcd…

You were missing a couple of lines for the SimpleTimer and hopefully you have installed the library for this.
You can’t use toFloat for integers. You would need to convert the floats you get from toFloat into integers but I have just changed the integers to floats for now.

Moved everything out of the loop except 2 lines for Blynk and put them in a 10s timer loop function called brewingstuff().

Getting much further through the compilation now but still an issue with an array etc. Search the sketch for todo and compare new sketch with old sketch. Still plenty of things left for you to fix.

Noticed you are using tone, it was only recently added for ESP’s.

Think I’m ready for a beer now after another 24 hour ‘shift’.

#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
//#include <Time.h>
// Data wire (containing the Temp Sensors) is plugged into pin 3 on the Arduino
#define ONE_WIRE_BUS 3
// Setup a oneWire instance to communicate with any OneWire device
OneWire oneWire(ONE_WIRE_BUS);
// Pass the oneWire reference to Dallas Temperature. 
DallasTemperature sensor(&oneWire);
// Assign the addresses of the 1-Wire DS18B20 Temp sensors.
DeviceAddress TEMPSENSOR = { 0x28, 0xC3, 0x14, 0xAC, 0x04, 0x00, 0x00, 0x9E };
//LCD Library
//todo LiquidCrystal_I2C lcd(0x38);
const char degree = 223;  //Degree symbol

#include <SimpleTimer.h> // todo
SimpleTimer timer;       // todo

//////////////////////BLYNK CODE
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "da8b62f0ecec4fd283a1121c7821b6c4";

////////Setting up variables to be declared by Blynk app
float MASHTEMP; // Desired Mash Temp(deg F)
float MASHTIME; //Desired Mash Time(milli sec.)
float BOILTIME; //Desired Boil Time(milli sec.)
float CHILLTIME; //Desired time to pump all wort through the wort chiller (milli sec.)
//HOP ADDITIONS, HOPADDS and HOPADDSINFO must be the same array length
float HOPADDS; //Hop times
String HOPADDSINFO; //todo Hop adds contents
float HopAddtime; //Creating variable for for loop below
int h; //Declare the for loop variable

//////////////////////USER INPUTS from Blynk Terminal
BLYNK_WRITE(V0)  // Terminal
{
  String fromTerminal = param.asStr();
  if (fromTerminal.endsWith("MASHTEMP") ){
    MASHTEMP = fromTerminal.toFloat(); 
  }
  else if (fromTerminal.endsWith("MASHTIME") ) {
    MASHTIME = fromTerminal.toFloat();
  }
  else if (fromTerminal.endsWith("BOILTIME") ) {
    BOILTIME = fromTerminal.toFloat();
  }
  else if (fromTerminal.endsWith("CHILLTIME") ) {
    CHILLTIME = fromTerminal.toFloat();
  }
  else if (fromTerminal.endsWith("HOPADDS") ) {
    HOPADDS = fromTerminal.toFloat();
  }
  
  else {
    HOPADDSINFO = fromTerminal; //todo
    //HOPADDSINFO = fromTerminal; // todo
  }
}




////////////////////////Assign variables
float mashtanktemp; //Declaring temperature variables
unsigned long minutes = (millis()/60000); //Code to switch elapsed time from milliseconds to minutes 
unsigned long MashStartTime; //used for MASH TIME
unsigned long ElapsedMashTime; //Time minutes-mashstarttime
unsigned long BoilStartTime; //used for BOIL TIME
unsigned long ElapsedBoilTime; // time minutes-boilstarttime
unsigned long ChillStartTime; //used for BOIL TIME
unsigned long ElapsedChillTime; // time minutes-boilstarttime

//Setup all states
boolean mashcycle = true;
boolean premash;
boolean mashstart;
boolean mashrun;
boolean mashend;
boolean boilcycle;
boolean preboil;
boolean boilstart;
boolean boilrun;
boolean boilend;
boolean chillstart;
boolean chillrun;
boolean chillend;


//Pin Inputs/Outputs to Arduino:
//BUZZER module = Pin 5, called by tone function so doesnt need to be initialized
const int PUMP = 9;
const int HEATER1 = 10;
const int HEATER2 = 11;
const int START = 0;
const int PAUSE = 1;
const int PUMPBUTTON = 2;
const int HEATER1BUTTON = 3;
const int HEATER2BUTTON = 4;

//Status variables for buttons
int val_start = 0; 
int val_pause = 0;
int val_pumpbutton = 0;
int val_heater1button = 0;
int val_heater2button = 0;

void brewingstuff(){  //todo
  val_start = digitalRead(START); 
  val_pause = digitalRead(PAUSE);
  val_pumpbutton = digitalRead(PUMPBUTTON);
  val_heater1button = digitalRead(HEATER1BUTTON);
  val_heater2button = digitalRead(HEATER2BUTTON);
  
if (val_start == HIGH && val_pause == HIGH){

      analogWrite(HEATER1, 0);
      analogWrite(HEATER2, 0);
      analogWrite(PUMP, 0);
      ////lcd.clear();
      ////lcd.setCursor(0,1);
      ////lcd.print("Start and Pause Pressed, Fix issue");
      delay(1000); 

  }

  
if (val_start == LOW && val_pause == HIGH){

      analogWrite(HEATER1, 0);
      analogWrite(HEATER2, 0);
      analogWrite(PUMP, 0);
      ////lcd.clear();
      ////lcd.setCursor(0,1);
      ////lcd.print("Manual Pause");
      delay(1000); 

  }

if (val_start == LOW && val_pause == LOW && val_pumpbutton == HIGH){
      
      tone(5, 500, 5000);
      ////lcd.clear();
      ////lcd.setCursor(0,1);
      ////lcd.print("Pump starting, need to open ball valve!!");
      delay(30000);
      analogWrite(PUMP, 255);
      ////lcd.clear();
      ////lcd.setCursor(0,1);
      ////lcd.print("Manual Pump On");
      delay(1000);

  }

if (val_start == LOW && val_pause == LOW && val_heater1button == HIGH){

      tone(5, 500, 5000);
      ////lcd.clear();
      ////lcd.setCursor(0,1);
      ////lcd.print("Heat 1 starting, need cover w water!!");
      delay(30000);
      analogWrite(HEATER1, 255);
      ////lcd.clear();
      ////lcd.setCursor(0,1);
      ////lcd.print("Manual Heater 1 On");
      delay(1000);

  } 
  
if (val_start == LOW && val_pause == LOW && val_heater2button == HIGH){

      tone(5, 500, 5000);
      ////lcd.clear();
      ////lcd.setCursor(0,1);
      ////lcd.print("Heat 2 starting, need cover w water!!");
      delay(30000);
      analogWrite(HEATER2, 255);
      ////lcd.clear();
      ////lcd.setCursor(0,1);
      ////lcd.print("Manual Heater 2 On");
      delay(1000);

  } 
  
 
if (val_start == HIGH && val_pause == LOW && val_pumpbutton == LOW && val_heater1button == LOW && val_heater2button == LOW){

  delay(2000); //give a reading every 2.0 sec
  sensor.requestTemperatures();
  mashtanktemp = sensor.getTempF(TEMPSENSOR);
  ElapsedMashTime = minutes-MashStartTime; //If this global formulas dont work then have to put the raw formula into each line like it used to be
  ElapsedBoilTime = minutes-BoilStartTime;
  ElapsedChillTime = minutes-ChillStartTime;


//////////////////SETTING UP STATES CODE  
//premash
if (mashtanktemp < MASHTEMP && mashcycle == true) { 
    premash=true;
  }

//mashstart
if (mashtanktemp >= MASHTEMP - 2.0 && mashtanktemp <= MASHTEMP + 2.0 && premash == true) { 
    mashstart = true;
    premash=false;
  }

//mashrun
if (mashstart = true) { 
    MashStartTime = minutes;
    mashrun = true;
    mashstart = false;
    //lcd.clear();
    //lcd.setCursor(0, 1);
    //lcd.print("Mash Elapsed Time Test: Should be very low");
    //lcd.print(ElapsedMashTime);
    delay(1000);
  }

//mashsend
if (ElapsedMashTime >= MASHTIME) { 
    mashend = true;
    mashrun = false;
    mashcycle = false;
  }

//preboil
if (mashend = true) { 
    boilcycle = true;
    preboil = true;
    mashend= false;
  }

//boilstart
if (preboil = true && mashtanktemp >= 212) { 
    boilstart = true;
    preboil = false;
  }

//boilrun
if (boilstart = true) { 
    BoilStartTime = minutes;
    boilrun = true;
    boilstart = false;
    //lcd.clear();
    //lcd.setCursor(0, 1);
    //lcd.print("Boil Elapsed Time Test: Should be very low");
    //lcd.print(ElapsedBoilTime);
    delay(1000);
  }

//boilend
if (ElapsedBoilTime >= BOILTIME) { 
    boilend = true;
    boilrun = false;
    boilcycle = false;
  }

//chill start
if (boilend = true && mashtanktemp <= 100) { 
    chillstart = true;
    boilend = false;
  }

//chill run
if (chillstart = true) { 
    ChillStartTime = minutes;
    chillrun = true;
    chillstart = false;
    //lcd.clear();
    //lcd.setCursor(0, 1);
    //lcd.print("Chil Elapsed Time Test: Should be very low");
    //lcd.print(ElapsedChillTime);
    delay(1000);
  }

//chill end
if (ElapsedChillTime >= CHILLTIME) { 
    chillend = true;
    chillrun = false;
  }



////////////////////ACTIONS CODES
//premash = Heater 1 & 2 on, pump on
if (premash = true) {
    tone(5, 500, 5000);
    //lcd.clear();
    //lcd.setCursor(0,1);
    //lcd.print("Pump & Heat starting, need to open ball valve!!");
    delay(10000);
    analogWrite(HEATER1, 255);
    analogWrite(HEATER2, 255);
    analogWrite(PUMP, 255);
    //lcd.clear();
    //lcd.setCursor(0, 1);
    //lcd.print("T:");
    //lcd.print(mashtanktemp);
    //lcd.print(degree);
    //lcd.print("F");
    //lcd.setCursor(0, 2);
    //lcd.print(" Pump and Heaters On");
    delay(1000);
  }

//mashrun == mashstart is skipped because that is only used to initialize the time, mashrun heaters off, pump on  
if (mashrun = true) {
    analogWrite(HEATER1, 0);
    analogWrite(HEATER2, 0);
    //lcd.clear();
    //lcd.setCursor(0, 1);
    //lcd.print("Mash Temp hit");
    //lcd.print(mashtanktemp);
    //lcd.print(degree);
    //lcd.print("F");
    delay(1000);
  }
  
//mashend = heaters both on, pump off
if(mashend = true){
    analogWrite(HEATER1, 255);
    analogWrite(HEATER2, 255);
    analogWrite(PUMP, 0);
    tone(5, 500, 2000);
    //lcd.clear();
    //lcd.setCursor(0, 1);
    //lcd.print("Mash Complete, heat on, pump off");
    //lcd.print(mashtanktemp);
    //lcd.print(degree);
    //lcd.print("F");
    delay(1000);
  }  
  
//boilrun == skip preboil and boilstart as they are both just used to initialize the boil   , boilrun hits heaters stay on (need to test to see if both heat needs to be on) pump off  
if (boilrun = true){
    analogWrite(HEATER1, 255);
    analogWrite(HEATER2, 255);
    analogWrite(PUMP, 0); 
    //lcd.clear();
    //lcd.setCursor(0, 1);
    //lcd.print("Boiling, heaters on, pump off");
    //lcd.print(mashtanktemp);
    //lcd.print(degree);
    //lcd.print("F");
    delay(1000);   
  }

//Hop Additions Code
if (boilrun == true) {
  for (h=0 ; h=sizeof(HOPADDS); 1) {
  HopAddtime = HOPADDS[h];
    if (ElapsedBoilTime >= (HopAddtime - 1) && ElapsedBoilTime <= (HopAddtime + 1)) { //BE SURE THAT THE +/- of the elapsedboil time doesnt result in overlay of two hop additions or else it could be confusing
      tone(5, 500, 2000);
      //lcd.setCursor(0,1);
      //lcd.print(ElapsedBoilTime);    
      //lcd.print("Add");
      //lcd.print(HOPADDSINFO[h]);
      delay(15000);
      }
    }
  }
     
//boilend = heat off , pump off
if (boilend = true){
     chillrun = true;
     boilend = false;
     analogWrite(HEATER1, 0);
     analogWrite(HEATER2, 0);
     analogWrite(PUMP, 0);
     //lcd.setCursor(0, 1);
     //lcd.print("Boil Complete");
     //lcd.print(mashtanktemp);
     //lcd.print(degree);
     //lcd.print("F");
     delay(1000);
   }

//chillrun = skip chillstart as that just initialized the chill timer, chill run turn pump on
if (chillrun = true){
    tone(5, 500, 2000);
    //lcd.clear();
    //lcd.setCursor(0,1);
    //lcd.print("Pump starting, need to open ball valve!!");
    delay(10000);
    analogWrite(HEATER1, 0);
    analogWrite(HEATER2, 0);
    analogWrite(PUMP, 127);    
  }

//chillend == turn pump off once chill time is over THIS NEEDS TO BE TEST AND FIGURED OUT.
if (chillend = true){
    tone(5, 500, 5000);
    analogWrite(PUMP, 0); 
    analogWrite(HEATER1, 0);
    analogWrite(HEATER2, 0);
    ////lcd.clear();
    ////lcd.setCursor(0,1);
    ////lcd.print("Auto Brewing Complete");       
  }

 }  
}


void setup() 
{
  // start serial port to report back values and status
  Serial.begin(9600);
  //Start Blynk
  Blynk.begin(auth,"ssid", "pass");
  // Start up the library
  sensor.begin();
  // set the resolution to 9 bit
  sensor.setResolution(TEMPSENSOR, 9); //Resolution of 9 means 0.5degC increments.
 
  
  //initialize pin locations as output or input
  pinMode(PUMP, OUTPUT);
  pinMode(HEATER1, OUTPUT);
  pinMode(HEATER2, OUTPUT);
  pinMode(START, INPUT);
  pinMode(PAUSE, INPUT);
  pinMode(PUMPBUTTON, INPUT);
  pinMode(HEATER1BUTTON, INPUT);
  pinMode(HEATER2BUTTON, INPUT);
  
  //Initialize LCD to 16 characters by 2 lines
  //lcd.begin(16, 2);
  ////lcd.setBacklightPin(3,POSITIVE); MIGHT NEED TO CONTROL BACKLIGHT ETC
  ////lcd.setBacklight(HIGH);
  ////lcd.clear();
  ////lcd.setCursor(0, 1);
  ////lcd.print("Phil's beer is on the way, Ready?");
  timer.setInterval(10000, brewingstuff); // todo check every 10s
}




//The Control System script starts here:

void loop() 
{ 
  Blynk.run();
  timer.run();
}

If you want to loop through the elements of your array, I found that counting does not always work with sizeof(). I use it like this:

int sizeOfPrints = sizeof(prints) / sizeof(int);

This actually returns the number of elements of the array, but I have no idea why. Presuming of course it’s an the array is consisting of INT’s. Not sure if it works the same for floating numbers.

I would suggest changing the variable to an INT anyway. Is it really needed to have floats?

-edit-

The vars are not declared as Arrays from what I can tell (just put in the IDE), that for sure wouldn’t make your sketch work.

-edit some more-

The HOPPADD / INFO array should be created globally with the correct size or in the Terminal handling part, but it wouldn’t be global in that case. I’m not sure how to fix this. Because this is a highly interesting subject I will try to figure it out in a more simple setting. Sometimes it’s better to eliminate all the code and try to just achieve a small portion of your goal.

Arrays can be allocated dynamically apparently, but it’s bad practice:

He doesn’t need floats, it was just easier for me to make them floats as he was wrongly using toFloat from a String.

It should be possible to use toInt instead of toFloat for the Terminal string conversion.

That may be handier, but the concept of determining the number of elements also goes for float, so that shouldn’t be a problem anyway. The link should suffice to get something with dynamically arrays going on :smiley:

@philmurp below are screenshots from Serial Monitor, the Blynk app and the sketch of the ‘working’ Brewery.
My WeMos D1 Mini hasn’t produced any palatable beer yet though. Perhaps that’s because I don’t have any sensors, kegs, hops etc :smiley:

What it gives you is the basic Blynk sketch for the Terminal to collect your required variables and you will have to carefully add back all the real Brewing stuff. Your main Brewing stuff should go in the brewingstuff() function which is called with the timer every 10 seconds.

Don’t use delay in your sketch other than for very short periods (say under 1 second) or you may get disconnected from the Blynk server.

You will see some typos when I was entering the brewing data into the Terminal. This is due to my stubby fingers and poor eyesight but what it highlights it that you should consider shortening the endsWith to something like:

MD for MASHTEMP i.e. mash degrees
MT for MASHTIME
BT for BOILTIME
CT for CHILLTIME
HA for HOPADDS

For HOPADDSINFO the sketch is currently just char HOPADDSINFO[10]. This is something for you to work on as it wouldn’t be much fun if we did it all for you. If you get stuck please explain in full detail all what this might cover and Blynkers will try to advise a suitable way of doing it.

As pointed out by Dave there are probably much better ways of doing this than just with Terminal. Sliders, buttons and Menu widgets might make it much more user friendly.

//////////////////////BLYNK CODE
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h> // todo
SimpleTimer timer;       // todo
char auth[] = "da8b62f0ecec4fd283a1121c7821b6c4";

////////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.)
//HOP ADDITIONS, HOPADDS and HOPADDSINFO must be the same array length
long int HOPADDS = 10; // newtodo Hop times
char HOPADDSINFO[10];  // char array HOPADDSINFO; //newtodo Hop adds contents
int HopAddtime; //Creating variable for for loop below, todo was float
int h; //Declare the for loop variable

////////////////////////Assign variables
float mashtanktemp; //Declaring temperature variables
unsigned long minutes = (millis()/60000); //Code to switch elapsed time from milliseconds to minutes 
unsigned long MashStartTime; //used for MASH TIME
unsigned long ElapsedMashTime; //Time minutes-mashstarttime
unsigned long BoilStartTime; //used for BOIL TIME
unsigned long ElapsedBoilTime; // time minutes-boilstarttime
unsigned long ChillStartTime; //used for BOIL TIME
unsigned long ElapsedChillTime; // time minutes-boilstarttime

//Setup all states
boolean mashcycle = true;
boolean premash;
boolean mashstart;
boolean mashrun;
boolean mashend;
boolean boilcycle;
boolean preboil;
boolean boilstart;
boolean boilrun;
boolean boilend;
boolean chillstart;
boolean chillrun;
boolean chillend;

//Status variables for buttons
int val_start = 0; 
int val_pause = 0;
int val_pumpbutton = 0;
int val_heater1button = 0;
int val_heater2button = 0;

void brewingstuff(){  //todo
  //Serial.println("...");
}

//////////////////////USER INPUTS from Blynk Terminal
BLYNK_WRITE(V0)  // Terminal
{
  String fromTerminal = param.asStr();
  if (fromTerminal.endsWith("MASHTEMP") ){
    MASHTEMP = fromTerminal.toInt();
    Serial.print(MASHTEMP);
    Serial.println(" from XMASHTEMP");
  }
  else if (fromTerminal.endsWith("MASHTIME") ) {
    MASHTIME = fromTerminal.toInt();
    Serial.print(MASHTIME);
    Serial.println(" from XMASHTIME");
  }
  else if (fromTerminal.endsWith("BOILTIME") ) {
    BOILTIME = fromTerminal.toInt();
    Serial.print(BOILTIME);
    Serial.println(" from XBOILTIME");
  }
  else if (fromTerminal.endsWith("CHILLTIME") ) {
    CHILLTIME = fromTerminal.toInt();
    Serial.print(CHILLTIME);
    Serial.println(" from XCHILLTIME");
  }
  else if (fromTerminal.endsWith("HOPADDS") ) {
    HOPADDS = fromTerminal.toInt();
    Serial.print(HOPADDS);
    Serial.println(" from XHOPADDS");
  }
  
  else {
    fromTerminal.toCharArray(HOPADDSINFO, 10); //todo
    for (int x = 0; x < 10; x++){
      Serial.write(HOPADDSINFO[x]);
    }
    Serial.println(" from CharArrayHOPADDSINFO");
  }
}

void setup() 
{
  Serial.begin(115200);
  Blynk.begin(auth,"XXXXXXXXXXX", "XXXXXXXXXXXXX");   // todo enter your router credentials
  timer.setInterval(10000, brewingstuff); // todo check every 10s
}


void loop() 
{ 
  Blynk.run();
  timer.run();
}

Don’t forget to put your router credentials in the Blynk.begin line.
Good luck.

philmurp21m
So I have tried for a while to figure out getting HOPADDS and HOPADDSINFO from array. Here is what I have gotten too. This works with the IDE verify, but I have not yet figured out how to get the first line “int hopsize=4” automated. I want to write a line that says count number of “,” + 1 and then input that as hopsize, but I have yet to find a function that can count the number of specific characters in a string.

else if (fromTerminal.startsWith("HOPADDSINFO")){
   int hopsize = 4;
   String HOPINFO[hopsize];
   // Keep track of current position in array
   int counter = 0;
   // Keep track of the last comma so we know where to start the substring
   int lastIndex = 0;
  
      for (int i = 0; i < fromTerminal.length(); i++) {
        // Loop through each character and check if it's a comma
        if (fromTerminal.substring(i, i+1) == ",") {
          // Grab the piece from the last index up to the current position and store it
          HOPINFO[counter] = fromTerminal.substring(lastIndex, i);
          // Update the last position and add 1, so it starts from the next character
          lastIndex = i + 1;
          // Increase the position in the array that we store into
          counter++;
        }

        // If we're at the end of the string (no more commas to stop us)
        if (i == fromTerminal.length() - 1) {
          // Grab the last part of the string from the lastIndex to the end
          HOPINFO[counter] = fromTerminal.substring(lastIndex, i);
        }
      }
      
      // Clear out counters to get ready for the next incoming string
      counter = 0;
      lastIndex = 0;

Reply

Costas15m
Is hopsize a fixed number of 4 or does it vary depending what you are brewing?

Reply

philmurp13m
It varies depends on what hops are going into the beer so I need to convert that line into automated, hence why I was trying to count number of “,” or something like that

Reply

philmurp10m
I could add an if statement saying HOPNUMBER and input that variable through terminal

Reply

philmurp4m
So I have it now that I need to input the hopsize in terminal. However at the end of the HOPADDS loop, I am not sure how to convert string array to int array. I can do one part of the array at a time but cant do the whole thing. Any thoughts?

 else if (fromTerminal.endsWith("HOPNUMBER") ){
    int hopsize = fromTerminal.toInt();
    Serial.print(hopsize);
    Serial.println(" from Xhopsize");
  }
  else if (fromTerminal.endsWith("HOPADDS") ) {
   String HOPTIME[hopsize];
   // Keep track of current position in array
   int counter = 0;
   // Keep track of the last comma so we know where to start the substring
   int lastIndex = 0;
  
      for (int i = 0; i < fromTerminal.length(); i++) {
        // Loop through each character and check if it's a comma
        if (fromTerminal.substring(i, i+1) == ",") {
          // Grab the piece from the last index up to the current position and store it
          HOPTIME[counter] = fromTerminal.substring(lastIndex, i);
          // Update the last position and add 1, so it starts from the next character
          lastIndex = i + 1;
          // Increase the position in the array that we store into
          counter++;
        }

        // If we're at the end of the string (no more commas to stop us)
        if (i == fromTerminal.length() - 1) {
          // Grab the last part of the string from the lastIndex to the end
          HOPTIME[counter] = fromTerminal.substring(lastIndex, i);
        }
      }
      
      int HOPTIMEVALUE = HOPTIME[0].toInt();
      // Clear out counters to get ready for the next incoming string
      counter = 0;
      lastIndex = 0; 
  }
  
  else if (fromTerminal.startsWith("HOPADDSINFO")){
   String HOPINFO[hopsize];
   // Keep track of current position in array
   int counter = 0;
   // Keep track of the last comma so we know where to start the substring
   int lastIndex = 0;
  
      for (int i = 0; i < fromTerminal.length(); i++) {
        // Loop through each character and check if it's a comma
        if (fromTerminal.substring(i, i+1) == ",") {
          // Grab the piece from the last index up to the current position and store it
          HOPINFO[counter] = fromTerminal.substring(lastIndex, i);
          // Update the last position and add 1, so it starts from the next character
          lastIndex = i + 1;
          // Increase the position in the array that we store into
          counter++;
        }

        // If we're at the end of the string (no more commas to stop us)
        if (i == fromTerminal.length() - 1) {
          // Grab the last part of the string from the lastIndex to the end
          HOPINFO[counter] = fromTerminal.substring(lastIndex, i);
        }
      }
      
      // Clear out counters to get ready for the next incoming string
      counter = 0;
      lastIndex = 0; 

            
       }
    Serial.println(" from CharArrayHOPADDSINFO");
  }

I am not sure this is working as I am getting error

invalid types ‘long int[int]’ for array subscript

when I try and do this:

//Hop Additions Code
if (boilrun == true) {
  
  for (h=0 ; h=sizeof(HOPTIME); 1) {
  HopAddtime = HOPTIME[h].toInt();
     if (ElapsedBoilTime >= (HopAddtime - 1) && ElapsedBoilTime <= (HopAddtime + 1)) { //BE SURE THAT THE +/- of the elapsedboil time doesnt result in overlay of two hop additions or else it could be confusing
        tone(5, 500, 2000);
        lcd.setCursor(0,1);
        lcd.print(ElapsedBoilTime);    
        lcd.print("Add");
        lcd.print(HOPINFO[h]);
       delay(15000);
       }
      }
    }

I cant seem to find out what this would mean.

Here is where I am now. I am worried that my hop calculation for HOPTIME wont work because HopAddtime is set to a string value. But Aruidno says this is verified. If you get a chance to look it over and give feedback that would be very helpful as I have been looking at it for to long I think.

#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Data wire (containing the Temp Sensors) is plugged into pin 3 on the Arduino
#define ONE_WIRE_BUS 3
// Setup a oneWire instance to communicate with any OneWire device
OneWire oneWire(ONE_WIRE_BUS);
// Pass the oneWire reference to Dallas Temperature. 
DallasTemperature sensor(&oneWire);
// Assign the addresses of the 1-Wire DS18B20 Temp sensors.
DeviceAddress TEMPSENSOR = { 0x28, 0xC3, 0x14, 0xAC, 0x04, 0x00, 0x00, 0x9E };
//LCD Library
LiquidCrystal_I2C lcd(0x27);
const char degree = 223;  //Degree symbol

//////////////////////BLYNK CODE
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h> // todo
SimpleTimer timer;       // todo
char auth[] = "da8b62f0ecec4fd283a1121c7821b6c4";

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

//HOP ADDITIONS, HOPTIME and HOPINFO must be the same array length
String HOPTIME; // Hop times
String HOPINFO;  // char array HOPINFO;
int HopAddtime; //Creating variable for for loop below
int h; //Declare the for loop variable
int hopsize;//Declare to make hop arrays=setting array size


////////////////////////Assign variables
float mashtanktemp; //Declaring temperature variables
unsigned long minutes = (millis()/60000); //Code to switch elapsed time from milliseconds to minutes 
unsigned long MashStartTime; //used for MASH TIME
unsigned long ElapsedMashTime; //Time minutes-mashstarttime
unsigned long BoilStartTime; //used for BOIL TIME
unsigned long ElapsedBoilTime; // time minutes-boilstarttime
unsigned long ChillStartTime; //used for BOIL TIME
unsigned long ElapsedChillTime; // time minutes-boilstarttime

//Setup all states
boolean mashcycle = true;
boolean premash;
boolean mashstart;
boolean mashrun;
boolean mashend;
boolean boilcycle;
boolean preboil;
boolean boilstart;
boolean boilrun;
boolean boilend;
boolean chillstart;
boolean chillrun;
boolean chillend;

//Pin Inputs/Outputs to Arduino:
const int PUMP = 9;
const int HEATER1 = 10;
const int HEATER2 = 11;
const int START = 0;
const int PAUSE = 1;
const int PUMPBUTTON = 2;
const int HEATER1BUTTON = 3;
const int HEATER2BUTTON = 4;

//Status variables for buttons
int val_start = 0; 
int val_pause = 0;
int val_pumpbutton = 0;
int val_heater1button = 0;
int val_heater2button = 0;

void brewingstuff(){  //todo
  val_start = digitalRead(START); 
  val_pause = digitalRead(PAUSE);
  val_pumpbutton = digitalRead(PUMPBUTTON);
  val_heater1button = digitalRead(HEATER1BUTTON);
  val_heater2button = digitalRead(HEATER2BUTTON);
  
if (val_start == HIGH && val_pause == HIGH){

      analogWrite(HEATER1, 0);
      analogWrite(HEATER2, 0);
      analogWrite(PUMP, 0);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Start and Pause Pressed, Fix issue");
      delay(1000); 

  }

  
if (val_start == LOW && val_pause == HIGH){

      analogWrite(HEATER1, 0);
      analogWrite(HEATER2, 0);
      analogWrite(PUMP, 0);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Manual Pause");
      delay(1000); 

  }

if (val_start == LOW && val_pause == LOW && val_pumpbutton == HIGH){
      
      tone(5, 500, 5000);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Pump starting, need to open ball valve!!");
      delay(30000);
      analogWrite(PUMP, 255);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Manual Pump On");
      delay(1000);

  }

if (val_start == LOW && val_pause == LOW && val_heater1button == HIGH){

      tone(5, 500, 5000);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Heat 1 starting, need cover w water!!");
      delay(30000);
      analogWrite(HEATER1, 255);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Manual Heater 1 On");
      delay(1000);

  } 
  
if (val_start == LOW && val_pause == LOW && val_heater2button == HIGH){

      tone(5, 500, 5000);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Heat 2 starting, need cover w water!!");
      delay(30000);
      analogWrite(HEATER2, 255);
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Manual Heater 2 On");
      delay(1000);

  } 
  
 
if (val_start == HIGH && val_pause == LOW && val_pumpbutton == LOW && val_heater1button == LOW && val_heater2button == LOW){

  delay(2000); //give a reading every 2.0 sec
  sensor.requestTemperatures();
  mashtanktemp = sensor.getTempF(TEMPSENSOR);
  ElapsedMashTime = minutes-MashStartTime; //If this global formulas dont work then have to put the raw formula into each line like it used to be
  ElapsedBoilTime = minutes-BoilStartTime;
  ElapsedChillTime = minutes-ChillStartTime;


//////////////////SETTING UP STATES CODE  
//premash
if (mashtanktemp < MASHTEMP && mashcycle == true) { 
    premash=true;
  }

//mashstart
if (mashtanktemp >= MASHTEMP - 2.0 && mashtanktemp <= MASHTEMP + 2.0 && premash == true) { 
    mashstart = true;
    premash=false;
  }

//mashrun
if (mashstart = true) { 
    MashStartTime = minutes;
    mashrun = true;
    mashstart = false;
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Mash Elapsed Time Test: Should be very low");
    lcd.print(ElapsedMashTime);
    delay(1000);
  }

//mashsend
if (ElapsedMashTime >= MASHTIME) { 
    mashend = true;
    mashrun = false;
    mashcycle = false;
  }

//preboil
if (mashend = true) { 
    boilcycle = true;
    preboil = true;
    mashend= false;
  }

//boilstart
if (preboil = true && mashtanktemp >= 212) { 
    boilstart = true;
    preboil = false;
  }

//boilrun
if (boilstart = true) { 
    BoilStartTime = minutes;
    boilrun = true;
    boilstart = false;
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Boil Elapsed Time Test: Should be very low");
    lcd.print(ElapsedBoilTime);
    delay(1000);
  }

//boilend
if (ElapsedBoilTime >= BOILTIME) { 
    boilend = true;
    boilrun = false;
    boilcycle = false;
  }

//chill start
if (boilend = true && mashtanktemp <= 100) { 
    chillstart = true;
    boilend = false;
  }

//chill run
if (chillstart = true) { 
    ChillStartTime = minutes;
    chillrun = true;
    chillstart = false;
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Chil Elapsed Time Test: Should be very low");
    lcd.print(ElapsedChillTime);
    delay(1000);
  }

//chill end
if (ElapsedChillTime >= CHILLTIME) { 
    chillend = true;
    chillrun = false;
  }



////////////////////ACTIONS CODES
//premash = Heater 1 & 2 on, pump on
if (premash = true) {
    tone(5, 500, 5000);
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print("Pump & Heat starting, need to open ball valve!!");
    delay(10000);
    analogWrite(HEATER1, 255);
    analogWrite(HEATER2, 255);
    analogWrite(PUMP, 255);
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("T:");
    lcd.print(mashtanktemp);
    lcd.print(degree);
    lcd.print("F");
    lcd.setCursor(0, 2);
    lcd.print(" Pump and Heaters On");
    delay(1000);
  }

//mashrun == mashstart is skipped because that is only used to initialize the time, mashrun heaters off, pump on  
if (mashrun = true) {
    analogWrite(HEATER1, 0);
    analogWrite(HEATER2, 0);
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Mash Temp hit");
    lcd.print(mashtanktemp);
    lcd.print(degree);
    lcd.print("F");
    delay(1000);
  }
  
//mashend = heaters both on, pump off
if(mashend = true){
    analogWrite(HEATER1, 255);
    analogWrite(HEATER2, 255);
    analogWrite(PUMP, 0);
    tone(5, 500, 2000);
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Mash Complete, heat on, pump off");
    lcd.print(mashtanktemp);
    lcd.print(degree);
    lcd.print("F");
    delay(1000);
  }  
  
//boilrun == skip preboil and boilstart as they are both just used to initialize the boil timer, boilrun hits heaters stay on (need to test to see if both heat needs to be on) pump off  
if (boilrun = true){
    analogWrite(HEATER1, 255);
    analogWrite(HEATER2, 255);
    analogWrite(PUMP, 0); 
    lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("Boiling, heaters on, pump off");
    lcd.print(mashtanktemp);
    lcd.print(degree);
    lcd.print("F");
    delay(1000);   
  }

//Hop Additions Code
if (boilrun == true) {
  
  for (h=0 ; h=sizeof(HOPTIME); 1) {
  HopAddtime = HOPTIME[h];
       if (ElapsedBoilTime >= (HopAddtime - 1) && ElapsedBoilTime <= (HopAddtime + 1)) { //BE SURE THAT THE +/- of the elapsedboil time doesnt result in overlay of two hop additions or else it could be confusing
        tone(5, 500, 2000);
        lcd.setCursor(0,1);
        lcd.print(ElapsedBoilTime);    
        lcd.print("Add");
        lcd.print(HOPINFO[h]);
       delay(15000);
       }
      }
    }
     
//boilend = heat off , pump off
if (boilend = true){
     chillrun = true;
     boilend = false;
     analogWrite(HEATER1, 0);
     analogWrite(HEATER2, 0);
     analogWrite(PUMP, 0);
     lcd.setCursor(0, 1);
     lcd.print("Boil Complete");
     lcd.print(mashtanktemp);
     lcd.print(degree);
     lcd.print("F");
     delay(1000);
   }

//chillrun = skip chillstart as that just initialized the chill timer, chill run turn pump on
if (chillrun = true){
    tone(5, 500, 2000);
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print("Pump starting, need to open ball valve!!");
    delay(10000);
    analogWrite(HEATER1, 0);
    analogWrite(HEATER2, 0);
    analogWrite(PUMP, 127);    
  }

//chillend == turn pump off once chill time is over THIS NEEDS TO BE TEST AND FIGURED OUT.
if (chillend = true){
    tone(5, 500, 5000);
    analogWrite(PUMP, 0); 
    analogWrite(HEATER1, 0);
    analogWrite(HEATER2, 0);
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print("Auto Brewing Complete");       
  }

 }
}

//////////////////////USER INPUTS from Blynk Terminal
BLYNK_WRITE(V0)  // Terminal
{
  String fromTerminal = param.asStr();
  
  if (fromTerminal.endsWith("MD") ){
    MASHTEMP = fromTerminal.toInt();
    Serial.print(MASHTEMP);
    Serial.println(" from XMASHTEMP");
  }
  else if (fromTerminal.endsWith("MT") ) {
    MASHTIME = fromTerminal.toInt();
    Serial.print(MASHTIME);
    Serial.println(" from XMASHTIME");
  }
  else if (fromTerminal.endsWith("BT") ) {
    BOILTIME = fromTerminal.toInt();
    Serial.print(BOILTIME);
    Serial.println(" from XBOILTIME");
  }
  else if (fromTerminal.endsWith("CT") ) {
    CHILLTIME = fromTerminal.toInt();
    Serial.print(CHILLTIME);
    Serial.println(" from XCHILLTIME");
  }
  else if (fromTerminal.endsWith("HN") ){
    int hopsize = fromTerminal.toInt();
    Serial.print(hopsize);
    Serial.println(" from Xhopsize");
  }
  else if (fromTerminal.endsWith("HA") ) {
   String HOPTIME[hopsize];
   // Keep track of current position in array
   int counter = 0;
   // Keep track of the last comma so we know where to start the substring
   int lastIndex = 0;
  
      for (int i = 0; i < fromTerminal.length(); i++) {
        // Loop through each character and check if it's a comma
        if (fromTerminal.substring(i, i+1) == ",") {
          // Grab the piece from the last index up to the current position and store it
          HOPTIME[counter] = fromTerminal.substring(lastIndex, i);
          // Update the last position and add 1, so it starts from the next character
          lastIndex = i + 1;
          // Increase the position in the array that we store into
          counter++;
        }

        // If we're at the end of the string (no more commas to stop us)
        if (i == fromTerminal.length() - 1) {
          // Grab the last part of the string from the lastIndex to the end
          HOPTIME[counter] = fromTerminal.substring(lastIndex, i);
        }
      }
           
      // Clear out counters to get ready for the next incoming string
      counter = 0;
      lastIndex = 0; 
  }
  
  else if (fromTerminal.startsWith("HI")){
   String HOPINFO[hopsize];
   // Keep track of current position in array
   int counter = 0;
   // Keep track of the last comma so we know where to start the substring
   int lastIndex = 0;
  
      for (int i = 0; i < fromTerminal.length(); i++) {
        // Loop through each character and check if it's a comma
        if (fromTerminal.substring(i, i+1) == ",") {
          // Grab the piece from the last index up to the current position and store it
          HOPINFO[counter] = fromTerminal.substring(lastIndex, i);
          // Update the last position and add 1, so it starts from the next character
          lastIndex = i + 1;
          // Increase the position in the array that we store into
          counter++;
        }

        // If we're at the end of the string (no more commas to stop us)
        if (i == fromTerminal.length() - 1) {
          // Grab the last part of the string from the lastIndex to the end
          HOPINFO[counter] = fromTerminal.substring(lastIndex, i);
        }
      }
      
      // Clear out counters to get ready for the next incoming string
      counter = 0;
      lastIndex = 0; 

            
       }
    Serial.println(" from CharArrayHOPADDSINFO");
  }


void setup() 
{
  Serial.begin(115200);
  Blynk.begin(auth,"XXXXXXXXXXX", "XXXXXXXXXXXXX");   // todo enter your router credentials
  timer.setInterval(10000, brewingstuff); // todo check every 10s
  // Start up the library
  sensor.begin();
  // set the resolution to 9 bit
  sensor.setResolution(TEMPSENSOR, 9); //Resolution of 9 means 0.5degC increments.

  //initialize pin locations as output or input
  pinMode(PUMP, OUTPUT);
  pinMode(HEATER1, OUTPUT);
  pinMode(HEATER2, OUTPUT);
  pinMode(START, INPUT);
  pinMode(PAUSE, INPUT);
  pinMode(PUMPBUTTON, INPUT);
  pinMode(HEATER1BUTTON, INPUT);
  pinMode(HEATER2BUTTON, INPUT);
  
  //Initialize LCD to 16 characters by 2 lines
  lcd.begin(16, 2);
  //lcd.setBacklightPin(3,POSITIVE); MIGHT NEED TO CONTROL BACKLIGHT ETC
  //lcd.setBacklight(HIGH);
  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print("Phil's beer is on the way, Ready?");
}


void loop() 
{ 
  Blynk.run();
  timer.run();
}

Below is the routine to search for commas if you still need it.

// find number of times a character (,) occurs in a character array
// you will need to convert the Terminal string to a char array before this routine is called

char *fromTerminal = "HT100,30,60,90,120"; // HT is HOPTIMES from HOPADDS
unsigned int i;

void searcharray(){
  for (i=0; fromTerminal[i]; fromTerminal[i]==',' ? i++ : *fromTerminal++);
  Serial.print("Number of commas in the HOPADDS char Array is ");
  Serial.print(i);  
}

void setup() {
  Serial.begin(115200);
  delay(20);
  Serial.println();
  Serial.println(fromTerminal);
  searcharray();
}

void loop() {

}

https://www.arduino.cc/en/Reference/StringObject

here is the whole String reference. SubString may be suitable to your needs if you want to chop off a couple characters in the beginning and/or end.

In the code, I am using substring in a for loop to chop up one connected string into an array of strings, if you look at the code below, that is hopefully what I am getting out. Which then I can call for example HOPTIME[0] and recieve just that first substring.

My issue is once I have the HOPTIME array setup, I cant seem to figure out a way to convert it to an int so that when I call HOPTIME[0] it gives me the number which then can be compared against a timer value to trigger something. I am getting errors like “invalid type long int[int]”

String HOPTIME[hopsize];
   // Keep track of current position in array
   int counter = 0;
   // Keep track of the last comma so we know where to start the substring
   int lastIndex = 0;
  
      for (int i = 0; i < fromTerminal.length(); i++) {
        // Loop through each character and check if it's a comma
        if (fromTerminal.substring(i, i+1) == ",") {
          // Grab the piece from the last index up to the current position and store it
          HOPTIME[counter] = fromTerminal.substring(lastIndex, i);
          // Update the last position and add 1, so it starts from the next character
          lastIndex = i + 1;
          // Increase the position in the array that we store into
          counter++;
        }

        // If we're at the end of the string (no more commas to stop us)
        if (i == fromTerminal.length() - 1) {
          // Grab the last part of the string from the lastIndex to the end
          HOPTIME[counter] = fromTerminal.substring(lastIndex, i);
        }
      }
           
      // Clear out counters to get ready for the next incoming string
      counter = 0;
      lastIndex = 0;

https://www.arduino.cc/en/Reference/StringToInt

This is your solution I think :slight_smile:

Yeah I tried using that

int HopAddtime
String HOPTIME

HopAddtime= HOPTIME(0).toInt();

Using this basic code I am getting the invalid type errors saying “invalid type long int[int]” I tried looking this up for hours but I still dont understand why it is giving this error.

When I simply do

HopAddtime = HOPTIME[0];

I dont get an error, but I am worried that HopAddtime is not an int and thus the following code calling HopAddtime wont give me the proper calculation.

Well, worrying has never gotten us anywhere anyway, so I suggest trying it and output your serial code to debug things.

Maybe even just write a little piece of code so you can gather your thoughts and see what is happening with that particular piece of code.

Yeah I am planning on doing so as soon as I have access to my board again, it is at my gf house where I dont live. I will post an update once I can run this.